diff --git a/Examples/UIExplorer/ActionSheetIOSExample.js b/Examples/UIExplorer/ActionSheetIOSExample.js
new file mode 100644
index 000000000..9b164de14
--- /dev/null
+++ b/Examples/UIExplorer/ActionSheetIOSExample.js
@@ -0,0 +1,112 @@
+/**
+* * Copyright 2004-present Facebook. All Rights Reserved.
+* */
+'use strict';
+
+var React = require('react-native');
+var {
+ StyleSheet,
+ Text,
+ View,
+} = React;
+var ActionSheetIOS = require('ActionSheetIOS');
+var BUTTONS = [
+ 'Button Index: 0',
+ 'Button Index: 1',
+ 'Button Index: 2',
+ 'Destruct',
+ 'Cancel',
+];
+var DESTRUCTIVE_INDEX = 3;
+var CANCEL_INDEX = 4;
+
+var ActionSheetExample = React.createClass({
+ getInitialState() {
+ return {
+ clicked: 'none',
+ };
+ },
+
+ render() {
+ return (
+
+
+ Click to show the ActionSheet
+
+
+ Clicked button at index: "{this.state.clicked}"
+
+
+ );
+ },
+
+ showActionSheet() {
+ ActionSheetIOS.showActionSheetWithOptions({
+ options: BUTTONS,
+ cancelButtonIndex: CANCEL_INDEX,
+ destructiveButtonIndex: DESTRUCTIVE_INDEX,
+ },
+ (buttonIndex) => {
+ this.setState({ clicked: BUTTONS[buttonIndex] });
+ });
+ }
+});
+
+var ShareActionSheetExample = React.createClass({
+ getInitialState() {
+ return {
+ text: ''
+ };
+ },
+
+ render() {
+ return (
+
+
+ Click to show the Share ActionSheet
+
+
+ {this.state.text}
+
+
+ );
+ },
+
+ showShareActionSheet() {
+ ActionSheetIOS.showShareActionSheetWithOptions({
+ url: 'https://code.facebook.com',
+ },
+ (error) => {
+ console.error(error);
+ },
+ (success, method) => {
+ var text;
+ if (success) {
+ text = `Shared via ${method}`;
+ } else {
+ text = 'You didn\'t share';
+ }
+ this.setState({text})
+ });
+ }
+});
+
+var style = StyleSheet.create({
+ button: {
+ marginBottom: 10,
+ fontWeight: 'bold',
+ }
+});
+
+exports.title = 'ActionSheetIOS';
+exports.description = 'Interface to show iOS\' action sheets';
+exports.examples = [
+ {
+ title: 'Show Action Sheet',
+ render() { return ; }
+ },
+ {
+ title: 'Show Share Action Sheet',
+ render() { return ; }
+ }
+];
diff --git a/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj b/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj
index c1f6820cc..f33ddefce 100644
--- a/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj
+++ b/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj
@@ -18,6 +18,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 */; };
+ 147CED4C1AB3532B00DA3E4C /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 147CED4B1AB34F8C00DA3E4C /* libRCTActionSheet.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -70,6 +71,13 @@
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTGeolocation;
};
+ 147CED4A1AB34F8C00DA3E4C /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 14E0EEC81AB118F7000DECC3 /* RCTActionSheet.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 134814201AA4EA6300B7C361;
+ remoteInfo = RCTActionSheet;
+ };
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
@@ -89,6 +97,7 @@
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
+ 14E0EEC81AB118F7000DECC3 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = ../../Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -103,6 +112,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 147CED4C1AB3532B00DA3E4C /* libRCTActionSheet.a in Frameworks */,
134454601AAFCABD003F0779 /* libRCTAdSupport.a in Frameworks */,
134A8A2A1AACED7A00945AAE /* libRCTGeolocation.a in Frameworks */,
1341802C1AA9178B003F314A /* libRCTNetwork.a in Frameworks */,
@@ -135,6 +145,7 @@
1316A21D1AA397F400C0188E /* Libraries */ = {
isa = PBXGroup;
children = (
+ 14E0EEC81AB118F7000DECC3 /* RCTActionSheet.xcodeproj */,
13417FFA1AA91531003F314A /* ReactKit.xcodeproj */,
134454551AAFCAAE003F0779 /* RCTAdSupport.xcodeproj */,
134A8A201AACED6A00945AAE /* RCTGeolocation.xcodeproj */,
@@ -206,6 +217,14 @@
name = UIExplorer;
sourceTree = "";
};
+ 147CED471AB34F8C00DA3E4C /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 147CED4B1AB34F8C00DA3E4C /* libRCTActionSheet.a */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
@@ -290,6 +309,10 @@
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
projectDirPath = "";
projectReferences = (
+ {
+ ProductGroup = 147CED471AB34F8C00DA3E4C /* Products */;
+ ProjectRef = 14E0EEC81AB118F7000DECC3 /* RCTActionSheet.xcodeproj */;
+ },
{
ProductGroup = 134454561AAFCAAE003F0779 /* Products */;
ProjectRef = 134454551AAFCAAE003F0779 /* RCTAdSupport.xcodeproj */;
@@ -366,6 +389,13 @@
remoteRef = 134A8A241AACED6A00945AAE /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
+ 147CED4B1AB34F8C00DA3E4C /* libRCTActionSheet.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libRCTActionSheet.a;
+ remoteRef = 147CED4A1AB34F8C00DA3E4C /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
diff --git a/Examples/UIExplorer/UIExplorerList.js b/Examples/UIExplorer/UIExplorerList.js
index ab8aed798..59653055e 100644
--- a/Examples/UIExplorer/UIExplorerList.js
+++ b/Examples/UIExplorer/UIExplorerList.js
@@ -43,6 +43,7 @@ var EXAMPLES = [
require('./AppStateIOSExample'),
require('./AdSupportIOSExample'),
require('./AppStateExample'),
+ require('./ActionSheetIOSExample'),
];
var UIExplorerList = React.createClass({
diff --git a/Libraries/ActionSheetIOS/ActionSheetIOS.js b/Libraries/ActionSheetIOS/ActionSheetIOS.js
new file mode 100644
index 000000000..d4cc84a48
--- /dev/null
+++ b/Libraries/ActionSheetIOS/ActionSheetIOS.js
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2004-present Facebook. All Rights Reserved.
+ *
+ * @providesModule ActionSheetIOS
+ */
+'use strict';
+
+var invariant = require('invariant');
+var RCTActionSheetManager = require('NativeModulesDeprecated').RKActionSheetManager;
+
+var ActionSheetIOS = {
+ showActionSheetWithOptions(options, callback) {
+ invariant(
+ typeof options === 'object' && options !== null,
+ 'Options must a valid object'
+ );
+ invariant(
+ typeof callback === 'function',
+ 'Must provide a valid callback'
+ );
+ RCTActionSheetManager.showActionSheetWithOptions(
+ options,
+ () => {}, // RKActionSheet compatibility hack
+ callback
+ );
+ },
+
+ showShareActionSheetWithOptions(options, failureCallback, successCallback) {
+ invariant(
+ typeof options === 'object' && options !== null,
+ 'Options must a valid object'
+ );
+ invariant(
+ typeof failureCallback === 'function',
+ 'Must provide a valid failureCallback'
+ );
+ invariant(
+ typeof successCallback === 'function',
+ 'Must provide a valid successCallback'
+ );
+ RCTActionSheetManager.showShareActionSheetWithOptions(
+ options,
+ failureCallback,
+ successCallback
+ );
+ }
+};
+
+module.exports = ActionSheetIOS;
diff --git a/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj/project.pbxproj b/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj/project.pbxproj
new file mode 100644
index 000000000..095c4de35
--- /dev/null
+++ b/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj/project.pbxproj
@@ -0,0 +1,250 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 14C644C41AB0DFC900DE3C65 /* RCTActionSheetManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 14C644C21AB0DFC900DE3C65 /* RCTActionSheetManager.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 58B511D91A9E6C8500147676 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "include/$(PRODUCT_NAME)";
+ dstSubfolderSpec = 16;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 134814201AA4EA6300B7C361 /* libRCTActionSheet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTActionSheet.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ 14C644C11AB0DFC900DE3C65 /* RCTActionSheetManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTActionSheetManager.h; sourceTree = ""; };
+ 14C644C21AB0DFC900DE3C65 /* RCTActionSheetManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTActionSheetManager.m; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 58B511D81A9E6C8500147676 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 134814211AA4EA7D00B7C361 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 134814201AA4EA6300B7C361 /* libRCTActionSheet.a */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 58B511D21A9E6C8500147676 = {
+ isa = PBXGroup;
+ children = (
+ 14C644C11AB0DFC900DE3C65 /* RCTActionSheetManager.h */,
+ 14C644C21AB0DFC900DE3C65 /* RCTActionSheetManager.m */,
+ 134814211AA4EA7D00B7C361 /* Products */,
+ );
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 58B511DA1A9E6C8500147676 /* RCTActionSheet */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTActionSheet" */;
+ buildPhases = (
+ 58B511D71A9E6C8500147676 /* Sources */,
+ 58B511D81A9E6C8500147676 /* Frameworks */,
+ 58B511D91A9E6C8500147676 /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = RCTActionSheet;
+ productName = RCTDataManager;
+ productReference = 134814201AA4EA6300B7C361 /* libRCTActionSheet.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 58B511D31A9E6C8500147676 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0610;
+ ORGANIZATIONNAME = Facebook;
+ TargetAttributes = {
+ 58B511DA1A9E6C8500147676 = {
+ CreatedOnToolsVersion = 6.1.1;
+ };
+ };
+ };
+ buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTActionSheet" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 58B511D21A9E6C8500147676;
+ productRefGroup = 58B511D21A9E6C8500147676;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 58B511DA1A9E6C8500147676 /* RCTActionSheet */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 58B511D71A9E6C8500147676 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 14C644C41AB0DFC900DE3C65 /* RCTActionSheetManager.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 58B511ED1A9E6C8500147676 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.1;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ 58B511EE1A9E6C8500147676 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = YES;
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.1;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 58B511F01A9E6C8500147676 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+ "$(SRCROOT)/../../ReactKit/**",
+ );
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = RCTActionSheet;
+ SKIP_INSTALL = YES;
+ };
+ name = Debug;
+ };
+ 58B511F11A9E6C8500147676 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+ "$(SRCROOT)/../../ReactKit/**",
+ );
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = RCTActionSheet;
+ SKIP_INSTALL = YES;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTActionSheet" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 58B511ED1A9E6C8500147676 /* Debug */,
+ 58B511EE1A9E6C8500147676 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTActionSheet" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 58B511F01A9E6C8500147676 /* Debug */,
+ 58B511F11A9E6C8500147676 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 58B511D31A9E6C8500147676 /* Project object */;
+}
diff --git a/Libraries/ActionSheetIOS/RCTActionSheetManager.h b/Libraries/ActionSheetIOS/RCTActionSheetManager.h
new file mode 100644
index 000000000..0ef25b520
--- /dev/null
+++ b/Libraries/ActionSheetIOS/RCTActionSheetManager.h
@@ -0,0 +1,9 @@
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+#import
+
+#import "RCTBridge.h"
+
+@interface RCTActionSheetManager : NSObject
+
+@end
diff --git a/Libraries/ActionSheetIOS/RCTActionSheetManager.m b/Libraries/ActionSheetIOS/RCTActionSheetManager.m
new file mode 100644
index 000000000..2c628e2be
--- /dev/null
+++ b/Libraries/ActionSheetIOS/RCTActionSheetManager.m
@@ -0,0 +1,120 @@
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+#import "RCTActionSheetManager.h"
+
+#import "RCTLog.h"
+
+@interface RCTActionSheetManager()
+
+@end
+
+@implementation RCTActionSheetManager {
+ NSMutableDictionary *_callbacks;
+}
+
+- (instancetype)init
+{
+ if ((self = [super init])) {
+ _callbacks = [[NSMutableDictionary alloc] init];
+ }
+ return self;
+}
+
+- (void)showActionSheetWithOptions:(NSDictionary *)options
+ failureCallback:(RCTResponseSenderBlock)failureCallback
+ successCallback:(RCTResponseSenderBlock)successCallback
+{
+ RCT_EXPORT();
+
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIActionSheet *actionSheet = [[UIActionSheet alloc] init];
+
+ actionSheet.title = options[@"title"];
+
+ for (NSString *option in options[@"options"]) {
+ [actionSheet addButtonWithTitle:option];
+ }
+
+ if (options[@"destructiveButtonIndex"]) {
+ actionSheet.destructiveButtonIndex = [options[@"destructiveButtonIndex"] integerValue];
+ }
+ if (options[@"cancelButtonIndex"]) {
+ actionSheet.cancelButtonIndex = [options[@"cancelButtonIndex"] integerValue];
+ }
+
+ actionSheet.delegate = self;
+
+ _callbacks[keyForInstance(actionSheet)] = successCallback;
+
+ UIWindow *appWindow = [[[UIApplication sharedApplication] delegate] window];
+ if (appWindow == nil) {
+ RCTLogError(@"Tried to display action sheet but there is no application window. options: %@", options);
+ return;
+ }
+ [actionSheet showInView:appWindow];
+ });
+}
+
+- (void)showShareActionSheetWithOptions:(NSDictionary *)options
+ failureCallback:(RCTResponseSenderBlock)failureCallback
+ successCallback:(RCTResponseSenderBlock)successCallback
+{
+ RCT_EXPORT();
+
+ dispatch_async(dispatch_get_main_queue(), ^{
+ NSMutableArray *items = [NSMutableArray array];
+ id message = options[@"message"];
+ id url = options[@"url"];
+ if ([message isKindOfClass:[NSString class]]) {
+ [items addObject:message];
+ }
+ if ([url isKindOfClass:[NSString class]]) {
+ [items addObject:[NSURL URLWithString:url]];
+ }
+ if ([items count] == 0) {
+ failureCallback(@[@"No `url` or `message` to share"]);
+ return;
+ }
+ UIActivityViewController *share = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:nil];
+ UIViewController *ctrl = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
+ if ([share respondsToSelector:@selector(setCompletionWithItemsHandler:)]) {
+ share.completionWithItemsHandler = ^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
+ if (activityError) {
+ failureCallback(@[[activityError localizedDescription]]);
+ } else {
+ successCallback(@[@(completed), (activityType ?: [NSNull null])]);
+ }
+ };
+ } else {
+ share.completionHandler = ^(NSString *activityType, BOOL completed) {
+ successCallback(@[@(completed), (activityType ?: [NSNull null])]);
+ };
+ }
+ [ctrl presentViewController:share animated:YES completion:nil];
+ });
+}
+
+#pragma mark UIActionSheetDelegate Methods
+
+- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ NSString *key = keyForInstance(actionSheet);
+ RCTResponseSenderBlock callback = _callbacks[key];
+ if (callback) {
+ callback(@[@(buttonIndex)]);
+ [_callbacks removeObjectForKey:key];
+ } else {
+ RCTLogWarn(@"No callback registered for action sheet: %@", actionSheet.title);
+ }
+
+ [[[[UIApplication sharedApplication] delegate] window] makeKeyWindow];
+}
+
+#pragma mark Private
+
+static NSString *keyForInstance(id instance)
+{
+ return [NSString stringWithFormat:@"%p", instance];
+}
+
+@end