Commit 23e876f0 authored by Greg Wilson's avatar Greg Wilson

creating example app demonstrating interaction with body measurement healthkit data

parent 3a584ee9
/**
* Created by greg on 2016-06-27.
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Navigator,
Text,
View
} from 'react-native';
let Dashboard = require('./components/dashboard/dashboard');
let Weight = require('./components/weight/weight');
let Height = require('./components/height/height');
let BodyMassIndex = require('./components/bodyMassIndex/bodyMassIndex');
let BodyFatPercentage = require('./components/bodyFatPercentage/bodyFatPercentage');
let LeanBodyMass = require('./components/leanBodyMass/leanBodyMass');
class BodyMeasurementsApp extends Component {
render() {
return (
<Navigator
style={{ flex:1 }}
initialRoute={{ name: 'Dashboard' }}
renderScene={ this.renderScene } />
);
}
renderScene(route, navigator) {
if(route.name == 'Dashboard') {
return <Dashboard navigator={navigator} />
}
if(route.name == 'Weight') {
return <Weight navigator={navigator} />
}
if(route.name == 'Height') {
return <Height navigator={navigator} />
}
if(route.name == 'BodyMassIndex') {
return <BodyMassIndex navigator={navigator} />
}
if(route.name == 'BodyFatPercentage') {
return <BodyFatPercentage navigator={navigator} />
}
if(route.name == 'LeanBodyMass') {
return <LeanBodyMass navigator={navigator} />
}
}
}
module.exports = BodyMeasurementsApp;
export default BodyMeasurementsApp;
/**
* Created by greg on 2016-06-27.
*/
import React, { Component } from 'react';
import {
Navigator,
TouchableOpacity,
Text,
View
} from 'react-native';
import styles from '../../styles/styles';
import BodyStore from '../../stores/body';
class BodyFatPercentage extends Component {
constructor(props) {
super(props);
this.state = this._getStateObject();
}
componentDidMount() {
this.unsub = BodyStore.listen(this._onBodyStoreEvent.bind(this));
}
componentWillUnmount() {
this.unsub();
}
_onBodyStoreEvent(evt) {
this.setState(this._getStateObject())
}
_getStateObject() {
return {
bodyFatFormatted: BodyStore.GetBodyFatPercentageFormatted(),
};
}
render() {
return (
<Navigator
renderScene={this.renderScene.bind(this)}
navigator={this.props.navigator}
navigationBar={
<Navigator.NavigationBar style={styles.navigationBar}
routeMapper={NavigationBarRouteMapper} />
}/>
);
}
renderScene(route, navigator) {
return (
<View style={styles.sceneContainerNavbar}>
<View style={styles.row_1_3}>
<Text style={styles.largeCenteredText}>
{this.state.bodyFatFormatted}
</Text>
</View>
<View style={[styles.row_2_3, styles.borderTopLightGrey]}>
<Text></Text>
</View>
</View>
);
}
}
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable} onPress={() => {navigator.parentNavigator.pop()}}>
<Text style={styles.navbarTitle}>
Back
</Text>
</TouchableOpacity>
);
},
RightButton(route, navigator, index, nextState) {
return null;
},
Title(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable}>
<Text style={styles.navbarTitle}>
Body Fat Percentage
</Text>
</TouchableOpacity>
);
}
};
module.exports = BodyFatPercentage;
export default BodyFatPercentage;
/**
* Created by greg on 2016-06-27.
*/
import React, { Component } from 'react';
import {
Navigator,
TouchableOpacity,
Text,
View
} from 'react-native';
import styles from '../../styles/styles';
import BodyStore from '../../stores/body';
class BodyMassIndex extends Component {
constructor(props) {
super(props);
this.state = this._getStateObject();
}
componentDidMount() {
this.unsub = BodyStore.listen(this._onBodyStoreEvent.bind(this));
}
componentWillUnmount() {
this.unsub();
}
_onBodyStoreEvent(evt) {
this.setState(this._getStateObject())
}
_getStateObject() {
return {
bmiFormatted: BodyStore.GetBMIFormatted(),
};
}
render() {
return (
<Navigator
renderScene={this.renderScene.bind(this)}
navigator={this.props.navigator}
navigationBar={
<Navigator.NavigationBar style={styles.navigationBar}
routeMapper={NavigationBarRouteMapper} />
}/>
);
}
renderScene(route, navigator) {
return (
<View style={styles.sceneContainerNavbar}>
<View style={styles.row_1_3}>
<Text style={styles.largeCenteredText}>
{this.state.bmiFormatted}
</Text>
</View>
<View style={[styles.row_2_3, styles.borderTopLightGrey]}>
<Text></Text>
</View>
</View>
);
}
}
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable} onPress={() => {navigator.parentNavigator.pop()}}>
<Text style={styles.navbarTitle}>
Back
</Text>
</TouchableOpacity>
);
},
RightButton(route, navigator, index, nextState) {
return null;
},
Title(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable}>
<Text style={styles.navbarTitle}>
Body Mass Index
</Text>
</TouchableOpacity>
);
}
};
module.exports = BodyMassIndex;
export default BodyMassIndex;
/**
* Created by greg on 2016-06-27.
*/
import React, { Component } from 'react';
import {
Navigator,
TouchableOpacity,
ScrollView,
Text,
View
} from 'react-native';
import TimerMixin from 'react-timer-mixin';
var reactMixin = require('react-mixin');
import styles from '../../styles/styles';
import BodyStore from '../../stores/body';
import DashboardItem from './item';
class Dashboard extends Component {
constructor(props) {
super(props);
this.state = this._getStateObject();
}
componentDidMount() {
this.unsub = BodyStore.listen(this._onBodyStoreEvent.bind(this));
}
componentWillUnmount() {
this.unsub();
}
_onBodyStoreEvent(evt) {
this.setState(this._getStateObject())
}
_getStateObject() {
return {
weightFormatted: BodyStore.GetWeightFormatted(),
heightFormatted: BodyStore.GetHeightFormatted(),
bmiFormatted: BodyStore.GetBMIFormatted(),
bodyFatFormatted: BodyStore.GetBodyFatPercentageFormatted(),
leanBodyMassFormatted: BodyStore.GetLeanBodyMassFormatted(),
};
}
_onPressItem(key) {
console.log('_onPressItem() ==> ', key);
let self = this;
this.requestAnimationFrame(() => {
this.props.navigator.push({
name: key
});
})
}
render() {
return (
<Navigator
renderScene={this.renderScene.bind(this)}
navigator={this.props.navigator}
navigationBar={
<Navigator.NavigationBar style={styles.navigationBar}
routeMapper={NavigationBarRouteMapper} />
}/>
);
}
renderScene(route, navigator) {
return (
<View style={styles.sceneContainerNavbar}>
<ScrollView automaticallyAdjustContentInsets={false} style={{flex:1,}}>
<DashboardItem icon="scale"
label="Weight"
value={this.state.weightFormatted}
onPress={this._onPressItem.bind(this, 'Weight')} />
<DashboardItem icon="ruler"
label="Height"
value={this.state.heightFormatted}
onPress={this._onPressItem.bind(this, 'Height')} />
<DashboardItem icon="bmi"
label="BMI"
value={this.state.bmiFormatted}
onPress={this._onPressItem.bind(this, 'BodyMassIndex')} />
<DashboardItem icon="bodyfat"
label="Body Fat Percentage"
value={this.state.bodyFatFormatted}
onPress={this._onPressItem.bind(this, 'BodyFatPercentage')} />
<DashboardItem icon="musclemass"
label="Lean Body Mass"
value={this.state.leanBodyMassFormatted}
onPress={this._onPressItem.bind(this, 'LeanBodyMass')} />
</ScrollView>
</View>
);
}
}
reactMixin(Dashboard.prototype, TimerMixin);
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, nextState) {
return null;
},
RightButton(route, navigator, index, nextState) {
return null;
},
Title(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable}>
<Text style={styles.navbarTitle}>
HealthKit Body Measurements
</Text>
</TouchableOpacity>
);
}
};
module.exports = Dashboard;
export default Dashboard;
/**
* Created by greg on 2016-06-27.
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Navigator,
TouchableOpacity,
TouchableHighlight,
ScrollView,
Image,
Text,
View
} from 'react-native';
import styles from '../../styles/styles';
const ICONS = {
"scale": require("../../assets/images/scale.png"),
"ruler": require("../../assets/images/ruler.png"),
"bmi": require("../../assets/images/bmi.png"),
"bodyfat": require("../../assets/images/bodyfat.png"),
"musclemass": require("../../assets/images/muscle-mass.png"),
"arrowright": require('../../assets/images/arrow-right.png'),
"heartbeat": require('../../assets/images/heartbeat.png')
};
class DashboardItem extends Component {
constructor(props) {
super(props);
this.state = this._getStateObject(this.props);
}
componentWillReceiveProps(newProps) {
this.setState(this._getStateObject(newProps));
}
_getStateObject(props) {
let label = props.label ? props.label : 'Label';
let value = props.value ? props.value : 'Value';
let iconSource = (props.icon && ICONS.hasOwnProperty(props.icon)) ? ICONS[props.icon] : ICONS.heartbeat;
return {label,value,iconSource};
}
render() {
return (
<TouchableHighlight onPress={this.props.onPress} style={ styles.dashboardListItemHighlight } underlayColor="#0088cc">
<View style={ styles.dashboardListItemView }>
<View style={ styles.dashboardListItem }>
<Image source={this.state.iconSource}
style={styles.dashboardListItemIcon}/>
<Text style={styles.dashboardListItemLabel}>
{this.state.label}
</Text>
<Text style={styles.dashboardListItemValue}>
{this.state.value}
</Text>
<Image source={ICONS.arrowright}
style={styles.dashboardListItemIcon}/>
</View>
</View>
</TouchableHighlight>
)
}
}
DashboardItem.propTypes = {
icon: React.PropTypes.string,
label: React.PropTypes.string,
value: React.PropTypes.string,
onPress: React.PropTypes.func
};
DashboardItem.defaultProps = {
onPress: function(){
console.log('default onPress()');
}
};
module.exports = DashboardItem;
export default DashboardItem;
/**
* Created by greg on 2016-06-27.
*/
import React, { Component } from 'react';
import {
Navigator,
TouchableOpacity,
Text,
View
} from 'react-native';
import styles from '../../styles/styles';
import BodyStore from '../../stores/body';
class Height extends Component {
constructor(props) {
super(props);
this.state = this._getStateObject();
}
componentDidMount() {
this.unsub = BodyStore.listen(this._onBodyStoreEvent.bind(this));
}
componentWillUnmount() {
this.unsub();
}
_onBodyStoreEvent(evt) {
this.setState(this._getStateObject())
}
_getStateObject() {
return {
heightFormatted: BodyStore.GetHeightFormatted(),
};
}
render() {
return (
<Navigator
renderScene={this.renderScene.bind(this)}
navigator={this.props.navigator}
navigationBar={
<Navigator.NavigationBar style={styles.navigationBar}
routeMapper={NavigationBarRouteMapper} />
}/>
);
}
renderScene(route, navigator) {
return (
<View style={styles.sceneContainerNavbar}>
<View style={styles.row_1_3}>
<Text style={styles.largeCenteredText}>
{this.state.heightFormatted}
</Text>
</View>
<View style={[styles.row_2_3, styles.borderTopLightGrey]}>
<Text></Text>
</View>
</View>
);
}
}
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable} onPress={() => {navigator.parentNavigator.pop()}}>
<Text style={styles.navbarTitle}>
Back
</Text>
</TouchableOpacity>
);
},
RightButton(route, navigator, index, nextState) {
return null;
},
Title(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable}>
<Text style={styles.navbarTitle}>
Height
</Text>
</TouchableOpacity>
);
}
};
module.exports = Height;
export default Height;
/**
* Created by greg on 2016-06-27.
*/
import React, { Component } from 'react';
import {
Navigator,
TouchableOpacity,
Text,
View
} from 'react-native';
import styles from '../../styles/styles';
import BodyStore from '../../stores/body';
class LeanBodyMass extends Component {
constructor(props) {
super(props);
this.state = this._getStateObject();
}
componentDidMount() {
this.unsub = BodyStore.listen(this._onBodyStoreEvent.bind(this));
}
componentWillUnmount() {
this.unsub();
}
_onBodyStoreEvent(evt) {
this.setState(this._getStateObject())
}
_getStateObject() {
return {
leanBodyMassFormatted: BodyStore.GetLeanBodyMassFormatted(),
};
}
render() {
return (
<Navigator
renderScene={this.renderScene.bind(this)}
navigator={this.props.navigator}
navigationBar={
<Navigator.NavigationBar style={styles.navigationBar}
routeMapper={NavigationBarRouteMapper} />
}/>
);
}
renderScene(route, navigator) {
return (
<View style={styles.sceneContainerNavbar}>
<View style={styles.row_1_3}>
<Text style={styles.largeCenteredText}>
{this.state.leanBodyMassFormatted}
</Text>
</View>
<View style={[styles.row_2_3, styles.borderTopLightGrey]}>
<Text></Text>
</View>
</View>
);
}
}
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable} onPress={() => {navigator.parentNavigator.pop()}}>
<Text style={styles.navbarTitle}>
Back
</Text>
</TouchableOpacity>
);
},
RightButton(route, navigator, index, nextState) {
return null;
},
Title(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable}>
<Text style={styles.navbarTitle}>
Lean Body Mass
</Text>
</TouchableOpacity>
);
}
};
module.exports = LeanBodyMass;
export default LeanBodyMass;
/**
* Created by greg on 2016-06-27.
*/
import React, { Component } from 'react';
import {
Navigator,
TouchableOpacity,
Text,
View
} from 'react-native';
import styles from '../../styles/styles';
import BodyStore from '../../stores/body';
class Weight extends Component {
constructor(props) {
super(props);
this.state = this._getStateObject();
}
componentDidMount() {
this.unsub = BodyStore.listen(this._onBodyStoreEvent.bind(this));
}
componentWillUnmount() {
this.unsub();
}
_onBodyStoreEvent(evt) {
this.setState(this._getStateObject())
}
_getStateObject() {
return {
weightFormatted: BodyStore.GetWeightFormatted(),
};
}
render() {
return (
<Navigator
renderScene={this.renderScene.bind(this)}
navigator={this.props.navigator}
navigationBar={
<Navigator.NavigationBar style={styles.navigationBar}
routeMapper={NavigationBarRouteMapper} />
}/>
);
}
renderScene(route, navigator) {
return (
<View style={styles.sceneContainerNavbar}>
<View style={styles.row_1_3}>
<Text style={styles.largeCenteredText}>
{this.state.weightFormatted}
</Text>
</View>
<View style={[styles.row_2_3, styles.borderTopLightGrey]}>
<Text></Text>
</View>
</View>
);
}
}
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable} onPress={() => {navigator.parentNavigator.pop()}}>
<Text style={styles.navbarTitle}>
Back
</Text>
</TouchableOpacity>
);
},
RightButton(route, navigator, index, nextState) {
return null;
},
Title(route, navigator, index, nextState) {
return (
<TouchableOpacity style={styles.navbarTitleTouchable}>
<Text style={styles.navbarTitle}>
Weight
</Text>
</TouchableOpacity>
);
}
};
module.exports = Weight;
export default Weight;
/**
* Created by greg on 2016-06-27.
*/
var airflux = require( 'airflux' );
var _ = require('lodash');
var moment = require('moment');
var Immutable = require('immutable');
//var actions = require('../actions/actions');
var AppleHealthKit = require('react-native-apple-healthkit');
var DATA = {
weight: 0,
height: 0,
bmi: 0,
bodyFatPercentage: 0,
leanBodyMass: 0,
steps: 0,
};
/**
* @namespace Stores
*/
/**
* @class WeightStore
* @classdesc Airflux store to handle data, actions, and events relating to the WeightStore
* @memberof Stores
*/
class BodyStore extends airflux.Store {
/**
* Initialize the WeightStore, optionally with 'props' object
* @constructs Stores.TestingEventService
* @param {object} props - an optional properties object to initialize the store with
*
*/
constructor(props) {
//console.log("WeightStore props --> ", props);
super(props);
let self = this;
//this.listenTo(actions.addWeight, this._onactn_addWeight)
this._initHealthKit = this._initHealthKit.bind(this);
this._fetchHealthKitUserWeight = this._fetchHealthKitUserWeight.bind(this);
this._fetchHealthKitUserHeight = this._fetchHealthKitUserHeight.bind(this);
this._fetchHealthKitUserBmi = this._fetchHealthKitUserBmi.bind(this);
this._fetchHealthKitStepCountToday = this._fetchHealthKitStepCountToday.bind(this);
this._fetchHealthKitBodyFatPercentage = this._fetchHealthKitBodyFatPercentage.bind(this);
this._fetchHealthKitLeanBodyMass = this._fetchHealthKitLeanBodyMass.bind(this);
this.GetWeightValue = this.GetWeightValue.bind(this);
this.GetWeightFormatted = this.GetWeightFormatted.bind(this);
this.GetSteps = this.GetSteps.bind(this);
this.GetHeightFormatted = this.GetHeightFormatted.bind(this);
this.GetHeightValue = this.GetHeightValue.bind(this);
this.GetBMIValue = this.GetBMIValue.bind(this);
this.GetBMIFormatted = this.GetBMIFormatted.bind(this);
this.GetBodyFatPercentageValue = this.GetBodyFatPercentageValue.bind(this);
this.GetBodyFatPercentageFormatted = this.GetBodyFatPercentageFormatted.bind(this);
this.GetLeanBodyMassValue = this.GetLeanBodyMassValue.bind(this);
this.GetLeanBodyMassFormatted = this.GetLeanBodyMassFormatted.bind(this);
AppleHealthKit.isAvailable((err,available) => {
console.log('AppleHealthKit.isAvailable(): ', available);
if(available){
self._initHealthKit();
}
});
//AppleHealthKit.getInfo({init:"true"}, (err,res) => {
// if(err) {
// console.log("ERROR GETTING HEALTHKIT MODULE INFO");
// console.log(err);
// return;
// }
// console.log("HEALTHKIT MODULE INFO: ", res);
//});
}
_initHealthKit() {
let self = this;
let healthKitOptions = {
permissions: {
read: ["Height", "Weight", "Steps", "DateOfBirth", "BodyMassIndex", "LeanBodyMass", "BodyFatPercentage"],
write: ["Weight"]
}
};
AppleHealthKit.initHealthKit(healthKitOptions, (err, res) => {
if(this._handleHealthKitError(err, 'initHealthKit')){
return;
}
console.log("HEALTHKIT INITIALIZED!! ", res);
self._fetchHealthKitUserWeight();
self._fetchHealthKitUserBmi();
self._fetchHealthKitStepCountToday();
self._fetchHealthKitUserHeight();
self._fetchHealthKitBodyFatPercentage();
self._fetchHealthKitLeanBodyMass();
});
}
_handleHealthKitError(err, method) : boolean {
if(err){
let errStr = 'HealthKit_ERROR['+method+'] : ';
if(typeof err === 'string'){
errStr += err;
} else if (typeof err === 'object' && err.message){
errStr += err.message;
}
console.log(errStr);
return true;
}
return false;
}
_onactn_addWeight(options) {
console.log('_onactn_addWeight() --> ', options);
if(options && options.weight){
let weightVal = parseFloat(options.weight);
let self = this;
AppleHealthKit.saveWeight({weight:weightVal}, (err, res) => {
if(this._handleHealthKitError(err, 'saveWeight')){
return;
}
DATA.weight = weightVal;
self.trigger({
name: 'change:weight',
target: null,
data: DATA.weight
});
});
}
}
_fetchHealthKitUserWeight() {
let self = this;
AppleHealthKit.getCurrentWeight(null, (err, weight) => {
if(this._handleHealthKitError(err, 'getCurrentWeight')){
return;
}
weight = _.round(weight,1);
DATA.weight = weight;
self.trigger({
name: 'change:weight',
target: null,
data: weight
});
});
}
_fetchHealthKitUserHeight() {
let self = this;
AppleHealthKit.getMostRecentHeight(null, (err, height) => {
if(this._handleHealthKitError(err, 'getMostRecentHeight')){
return;
}
console.log("HEIGHT: ", height);
if(typeof height === "number" && height > 0){
DATA.height = height;
self.trigger({
name: 'change:height',
target: null,
data: height
});
}
});
}
_fetchHealthKitUserBmi() {
let self = this;
AppleHealthKit.getLatestBmi({blah:true}, (err, bmi) => {
if(this._handleHealthKitError(err, 'getLatestBmi')){
return;
}
console.log("LATEST BMI: ", bmi);
if(bmi && bmi.value){
DATA.bmi = _.round(bmi.value,1);
self.trigger({
name: 'change:bmi',
target: null,
data: DATA.bmi
});
}
});
}
_fetchHealthKitBodyFatPercentage() {
let self = this;
AppleHealthKit.getMostRecentBodyFatPercentage({blah:true}, (err, fatPercentage) => {
if(this._handleHealthKitError(err, 'getMostRecentBodyFatPercentage')){
return;
}
console.log("BODY FAT PERCENTAGE: ", fatPercentage);
DATA.bodyFatPercentage = fatPercentage;
self.trigger({
name: 'change:body_fat_percentage',
target: null,
data: DATA.bodyFatPercentage
});
});
}
_fetchHealthKitLeanBodyMass() {
let self = this;
AppleHealthKit.getMostRecentLeanBodyMass({blah:true}, (err, leanMass) => {
if(this._handleHealthKitError(err, 'getMostRecentLeanBodyMass')){
return;
}
console.log("LEAN BODY MASS: ", leanMass);
DATA.leanBodyMass = _.round(leanMass,0);
self.trigger({
name: 'change:lean_body_mass',
target: null,
data: DATA.leanBodyMass
});
});
}
_fetchHealthKitStepCountToday() {
let self = this;
AppleHealthKit.getStepCountForToday({options:"true"}, (err, steps) => {
if(this._handleHealthKitError(err, 'getStepCountForToday')){
return;
}
console.log("STEPS : ", steps);
steps = _.round(steps,0);
DATA.steps = steps;
self.trigger({
name: 'change:steps',
target: null,
data: steps
});
});
}
GetHeightValue() {
return DATA.height;
}
GetHeightFormatted() {
let feet = _.floor((DATA.height / 12));
let inches = DATA.height % 12;
let formatted = '' + feet + '\'' + inches + '"';
return formatted;
}
GetWeightValue() {
return DATA.weight;
}
GetWeightFormatted() {
return DATA.weight + ' lbs';
}
GetBMIValue() {
return DATA.bmi;
}
GetBMIFormatted() {
return '' + DATA.bmi;
}
GetBodyFatPercentageValue() {
return DATA.bodyFatPercentage;
}
GetBodyFatPercentageFormatted() {
return '' + DATA.bodyFatPercentage + '%';
}
GetLeanBodyMassValue() {
return DATA.leanBodyMass;
}
GetLeanBodyMassFormatted() {
return '' + DATA.leanBodyMass + ' lbs';
}
GetSteps() {
return DATA.steps;
}
}
let storeInstance = new BodyStore();
export default storeInstance;
module.exports = storeInstance;
\ No newline at end of file
/**
* Created by greg on 2016-06-27.
*/
import {
Platform,
StyleSheet
} from 'react-native';
const styles = StyleSheet.create({
sceneContainerNavbar: {
flex: 1,
flexDirection: 'column',
//justifyContent: 'flex-start',
//alignItems: 'flex-start',
marginTop: (Platform.OS === 'ios') ? 64 : 54,
backgroundColor: '#FFFFFF'
},
navigationBar: {
borderBottomWidth: 1,
borderBottomColor: '#cccccc',
backgroundColor: '#f5f5f5'
},
navbarTitleTouchable: {
flex: 1,
justifyContent: 'center'
},
navbarTitle: {
color: '#FD2D55',
margin: 10,
fontSize: 18
},
row_1_3: {
flex: 0.33,
flexDirection:'column',
padding:10,
//backgroundColor: '#FF8000'
},
row_2_3: {
flex: 0.66,
flexDirection:'column',
padding:10,
//backgroundColor: '#0088cc'
},
borderTopLightGrey: {
borderTopColor: '#CCCCCC',
borderTopWidth: 1,
},
largeCenteredText: {
textAlign: 'center',
flexDirection:'row',
fontSize:34,
marginTop:60,
},
dashboardListItemLabel: {
fontSize:12,
color: '#FD2D55',
position:'absolute',
left: 70,
top:0,
},
dashboardListItemValue: {
fontSize:22,
color: '#47a292',
position:'absolute',
left: 70,
top:15,
},
sceneContainerFull: {
flex: 1,
flexDirection: 'column',
//justifyContent: 'flex-start',
//alignItems: 'flex-start',
marginTop: 0,
backgroundColor: '#FFFFFF'
},
dashboardToday: {
height: 30,
alignItems: 'stretch',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(162, 162, 162, 0.2)',
},
dashboardTodayText: {
color: '#a2a2a2',
},
dashboardListItemHighlight: {
flexDirection: 'row',
alignSelf: 'stretch',
justifyContent: 'center',
//flex:1,
//alignSelf: 'stretch',
//overflow: 'hidden',
},
dashboardListItemView: {
flex: 1,
//backgroundColor: '#FDFDFD',
backgroundColor: '#FDFDFD',
//paddingTop:74,
//flexDirection: 'row',
flexDirection: 'column',
alignSelf: 'stretch',
justifyContent: 'flex-start',
alignItems: 'flex-start',
paddingTop:15,
paddingBottom: 15,
//flexWrap: 'wrap',
borderBottomColor: '#AAAAAA',
borderBottomWidth: 1,
},
dashboardListItemViewTransparent: {
flex: 1,
//backgroundColor: '#FDFDFD',
backgroundColor: 'transparent',
//paddingTop:74,
//flexDirection: 'row',
flexDirection: 'column',
alignSelf: 'stretch',
justifyContent: 'flex-start',
alignItems: 'flex-start',
paddingTop:15,
paddingBottom: 15,
//flexWrap: 'wrap',
borderBottomColor: '#AAAAAA',
borderBottomWidth: 1,
},
dashboardListItem: {
flexDirection: 'row',
alignSelf: 'stretch',
justifyContent: 'space-between',
flex:1,
backgroundColor: 'transparent',
},
dashboardListItemIcon: {
width: 40,
height: 40,
marginLeft: 10,
opacity:0.7,
//marginTop: 50,
//backgroundColor: 'transparent',
alignSelf: 'flex-start',
},
dashboardListItemText: {
flex: 1,
flexDirection: 'column',
alignSelf: 'flex-start',
marginLeft: 20,
fontSize: 29,
color: '#47a292',
//color: '#98CA3F',
//color: '#644496',
flexWrap: 'wrap',
backgroundColor:'transparent',
},
});
module.exports = styles;
export default styles;
...@@ -13,67 +13,14 @@ import { ...@@ -13,67 +13,14 @@ import {
View View
} from 'react-native'; } from 'react-native';
let App = require('./app/app');
let Index = require('./src/components/Index');
class BodyMeasurements extends Component { class BodyMeasurements extends Component {
render() { render() {
return ( return (
<Navigator <App />
style={{ flex:1 }} )
initialRoute={{ name: 'Index' }}
renderScene={ this.renderScene } />
);
//
//
//return (
// <View style={styles.container}>
// <Text style={styles.welcome}>
// Welcome to React Native!
// </Text>
// <Text style={styles.instructions}>
// To get started, edit index.ios.js
// </Text>
// <Text style={styles.instructions}>
// Press Cmd+R to reload,{'\n'}
// Cmd+D or shake for dev menu
// </Text>
// </View>
//);
}
renderScene(route, navigator) {
if(route.name == 'Index') {
return <Index navigator={navigator} />
}
//if(route.name == 'Home') {
// return <Index navigator={navigator} />
//}
} }
} }
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
AppRegistry.registerComponent('BodyMeasurements', () => BodyMeasurements); AppRegistry.registerComponent('BodyMeasurements', () => BodyMeasurements);
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
37E9B8741D21B52F0090B19B /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37E9B8731D21B52F0090B19B /* HealthKit.framework */; };
37E9B89D1D21C63C0090B19B /* libRCTAppleHealthKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 37E9B89C1D21C6380090B19B /* libRCTAppleHealthKit.a */; };
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
...@@ -89,6 +91,13 @@ ...@@ -89,6 +91,13 @@
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192; remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
remoteInfo = React; remoteInfo = React;
}; };
37E9B89B1D21C6380090B19B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 37E9B8971D21C6380090B19B /* RCTAppleHealthKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3774C88D1D2092F20000B3F3;
remoteInfo = RCTAppleHealthKit;
};
78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = { 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
...@@ -125,6 +134,9 @@ ...@@ -125,6 +134,9 @@
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = BodyMeasurements/Info.plist; sourceTree = "<group>"; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = BodyMeasurements/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = BodyMeasurements/main.m; sourceTree = "<group>"; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = BodyMeasurements/main.m; sourceTree = "<group>"; };
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; }; 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
37E9B8731D21B52F0090B19B /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = System/Library/Frameworks/HealthKit.framework; sourceTree = SDKROOT; };
37E9B8751D21B52F0090B19B /* BodyMeasurements.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = BodyMeasurements.entitlements; path = BodyMeasurements/BodyMeasurements.entitlements; sourceTree = "<group>"; };
37E9B8971D21C6380090B19B /* RCTAppleHealthKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAppleHealthKit.xcodeproj; path = "../node_modules/react-native-apple-healthkit/RCTAppleHealthKit.xcodeproj"; sourceTree = "<group>"; };
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; }; 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; }; 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
...@@ -142,8 +154,10 @@ ...@@ -142,8 +154,10 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
37E9B89D1D21C63C0090B19B /* libRCTAppleHealthKit.a in Frameworks */,
146834051AC3E58100842450 /* libReact.a in Frameworks */, 146834051AC3E58100842450 /* libReact.a in Frameworks */,
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
37E9B8741D21B52F0090B19B /* HealthKit.framework in Frameworks */,
00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */,
00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */,
133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */, 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */,
...@@ -234,6 +248,7 @@ ...@@ -234,6 +248,7 @@
13B07FAE1A68108700A75B9A /* BodyMeasurements */ = { 13B07FAE1A68108700A75B9A /* BodyMeasurements */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
37E9B8751D21B52F0090B19B /* BodyMeasurements.entitlements */,
008F07F21AC5B25A0029DE68 /* main.jsbundle */, 008F07F21AC5B25A0029DE68 /* main.jsbundle */,
13B07FAF1A68108700A75B9A /* AppDelegate.h */, 13B07FAF1A68108700A75B9A /* AppDelegate.h */,
13B07FB01A68108700A75B9A /* AppDelegate.m */, 13B07FB01A68108700A75B9A /* AppDelegate.m */,
...@@ -253,6 +268,14 @@ ...@@ -253,6 +268,14 @@
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
37E9B8981D21C6380090B19B /* Products */ = {
isa = PBXGroup;
children = (
37E9B89C1D21C6380090B19B /* libRCTAppleHealthKit.a */,
);
name = Products;
sourceTree = "<group>";
};
78C398B11ACF4ADC00677621 /* Products */ = { 78C398B11ACF4ADC00677621 /* Products */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
...@@ -264,6 +287,7 @@ ...@@ -264,6 +287,7 @@
832341AE1AAA6A7D00B99B32 /* Libraries */ = { 832341AE1AAA6A7D00B99B32 /* Libraries */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
37E9B8971D21C6380090B19B /* RCTAppleHealthKit.xcodeproj */,
146833FF1AC3E56700842450 /* React.xcodeproj */, 146833FF1AC3E56700842450 /* React.xcodeproj */,
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */,
00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */,
...@@ -289,6 +313,7 @@ ...@@ -289,6 +313,7 @@
83CBB9F61A601CBA00E9B192 = { 83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
37E9B8731D21B52F0090B19B /* HealthKit.framework */,
13B07FAE1A68108700A75B9A /* BodyMeasurements */, 13B07FAE1A68108700A75B9A /* BodyMeasurements */,
832341AE1AAA6A7D00B99B32 /* Libraries */, 832341AE1AAA6A7D00B99B32 /* Libraries */,
00E356EF1AD99517003FC87E /* BodyMeasurementsTests */, 00E356EF1AD99517003FC87E /* BodyMeasurementsTests */,
...@@ -359,6 +384,14 @@ ...@@ -359,6 +384,14 @@
CreatedOnToolsVersion = 6.2; CreatedOnToolsVersion = 6.2;
TestTargetID = 13B07F861A680F5B00A75B9A; TestTargetID = 13B07F861A680F5B00A75B9A;
}; };
13B07F861A680F5B00A75B9A = {
DevelopmentTeam = 95ZTJFHCUG;
SystemCapabilities = {
com.apple.HealthKit = {
enabled = 1;
};
};
};
}; };
}; };
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "BodyMeasurements" */; buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "BodyMeasurements" */;
...@@ -377,6 +410,10 @@ ...@@ -377,6 +410,10 @@
ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */;
ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;
}, },
{
ProductGroup = 37E9B8981D21C6380090B19B /* Products */;
ProjectRef = 37E9B8971D21C6380090B19B /* RCTAppleHealthKit.xcodeproj */;
},
{ {
ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */; ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */;
ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
...@@ -479,6 +516,13 @@ ...@@ -479,6 +516,13 @@
remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */; remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR; sourceTree = BUILT_PRODUCTS_DIR;
}; };
37E9B89C1D21C6380090B19B /* libRCTAppleHealthKit.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTAppleHealthKit.a;
remoteRef = 37E9B89B1D21C6380090B19B /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = { 78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = {
isa = PBXReferenceProxy; isa = PBXReferenceProxy;
fileType = archive.ar; fileType = archive.ar;
...@@ -605,6 +649,7 @@ ...@@ -605,6 +649,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = BodyMeasurements/BodyMeasurements.entitlements;
DEAD_CODE_STRIPPING = NO; DEAD_CODE_STRIPPING = NO;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
...@@ -625,6 +670,7 @@ ...@@ -625,6 +670,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = BodyMeasurements/BodyMeasurements.entitlements;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.healthkit</key>
<true/>
</dict>
</plist>
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
<true/> <true/>
<key>NSAppTransportSecurity</key> <key>NSAppTransportSecurity</key>
<dict> <dict>
<!--Include to allow all connections (DANGER)-->
<key>NSAllowsArbitraryLoads</key> <key>NSAllowsArbitraryLoads</key>
<true/> <true/>
</dict> </dict>
...@@ -35,6 +34,7 @@ ...@@ -35,6 +34,7 @@
<key>UIRequiredDeviceCapabilities</key> <key>UIRequiredDeviceCapabilities</key>
<array> <array>
<string>armv7</string> <string>armv7</string>
<string>healthkit</string>
</array> </array>
<key>UISupportedInterfaceOrientations</key> <key>UISupportedInterfaceOrientations</key>
<array> <array>
......
...@@ -6,7 +6,10 @@ ...@@ -6,7 +6,10 @@
"start": "node node_modules/react-native/local-cli/cli.js start" "start": "node node_modules/react-native/local-cli/cli.js start"
}, },
"dependencies": { "dependencies": {
"airflux": "^0.5.1",
"react": "15.1.0", "react": "15.1.0",
"react-native": "^0.28.0" "react-mixin": "^2.0.2",
"react-native": "^0.28.0",
"react-native-apple-healthkit": "file:///Users/greg/Dev/experimental/RCTAppleHealthKit"
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment