diff --git a/OneSignal.podspec b/OneSignal.podspec index 4fce2b2e8..3925862f4 100755 --- a/OneSignal.podspec +++ b/OneSignal.podspec @@ -12,5 +12,5 @@ Pod::Spec.new do |s| s.requires_arc = true s.ios.vendored_frameworks = 'iOS_SDK/Framework/OneSignal.framework' - s.framework = 'SystemConfiguration' + s.framework = 'SystemConfiguration', 'UIKit' end diff --git a/OneSignalExample/OSServiceExtension/Info.plist b/OneSignalExample/NotificationServiceExtension/Info.plist similarity index 95% rename from OneSignalExample/OSServiceExtension/Info.plist rename to OneSignalExample/NotificationServiceExtension/Info.plist index 811d19563..f4bf92b5a 100644 --- a/OneSignalExample/OSServiceExtension/Info.plist +++ b/OneSignalExample/NotificationServiceExtension/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion en CFBundleDisplayName - OSServiceExtension + NotificationServiceExtension CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier diff --git a/OneSignalExample/NotificationServiceExtension/NotificationService.h b/OneSignalExample/NotificationServiceExtension/NotificationService.h new file mode 100644 index 000000000..521d4e11c --- /dev/null +++ b/OneSignalExample/NotificationServiceExtension/NotificationService.h @@ -0,0 +1,32 @@ +/** + * Modified MIT License + * + * Copyright 2017 OneSignal + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * 1. The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * 2. All copies of substantial portions of the Software may only be used in connection + * with services provided by OneSignal. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#import + +@interface NotificationService : UNNotificationServiceExtension + +@end diff --git a/OneSignalExample/NotificationServiceExtension/NotificationService.m b/OneSignalExample/NotificationServiceExtension/NotificationService.m new file mode 100644 index 000000000..7b41c52a4 --- /dev/null +++ b/OneSignalExample/NotificationServiceExtension/NotificationService.m @@ -0,0 +1,61 @@ +/** + * Modified MIT License + * + * Copyright 2017 OneSignal + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * 1. The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * 2. All copies of substantial portions of the Software may only be used in connection + * with services provided by OneSignal. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#import + +#import "NotificationService.h" + +@interface NotificationService () + +@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver); +@property (nonatomic, strong) UNNotificationRequest *recievedRequest; +@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent; + +@end + +@implementation NotificationService + +- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { + self.recievedRequest = request; + self.contentHandler = contentHandler; + self.bestAttemptContent = [request.content mutableCopy]; + + [OneSignal didReceiveNotificatioExtensionnRequest:self.recievedRequest withMutableNotificationContent:self.bestAttemptContent]; + + self.contentHandler(self.bestAttemptContent); +} + +- (void)serviceExtensionTimeWillExpire { + // Called just before the extension will be terminated by the system. + // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. + + [OneSignal serviceExtensionTimeWillExpireRequest:self.recievedRequest withMutableNotificationContent:self.bestAttemptContent]; + + self.contentHandler(self.bestAttemptContent); +} + +@end diff --git a/OneSignalExample/OSContentExension/Base.lproj/MainInterface.storyboard b/OneSignalExample/OSContentExension/Base.lproj/MainInterface.storyboard deleted file mode 100644 index 0debd0918..000000000 --- a/OneSignalExample/OSContentExension/Base.lproj/MainInterface.storyboard +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/OneSignalExample/OSContentExension/Info.plist b/OneSignalExample/OSContentExension/Info.plist deleted file mode 100644 index d41942160..000000000 --- a/OneSignalExample/OSContentExension/Info.plist +++ /dev/null @@ -1,38 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - OSContentExension - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - XPC! - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - NSExtension - - NSExtensionAttributes - - UNNotificationExtensionCategory - myOSContentCategory - UNNotificationExtensionInitialContentSizeRatio - 1 - - NSExtensionMainStoryboard - MainInterface - NSExtensionPointIdentifier - com.apple.usernotifications.content-extension - - - diff --git a/OneSignalExample/OSContentExension/NotificationViewController.h b/OneSignalExample/OSContentExension/NotificationViewController.h deleted file mode 100644 index 5d49461b9..000000000 --- a/OneSignalExample/OSContentExension/NotificationViewController.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// NotificationViewController.h -// OSContentExension -// -// Created by Joseph Kalash on 9/12/16. -// Copyright © 2016 OneSignal. All rights reserved. -// - -#import - -@interface NotificationViewController : UIViewController - -@end diff --git a/OneSignalExample/OSContentExension/NotificationViewController.m b/OneSignalExample/OSContentExension/NotificationViewController.m deleted file mode 100644 index 4c4c8e9a3..000000000 --- a/OneSignalExample/OSContentExension/NotificationViewController.m +++ /dev/null @@ -1,30 +0,0 @@ -// -// NotificationViewController.m -// OSContentExension -// -// Created by Joseph Kalash on 9/12/16. -// Copyright © 2016 OneSignal. All rights reserved. -// - -#import "NotificationViewController.h" -#import -#import - -@interface NotificationViewController () - -@property IBOutlet UILabel *label; - -@end - -@implementation NotificationViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - -} - -- (void)didReceiveNotification:(UNNotification *)notification { - self.label.text = notification.request.content.body; -} - -@end diff --git a/OneSignalExample/OSServiceExtension/NotificationService.h b/OneSignalExample/OSServiceExtension/NotificationService.h deleted file mode 100644 index c03e70844..000000000 --- a/OneSignalExample/OSServiceExtension/NotificationService.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// NotificationService.h -// OSServiceExtension -// -// Created by Joseph Kalash on 9/12/16. -// Copyright © 2016 OneSignal. All rights reserved. -// - -#import - -@interface NotificationService : UNNotificationServiceExtension - -@end diff --git a/OneSignalExample/OSServiceExtension/NotificationService.m b/OneSignalExample/OSServiceExtension/NotificationService.m deleted file mode 100644 index 62d038872..000000000 --- a/OneSignalExample/OSServiceExtension/NotificationService.m +++ /dev/null @@ -1,37 +0,0 @@ -// -// NotificationService.m -// OSServiceExtension -// -// Created by Joseph Kalash on 9/12/16. -// Copyright © 2016 OneSignal. All rights reserved. -// - -#import "NotificationService.h" - -@interface NotificationService () - -@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver); -@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent; - -@end - -@implementation NotificationService - -- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { - - self.contentHandler = contentHandler; - self.bestAttemptContent = [request.content mutableCopy]; - - // Modify the notification content here... - self.bestAttemptContent.title = [NSString stringWithFormat:@"[Modified-thorugh-OneSignal] %@", self.bestAttemptContent.title]; - - self.contentHandler(self.bestAttemptContent); -} - -- (void)serviceExtensionTimeWillExpire { - // Called just before the extension will be terminated by the system. - // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. - self.contentHandler(self.bestAttemptContent); -} - -@end diff --git a/OneSignalExample/OSServiceExtension/OSServiceExtension.entitlements b/OneSignalExample/OSServiceExtension/OSServiceExtension.entitlements deleted file mode 100644 index 903def2af..000000000 --- a/OneSignalExample/OSServiceExtension/OSServiceExtension.entitlements +++ /dev/null @@ -1,8 +0,0 @@ - - - - - aps-environment - development - - diff --git a/OneSignalExample/OneSignalExample.xcodeproj/project.pbxproj b/OneSignalExample/OneSignalExample.xcodeproj/project.pbxproj index 6e58094f6..3669fee88 100755 --- a/OneSignalExample/OneSignalExample.xcodeproj/project.pbxproj +++ b/OneSignalExample/OneSignalExample.xcodeproj/project.pbxproj @@ -12,12 +12,11 @@ 37D0A46A192B077E009DC9F4 /* notification.wav in Resources */ = {isa = PBXBuildFile; fileRef = 37D0A469192B077E009DC9F4 /* notification.wav */; }; 37E277221ACBB40100D49C8D /* OneSignal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37E277211ACBB40100D49C8D /* OneSignal.framework */; }; 37F9CA1D19D9CBAD0084DB7F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37F9CA1C19D9CBAD0084DB7F /* UIKit.framework */; }; - 3EA62ED41D877A9600E5845A /* NotificationService.m in Sources */ = {isa = PBXBuildFile; fileRef = 3EA62ED31D877A9600E5845A /* NotificationService.m */; }; - 3EA62ED81D877A9600E5845A /* OSServiceExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 3EA62ED01D877A9600E5845A /* OSServiceExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 3EA62EE81D877B1100E5845A /* NotificationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3EA62EE71D877B1100E5845A /* NotificationViewController.m */; }; - 3EA62EEB1D877B1100E5845A /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3EA62EE91D877B1100E5845A /* MainInterface.storyboard */; }; - 3EA62EEF1D877B1100E5845A /* OSContentExension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 3EA62EE01D877B1100E5845A /* OSContentExension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 913D1E191DC052D30060EB25 /* UserNotifications.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 913D1E181DC052D30060EB25 /* UserNotifications.framework */; }; + 91172A5D1E6F6D6700D13B84 /* OneSignal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37E277211ACBB40100D49C8D /* OneSignal.framework */; }; + 91172A5E1E6F6DC200D13B84 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37F9CA1C19D9CBAD0084DB7F /* UIKit.framework */; }; + 91172A5F1E6F6DDB00D13B84 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37668EEA1AA810740095D813 /* SystemConfiguration.framework */; }; + 916B37141E6F520E00CEE4AA /* NotificationService.m in Sources */ = {isa = PBXBuildFile; fileRef = 916B37131E6F520E00CEE4AA /* NotificationService.m */; }; + 916B37181E6F520E00CEE4AA /* NotificationServiceExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 916B37101E6F520D00CEE4AA /* NotificationServiceExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; DE4BCB72161638D4003F4A66 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DE4BCB70161638D4003F4A66 /* InfoPlist.strings */; }; DE4BCB74161638D4003F4A66 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DE4BCB73161638D4003F4A66 /* main.m */; }; DE4BCB78161638D4003F4A66 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DE4BCB77161638D4003F4A66 /* AppDelegate.m */; }; @@ -27,19 +26,12 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 3EA62ED61D877A9600E5845A /* PBXContainerItemProxy */ = { + 916B37161E6F520E00CEE4AA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = DE4BCB5A161638D4003F4A66 /* Project object */; proxyType = 1; - remoteGlobalIDString = 3EA62ECF1D877A9600E5845A; - remoteInfo = OSServiceExtension; - }; - 3EA62EED1D877B1100E5845A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = DE4BCB5A161638D4003F4A66 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3EA62EDF1D877B1100E5845A; - remoteInfo = OSContentExension; + remoteGlobalIDString = 916B370F1E6F520D00CEE4AA; + remoteInfo = NotificationServiceExtension; }; /* End PBXContainerItemProxy section */ @@ -50,8 +42,7 @@ dstPath = ""; dstSubfolderSpec = 13; files = ( - 3EA62ED81D877A9600E5845A /* OSServiceExtension.appex in Embed App Extensions */, - 3EA62EEF1D877B1100E5845A /* OSContentExension.appex in Embed App Extensions */, + 916B37181E6F520E00CEE4AA /* NotificationServiceExtension.appex in Embed App Extensions */, ); name = "Embed App Extensions"; runOnlyForDeploymentPostprocessing = 0; @@ -64,18 +55,12 @@ 37D0A469192B077E009DC9F4 /* notification.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = notification.wav; sourceTree = ""; }; 37E277211ACBB40100D49C8D /* OneSignal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OneSignal.framework; path = ../iOS_SDK/Framework/OneSignal.framework; sourceTree = ""; }; 37F9CA1C19D9CBAD0084DB7F /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; - 3EA62ED01D877A9600E5845A /* OSServiceExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = OSServiceExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; - 3EA62ED21D877A9600E5845A /* NotificationService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificationService.h; sourceTree = ""; }; - 3EA62ED31D877A9600E5845A /* NotificationService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationService.m; sourceTree = ""; }; - 3EA62ED51D877A9600E5845A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 3EA62EE01D877B1100E5845A /* OSContentExension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = OSContentExension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; - 3EA62EE61D877B1100E5845A /* NotificationViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificationViewController.h; sourceTree = ""; }; - 3EA62EE71D877B1100E5845A /* NotificationViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationViewController.m; sourceTree = ""; }; - 3EA62EEA1D877B1100E5845A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; }; - 3EA62EEC1D877B1100E5845A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 913D1E181DC052D30060EB25 /* UserNotifications.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserNotifications.framework; path = System/Library/Frameworks/UserNotifications.framework; sourceTree = SDKROOT; }; + 91172A4D1E6F5DD100D13B84 /* UserNotificationsUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserNotificationsUI.framework; path = System/Library/Frameworks/UserNotificationsUI.framework; sourceTree = SDKROOT; }; + 916B37101E6F520D00CEE4AA /* NotificationServiceExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = NotificationServiceExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 916B37121E6F520E00CEE4AA /* NotificationService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificationService.h; sourceTree = ""; }; + 916B37131E6F520E00CEE4AA /* NotificationService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationService.m; sourceTree = ""; }; + 916B37151E6F520E00CEE4AA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 91D311361DB9A996001B7365 /* OneSignalExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = OneSignalExample.entitlements; sourceTree = ""; }; - 91D684CE1DC2D7FB00D09C41 /* OSServiceExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = OSServiceExtension.entitlements; sourceTree = ""; }; DE4BCB63161638D4003F4A66 /* OneSignalExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OneSignalExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; DE4BCB6F161638D4003F4A66 /* OneSignalExample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "OneSignalExample-Info.plist"; sourceTree = ""; }; DE4BCB71161638D4003F4A66 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -90,17 +75,13 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 3EA62ECD1D877A9600E5845A /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3EA62EDD1D877B1100E5845A /* Frameworks */ = { + 916B370D1E6F520D00CEE4AA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 91172A5F1E6F6DDB00D13B84 /* SystemConfiguration.framework in Frameworks */, + 91172A5E1E6F6DC200D13B84 /* UIKit.framework in Frameworks */, + 91172A5D1E6F6D6700D13B84 /* OneSignal.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -108,7 +89,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 913D1E191DC052D30060EB25 /* UserNotifications.framework in Frameworks */, 37E277221ACBB40100D49C8D /* OneSignal.framework in Frameworks */, 37668EEB1AA810740095D813 /* SystemConfiguration.framework in Frameworks */, 37F9CA1D19D9CBAD0084DB7F /* UIKit.framework in Frameworks */, @@ -118,26 +98,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 3EA62ED11D877A9600E5845A /* OSServiceExtension */ = { - isa = PBXGroup; - children = ( - 91D684CE1DC2D7FB00D09C41 /* OSServiceExtension.entitlements */, - 3EA62ED21D877A9600E5845A /* NotificationService.h */, - 3EA62ED31D877A9600E5845A /* NotificationService.m */, - 3EA62ED51D877A9600E5845A /* Info.plist */, - ); - path = OSServiceExtension; - sourceTree = ""; - }; - 3EA62EE51D877B1100E5845A /* OSContentExension */ = { + 916B37111E6F520E00CEE4AA /* NotificationServiceExtension */ = { isa = PBXGroup; children = ( - 3EA62EE61D877B1100E5845A /* NotificationViewController.h */, - 3EA62EE71D877B1100E5845A /* NotificationViewController.m */, - 3EA62EE91D877B1100E5845A /* MainInterface.storyboard */, - 3EA62EEC1D877B1100E5845A /* Info.plist */, + 916B37121E6F520E00CEE4AA /* NotificationService.h */, + 916B37131E6F520E00CEE4AA /* NotificationService.m */, + 916B37151E6F520E00CEE4AA /* Info.plist */, ); - path = OSContentExension; + path = NotificationServiceExtension; sourceTree = ""; }; DE4BCB58161638D4003F4A66 = { @@ -147,8 +115,7 @@ 373D19141ACCC60F00BBAB2E /* AppIcon.xcassets */, 37D0A469192B077E009DC9F4 /* notification.wav */, DE4BCB6D161638D4003F4A66 /* push-notifications */, - 3EA62ED11D877A9600E5845A /* OSServiceExtension */, - 3EA62EE51D877B1100E5845A /* OSContentExension */, + 916B37111E6F520E00CEE4AA /* NotificationServiceExtension */, DE4BCB66161638D4003F4A66 /* Frameworks */, DE4BCB64161638D4003F4A66 /* Products */, ); @@ -158,8 +125,7 @@ isa = PBXGroup; children = ( DE4BCB63161638D4003F4A66 /* OneSignalExample.app */, - 3EA62ED01D877A9600E5845A /* OSServiceExtension.appex */, - 3EA62EE01D877B1100E5845A /* OSContentExension.appex */, + 916B37101E6F520D00CEE4AA /* NotificationServiceExtension.appex */, ); name = Products; sourceTree = ""; @@ -167,10 +133,10 @@ DE4BCB66161638D4003F4A66 /* Frameworks */ = { isa = PBXGroup; children = ( - 913D1E181DC052D30060EB25 /* UserNotifications.framework */, 37E277211ACBB40100D49C8D /* OneSignal.framework */, 37668EEA1AA810740095D813 /* SystemConfiguration.framework */, 37F9CA1C19D9CBAD0084DB7F /* UIKit.framework */, + 91172A4D1E6F5DD100D13B84 /* UserNotificationsUI.framework */, ); name = Frameworks; sourceTree = ""; @@ -203,38 +169,21 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 3EA62ECF1D877A9600E5845A /* OSServiceExtension */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3EA62ED91D877A9600E5845A /* Build configuration list for PBXNativeTarget "OSServiceExtension" */; - buildPhases = ( - 3EA62ECC1D877A9600E5845A /* Sources */, - 3EA62ECD1D877A9600E5845A /* Frameworks */, - 3EA62ECE1D877A9600E5845A /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = OSServiceExtension; - productName = OSServiceExtension; - productReference = 3EA62ED01D877A9600E5845A /* OSServiceExtension.appex */; - productType = "com.apple.product-type.app-extension"; - }; - 3EA62EDF1D877B1100E5845A /* OSContentExension */ = { + 916B370F1E6F520D00CEE4AA /* NotificationServiceExtension */ = { isa = PBXNativeTarget; - buildConfigurationList = 3EA62EF01D877B1100E5845A /* Build configuration list for PBXNativeTarget "OSContentExension" */; + buildConfigurationList = 916B371B1E6F520E00CEE4AA /* Build configuration list for PBXNativeTarget "NotificationServiceExtension" */; buildPhases = ( - 3EA62EDC1D877B1100E5845A /* Sources */, - 3EA62EDD1D877B1100E5845A /* Frameworks */, - 3EA62EDE1D877B1100E5845A /* Resources */, + 916B370C1E6F520D00CEE4AA /* Sources */, + 916B370D1E6F520D00CEE4AA /* Frameworks */, + 916B370E1E6F520D00CEE4AA /* Resources */, ); buildRules = ( ); dependencies = ( ); - name = OSContentExension; - productName = OSContentExension; - productReference = 3EA62EE01D877B1100E5845A /* OSContentExension.appex */; + name = NotificationServiceExtension; + productName = NotificationServiceExtension; + productReference = 916B37101E6F520D00CEE4AA /* NotificationServiceExtension.appex */; productType = "com.apple.product-type.app-extension"; }; DE4BCB62161638D4003F4A66 /* OneSignalExample */ = { @@ -249,8 +198,7 @@ buildRules = ( ); dependencies = ( - 3EA62ED71D877A9600E5845A /* PBXTargetDependency */, - 3EA62EEE1D877B1100E5845A /* PBXTargetDependency */, + 916B37171E6F520E00CEE4AA /* PBXTargetDependency */, ); name = OneSignalExample; productName = "push-notifications"; @@ -267,18 +215,8 @@ LastUpgradeCheck = 0800; ORGANIZATIONNAME = OneSignal; TargetAttributes = { - 3EA62ECF1D877A9600E5845A = { - CreatedOnToolsVersion = 8.0; - DevelopmentTeam = 99SW8E36CT; - ProvisioningStyle = Automatic; - SystemCapabilities = { - com.apple.Push = { - enabled = 0; - }; - }; - }; - 3EA62EDF1D877B1100E5845A = { - CreatedOnToolsVersion = 8.0; + 916B370F1E6F520D00CEE4AA = { + CreatedOnToolsVersion = 8.2.1; DevelopmentTeam = 99SW8E36CT; ProvisioningStyle = Automatic; }; @@ -310,25 +248,16 @@ projectRoot = ""; targets = ( DE4BCB62161638D4003F4A66 /* OneSignalExample */, - 3EA62ECF1D877A9600E5845A /* OSServiceExtension */, - 3EA62EDF1D877B1100E5845A /* OSContentExension */, + 916B370F1E6F520D00CEE4AA /* NotificationServiceExtension */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - 3EA62ECE1D877A9600E5845A /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3EA62EDE1D877B1100E5845A /* Resources */ = { + 916B370E1E6F520D00CEE4AA /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 3EA62EEB1D877B1100E5845A /* MainInterface.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -347,19 +276,11 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 3EA62ECC1D877A9600E5845A /* Sources */ = { + 916B370C1E6F520D00CEE4AA /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 3EA62ED41D877A9600E5845A /* NotificationService.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3EA62EDC1D877B1100E5845A /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3EA62EE81D877B1100E5845A /* NotificationViewController.m in Sources */, + 916B37141E6F520E00CEE4AA /* NotificationService.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -376,27 +297,14 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 3EA62ED71D877A9600E5845A /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3EA62ECF1D877A9600E5845A /* OSServiceExtension */; - targetProxy = 3EA62ED61D877A9600E5845A /* PBXContainerItemProxy */; - }; - 3EA62EEE1D877B1100E5845A /* PBXTargetDependency */ = { + 916B37171E6F520E00CEE4AA /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 3EA62EDF1D877B1100E5845A /* OSContentExension */; - targetProxy = 3EA62EED1D877B1100E5845A /* PBXContainerItemProxy */; + target = 916B370F1E6F520D00CEE4AA /* NotificationServiceExtension */; + targetProxy = 916B37161E6F520E00CEE4AA /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ - 3EA62EE91D877B1100E5845A /* MainInterface.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 3EA62EEA1D877B1100E5845A /* Base */, - ); - name = MainInterface.storyboard; - sourceTree = ""; - }; DE4BCB70161638D4003F4A66 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( @@ -416,34 +324,7 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ - 3EA62EDA1D877A9600E5845A /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - CODE_SIGN_IDENTITY = "iOS Distribution: Lilomi Inc."; - "CODE_SIGN_IDENTITY[sdk=*]" = "iPhone Developer"; - DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = 99SW8E36CT; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - INFOPLIST_FILE = OSServiceExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MTL_ENABLE_DEBUG_INFO = YES; - PRODUCT_BUNDLE_IDENTIFIER = com.onesignal.example.OSServiceExtension; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 3EA62EDB1D877A9600E5845A /* Release */ = { + 916B37191E6F520E00CEE4AA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_NONNULL = YES; @@ -453,53 +334,24 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - CODE_SIGN_IDENTITY = "iOS Distribution: Lilomi Inc."; - "CODE_SIGN_IDENTITY[sdk=*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = 99SW8E36CT; - ENABLE_NS_ASSERTIONS = NO; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - INFOPLIST_FILE = OSServiceExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = com.onesignal.example.OSServiceExtension; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Release; - }; - 3EA62EF11D877B1100E5845A /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - CODE_SIGN_IDENTITY = "iOS Distribution: Lilomi Inc."; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 99SW8E36CT; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - INFOPLIST_FILE = OSContentExension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + INFOPLIST_FILE = NotificationServiceExtension/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; - PRODUCT_BUNDLE_IDENTIFIER = com.onesignal.example.OSContentExension; + PRODUCT_BUNDLE_IDENTIFIER = com.onesignal.example.NotificationServiceExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; }; name = Debug; }; - 3EA62EF21D877B1100E5845A /* Release */ = { + 916B371A1E6F520E00CEE4AA /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_NONNULL = YES; @@ -509,8 +361,8 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - CODE_SIGN_IDENTITY = "iOS Distribution: Lilomi Inc."; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -518,11 +370,11 @@ ENABLE_NS_ASSERTIONS = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - INFOPLIST_FILE = OSContentExension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + INFOPLIST_FILE = NotificationServiceExtension/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = com.onesignal.example.OSContentExension; + PRODUCT_BUNDLE_IDENTIFIER = com.onesignal.example.NotificationServiceExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; }; @@ -544,6 +396,10 @@ COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/../iOS_SDK/Framework\"/**", + ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -560,6 +416,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../iOS_SDK/Framework\"/**"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; @@ -583,6 +440,10 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/../iOS_SDK/Framework\"/**", + ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; @@ -592,6 +453,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../iOS_SDK/Framework\"/**"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; OTHER_LDFLAGS = "-ObjC"; @@ -654,20 +516,11 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 3EA62ED91D877A9600E5845A /* Build configuration list for PBXNativeTarget "OSServiceExtension" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3EA62EDA1D877A9600E5845A /* Debug */, - 3EA62EDB1D877A9600E5845A /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3EA62EF01D877B1100E5845A /* Build configuration list for PBXNativeTarget "OSContentExension" */ = { + 916B371B1E6F520E00CEE4AA /* Build configuration list for PBXNativeTarget "NotificationServiceExtension" */ = { isa = XCConfigurationList; buildConfigurations = ( - 3EA62EF11D877B1100E5845A /* Debug */, - 3EA62EF21D877B1100E5845A /* Release */, + 916B37191E6F520E00CEE4AA /* Debug */, + 916B371A1E6F520E00CEE4AA /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/OneSignalExample/push-notifications/AppDelegate.h b/OneSignalExample/push-notifications/AppDelegate.h index 3dfaa654e..722a35474 100755 --- a/OneSignalExample/push-notifications/AppDelegate.h +++ b/OneSignalExample/push-notifications/AppDelegate.h @@ -1,7 +1,7 @@ /** * Modified MIT License * - * Copyright 2016 OneSignal + * Copyright 2017 OneSignal * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/OneSignalExample/push-notifications/AppDelegate.m b/OneSignalExample/push-notifications/AppDelegate.m index 92b2f5730..c4425b865 100755 --- a/OneSignalExample/push-notifications/AppDelegate.m +++ b/OneSignalExample/push-notifications/AppDelegate.m @@ -1,7 +1,7 @@ /** * Modified MIT License * - * Copyright 2016 OneSignal + * Copyright 2017 OneSignal * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,14 +32,17 @@ @implementation AppDelegate - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { - // Eanble logging to help debug issues. visualLevel will show alert dialog boxes. - [OneSignal setLogLevel:ONE_S_LL_VERBOSE visualLevel:ONE_S_LL_INFO]; + // (Optional) - Eanble logging to help debug issues. visualLevel will show alert dialog boxes. + // Remove setLogLevel in the production version of your app. + [OneSignal setLogLevel:ONE_S_LL_VERBOSE visualLevel:ONE_S_LL_WARN]; - [OneSignal initWithLaunchOptions:launchOptions appId:@"b2f7f966-d8cc-11e4-bed1-df8f05be55ba" handleNotificationReceived:^(OSNotification *notification) { + // (Optional) - Create block the will fire when a notification is recieved while the app is in focus. + id notificationRecievedBlock = ^(OSNotification *notification) { NSLog(@"Received Notification - %@", notification.payload.notificationID); - } handleNotificationAction:^(OSNotificationOpenedResult *result) { - - // This block gets called when the user reacts to a notification received + }; + + // (Optional) - Create block that will fire when a notification is tapped on. + id notificationOpenedBlock = ^(OSNotificationOpenedResult *result) { OSNotificationPayload* payload = result.notification.payload; NSString* messageTitle = @"OneSignal Example"; @@ -47,7 +50,7 @@ - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(N if (payload.additionalData) { - if(payload.title) + if (payload.title) messageTitle = payload.title; if (result.action.actionID) @@ -60,33 +63,19 @@ - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(N cancelButtonTitle:@"Close" otherButtonTitles:nil, nil]; [alertView show]; - - } settings:@{kOSSettingsKeyInFocusDisplayOption : @(OSNotificationDisplayTypeNotification), kOSSettingsKeyAutoPrompt : @YES}]; + }; + + // (Optional) - Configuration options for OneSignal settings. + id oneSignalSetting = @{kOSSettingsKeyInFocusDisplayOption : @(OSNotificationDisplayTypeNotification), kOSSettingsKeyAutoPrompt : @YES}; - [OneSignal IdsAvailable:^(NSString *userId, NSString *pushToken) { - if(pushToken) { - NSLog(@"Received push token - %@", pushToken); - NSLog(@"User ID - %@", userId); - } - }]; - /* - // iOS 10 ONLY - Add category for the OSContentExtension - // Make sure to add UserNotifications framework in the Linked Frameworks & Libraries. - - [[UNUserNotificationCenter currentNotificationCenter] getNotificationCategoriesWithCompletionHandler:^(NSSet * _Nonnull categories) { - - UNNotificationAction* myAction = [UNNotificationAction actionWithIdentifier:@"action0" title:@"Hit Me!" options:UNNotificationActionOptionForeground]; - UNNotificationCategory* myCategory = [UNNotificationCategory categoryWithIdentifier:@"myOSContentCategory" actions:@[myAction] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction]; - NSSet* mySet = [[NSSet alloc] initWithArray:@[myCategory]]; - - //Add existing cateogories - mySet = [mySet setByAddingObjectsFromSet:categories]; - - [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:mySet]; - }]; - */ + // (REQUIRED) - Initializes OneSignal + [OneSignal initWithLaunchOptions:launchOptions + appId:@"b2f7f966-d8cc-11e4-bed1-df8f05be55ba" + handleNotificationReceived:notificationRecievedBlock + handleNotificationAction:notificationOpenedBlock + settings:oneSignalSetting]; return YES; } diff --git a/OneSignalExample/push-notifications/ViewController.h b/OneSignalExample/push-notifications/ViewController.h index 7cc9bd672..759f6224e 100755 --- a/OneSignalExample/push-notifications/ViewController.h +++ b/OneSignalExample/push-notifications/ViewController.h @@ -1,7 +1,7 @@ /** * Modified MIT License * - * Copyright 2015 OneSignal + * Copyright 2017 OneSignal * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/OneSignalExample/push-notifications/ViewController.m b/OneSignalExample/push-notifications/ViewController.m index 2bb7a0635..ce4d2a90b 100755 --- a/OneSignalExample/push-notifications/ViewController.m +++ b/OneSignalExample/push-notifications/ViewController.m @@ -1,7 +1,7 @@ /** * Modified MIT License * - * Copyright 2015 OneSignal + * Copyright 2017 OneSignal * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/iOS_SDK/OneSignal/OneSignal.h b/iOS_SDK/OneSignal/OneSignal.h index b3b819460..f8cc5c0cb 100755 --- a/iOS_SDK/OneSignal/OneSignal.h +++ b/iOS_SDK/OneSignal/OneSignal.h @@ -1,7 +1,7 @@ /** * Modified MIT License * - * Copyright 2016 OneSignal + * Copyright 2017 OneSignal * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,21 +28,18 @@ /*** ### Setting up the SDK ### - Follow the documentation from https://documentation.onesignal.com/docs/installing-the-onesignal-ios-sdk to setup OneSignal in your app. + Follow the documentation from https://documentation.onesignal.com/docs/ios-sdk-setupto setup OneSignal in your app. ### API Reference ### Follow the documentation from https://documentation.onesignal.com/docs/ios-sdk-api for a detailed explanation of the API. - ### FAQ & Troubleshoot ### - FAQ: https://documentation.onesignal.com/docs/frequently-asked-questions-1 - Troubleshoot: https://documentation.onesignal.com/docs/common-problems-1 + ### Troubleshoot ### + Follow the documentation from https://documentation.onesignal.com/docs/troubleshooting-ios to fix common problems. - For help on how to upgrade your code from 1.* SDK to 2.*: https://documentation.onesignal.com/docs/upgrading-to-sdk-20 + For help on how to upgrade your code from 1.* SDK to 2.*: https://documentation.onesignal.com/docs/upgrading-to-ios-sdk-20 ### More ### - iOS Configuration: https://documentation.onesignal.com/docs/generating-an-ios-push-certificate - REST API: https://documentation.onesignal.com/docs/server-api-overview - Create Notification API: https://documentation.onesignal.com/docs/notifications-create-notification + iOS Push Cert: https://documentation.onesignal.com/docs/generating-an-ios-push-certificate ***/ @@ -278,4 +275,13 @@ typedef NS_ENUM(NSUInteger, ONE_S_LOG_LEVEL) { // Only used for wrapping SDKs, such as Unity, Cordova, Xamarin, etc. + (void)setMSDKType:(NSString*)type; + +#ifdef XC8_AVAILABLE +// iOS 10 only +// Process from Notification Service Extension. +// Used for iOS Media Attachemtns and Action Buttons. ++ (UNMutableNotificationContent*)didReceiveNotificatioExtensionnRequest:(UNNotificationRequest *)request withMutableNotificationContent:(UNMutableNotificationContent*)replacementContent; ++ (UNMutableNotificationContent*)serviceExtensionTimeWillExpireRequest:(UNNotificationRequest *)request withMutableNotificationContent:(UNMutableNotificationContent*)replacementContent; +#endif + @end diff --git a/iOS_SDK/OneSignal/OneSignal.m b/iOS_SDK/OneSignal/OneSignal.m index 12dc922a8..6ce90b1f5 100755 --- a/iOS_SDK/OneSignal/OneSignal.m +++ b/iOS_SDK/OneSignal/OneSignal.m @@ -47,6 +47,8 @@ #import #import +#import + #define NOTIFICATION_TYPE_NONE 0 #define NOTIFICATION_TYPE_BADGE 1 #define NOTIFICATION_TYPE_SOUND 2 @@ -1242,22 +1244,22 @@ + (void)didRegisterForRemoteNotifications:(UIApplication*)app deviceToken:(NSDat + (BOOL) remoteSilentNotification:(UIApplication*)application UserInfo:(NSDictionary*)userInfo completionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { BOOL startedBackgroundJob = false; - // If 'm' present then the notification has action buttons attached to it. NSDictionary* data = nil; - // Check for buttons or attachments - if (userInfo[@"os_data"][@"buttons"] || userInfo[@"at"] || userInfo[@"o"]) + // Check for buttons or attachments pre-2.4.0 version + if ((userInfo[@"os_data"][@"buttons"] && [userInfo[@"os_data"][@"buttons"] isKindOfClass:[NSDictionary class]]) || userInfo[@"at"] || userInfo[@"o"]) data = userInfo; // Generate local notification for action button and/or attachments. if (data) { + // iOS 10 if (NSClassFromString(@"UNUserNotificationCenter")) { startedBackgroundJob = true; #if XC8_AVAILABLE [OneSignalHelper addnotificationRequest:data userInfo:userInfo completionHandler:completionHandler]; #endif } - else { + else { // Pre-iOS 10 UILocalNotification* notification = [OneSignalHelper prepareUILocalNotification:data :userInfo]; [[UIApplication sharedApplication] scheduleLocalNotification:notification]; } @@ -1336,9 +1338,51 @@ + (void)syncHashedEmail:(NSString *)email { onFailure:nil]; } ++ (void)addActionButtonsToExtentionRequest:(UNNotificationRequest *)request withMutableNotificationContent:(UNMutableNotificationContent*)replacementContent { + if (request.content.categoryIdentifier && ![request.content.categoryIdentifier isEqualToString:@""]) + return; + + NSArray* buttonsPayloadList = request.content.userInfo[@"os_data"][@"buttons"]; + if (!buttonsPayloadList) + buttonsPayloadList = request.content.userInfo[@"buttons"]; + + if (buttonsPayloadList) + [OneSignalHelper addActionButtons:buttonsPayloadList toNotificationContent:replacementContent]; +} + +// Called from the app's Notification Service Extension ++ (UNMutableNotificationContent*)didReceiveNotificatioExtensionnRequest:(UNNotificationRequest *)request withMutableNotificationContent:(UNMutableNotificationContent*)replacementContent { + if (!replacementContent) + replacementContent = [request.content mutableCopy]; + + // Action Buttons + [self addActionButtonsToExtentionRequest:request withMutableNotificationContent:replacementContent]; + + // Media Attachments + NSDictionary* attachments = request.content.userInfo[@"os_data"][@"att"]; + if (!attachments) + attachments = request.content.userInfo[@"att"]; + if (attachments) + [OneSignalHelper addAttachments:attachments toNotificationContent:replacementContent]; + + return replacementContent; +} + + +// Called from the app's Notification Service Extension ++ (UNMutableNotificationContent*)serviceExtensionTimeWillExpireRequest:(UNNotificationRequest *)request withMutableNotificationContent:(UNMutableNotificationContent*)replacementContent { + if (!replacementContent) + replacementContent = [request.content mutableCopy]; + + [self addActionButtonsToExtentionRequest:request withMutableNotificationContent:replacementContent]; + + return replacementContent; +} + + @end -// Swizzles UIApplication class to swizzling the other following classes: +// Swizzles UIApplication class to swizzling the following: // - UIApplication // - setDelegate: // - Used to swizzle all UIApplicationDelegate selectors on the passed in class. diff --git a/iOS_SDK/OneSignal/OneSignalHelper.h b/iOS_SDK/OneSignal/OneSignalHelper.h index 45e94e6f8..d96a9fa3b 100644 --- a/iOS_SDK/OneSignal/OneSignalHelper.h +++ b/iOS_SDK/OneSignal/OneSignalHelper.h @@ -75,6 +75,8 @@ + (BOOL) isValidEmail:(NSString*)email; + (NSString*)hashUsingSha1:(NSString*)string; + (NSString*)hashUsingMD5:(NSString*)string; ++ (void)addAttachments:(NSDictionary*)attachments toNotificationContent:(id)content; ++ (void)addActionButtons:(NSArray*)buttonsPayloadList toNotificationContent:(id)content; #pragma clang diagnostic pop @end diff --git a/iOS_SDK/OneSignal/OneSignalHelper.m b/iOS_SDK/OneSignal/OneSignalHelper.m index b1636c816..a0defc973 100644 --- a/iOS_SDK/OneSignal/OneSignalHelper.m +++ b/iOS_SDK/OneSignal/OneSignalHelper.m @@ -72,6 +72,8 @@ - (id)initWithRawMessage:(NSDictionary*)message { if (self && message) { _rawPayload = [NSDictionary dictionaryWithDictionary:message]; + BOOL is2dot4Format = [_rawPayload[@"os_data"][@"buttons"] isKindOfClass:[NSArray class]]; + if (_rawPayload[@"aps"][@"content-available"]) _contentAvailable = (BOOL)_rawPayload[@"aps"][@"content-available"]; else @@ -83,18 +85,22 @@ - (id)initWithRawMessage:(NSDictionary*)message { _badge = [_rawPayload[@"badge"] intValue]; _actionButtons = _rawPayload[@"o"]; - if (!_actionButtons) - _actionButtons = _rawPayload[@"os_data"][@"buttons"][@"o"]; + if (!_actionButtons) { + if (is2dot4Format) + _actionButtons = _rawPayload[@"os_data"][@"buttons"]; + else + _actionButtons = _rawPayload[@"os_data"][@"buttons"][@"o"]; + } if(_rawPayload[@"aps"][@"sound"]) _sound = _rawPayload[@"aps"][@"sound"]; else if(_rawPayload[@"s"]) _sound = _rawPayload[@"s"]; - else + else if (!is2dot4Format) _sound = _rawPayload[@"os_data"][@"buttons"][@"s"]; if(_rawPayload[@"custom"]) { - NSDictionary * custom = _rawPayload[@"custom"]; + NSDictionary* custom = _rawPayload[@"custom"]; if (custom[@"a"]) _additionalData = [custom[@"a"] copy]; _notificationID = custom[@"i"]; @@ -113,8 +119,14 @@ - (id)initWithRawMessage:(NSDictionary*)message { _notificationID = os_data[@"i"]; _launchURL = os_data[@"u"]; - if(os_data[@"buttons"][@"at"]) - _attachments = [os_data[@"buttons"][@"at"] copy]; + if (is2dot4Format) { + if (os_data[@"att"]) + _attachments = [os_data[@"att"] copy]; + } + else { + if (os_data[@"buttons"][@"at"]) + _attachments = [os_data[@"buttons"][@"at"] copy]; + } } if(_rawPayload[@"m"]) { @@ -138,10 +150,14 @@ - (id)initWithRawMessage:(NSDictionary*)message { _body = a; } else if(_rawPayload[@"os_data"][@"buttons"][@"m"]) { - NSDictionary * m = _rawPayload[@"os_data"][@"buttons"][@"m"]; - _body = m[@"body"]; - _title = m[@"title"]; - _subtitle = m[@"subtitle"]; + id m = _rawPayload[@"os_data"][@"buttons"][@"m"]; + if ([m isKindOfClass:[NSDictionary class]]) { + _body = m[@"body"]; + _title = m[@"title"]; + _subtitle = m[@"subtitle"]; + } + else + _body = m; } } @@ -331,6 +347,10 @@ + (NSArray*)getActionButtons:(NSDictionary*)messageDict { return messageDict[@"o"]; } ++ (NSString*)getAppName { + return [[[NSBundle mainBundle] infoDictionary] objectForKey:(id)kCFBundleNameKey]; +} + + (NSDictionary*)getPushTitleBody:(NSDictionary*)messageDict { NSString *title; @@ -350,7 +370,7 @@ + (NSDictionary*)getPushTitleBody:(NSDictionary*)messageDict { } if (!title) - title = [[[NSBundle mainBundle] infoDictionary] objectForKey:(id)kCFBundleNameKey]; + title = [self getAppName]; if (!title) title = @""; @@ -405,17 +425,25 @@ + (NSDictionary*)getPushTitleBody:(NSDictionary*)messageDict { + (NSMutableDictionary*) formatApsPayloadIntoStandard:(NSDictionary*)remoteUserInfo identifier:(NSString*)identifier { NSMutableDictionary* userInfo, *customDict, *additionalData, *optionsDict; + BOOL is2dot4Format = false; if (remoteUserInfo[@"os_data"][@"buttons"]) { userInfo = [remoteUserInfo mutableCopy]; additionalData = [NSMutableDictionary dictionary]; - optionsDict = userInfo[@"os_data"][@"buttons"][@"o"]; + + is2dot4Format = [userInfo[@"os_data"][@"buttons"] isKindOfClass:[NSArray class]]; + if (is2dot4Format) + optionsDict = userInfo[@"os_data"][@"buttons"]; + else + optionsDict = userInfo[@"os_data"][@"buttons"][@"o"]; } else if (remoteUserInfo[@"custom"]) { userInfo = [remoteUserInfo mutableCopy]; customDict = [userInfo[@"custom"] mutableCopy]; if (customDict[@"a"]) additionalData = [[NSMutableDictionary alloc] initWithDictionary:customDict[@"a"]]; + else + additionalData = [[NSMutableDictionary alloc] init]; optionsDict = userInfo[@"o"]; } else @@ -433,15 +461,19 @@ + (NSMutableDictionary*) formatApsPayloadIntoStandard:(NSDictionary*)remoteUserI if (![@"com.apple.UNNotificationDefaultActionIdentifier" isEqualToString:identifier]) additionalData[@"actionSelected"] = identifier; + if ([additionalData count] == 0) + additionalData = nil; + if (remoteUserInfo[@"os_data"]) { [userInfo addEntriesFromDictionary:additionalData]; - userInfo[@"aps"] = @{@"alert" : userInfo[@"os_data"][@"buttons"][@"m"]}; + if (!is2dot4Format) + userInfo[@"aps"] = @{@"alert" : userInfo[@"os_data"][@"buttons"][@"m"]}; } else { customDict[@"a"] = additionalData; userInfo[@"custom"] = customDict; - if(userInfo[@"m"]) + if (userInfo[@"m"]) userInfo[@"aps"] = @{@"alert" : userInfo[@"m"]}; } @@ -545,11 +577,11 @@ + (UILocalNotification*)createUILocalNotification:(NSDictionary*)data { + (UILocalNotification*)prepareUILocalNotification:(NSDictionary*)data :(NSDictionary*)userInfo { - UILocalNotification * notification = [self createUILocalNotification:data]; + UILocalNotification *notification = [self createUILocalNotification:data]; if ([data[@"m"] isKindOfClass:[NSDictionary class]]) { if ([notification respondsToSelector:NSSelectorFromString(@"alertTitle")]) - [notification setValue:data[@"m"][@"title"] forKey:@"alertTitle"]; // Using reflection for pre-Xcode 6.2 support. + notification.alertTitle = data[@"m"][@"title"]; notification.alertBody = data[@"m"][@"body"]; } else @@ -603,29 +635,13 @@ + (void)registerAsUNNotificationCenterDelegate { } + (id)prepareUNNotificationRequest:(NSDictionary *)data :(NSDictionary *)userInfo { - + // iOS 10 Only if (!NSClassFromString(@"UNNotificationAction") || !NSClassFromString(@"UNNotificationRequest")) return NULL; - NSMutableArray * actionArray = [[NSMutableArray alloc] init]; - for(NSDictionary* button in [OneSignalHelper getActionButtons:data]) { - NSString* title = button[@"n"] != NULL ? button[@"n"] : @""; - NSString* buttonID = button[@"i"] != NULL ? button[@"i"] : title; - id action = [NSClassFromString(@"UNNotificationAction") actionWithIdentifier:buttonID title:title options:UNNotificationActionOptionForeground]; - [actionArray addObject:action]; - } - - if ([actionArray count] == 2) - actionArray = (NSMutableArray*)[[actionArray reverseObjectEnumerator] allObjects]; - - id category = [NSClassFromString(@"UNNotificationCategory") categoryWithIdentifier:@"__dynamic__" actions:actionArray intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction]; - - NSSet* set = [[NSSet alloc] initWithArray:@[category]]; - - [[NSClassFromString(@"UNUserNotificationCenter") currentNotificationCenter] setNotificationCategories:set]; - id content = [[NSClassFromString(@"UNMutableNotificationContent") alloc] init]; - [content setValue:@"__dynamic__" forKey:@"categoryIdentifier"]; + + [self addActionButtons:[OneSignalHelper getActionButtons:data] toNotificationContent:content]; NSDictionary* alertDict = [OneSignalHelper getPushTitleBody:data]; [content setValue:alertDict[@"title"] forKey:@"title"]; @@ -643,14 +659,61 @@ + (id)prepareUNNotificationRequest:(NSDictionary *)data :(NSDictionary *)userInf [content setValue:data[@"b"] forKey:@"badge"]; - //Check if media attached - NSMutableArray *attachments = [NSMutableArray new]; - NSDictionary * att = userInfo[@"at"]; - if(!att && userInfo[@"os_data"][@"buttons"]) + // Check if media attached + NSDictionary *att = userInfo[@"at"]; + if (!att && userInfo[@"os_data"][@"buttons"]) att = userInfo[@"os_data"][@"buttons"][@"at"]; - for(id key in att) { - NSString * URI = [att valueForKey:key]; + [self addAttachments:att toNotificationContent:content]; + + id trigger = [NSClassFromString(@"UNTimeIntervalNotificationTrigger") triggerWithTimeInterval:0.25 repeats:NO]; + + return [NSClassFromString(@"UNNotificationRequest") requestWithIdentifier:[self randomStringWithLength:16] content:content trigger:trigger]; +} + ++ (void)addActionButtons:(NSArray*)buttonsPayloadList toNotificationContent:(id)content { + if (!buttonsPayloadList || [buttonsPayloadList count] == 0) + return; + + NSMutableArray* actionArray = [[NSMutableArray alloc] init]; + for(NSDictionary* button in buttonsPayloadList) { + NSString* title = button[@"n"] != NULL ? button[@"n"] : @""; + NSString* buttonID = button[@"i"] != NULL ? button[@"i"] : title; + id action = [NSClassFromString(@"UNNotificationAction") actionWithIdentifier:buttonID title:title options:UNNotificationActionOptionForeground]; + [actionArray addObject:action]; + } + + if ([actionArray count] == 2) + actionArray = (NSMutableArray*)[[actionArray reverseObjectEnumerator] allObjects]; + + + // Get a full list of categories so we don't replace any exisiting ones. + __block NSMutableSet* allCategories; + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + [[NSClassFromString(@"UNUserNotificationCenter") currentNotificationCenter] getNotificationCategoriesWithCompletionHandler:^(NSSet *categories) { + allCategories = [categories mutableCopy]; + dispatch_semaphore_signal(semaphore); + }]; + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + + id category = [NSClassFromString(@"UNNotificationCategory") categoryWithIdentifier:@"__dynamic__" actions:actionArray intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction]; + + if (allCategories) + [allCategories addObject:category]; + else + allCategories = [[NSMutableSet alloc] initWithArray:@[category]]; + + + [[NSClassFromString(@"UNUserNotificationCenter") currentNotificationCenter] setNotificationCategories:allCategories]; + + [content setValue:@"__dynamic__" forKey:@"categoryIdentifier"]; +} + ++ (void)addAttachments:(NSDictionary*)attachments toNotificationContent:(id)content { + NSMutableArray *unAttachments = [NSMutableArray new]; + + for(id key in attachments) { + NSString * URI = [attachments valueForKey:key]; /* Remote Object */ if ([self verifyURL:URI]) { @@ -664,7 +727,7 @@ + (id)prepareUNNotificationRequest:(NSDictionary *)data :(NSDictionary *)userInf NSError* error; id attachment = [NSClassFromString(@"UNNotificationAttachment") attachmentWithIdentifier:key URL:url options:0 error:&error]; if (attachment) - [attachments addObject:attachment]; + [unAttachments addObject:attachment]; } /* Local in bundle resources */ else { @@ -680,25 +743,24 @@ + (id)prepareUNNotificationRequest:(NSDictionary *)data :(NSDictionary *)userInf NSError *error; id attachment = [NSClassFromString(@"UNNotificationAttachment") attachmentWithIdentifier:key URL:url options:0 error:&error]; if (attachment) - [attachments addObject:attachment]; + [unAttachments addObject:attachment]; } } } - [content setValue:attachments forKey:@"attachments"]; - - id trigger = [NSClassFromString(@"UNTimeIntervalNotificationTrigger") triggerWithTimeInterval:0.25 repeats:NO]; - - return [NSClassFromString(@"UNNotificationRequest") requestWithIdentifier:[self randomStringWithLength:16] content:content trigger:trigger]; + [content setValue:unAttachments forKey:@"attachments"]; } + (void)addnotificationRequest:(NSDictionary *)data userInfo:(NSDictionary *)userInfo completionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { + // Start background thread to download media so we don't lock the main UI thread. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [OneSignalHelper beginBackgroundMediaTask]; + id notificationRequest = [OneSignalHelper prepareUNNotificationRequest:data :userInfo]; [[NSClassFromString(@"UNUserNotificationCenter") currentNotificationCenter] addNotificationRequest:notificationRequest withCompletionHandler:^(NSError * _Nullable error) {}]; if (completionHandler) completionHandler(UIBackgroundFetchResultNewData); + [OneSignalHelper endBackgroundMediaTask]; }); diff --git a/iOS_SDK/OneSignalTracker.m b/iOS_SDK/OneSignalTracker.m index cd7e09460..0695c257d 100644 --- a/iOS_SDK/OneSignalTracker.m +++ b/iOS_SDK/OneSignalTracker.m @@ -43,10 +43,20 @@ + (NSString*)mUserId; @implementation OneSignalTracker -NSNumber* unSentActiveTime; -UIBackgroundTaskIdentifier focusBackgroundTask; -NSTimeInterval lastOpenedTime; -BOOL lastOnFocusWasToBackground = YES; +static NSNumber* unSentActiveTime; +static UIBackgroundTaskIdentifier focusBackgroundTask; +static NSTimeInterval lastOpenedTime; +static BOOL lastOnFocusWasToBackground = YES; + + ++ (void)resetLocals { + unSentActiveTime = nil; + focusBackgroundTask = nil; + lastOpenedTime = 0; + lastOnFocusWasToBackground = YES; +} + + + (void) beginBackgroundFocusTask { focusBackgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ diff --git a/iOS_SDK/UnitTests/UnitTests.m b/iOS_SDK/UnitTests/UnitTests.m index 882709de4..274cd9c6b 100644 --- a/iOS_SDK/UnitTests/UnitTests.m +++ b/iOS_SDK/UnitTests/UnitTests.m @@ -17,6 +17,7 @@ #import "OneSignal.h" #import "OneSignalHelper.h" +#import "OneSignalTracker.h" #import "OneSignalSelectorHelpers.h" @@ -140,6 +141,23 @@ -(BOOL) overrideBoolForKey:(NSString*)key { @end +@interface NSDataOverrider : NSObject +@end +@implementation NSDataOverrider ++ (void)load { + injectStaticSelector([NSDataOverrider class], @selector(overrideDataWithContentsOfURL:), [NSData class], @selector(dataWithContentsOfURL:)); +} + +// Mock data being downloaded from a remote URL. ++ (NSData*) overrideDataWithContentsOfURL:(NSURL *)url { + char bytes[32]; + memset(bytes, 1, 32); + + return [NSData dataWithBytes:bytes length:32]; +} + +@end + @interface NSDateOverrider : NSObject @end @@ -167,10 +185,13 @@ @implementation NSBundleOverrider + (void)load { [NSBundleOverrider sizzleBundleIdentifier]; + injectToProperClass(@selector(overrideObjectForInfoDictionaryKey:), @selector(objectForInfoDictionaryKey:), @[], [NSBundleOverrider class], [NSBundle class]); + + // Doesn't work to swizzle for mocking. Both an NSDictionary and NSMutableDictionarys both throw odd selecotor not found errors. + // injectToProperClass(@selector(overrideInfoDictionary), @selector(infoDictionary), @[], [NSBundleOverrider class], [NSBundle class]); } - + (void)sizzleBundleIdentifier { injectToProperClass(@selector(overrideBundleIdentifier), @selector(bundleIdentifier), @[], [NSBundleOverrider class], [NSBundle class]); } @@ -267,6 +288,11 @@ @implementation OneSignalHelperOverrider + (void)load { injectStaticSelector([OneSignalHelperOverrider class], @selector(overrideEnqueueRequest:onSuccess:onFailure:isSynchronous:), [OneSignalHelper class], @selector(enqueueRequest:onSuccess:onFailure:isSynchronous:)); + injectStaticSelector([OneSignalHelperOverrider class], @selector(overrideGetAppName), [OneSignalHelper class], @selector(getAppName)); +} + ++ (NSString*) overrideGetAppName { + return @"App Name"; } + (void)overrideEnqueueRequest:(NSURLRequest*)request onSuccess:(OSResultSuccessBlock)successBlock onFailure:(OSFailureBlock)failureBlock isSynchronous:(BOOL)isSynchronous { @@ -328,12 +354,13 @@ - (void)setUp { [OneSignal setValue:nil forKeyPath:@"lastnonActiveMessageId"]; [OneSignal setValue:@0 forKeyPath:@"mSubscriptionStatus"]; + [OneSignalTracker performSelector:NSSelectorFromString(@"resetLocals")]; notifTypesOverride = 7; authorizationStatus = [NSNumber numberWithInteger:UNAuthorizationStatusAuthorized]; shouldFireDeviceToken = true; - didFailRegistarationErrorCode = nil; + didFailRegistarationErrorCode = 0; nsbundleDictionary = @{@"UIBackgroundModes": @[@"remote-notification"]}; // TODO: Keep commented out for now, might need this later. @@ -348,6 +375,10 @@ - (void)setUp { UIApplicationMain(0, nil, nil, NSStringFromClass([AppDelegate class])); setupUIApplicationDelegate = true; } + + // Uncomment to simulate slow travis-CI runs. + // NSLog(@"Sleeping for debugging"); + // [NSThread sleepForTimeInterval:15]; } // Called after each test. @@ -402,12 +433,15 @@ - (UNNotificationResponse*)createBasiciOSNotificationResponseWithPayload:(NSDict // Mocking an iOS 10 notification // Setting response.notification.request.content.userInfo UNNotificationResponse *notifResponse = [UNNotificationResponse alloc]; + // Normal tap on notification [notifResponse setValue:@"com.apple.UNNotificationDefaultActionIdentifier" forKeyPath:@"actionIdentifier"]; UNNotificationContent *unNotifContent = [UNNotificationContent alloc]; UNNotification *unNotif = [UNNotification alloc]; UNNotificationRequest *unNotifRequqest = [UNNotificationRequest alloc]; + // Set as remote push type + [unNotifRequqest setValue:[UNPushNotificationTrigger alloc] forKey:@"trigger"]; [unNotif setValue:unNotifRequqest forKeyPath:@"request"]; [notifResponse setValue:unNotif forKeyPath:@"notification"]; @@ -419,7 +453,7 @@ - (UNNotificationResponse*)createBasiciOSNotificationResponseWithPayload:(NSDict - (UNNotificationResponse*)createBasiciOSNotificationResponse { id userInfo = @{@"custom": @{ - @"i": @"b2f7f966-d8cc-11e4-bed1-df8f05be55bb" + @"i": @"b2f7f966-d8cc-11e4-bed1-df8f05be55bb" }}; return [self createBasiciOSNotificationResponseWithPayload:userInfo]; @@ -451,9 +485,6 @@ - (void)testBasicInitTest { XCTAssertNil(lastHTTPRequset); XCTAssertEqual(networkRequestCount, 1); - - // NSLog(@"Sleeping for debugging"); - // [NSThread sleepForTimeInterval:1000]; } - (void)testInitOnSimulator { @@ -478,9 +509,6 @@ - (void)testInitOnSimulator { XCTAssertNil(lastHTTPRequset); XCTAssertEqual(networkRequestCount, 1); - - // NSLog(@"Sleeping for debugging"); - // [NSThread sleepForTimeInterval:1000]; } - (void)testInitAcceptingNotificationsWithoutCapabilitesSet { @@ -579,7 +607,7 @@ - (void)testNotificationOpen { id notifResponse = [self createBasiciOSNotificationResponse]; UNUserNotificationCenter *notifCenter = [UNUserNotificationCenter currentNotificationCenter]; id notifCenterDelegate = notifCenter.delegate; - // UNUserNotificationCenterDelegate method iOS 10 calls directly when a notification is opend. + // UNUserNotificationCenterDelegate method iOS 10 calls directly when a notification is opened. [notifCenterDelegate userNotificationCenter:notifCenter didReceiveNotificationResponse:notifResponse withCompletionHandler:^() {}]; // Make sure open tracking network call was made. @@ -598,6 +626,100 @@ - (void)testNotificationOpen { XCTAssertEqual(networkRequestCount, 2); } +// Testing iOS 10 - old pre-2.4.0 button fromat - with original aps payload format +- (void)testNotificationOpenFromButtonPress { + __block BOOL openedWasFire = false; + + [OneSignal initWithLaunchOptions:nil appId:@"b2f7f966-d8cc-11e4-bed1-df8f05be55ba" handleNotificationAction:^(OSNotificationOpenedResult *result) { + XCTAssertEqualObjects(result.notification.payload.additionalData[@"actionSelected"], @"id1"); + XCTAssertEqual(result.action.type, OSNotificationActionTypeActionTaken); + XCTAssertEqualObjects(result.action.actionID, @"id1"); + openedWasFire = true; + }]; + [self runBackgroundThreads]; + + id userInfo = @{@"aps": @{@"content_available": @1}, + @"m": @"alert body only", + @"o": @[@{@"i": @"id1", @"n": @"text1"}], + @"custom": @{ + @"i": @"b2f7f966-d8cc-11e4-bed1-df8f05be55bb" + } + }; + + id notifResponse = [self createBasiciOSNotificationResponseWithPayload:userInfo]; + [notifResponse setValue:@"id1" forKeyPath:@"actionIdentifier"]; + + UNUserNotificationCenter *notifCenter = [UNUserNotificationCenter currentNotificationCenter]; + id notifCenterDelegate = notifCenter.delegate; + + // UNUserNotificationCenterDelegate method iOS 10 calls directly when a notification is opened. + [notifCenterDelegate userNotificationCenter:notifCenter didReceiveNotificationResponse:notifResponse withCompletionHandler:^() {}]; + + // Make sure open tracking network call was made. + XCTAssertEqual(openedWasFire, true); + XCTAssertEqualObjects(lastUrl, @"https://onesignal.com/api/v1/notifications/b2f7f966-d8cc-11e4-bed1-df8f05be55bb"); + XCTAssertEqualObjects(lastHTTPRequset[@"app_id"], @"b2f7f966-d8cc-11e4-bed1-df8f05be55ba"); + XCTAssertEqualObjects(lastHTTPRequset[@"opened"], @1); + + // Make sure if the device recieved a duplicate we don't fire the open network call again. + lastUrl = nil; + lastHTTPRequset = nil; + [notifCenterDelegate userNotificationCenter:notifCenter didReceiveNotificationResponse:notifResponse withCompletionHandler:^() {}]; + + XCTAssertNil(lastUrl); + XCTAssertNil(lastHTTPRequset); + XCTAssertEqual(networkRequestCount, 2); +} + + +// Testing iOS 10 - 2.4.0+ button fromat - with os_data aps payload format +- (void)testNotificationOpenFromButtonPressWithNewformat { + __block BOOL openedWasFire = false; + + [OneSignal initWithLaunchOptions:nil appId:@"b2f7f966-d8cc-11e4-bed1-df8f05be55ba" handleNotificationAction:^(OSNotificationOpenedResult *result) { + XCTAssertEqualObjects(result.notification.payload.additionalData[@"actionSelected"], @"id1"); + XCTAssertEqual(result.action.type, OSNotificationActionTypeActionTaken); + XCTAssertEqualObjects(result.action.actionID, @"id1"); + openedWasFire = true; + }]; + [self runBackgroundThreads]; + + id userInfo = @{@"aps": @{ + @"mutable-content": @1, + @"alert": @"Message Body" + }, + @"os_data": @{ + @"i": @"b2f7f966-d8cc-11e4-bed1-df8f05be55bb", + @"buttons": @[@{@"i": @"id1", @"n": @"text1"}], + }}; + + id notifResponse = [self createBasiciOSNotificationResponseWithPayload:userInfo]; + [notifResponse setValue:@"id1" forKeyPath:@"actionIdentifier"]; + + UNUserNotificationCenter *notifCenter = [UNUserNotificationCenter currentNotificationCenter]; + id notifCenterDelegate = notifCenter.delegate; + + // UNUserNotificationCenterDelegate method iOS 10 calls directly when a notification is opened. + [notifCenterDelegate userNotificationCenter:notifCenter didReceiveNotificationResponse:notifResponse withCompletionHandler:^() {}]; + + // Make sure open tracking network call was made. + XCTAssertEqual(openedWasFire, true); + XCTAssertEqualObjects(lastUrl, @"https://onesignal.com/api/v1/notifications/b2f7f966-d8cc-11e4-bed1-df8f05be55bb"); + XCTAssertEqualObjects(lastHTTPRequset[@"app_id"], @"b2f7f966-d8cc-11e4-bed1-df8f05be55ba"); + XCTAssertEqualObjects(lastHTTPRequset[@"opened"], @1); + + // Make sure if the device recieved a duplicate we don't fire the open network call again. + lastUrl = nil; + lastHTTPRequset = nil; + [notifCenterDelegate userNotificationCenter:notifCenter didReceiveNotificationResponse:notifResponse withCompletionHandler:^() {}]; + + XCTAssertNil(lastUrl); + XCTAssertNil(lastHTTPRequset); + XCTAssertEqual(networkRequestCount, 2); +} + + +// Testing iOS 10 - with original aps payload format - (void)testOpeningWithAdditionalData { __block BOOL openedWasFire = false; @@ -640,6 +762,40 @@ - (void)testOpeningWithAdditionalData { */ } + +// Testing iOS 10 - pre-2.4.0 button fromat - with os_data aps payload format +- (void)testRecievedCallbackWithButtons { + __block BOOL recievedWasFire = false; + + [OneSignal initWithLaunchOptions:nil appId:@"b2f7f966-d8cc-11e4-bed1-df8f05be55ba" handleNotificationReceived:^(OSNotification *notification) { + recievedWasFire = true; + id actionButons = @[ @{@"id": @"id1", @"text": @"text1"} ]; + // TODO: Fix code so it don't use the shortened format. + // XCTAssertEqualObjects(notification.payload.actionButtons, actionButons); + } handleNotificationAction:nil settings:nil]; + [self runBackgroundThreads]; + + id userInfo = @{@"aps": @{@"content_available": @1}, + @"os_data": @{ + @"i": @"b2f7f966-d8cc-11e4-bed1-df8f05be55bb", + @"buttons": @{ + @"m": @"alert body only", + @"o": @[@{@"i": @"id1", @"n": @"text1"}] + } + } + }; + + id notifResponse = [self createBasiciOSNotificationResponseWithPayload:userInfo]; + UNUserNotificationCenter *notifCenter = [UNUserNotificationCenter currentNotificationCenter]; + id notifCenterDelegate = notifCenter.delegate; + + //iOS 10 calls UNUserNotificationCenterDelegate method directly when a notification is received while the app is in focus. + [notifCenterDelegate userNotificationCenter:notifCenter willPresentNotification:[notifResponse notification] withCompletionHandler:^(UNNotificationPresentationOptions options) {}]; + + XCTAssertEqual(recievedWasFire, true); +} + + - (void)testSendTags { [self initOneSignal]; [self runBackgroundThreads]; @@ -693,7 +849,7 @@ - (void) testOnSessionWhenResuming { // Don't make an on_session call if only out of the app for 20 secounds [self backgroundApp]; - timeOffset = 20; + timeOffset = 10; [self resumeApp]; XCTAssertEqual(networkRequestCount, 1); @@ -706,6 +862,79 @@ - (void) testOnSessionWhenResuming { XCTAssertEqual(networkRequestCount, 2); } +// iOS 10 - Notification Service Extension test +- (void) testDidReceiveNotificatioExtensionRequest { + id userInfo = @{@"aps": @{ + @"mutable-content": @1, + @"alert": @"Message Body" + }, + @"os_data": @{ + @"i": @"b2f7f966-d8cc-11e4-bed1-df8f05be55bb", + @"buttons": @[@{@"i": @"id1", @"n": @"text1"}], + @"att": @{ @"id": @"http://domain.com/file.jpg" } + }}; + + id notifResponse = [self createBasiciOSNotificationResponseWithPayload:userInfo]; + + UNMutableNotificationContent* content = [OneSignal didReceiveNotificatioExtensionnRequest:[notifResponse notification].request withMutableNotificationContent:nil]; + + // Make sure butons were added. + XCTAssertEqualObjects(content.categoryIdentifier, @"__dynamic__"); + // Make sure attachments were added. + XCTAssertEqualObjects(content.attachments[0].identifier, @"id"); + XCTAssertEqualObjects(content.attachments[0].URL.scheme, @"file"); +} + +// iOS 10 - Notification Service Extension test +- (void) testDidReceiveNotificatioExtensionnRequestDontOverrideCateogory { + id userInfo = @{@"aps": @{ + @"mutable-content": @1, + @"alert": @"Message Body" + }, + @"os_data": @{ + @"i": @"b2f7f966-d8cc-11e4-bed1-df8f05be55bb", + @"buttons": @[@{@"i": @"id1", @"n": @"text1"}], + @"att": @{ @"id": @"http://domain.com/file.jpg" } + }}; + + id notifResponse = [self createBasiciOSNotificationResponseWithPayload:userInfo]; + + [[notifResponse notification].request.content setValue:@"some_category" forKey:@"categoryIdentifier"]; + + UNMutableNotificationContent* content = [OneSignal didReceiveNotificatioExtensionnRequest:[notifResponse notification].request withMutableNotificationContent:nil]; + + // Make sure butons were added. + XCTAssertEqualObjects(content.categoryIdentifier, @"some_category"); + // Make sure attachments were added. + XCTAssertEqualObjects(content.attachments[0].identifier, @"id"); + XCTAssertEqualObjects(content.attachments[0].URL.scheme, @"file"); +} + +// iOS 10 - Notification Service Extension test +- (void) testServiceExtensionTimeWillExpireRequest { + id userInfo = @{@"aps": @{ + @"mutable-content": @1, + @"alert": @"Message Body" + }, + @"os_data": @{ + @"i": @"b2f7f966-d8cc-11e4-bed1-df8f05be55bb", + @"buttons": @[@{@"i": @"id1", @"n": @"text1"}], + @"att": @{ @"id": @"http://domain.com/file.jpg" } + }}; + + id notifResponse = [self createBasiciOSNotificationResponseWithPayload:userInfo]; + + UNMutableNotificationContent* content = [OneSignal serviceExtensionTimeWillExpireRequest:[notifResponse notification].request withMutableNotificationContent:nil]; + + // Make sure butons were added. + XCTAssertEqualObjects(content.categoryIdentifier, @"__dynamic__"); + // Make sure attachments were NOT added. + // We should not try to download attachemts as iOS is about to kill the extension and this will take to much time. + XCTAssertNil(content.attachments); + +} + + - (void)testPerformanceExample { // This is an example of a performance test case. [self measureBlock:^{