[React Native][Device ID][wip] implement most basic js access

This commit is contained in:
Alex Akers 2015-03-10 12:09:35 -07:00
parent 184ae2314d
commit a8aedb3e78
9 changed files with 279 additions and 2 deletions

View File

@ -0,0 +1,73 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule AdSupportIOSExample
*/
/* eslint no-console: 0 */
'use strict';
var AdSupportIOS = require('AdSupportIOS');
var React = require('react-native');
var {
StyleSheet,
Text,
View,
} = React;
exports.framework = 'React';
exports.title = 'Advertising ID';
exports.description = 'Example of using the ad support API.';
exports.examples = [
{
title: 'Ad Support IOS',
render: function() {
return <AdSupportIOSExample />;
},
}
];
var AdSupportIOSExample = React.createClass({
getInitialState: function() {
return {
deviceID: 'No IDFA yet',
};
},
componentDidMount: function() {
AdSupportIOS.getAdvertisingId(
this._onSuccess,
this._onFailure
);
},
_onSuccess: function(deviceID) {
this.setState({
'deviceID': deviceID,
});
},
_onFailure: function(e) {
this.setState({
'deviceID': 'Error!',
});
},
render: function() {
return (
<View>
<Text>
<Text style={styles.title}>Advertising ID: </Text>
{JSON.stringify(this.state.deviceID)}
</Text>
</View>
);
}
});
var styles = StyleSheet.create({
title: {
fontWeight: 'bold',
},
});

View File

@ -16,6 +16,7 @@
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
832C81C71AAF73C5007FA2F7 /* libRCTAdSupport.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832C81A61AAF6EFF007FA2F7 /* libRCTAdSupport.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -54,6 +55,13 @@
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTGeolocation;
};
832C81A51AAF6EFF007FA2F7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 832C81A11AAF6EFE007FA2F7 /* RCTAdSupport.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 832C81801AAF6DEF007FA2F7;
remoteInfo = RCTAdSupport;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
@ -69,6 +77,7 @@
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
832C81A11AAF6EFE007FA2F7 /* RCTAdSupport.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAdSupport.xcodeproj; path = ../../Libraries/AdSupport/RCTAdSupport.xcodeproj; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -76,6 +85,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
832C81C71AAF73C5007FA2F7 /* libRCTAdSupport.a in Frameworks */,
134A8A2A1AACED7A00945AAE /* libRCTGeolocation.a in Frameworks */,
1341802C1AA9178B003F314A /* libRCTNetwork.a in Frameworks */,
134180011AA9153C003F314A /* libRCTText.a in Frameworks */,
@ -91,10 +101,11 @@
isa = PBXGroup;
children = (
13417FFA1AA91531003F314A /* ReactKit.xcodeproj */,
134180261AA91779003F314A /* RCTNetwork.xcodeproj */,
832C81A11AAF6EFE007FA2F7 /* RCTAdSupport.xcodeproj */,
134A8A201AACED6A00945AAE /* RCTGeolocation.xcodeproj */,
13417FEA1AA914B8003F314A /* RCTText.xcodeproj */,
13417FE31AA91428003F314A /* RCTImage.xcodeproj */,
134180261AA91779003F314A /* RCTNetwork.xcodeproj */,
13417FEA1AA914B8003F314A /* RCTText.xcodeproj */,
);
name = Libraries;
sourceTree = "<group>";
@ -152,6 +163,14 @@
name = UIExplorer;
sourceTree = "<group>";
};
832C81A21AAF6EFE007FA2F7 /* Products */ = {
isa = PBXGroup;
children = (
832C81A61AAF6EFF007FA2F7 /* libRCTAdSupport.a */,
);
name = Products;
sourceTree = "<group>";
};
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
@ -210,6 +229,10 @@
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 832C81A21AAF6EFE007FA2F7 /* Products */;
ProjectRef = 832C81A11AAF6EFE007FA2F7 /* RCTAdSupport.xcodeproj */;
},
{
ProductGroup = 134A8A211AACED6A00945AAE /* Products */;
ProjectRef = 134A8A201AACED6A00945AAE /* RCTGeolocation.xcodeproj */;
@ -274,6 +297,13 @@
remoteRef = 134A8A241AACED6A00945AAE /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
832C81A61AAF6EFF007FA2F7 /* libRCTAdSupport.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTAdSupport.a;
remoteRef = 832C81A51AAF6EFF007FA2F7 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */

View File

@ -39,6 +39,7 @@ var EXAMPLES = [
require('./SliderExample'),
require('./CameraRollExample.ios'),
require('./MapViewExample'),
require('./AdSupportIOSExample'),
];
var UIExplorerList = React.createClass({

View File

@ -0,0 +1,14 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule AdSupportIOS
*/
'use strict';
var AdSupport = require('NativeModules').RCTAdSupport;
module.exports = {
getAdvertisingId: function(onSuccess, onFailure) {
AdSupport.getAdvertisingId(onSuccess, onFailure);
},
};

View File

@ -0,0 +1,7 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#import "RCTBridgeModule.h"
@interface RCTAdSupport : NSObject <RCTBridgeModule>
@end

View File

@ -0,0 +1,20 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#import "RCTAdSupport.h"
#import <AdSupport/ASIdentifierManager.h>
@implementation RCTAdSupport
- (void)getAdvertisingId:(RCTResponseSenderBlock)callback withErrorCallback:(RCTResponseSenderBlock)errorCallback
{
RCT_EXPORT();
if ([ASIdentifierManager class]) {
callback(@[[[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]]);
} else {
return errorCallback(@[@"as_identifier_unavailable"]);
}
}
@end

View File

@ -0,0 +1,10 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule PickerIOS
*
* This is a controlled component version of RKPickerIOS
*/
'use strict';
module.exports = require('UnimplementedView');

View File

@ -0,0 +1,120 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule PickerIOS
*
* This is a controlled component version of RKPickerIOS
*/
'use strict';
var NativeMethodsMixin = require('NativeMethodsMixin');
var React = require('React');
var ReactChildren = require('ReactChildren');
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
var RKPickerIOSConsts = require('NativeModules').RKUIManager.RCTPicker.Constants;
var StyleSheet = require('StyleSheet');
var View = require('View');
var createReactIOSNativeComponentClass =
require('createReactIOSNativeComponentClass');
var merge = require('merge');
var PICKER = 'picker';
var PickerIOS = React.createClass({
mixins: [NativeMethodsMixin],
propTypes: {
onValueChange: React.PropTypes.func,
selectedValue: React.PropTypes.any, // string or integer basically
},
getInitialState: function() {
return this._stateFromProps(this.props);
},
componentWillReceiveProps: function(nextProps) {
this.setState(this._stateFromProps(nextProps));
},
// Translate PickerIOS prop and children into stuff that RKPickerIOS understands.
_stateFromProps: function(props) {
var selectedIndex = 0;
var items = [];
ReactChildren.forEach(props.children, function (child, index) {
if (child.props.value === props.selectedValue) {
selectedIndex = index;
}
items.push({value: child.props.value, label: child.props.label});
});
return {selectedIndex, items};
},
render: function() {
return (
<View style={this.props.style}>
<RKPickerIOS
ref={PICKER}
style={styles.rkPickerIOS}
items={this.state.items}
selectedIndex={this.state.selectedIndex}
onChange={this._onChange}
/>
</View>
);
},
_onChange: function(event) {
if (this.props.onChange) {
this.props.onChange(event);
}
if (this.props.onValueChange) {
this.props.onValueChange(event.nativeEvent.newValue);
}
// The picker is a controlled component. This means we expect the
// on*Change handlers to be in charge of updating our
// `selectedValue` prop. That way they can also
// disallow/undo/mutate the selection of certain values. In other
// words, the embedder of this component should be the source of
// truth, not the native component.
if (this.state.selectedIndex !== event.nativeEvent.newIndex) {
this.refs[PICKER].setNativeProps({
selectedIndex: this.state.selectedIndex
});
}
},
});
PickerIOS.Item = React.createClass({
propTypes: {
value: React.PropTypes.any, // string or integer basically
label: React.PropTypes.string,
},
render: function() {
// These items don't get rendered directly.
return null;
},
});
var styles = StyleSheet.create({
rkPickerIOS: {
// The picker will conform to whatever width is given, but we do
// have to set the component's height explicitly on the
// surrounding view to ensure it gets rendered.
height: RKPickerIOSConsts.ComponentHeight,
},
});
var rkPickerIOSAttributes = merge(ReactIOSViewAttributes.UIView, {
items: true,
selectedIndex: true,
});
var RKPickerIOS = createReactIOSNativeComponentClass({
validAttributes: rkPickerIOSAttributes,
uiViewClassName: 'RCTPicker',
});
module.exports = PickerIOS;

View File

@ -212,6 +212,8 @@
13B07FE81A69327A00A75B9A /* RCTAlertManager.m */,
13B07FE91A69327A00A75B9A /* RCTExceptionsManager.h */,
13B07FEA1A69327A00A75B9A /* RCTExceptionsManager.m */,
5F5F0D971A9E456B001279FA /* RCTLocationObserver.h */,
5F5F0D981A9E456B001279FA /* RCTLocationObserver.m */,
13723B4E1A82FD3C00F88898 /* RCTStatusBarManager.h */,
13723B4F1A82FD3C00F88898 /* RCTStatusBarManager.m */,
13B07FED1A69327A00A75B9A /* RCTTiming.h */,