diff --git a/examples/BodyMeasurements/app/app.js b/examples/BodyMeasurements/app/app.js new file mode 100644 index 0000000000000000000000000000000000000000..7fde17cc7460f81ce5b2b74bb3ee7b57b0b177e6 --- /dev/null +++ b/examples/BodyMeasurements/app/app.js @@ -0,0 +1,56 @@ +/** + * 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 ( + + ); + } + + renderScene(route, navigator) { + if(route.name == 'Dashboard') { + return + } + if(route.name == 'Weight') { + return + } + if(route.name == 'Height') { + return + } + if(route.name == 'BodyMassIndex') { + return + } + if(route.name == 'BodyFatPercentage') { + return + } + if(route.name == 'LeanBodyMass') { + return + } + } +} + +module.exports = BodyMeasurementsApp; +export default BodyMeasurementsApp; diff --git a/examples/BodyMeasurements/app/assets/images/arrow-right.png b/examples/BodyMeasurements/app/assets/images/arrow-right.png new file mode 100755 index 0000000000000000000000000000000000000000..3d3b577f21fbd604d49b166d41395979b05cac9d Binary files /dev/null and b/examples/BodyMeasurements/app/assets/images/arrow-right.png differ diff --git a/examples/BodyMeasurements/app/assets/images/bmi.png b/examples/BodyMeasurements/app/assets/images/bmi.png new file mode 100644 index 0000000000000000000000000000000000000000..562966ac36733b57013950dd01367954a338e91d Binary files /dev/null and b/examples/BodyMeasurements/app/assets/images/bmi.png differ diff --git a/examples/BodyMeasurements/app/assets/images/bodyfat.png b/examples/BodyMeasurements/app/assets/images/bodyfat.png new file mode 100644 index 0000000000000000000000000000000000000000..d1b2a37eb3f8df8b9c08a414b112bc19e706b941 Binary files /dev/null and b/examples/BodyMeasurements/app/assets/images/bodyfat.png differ diff --git a/examples/BodyMeasurements/app/assets/images/dumbbell.png b/examples/BodyMeasurements/app/assets/images/dumbbell.png new file mode 100644 index 0000000000000000000000000000000000000000..f4660f46943b93ab23cd432582d983fb520fec07 Binary files /dev/null and b/examples/BodyMeasurements/app/assets/images/dumbbell.png differ diff --git a/examples/BodyMeasurements/app/assets/images/heartbeat.png b/examples/BodyMeasurements/app/assets/images/heartbeat.png new file mode 100755 index 0000000000000000000000000000000000000000..b724ae73c69d98c595751a4c76ec37bd3031a735 Binary files /dev/null and b/examples/BodyMeasurements/app/assets/images/heartbeat.png differ diff --git a/examples/BodyMeasurements/app/assets/images/measuring-tape.png b/examples/BodyMeasurements/app/assets/images/measuring-tape.png new file mode 100644 index 0000000000000000000000000000000000000000..9151edd8b84e983f23e312e5d8301aa7adcf3768 Binary files /dev/null and b/examples/BodyMeasurements/app/assets/images/measuring-tape.png differ diff --git a/examples/BodyMeasurements/app/assets/images/muscle-mass.png b/examples/BodyMeasurements/app/assets/images/muscle-mass.png new file mode 100644 index 0000000000000000000000000000000000000000..fe14c4b2a8034a96f475dc1a428c649fa859ef0b Binary files /dev/null and b/examples/BodyMeasurements/app/assets/images/muscle-mass.png differ diff --git a/examples/BodyMeasurements/app/assets/images/ruler.png b/examples/BodyMeasurements/app/assets/images/ruler.png new file mode 100644 index 0000000000000000000000000000000000000000..9239c29d0ced5e00e502bea68e74ad072e9d3606 Binary files /dev/null and b/examples/BodyMeasurements/app/assets/images/ruler.png differ diff --git a/examples/BodyMeasurements/app/assets/images/scale.png b/examples/BodyMeasurements/app/assets/images/scale.png new file mode 100755 index 0000000000000000000000000000000000000000..37f5710ac52f39f948d198c8bc417e40b2f829c8 Binary files /dev/null and b/examples/BodyMeasurements/app/assets/images/scale.png differ diff --git a/examples/BodyMeasurements/app/assets/images/scale_purple.png b/examples/BodyMeasurements/app/assets/images/scale_purple.png new file mode 100755 index 0000000000000000000000000000000000000000..e78ac21bb2ed0f1b4b30fb82d32cbcdedd7ac5a1 Binary files /dev/null and b/examples/BodyMeasurements/app/assets/images/scale_purple.png differ diff --git a/examples/BodyMeasurements/app/assets/images/steps.png b/examples/BodyMeasurements/app/assets/images/steps.png new file mode 100755 index 0000000000000000000000000000000000000000..a32c9940fe139b7d11f60be169ea8614e8139731 Binary files /dev/null and b/examples/BodyMeasurements/app/assets/images/steps.png differ diff --git a/examples/BodyMeasurements/app/assets/images/strength.png b/examples/BodyMeasurements/app/assets/images/strength.png new file mode 100644 index 0000000000000000000000000000000000000000..84f24856180a3fa4216520d8c700210e44098d38 Binary files /dev/null and b/examples/BodyMeasurements/app/assets/images/strength.png differ diff --git a/examples/BodyMeasurements/app/components/bodyFatPercentage/bodyFatPercentage.js b/examples/BodyMeasurements/app/components/bodyFatPercentage/bodyFatPercentage.js new file mode 100644 index 0000000000000000000000000000000000000000..68c7c0accb5720297fee0c9123ca8252ccc8ca7c --- /dev/null +++ b/examples/BodyMeasurements/app/components/bodyFatPercentage/bodyFatPercentage.js @@ -0,0 +1,97 @@ +/** + * 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 ( + + }/> + ); + } + + renderScene(route, navigator) { + return ( + + + + {this.state.bodyFatFormatted} + + + + + + + + ); + } +} + +var NavigationBarRouteMapper = { + LeftButton(route, navigator, index, nextState) { + return ( + {navigator.parentNavigator.pop()}}> + + Back + + + ); + }, + RightButton(route, navigator, index, nextState) { + return null; + }, + Title(route, navigator, index, nextState) { + return ( + + + Body Fat Percentage + + + ); + } +}; + + +module.exports = BodyFatPercentage; +export default BodyFatPercentage; diff --git a/examples/BodyMeasurements/app/components/bodyMassIndex/bodyMassIndex.js b/examples/BodyMeasurements/app/components/bodyMassIndex/bodyMassIndex.js new file mode 100644 index 0000000000000000000000000000000000000000..0c862f9af6a4ed19634f0f68779818743e2c9f8c --- /dev/null +++ b/examples/BodyMeasurements/app/components/bodyMassIndex/bodyMassIndex.js @@ -0,0 +1,97 @@ +/** + * 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 ( + + }/> + ); + } + + renderScene(route, navigator) { + return ( + + + + {this.state.bmiFormatted} + + + + + + + + ); + } +} + +var NavigationBarRouteMapper = { + LeftButton(route, navigator, index, nextState) { + return ( + {navigator.parentNavigator.pop()}}> + + Back + + + ); + }, + RightButton(route, navigator, index, nextState) { + return null; + }, + Title(route, navigator, index, nextState) { + return ( + + + Body Mass Index + + + ); + } +}; + + +module.exports = BodyMassIndex; +export default BodyMassIndex; diff --git a/examples/BodyMeasurements/app/components/dashboard/dashboard.js b/examples/BodyMeasurements/app/components/dashboard/dashboard.js new file mode 100644 index 0000000000000000000000000000000000000000..6065754acc5110800824f430c79e86e6aae75bd7 --- /dev/null +++ b/examples/BodyMeasurements/app/components/dashboard/dashboard.js @@ -0,0 +1,127 @@ +/** + * 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 ( + + }/> + ); + } + + renderScene(route, navigator) { + return ( + + + + + + + + + + + + ); + } +} + +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 ( + + + HealthKit Body Measurements + + + ); + } +}; + + +module.exports = Dashboard; +export default Dashboard; diff --git a/examples/BodyMeasurements/app/components/dashboard/item.js b/examples/BodyMeasurements/app/components/dashboard/item.js new file mode 100644 index 0000000000000000000000000000000000000000..694d838d584e225c063aa0e0fa222f88eafd5753 --- /dev/null +++ b/examples/BodyMeasurements/app/components/dashboard/item.js @@ -0,0 +1,87 @@ +/** + * 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 ( + + + + + + + {this.state.label} + + + + {this.state.value} + + + + + + + ) + } +} + +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; diff --git a/examples/BodyMeasurements/app/components/height/height.js b/examples/BodyMeasurements/app/components/height/height.js new file mode 100644 index 0000000000000000000000000000000000000000..1d416fec6479a16ea9266acf722ed55fb97a4677 --- /dev/null +++ b/examples/BodyMeasurements/app/components/height/height.js @@ -0,0 +1,97 @@ +/** + * 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 ( + + }/> + ); + } + + renderScene(route, navigator) { + return ( + + + + {this.state.heightFormatted} + + + + + + + + ); + } +} + +var NavigationBarRouteMapper = { + LeftButton(route, navigator, index, nextState) { + return ( + {navigator.parentNavigator.pop()}}> + + Back + + + ); + }, + RightButton(route, navigator, index, nextState) { + return null; + }, + Title(route, navigator, index, nextState) { + return ( + + + Height + + + ); + } +}; + + +module.exports = Height; +export default Height; diff --git a/examples/BodyMeasurements/app/components/leanBodyMass/leanBodyMass.js b/examples/BodyMeasurements/app/components/leanBodyMass/leanBodyMass.js new file mode 100644 index 0000000000000000000000000000000000000000..f1a7ff1e57e79297e8d3e819de7a275791573f79 --- /dev/null +++ b/examples/BodyMeasurements/app/components/leanBodyMass/leanBodyMass.js @@ -0,0 +1,98 @@ +/** + * 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 ( + + }/> + ); + } + + renderScene(route, navigator) { + return ( + + + + {this.state.leanBodyMassFormatted} + + + + + + + + ); + } +} + +var NavigationBarRouteMapper = { + LeftButton(route, navigator, index, nextState) { + return ( + {navigator.parentNavigator.pop()}}> + + Back + + + ); + }, + RightButton(route, navigator, index, nextState) { + return null; + }, + Title(route, navigator, index, nextState) { + return ( + + + Lean Body Mass + + + ); + } +}; + + +module.exports = LeanBodyMass; +export default LeanBodyMass; diff --git a/examples/BodyMeasurements/app/components/weight/weight.js b/examples/BodyMeasurements/app/components/weight/weight.js new file mode 100644 index 0000000000000000000000000000000000000000..b5b6eb8840afea8b14b69b3628d7657cf07e658e --- /dev/null +++ b/examples/BodyMeasurements/app/components/weight/weight.js @@ -0,0 +1,97 @@ +/** + * 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 ( + + }/> + ); + } + + renderScene(route, navigator) { + return ( + + + + {this.state.weightFormatted} + + + + + + + + ); + } +} + +var NavigationBarRouteMapper = { + LeftButton(route, navigator, index, nextState) { + return ( + {navigator.parentNavigator.pop()}}> + + Back + + + ); + }, + RightButton(route, navigator, index, nextState) { + return null; + }, + Title(route, navigator, index, nextState) { + return ( + + + Weight + + + ); + } +}; + + +module.exports = Weight; +export default Weight; diff --git a/examples/BodyMeasurements/app/stores/body.js b/examples/BodyMeasurements/app/stores/body.js new file mode 100644 index 0000000000000000000000000000000000000000..fac640213b42a439f9d598a909a7e4f9b511a05e --- /dev/null +++ b/examples/BodyMeasurements/app/stores/body.js @@ -0,0 +1,308 @@ +/** + * 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 diff --git a/examples/BodyMeasurements/app/styles/styles.js b/examples/BodyMeasurements/app/styles/styles.js new file mode 100644 index 0000000000000000000000000000000000000000..d96fb7f9952638914e85ecfd4035176639121fd6 --- /dev/null +++ b/examples/BodyMeasurements/app/styles/styles.js @@ -0,0 +1,186 @@ +/** + * 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; diff --git a/examples/BodyMeasurements/index.ios.js b/examples/BodyMeasurements/index.ios.js index 3ca7816cdd1acd3b98c2b3b6c3b34ce555bdbc19..4c771b724615ac0c2080c44c003e0348e433d7ad 100644 --- a/examples/BodyMeasurements/index.ios.js +++ b/examples/BodyMeasurements/index.ios.js @@ -13,67 +13,14 @@ import { View } from 'react-native'; - -let Index = require('./src/components/Index'); - +let App = require('./app/app'); class BodyMeasurements extends Component { render() { return ( - - ); - - // - // - //return ( - // - // - // Welcome to React Native! - // - // - // To get started, edit index.ios.js - // - // - // Press Cmd+R to reload,{'\n'} - // Cmd+D or shake for dev menu - // - // - //); + + ) } - - - renderScene(route, navigator) { - if(route.name == 'Index') { - return - } - //if(route.name == 'Home') { - // return - //} - } - - } -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); diff --git a/examples/BodyMeasurements/ios/BodyMeasurements.xcodeproj/project.pbxproj b/examples/BodyMeasurements/ios/BodyMeasurements.xcodeproj/project.pbxproj index 5ad2d79565ef5c4255e88429248b3f2c86ab0630..49b92db3b8d5122c3ec7ed0331a7055170698992 100644 --- a/examples/BodyMeasurements/ios/BodyMeasurements.xcodeproj/project.pbxproj +++ b/examples/BodyMeasurements/ios/BodyMeasurements.xcodeproj/project.pbxproj @@ -22,6 +22,8 @@ 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 140ED2AC1D01E1AD002B40FF /* 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 */; }; /* End PBXBuildFile section */ @@ -89,6 +91,13 @@ remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192; remoteInfo = React; }; + 37E9B89B1D21C6380090B19B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 37E9B8971D21C6380090B19B /* RCTAppleHealthKit.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3774C88D1D2092F20000B3F3; + remoteInfo = RCTAppleHealthKit; + }; 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; @@ -125,6 +134,9 @@ 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = BodyMeasurements/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = BodyMeasurements/main.m; sourceTree = ""; }; 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; + 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 = ""; }; + 37E9B8971D21C6380090B19B /* RCTAppleHealthKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAppleHealthKit.xcodeproj; path = "../node_modules/react-native-apple-healthkit/RCTAppleHealthKit.xcodeproj"; sourceTree = ""; }; 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -142,8 +154,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 37E9B89D1D21C63C0090B19B /* libRCTAppleHealthKit.a in Frameworks */, 146834051AC3E58100842450 /* libReact.a in Frameworks */, 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, + 37E9B8741D21B52F0090B19B /* HealthKit.framework in Frameworks */, 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */, @@ -234,6 +248,7 @@ 13B07FAE1A68108700A75B9A /* BodyMeasurements */ = { isa = PBXGroup; children = ( + 37E9B8751D21B52F0090B19B /* BodyMeasurements.entitlements */, 008F07F21AC5B25A0029DE68 /* main.jsbundle */, 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 13B07FB01A68108700A75B9A /* AppDelegate.m */, @@ -253,6 +268,14 @@ name = Products; sourceTree = ""; }; + 37E9B8981D21C6380090B19B /* Products */ = { + isa = PBXGroup; + children = ( + 37E9B89C1D21C6380090B19B /* libRCTAppleHealthKit.a */, + ); + name = Products; + sourceTree = ""; + }; 78C398B11ACF4ADC00677621 /* Products */ = { isa = PBXGroup; children = ( @@ -264,6 +287,7 @@ 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( + 37E9B8971D21C6380090B19B /* RCTAppleHealthKit.xcodeproj */, 146833FF1AC3E56700842450 /* React.xcodeproj */, 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, @@ -289,6 +313,7 @@ 83CBB9F61A601CBA00E9B192 = { isa = PBXGroup; children = ( + 37E9B8731D21B52F0090B19B /* HealthKit.framework */, 13B07FAE1A68108700A75B9A /* BodyMeasurements */, 832341AE1AAA6A7D00B99B32 /* Libraries */, 00E356EF1AD99517003FC87E /* BodyMeasurementsTests */, @@ -359,6 +384,14 @@ CreatedOnToolsVersion = 6.2; TestTargetID = 13B07F861A680F5B00A75B9A; }; + 13B07F861A680F5B00A75B9A = { + DevelopmentTeam = 95ZTJFHCUG; + SystemCapabilities = { + com.apple.HealthKit = { + enabled = 1; + }; + }; + }; }; }; buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "BodyMeasurements" */; @@ -377,6 +410,10 @@ ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; }, + { + ProductGroup = 37E9B8981D21C6380090B19B /* Products */; + ProjectRef = 37E9B8971D21C6380090B19B /* RCTAppleHealthKit.xcodeproj */; + }, { ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */; ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; @@ -479,6 +516,13 @@ remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */; 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 */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -605,6 +649,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = BodyMeasurements/BodyMeasurements.entitlements; DEAD_CODE_STRIPPING = NO; HEADER_SEARCH_PATHS = ( "$(inherited)", @@ -625,6 +670,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = BodyMeasurements/BodyMeasurements.entitlements; HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, diff --git a/examples/BodyMeasurements/ios/BodyMeasurements/BodyMeasurements.entitlements b/examples/BodyMeasurements/ios/BodyMeasurements/BodyMeasurements.entitlements new file mode 100644 index 0000000000000000000000000000000000000000..e10f4302d524a2c6313dc968df134285905acfc8 --- /dev/null +++ b/examples/BodyMeasurements/ios/BodyMeasurements/BodyMeasurements.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.developer.healthkit + + + diff --git a/examples/BodyMeasurements/ios/BodyMeasurements/Info.plist b/examples/BodyMeasurements/ios/BodyMeasurements/Info.plist index 970fc6ac629ed4808f668e843326eb54c8850638..1680bf7e82c75d70cc371b972e9ddfb804930c34 100644 --- a/examples/BodyMeasurements/ios/BodyMeasurements/Info.plist +++ b/examples/BodyMeasurements/ios/BodyMeasurements/Info.plist @@ -23,11 +23,10 @@ LSRequiresIPhoneOS NSAppTransportSecurity - - - NSAllowsArbitraryLoads - - + + NSAllowsArbitraryLoads + + NSLocationWhenInUseUsageDescription UILaunchStoryboardName @@ -35,6 +34,7 @@ UIRequiredDeviceCapabilities armv7 + healthkit UISupportedInterfaceOrientations diff --git a/examples/BodyMeasurements/package.json b/examples/BodyMeasurements/package.json index 66c304e7906a090fcdc37ff7b7576cb77160db64..42c0e9910ae06b5c0b8d1699078319a4032c5e3d 100644 --- a/examples/BodyMeasurements/package.json +++ b/examples/BodyMeasurements/package.json @@ -6,7 +6,10 @@ "start": "node node_modules/react-native/local-cli/cli.js start" }, "dependencies": { + "airflux": "^0.5.1", "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" } }