From 5e516093535c0b676949b9980ac6c997b3e45c00 Mon Sep 17 00:00:00 2001 From: Dimitar Kerezov Date: Tue, 27 Jan 2015 16:29:04 +0200 Subject: [PATCH] CB-8084 conform AppDelegate.m with provisioning profile Hide the two methods in AppDelegate.m for push notifications when provisioning profile doesn't include the push notifications service Related to https://issues.apache.org/jira/browse/CB-8084 --- .../project/__CLI__.xcodeproj/project.pbxproj | 18 ++++ .../__NON-CLI__.xcodeproj/project.pbxproj | 18 ++++ .../__PROJECT_NAME__/Classes/AppDelegate.m | 4 + .../Classes/PushNotificationsEnabled.h | 1 + .../scripts/cordova/lib/push-notifications.js | 82 +++++++++++++++++++ 5 files changed, 123 insertions(+) create mode 100644 bin/templates/project/__PROJECT_NAME__/Classes/PushNotificationsEnabled.h create mode 100644 bin/templates/scripts/cordova/lib/push-notifications.js diff --git a/bin/templates/project/__CLI__.xcodeproj/project.pbxproj b/bin/templates/project/__CLI__.xcodeproj/project.pbxproj index 9edef21f6..8ccdaf491 100755 --- a/bin/templates/project/__CLI__.xcodeproj/project.pbxproj +++ b/bin/templates/project/__CLI__.xcodeproj/project.pbxproj @@ -61,6 +61,7 @@ /* Begin PBXFileReference section */ 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1D3623240D0F684500981E99 /* PushNotificationsEnabled.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PushNotificationsEnabled.h; sourceTree = ""; }; 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 1D6058910D05DD3D006BFB54 /* __PROJECT_NAME__.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "__PROJECT_NAME__.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 1F766FDD13BBADB100FB74C0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = Localizable.strings; sourceTree = ""; }; @@ -129,6 +130,7 @@ 302D95EF14D2391D003F00A1 /* MainViewController.m */, 302D95F014D2391D003F00A1 /* MainViewController.xib */, 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623240D0F684500981E99 /* PushNotificationsEnabled.h */, 1D3623250D0F684500981E51 /* AppDelegate.m */, ); name = Classes; @@ -263,6 +265,7 @@ isa = PBXNativeTarget; buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "__PROJECT_NAME__" */; buildPhases = ( + D83631551A790FDE00797B39 /* Push Notifications */, 304B58A110DAC018002A0835 /* Copy www directory */, 1D60588D0D05DD3D006BFB54 /* Resources */, 1D60588E0D05DD3D006BFB54 /* Sources */, @@ -362,6 +365,21 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + D83631551A790FDE00797B39 /* Push Notifications */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Push Notifications"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "node cordova/lib/push-notifications.js"; + showEnvVarsInLog = 0; + }; 304B58A110DAC018002A0835 /* Copy www directory */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/bin/templates/project/__NON-CLI__.xcodeproj/project.pbxproj b/bin/templates/project/__NON-CLI__.xcodeproj/project.pbxproj index 47db3a2c0..7096af394 100755 --- a/bin/templates/project/__NON-CLI__.xcodeproj/project.pbxproj +++ b/bin/templates/project/__NON-CLI__.xcodeproj/project.pbxproj @@ -61,6 +61,7 @@ /* Begin PBXFileReference section */ 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1D3623240D0F684500981E99 /* PushNotificationsEnabled.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PushNotificationsEnabled.h; sourceTree = ""; }; 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 1D6058910D05DD3D006BFB54 /* __PROJECT_NAME__.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "__PROJECT_NAME__.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; @@ -124,6 +125,7 @@ 302D95EF14D2391D003F00A1 /* MainViewController.m */, 302D95F014D2391D003F00A1 /* MainViewController.xib */, 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623240D0F684500981E99 /* PushNotificationsEnabled.h */, 1D3623250D0F684500981E51 /* AppDelegate.m */, ); name = Classes; @@ -247,6 +249,7 @@ isa = PBXNativeTarget; buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "__PROJECT_NAME__" */; buildPhases = ( + D83631551A790FDE00797B39 /* Push Notifications */, 304B58A110DAC018002A0835 /* Copy www directory */, 1D60588D0D05DD3D006BFB54 /* Resources */, 1D60588E0D05DD3D006BFB54 /* Sources */, @@ -346,6 +349,21 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + D83631551A790FDE00797B39 /* Push Notifications */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Push Notifications"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "node cordova/lib/push-notifications.js"; + showEnvVarsInLog = 0; + }; 304B58A110DAC018002A0835 /* Copy www directory */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/bin/templates/project/__PROJECT_NAME__/Classes/AppDelegate.m b/bin/templates/project/__PROJECT_NAME__/Classes/AppDelegate.m index fe4a7a079..b0a7bcf1a 100644 --- a/bin/templates/project/__PROJECT_NAME__/Classes/AppDelegate.m +++ b/bin/templates/project/__PROJECT_NAME__/Classes/AppDelegate.m @@ -26,6 +26,7 @@ Licensed to the Apache Software Foundation (ASF) under one // #import "AppDelegate.h" +#import "PushNotificationsEnabled.h" #import "MainViewController.h" #import @@ -115,6 +116,7 @@ - (void) application:(UIApplication*)application [[NSNotificationCenter defaultCenter] postNotificationName:CDVLocalNotification object:notification]; } +#if PUSH_NOTIFICATIONS_ENABLED - (void) application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken { @@ -134,6 +136,8 @@ - (void) application:(UIApplication*)application [[NSNotificationCenter defaultCenter] postNotificationName:CDVRemoteNotificationError object:error]; } +#endif + - (NSUInteger)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window { // iPhone doesn't support upside down by default, while the iPad does. Override to allow all orientations always, and let the root view controller decide what's allowed (the supported orientations mask gets intersected). diff --git a/bin/templates/project/__PROJECT_NAME__/Classes/PushNotificationsEnabled.h b/bin/templates/project/__PROJECT_NAME__/Classes/PushNotificationsEnabled.h new file mode 100644 index 000000000..4db91a127 --- /dev/null +++ b/bin/templates/project/__PROJECT_NAME__/Classes/PushNotificationsEnabled.h @@ -0,0 +1 @@ +#define PUSH_NOTIFICATIONS_ENABLED true \ No newline at end of file diff --git a/bin/templates/scripts/cordova/lib/push-notifications.js b/bin/templates/scripts/cordova/lib/push-notifications.js new file mode 100644 index 000000000..df7525819 --- /dev/null +++ b/bin/templates/scripts/cordova/lib/push-notifications.js @@ -0,0 +1,82 @@ +(function () { + var fs = require('fs'), + path = require('path'), + exec = require('child_process').exec, + PUSH_NOTIFICATIONS_ENABLED_HEADER_FILE = 'PushNotificationsEnabled.h', + PUSH_NOTIFICATIONS_ENABLED_HEADER_FILE_CONTENT = '#define PUSH_NOTIFICATIONS_ENABLED ', + EXPANDED_PROVISIONING_PROFILE = process.env.EXPANDED_PROVISIONING_PROFILE, + PATH_TO_MOBILE_PROVISIONS = path.join(process.env.HOME, 'Library', 'MobileDevice', 'Provisioning Profiles'), + PATH_TO_MOBILE_PUSH_NOTIFICATIONS_ENABLED_HEADER_FILE = path.join(process.env.PROJECT_DIR, process.env.PROJECT_NAME, 'Classes', PUSH_NOTIFICATIONS_ENABLED_HEADER_FILE), + PROVISIONING_PROFILE_REQUIRED = process.env.PROVISIONING_PROFILE_REQUIRED, + PROVISIONING_PROFILE_UUID_REGEX = new RegExp('UUID<\/key>[\\s\\S]*' + EXPANDED_PROVISIONING_PROFILE + '<\/string>'); + + function logErrorIfExists(error) { + if (error) { + console.error('ERROR: ' + error); + } + } + + function sanitizeMobileProvision(mobileProvision) { + if (mobileProvision.indexOf('.mobileprovision') === -1) { + mobileProvision += '.mobileprovision'; + } + + return mobileProvision; + } + + function createPushNotificationsEnabledHeaderFile(hasPushNotificationsEntitlement) { + fs.writeFileSync(PATH_TO_MOBILE_PUSH_NOTIFICATIONS_ENABLED_HEADER_FILE, PUSH_NOTIFICATIONS_ENABLED_HEADER_FILE_CONTENT + hasPushNotificationsEntitlement); + } + + function createPushNotificationsEnabledHeaderFileWithMobileProvision(mobileProvision) { + var pathToProvisioningProfile = path.join(PATH_TO_MOBILE_PROVISIONS, sanitizeMobileProvision(mobileProvision)); + + exec("security cms -D -i \"" + pathToProvisioningProfile + "\"", function (error, stdout, stderr) { + logErrorIfExists(error); + var hasPushNotificationsEntitlement = stdout.indexOf("aps-environment") > -1; + createPushNotificationsEnabledHeaderFile(hasPushNotificationsEntitlement); + }); + } + + function isProvisionUUIDSuitable(provisionContents) { + return PROVISIONING_PROFILE_UUID_REGEX.test(provisionContents); + } + + function findValidMobileProvision(provisions, errorCallback, successCallback) { + if (provisions.length === 0) { + return errorCallback('No suitable mobile provision found!'); + } + + var currentMobileProvision = provisions[0]; + var currentMobileProvisionPath = path.join(PATH_TO_MOBILE_PROVISIONS, currentMobileProvision); + + exec("security cms -D -i \"" + currentMobileProvisionPath + "\"", function (error, stdout, stderr) { + logErrorIfExists(error); + if (isProvisionUUIDSuitable(stdout)) { + return successCallback(currentMobileProvision); + } + provisions.splice(0, 1); + findValidMobileProvision(provisions, errorCallback, successCallback); + }); + } + + function getMobileProvisions() { + return fs.readdirSync(PATH_TO_MOBILE_PROVISIONS); + } + + if (PROVISIONING_PROFILE_REQUIRED) { + var mobileProvisions = getMobileProvisions(); + if (mobileProvisions.length === 0) { + return logErrorIfExists('No mobile provisions found!'); + } + + if (mobileProvisions.indexOf(sanitizeMobileProvision(EXPANDED_PROVISIONING_PROFILE)) !== -1) { + createPushNotificationsEnabledHeaderFileWithMobileProvision(EXPANDED_PROVISIONING_PROFILE); + return this; + } + + findValidMobileProvision(mobileProvisions, logErrorIfExists, createPushNotificationsEnabledHeaderFileWithMobileProvision); + } else { + createPushNotificationsEnabledHeaderFile(true); + } +}()); \ No newline at end of file