Skip to content

Commit

Permalink
Merge pull request #59 in MML/infobip-mobile-messaging-ios from okoro…
Browse files Browse the repository at this point in the history
…leva-MM-1878-InteractiveNotificationsBuilder to master

Squashed commit of the following:

commit cf67afa8f0e390e998b973f01a7e9fd38777157d
Author: okoroleva <[email protected]>
Date:   Tue Jul 25 12:37:40 2017 +0300

    isEqual added

commit 14fa33b0ce1f14401d54260464653ec44d2c4281
Author: okoroleva <[email protected]>
Date:   Tue Jul 25 11:26:48 2017 +0300

    improvements after review

commit 51d8e0ac57d8acecf7a74a9152248d0bb0a2a4b0
Author: okoroleva <[email protected]>
Date:   Mon Jul 24 17:53:17 2017 +0300

    provisionings

commit 030db65e5341bd3a1b3197c5744f515d3e711879
Author: okoroleva <[email protected]>
Date:   Mon Jul 24 17:51:35 2017 +0300

    provisionings

commit 3f82bace6dfd79a8d470f23e217f6307203e0723
Author: okoroleva <[email protected]>
Date:   Mon Jul 24 17:45:41 2017 +0300

    clean up

commit a4af6785f882dce8748a5238dd8253b8e3e94883
Author: okoroleva <[email protected]>
Date:   Mon Jul 24 17:13:29 2017 +0300

    test added

commit 334be5f79880a7e3ce9c1bd13e3c70319e7eff04
Author: okoroleva <[email protected]>
Date:   Mon Jul 24 16:27:59 2017 +0300

    in progress

commit 21c4bb76d30eb3455b5798a019310cf83b19d22e
Author: okoroleva <[email protected]>
Date:   Mon Jul 24 14:31:07 2017 +0300

    in progress

commit 801ba7d434d70edd1da805c055ed5a2ef55dac99
Author: okoroleva <[email protected]>
Date:   Mon Jul 24 11:56:33 2017 +0300

    in progress

commit d078f3d5d8e2232b5066393f3936fec397cadf98
Author: okoroleva <[email protected]>
Date:   Mon Jul 24 11:51:52 2017 +0300

    inProgress

commit 012fd9db6cdcf6c7d0f390ac665508d7d3bb116b
Author: okoroleva <[email protected]>
Date:   Mon Jul 24 11:43:28 2017 +0300

    in progress

commit 3aa3ad0d8fee453f03e5be11ab9bd74406a524d8
Author: okoroleva <[email protected]>
Date:   Mon Jul 24 11:26:34 2017 +0300

    handlers, Model Objects and library API
  • Loading branch information
riskpp committed Jul 25, 2017
1 parent 1349a95 commit c47d186
Show file tree
Hide file tree
Showing 13 changed files with 297 additions and 24 deletions.
20 changes: 12 additions & 8 deletions Example/MobileMessagingExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
A0DB0FBD1E2F8FC0005F5979 /* mocks in Resources */ = {isa = PBXBuildFile; fileRef = A0DB0FBC1E2F8FC0005F5979 /* mocks */; };
A0DB0FBE1E2F8FC0005F5979 /* mocks in Resources */ = {isa = PBXBuildFile; fileRef = A0DB0FBC1E2F8FC0005F5979 /* mocks */; };
A0DB0FBF1E2F8FC0005F5979 /* mocks in Resources */ = {isa = PBXBuildFile; fileRef = A0DB0FBC1E2F8FC0005F5979 /* mocks */; };
A0F6AAE31F262E7F0013A3E5 /* InteractiveNotificationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0F6AAE21F262E7F0013A3E5 /* InteractiveNotificationsTests.swift */; };
AA32881BA47AEF4481B9BCC4 /* Pods_MobileMessagingExample_Tests_Device.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D9B0E80C59C6CA0D8EAE8886 /* Pods_MobileMessagingExample_Tests_Device.framework */; };
BAE5D838C8F6AEEF8B54DEE6 /* Pods_NotificationServiceExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 962ACCC4D463FBBB0101DC5B /* Pods_NotificationServiceExtension.framework */; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -166,6 +167,7 @@
A0DB0FBC1E2F8FC0005F5979 /* mocks */ = {isa = PBXFileReference; lastKnownFileType = folder; path = mocks; sourceTree = "<group>"; };
A0ED51491CBFA72F00EF1B43 /* MessageSeenTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageSeenTests.swift; sourceTree = "<group>"; };
A0F30B0F1D410A3300247CED /* MOMessageSendingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MOMessageSendingTests.swift; sourceTree = "<group>"; };
A0F6AAE21F262E7F0013A3E5 /* InteractiveNotificationsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InteractiveNotificationsTests.swift; sourceTree = "<group>"; };
A0FF884A1DB1042F00A58F49 /* CheckVersionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckVersionTests.swift; sourceTree = "<group>"; };
A7C466A02407E2BAF333F832 /* Pods-MobileMessagingExample_Tests_Device.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MobileMessagingExample_Tests_Device.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MobileMessagingExample_Tests_Device/Pods-MobileMessagingExample_Tests_Device.debug.xcconfig"; sourceTree = "<group>"; };
D1BEEEDA83905CF0D1B101E6 /* Pods-MobileMessagingExample_Tests_Device.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MobileMessagingExample_Tests_Device.release.xcconfig"; path = "Pods/Target Support Files/Pods-MobileMessagingExample_Tests_Device/Pods-MobileMessagingExample_Tests_Device.release.xcconfig"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -387,6 +389,7 @@
A0FF884A1DB1042F00A58F49 /* CheckVersionTests.swift */,
A04CCEBB1DE7005C00D9E416 /* BaseSettingsTests.swift */,
A0015D7F1DF7EE0600DD4113 /* Mocks.swift */,
A0F6AAE21F262E7F0013A3E5 /* InteractiveNotificationsTests.swift */,
);
path = MobileMessagingTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -755,7 +758,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
E29CA7FF694F6C884B7A4A81 /* [CP] Copy Pods Resources */ = {
Expand Down Expand Up @@ -785,7 +788,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
FDAE422B74F7B1991521A7F6 /* [CP] Check Pods Manifest.lock */ = {
Expand All @@ -800,7 +803,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
FF4C78924BA3EAE65513FDC6 /* [CP] Check Pods Manifest.lock */ = {
Expand All @@ -815,7 +818,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
Expand All @@ -842,6 +845,7 @@
buildActionMask = 2147483647;
files = (
767B848C1EA8AD1100CCD81F /* CoreDataHelpersTests.swift in Sources */,
A0F6AAE31F262E7F0013A3E5 /* InteractiveNotificationsTests.swift in Sources */,
767B84961EA8AD1100CCD81F /* MMTestCase.swift in Sources */,
767B849B1EA8AD1100CCD81F /* SystemDataTests.swift in Sources */,
767B849C1EA8AD1100CCD81F /* CheckVersionTests.swift in Sources */,
Expand Down Expand Up @@ -1049,7 +1053,7 @@
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\"";
PRODUCT_BUNDLE_IDENTIFIER = com.infobip.mobilemessaging.example;
PRODUCT_NAME = MobileMessagingExample;
PROVISIONING_PROFILE = "e8f44623-f9be-445a-bfdc-8f5df6053ef5";
PROVISIONING_PROFILE = "9cb88896-fe03-4351-b2ca-cd71eb39b51d";
PROVISIONING_PROFILE_SPECIFIER = "Mobile Messaging Example - Development";
SWIFT_VERSION = 3.0.1;
};
Expand Down Expand Up @@ -1082,7 +1086,7 @@
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\"";
PRODUCT_BUNDLE_IDENTIFIER = com.infobip.mobilemessaging.example;
PRODUCT_NAME = MobileMessagingExample;
PROVISIONING_PROFILE = "56a4abfd-1436-4588-95ea-1d5c88e9f48f";
PROVISIONING_PROFILE = "9cb88896-fe03-4351-b2ca-cd71eb39b51d";
PROVISIONING_PROFILE_SPECIFIER = "Mobile Messaging Example - Development";
SWIFT_VERSION = 3.0.1;
};
Expand Down Expand Up @@ -1206,7 +1210,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.infobip.mobilemessaging.example.NotificationServiceExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "444b26a9-39a5-48f2-bf50-046cc04336c5";
PROVISIONING_PROFILE = "b126ffda-b3e5-4469-967b-b52b6c66ddfd";
PROVISIONING_PROFILE_SPECIFIER = "Dev ExampleApp NotificationServiceExtension";
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
Expand Down Expand Up @@ -1236,7 +1240,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.infobip.mobilemessaging.example.NotificationServiceExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "444b26a9-39a5-48f2-bf50-046cc04336c5";
PROVISIONING_PROFILE = "b126ffda-b3e5-4469-967b-b52b6c66ddfd";
PROVISIONING_PROFILE_SPECIFIER = "Dev ExampleApp NotificationServiceExtension";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "1"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
Expand Down
10 changes: 5 additions & 5 deletions Example/NotificationServiceExtension/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
Expand All @@ -25,6 +20,11 @@
<string>2.6.7</string>
<key>CFBundleVersion</key>
<string>1460136653774</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// InteractiveNotificationsTests.swift
// MobileMessagingExample
//
// Created by okoroleva on 24.07.17.
// Copyright © 2017 CocoaPods. All rights reserved.
//

import XCTest
import MobileMessaging

class InteractiveNotificationsTests: MMTestCase {
let actionId = "actionId"
let categoryId = "categoryId"

func testActionHandlerCalled() {
weak var actionHandlerCalled = expectation(description: "action handler called")
weak var testCompleted = expectation(description: "testCompleted")
let action = MMCategoryAction(identifier: actionId, title: "Action", options: nil) { (message, completion) in
actionHandlerCalled?.fulfill()
completion()
}

let category = MMInteractiveCategory(identifier: categoryId, actions: [action!])
var set = Set<MMInteractiveCategory>()
set.insert(category!)

cleanUpAndStop()
var mm = mockedMMInstanceWithApplicationCode(MMTestConstants.kTestCorrectApplicationCode)
mm = mm?.withInteractiveCategories(set)
mm?.start()

MobileMessaging.handleActionWithIdentifier(identifier: actionId, forRemoteNotification: ["messageId": "1", "aps": ["alert": ["body": "text"], "category": categoryId]], responseInfo: nil) {
testCompleted?.fulfill()
}

waitForExpectations(timeout: 10, handler: nil)
}

}
2 changes: 1 addition & 1 deletion MobileMessaging.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Pod::Spec.new do |s|
core.resources = 'Pod/Classes/MessageStorage/*.xcdatamodeld', 'Pod/Classes/Core/InternalStorage/*.xcdatamodeld'
core.public_header_files = 'Pod/Classes/Core/**/*.h'
core.private_header_files = 'Pod/Classes/Vendor/**/*.h'
core.source_files = 'Pod/Classes/Core/**/*.{h,m,swift}', 'Pod/Classes/Vendor/**/*.{h,m,swift}', 'Pod/Classes/MessageStorage/**/*.{h,m,swift}', 'Pod/Classes/RichNotifications/**'
core.source_files = 'Pod/Classes/Core/**/*.{h,m,swift}', 'Pod/Classes/Vendor/**/*.{h,m,swift}', 'Pod/Classes/MessageStorage/**/*.{h,m,swift}', 'Pod/Classes/RichNotifications/**', 'Pod/Classes/InteractiveNotifications/**'
end

s.subspec 'CocoaLumberjack' do |cl|
Expand Down
57 changes: 53 additions & 4 deletions Pod/Classes/Core/MobileMessaging.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ public final class MobileMessaging: NSObject {
return self
}

/// Fabric method for Mobile Messaging session.
///
///- parameter categories: Set of categories that indicating which buttons will be displayed and behavour of these buttons when a push notification arrives.
///- remark: Mobile Messaging SDK reserves category Ids and action Ids with "mm_" prefix. Custom actions and categories with this prefix will be discarded.

public func withInteractiveCategories(_ categories: Set<MMInteractiveCategory>) -> MobileMessaging {
self.interactiveCategories = categories
return self
}

/// Starts a new Mobile Messaging session.
///
/// This method should be called form AppDelegate's `application(_:didFinishLaunchingWithOptions:)` callback.
Expand All @@ -86,8 +96,8 @@ public final class MobileMessaging: NSObject {
MMLogDebug("The application is registered for remote notifications but MobileMessaging lacks of device token. Unregistering...")
self.application.unregisterForRemoteNotifications()
}

application.registerUserNotificationSettings(UIUserNotificationSettings(types: userNotificationType, categories: nil))
application.registerUserNotificationSettings(UIUserNotificationSettings(types: userNotificationType, categories: self.interactiveCategories?.uiUserNotificationCategoriesSet))

if application.isRegisteredForRemoteNotifications == false {
MMLogDebug("Registering for remote notifications...")
Expand Down Expand Up @@ -160,6 +170,7 @@ public final class MobileMessaging: NSObject {
MobileMessaging.sharedInstance?.reachabilityManager = nil
MobileMessaging.sharedInstance?.keychain = nil
MobileMessaging.sharedInstance?.sharedNotificationExtensionStorage = nil
MobileMessaging.sharedInstance?.interactiveCategories = nil

MobileMessaging.sharedInstance = nil
}
Expand Down Expand Up @@ -187,8 +198,6 @@ public final class MobileMessaging: NSObject {
})
}



/// This method is called when a running app receives a local notification. The method should be called from AppDelegate's `application(_:didReceiveLocalNotification:)` or `application(_:didReceive:)` callback.
///
/// - parameter notification: A local notification that encapsulates details about the notification, potentially including custom data.
Expand All @@ -205,6 +214,32 @@ public final class MobileMessaging: NSObject {
MMMessageHandler.handleNotificationTap(with: message)
}


///This method handles actions of interactive notification and triggers procedure for performing handling block that is defined for this action. The method should be called from AppDelegate's `application(_:handleActionWithIdentifier:localNotification:completionHandler:)` callback.
///
/// - parameter identifier: The identifier associated with the action of interactive notification.
/// - parameter localNotification: `UILocalNotification` object, which specifies notification that was scheduled.
/// - parameter completionHandler: The block to execute when specified action performing finished. The block is originally passed to AppDelegate's `application(_:handleActionWithIdentifier:forRemoteNotification:completionHandler:)` callback as a `completionHandler` parameter.
public class func handleActionWithIdentifier(identifier: String?, localNotification: UILocalNotification, responseInfo: [NSObject : AnyObject]?, completionHandler: @escaping () -> Void) {
guard let info = localNotification.userInfo,
let payload = info[LocalNotificationKeys.pushPayload] as? [String: Any],
let date = info[LocalNotificationKeys.createdDate] as? Date else {
completionHandler()
return
}

handleActionWithIdentifier(identifier: identifier, message: MTMessage(payload: payload, createdDate: date), completionHandler: completionHandler)
}

///This method handles actions of interactive notification and triggers procedure for performing operations that are defined for this action. The method should be called from AppDelegate's `application(_:handleActionWithIdentifier:forRemoteNotification:completionHandler:)` callback.

/// - parameter identifier: The identifier associated with the action of interactive notification.
/// - parameter userInfo: A dictionary that contains information related to the remote notification, potentially including a badge number for the app icon, an alert sound, an alert message to display to the user, a notification identifier, and custom data.
/// - parameter completionHandler: The block to execute when specified action performing finished. The block is originally passed to AppDelegate's `application(_:handleActionWithIdentifier:forRemoteNotification:completionHandler:)` callback as a `completionHandler` parameter.
public class func handleActionWithIdentifier(identifier: String?, forRemoteNotification userInfo: [AnyHashable : Any], responseInfo: [NSObject : AnyObject]?, completionHandler: @escaping () -> Void) {
handleActionWithIdentifier(identifier: identifier, message: MTMessage(payload: userInfo, createdDate: Date()), completionHandler: completionHandler)
}

/// Maintains attributes related to the current application installation such as APNs device token, badge number, etc.
public class var currentInstallation: MMInstallation? {
return MobileMessaging.sharedInstance?.currentInstallation
Expand Down Expand Up @@ -425,6 +460,20 @@ public final class MobileMessaging: NSObject {
static var date: MMDate = MMDate() // testability

var sharedNotificationExtensionStorage: AppGroupMessageStorage?
var interactiveCategories: Set<MMInteractiveCategory>?

private class func handleActionWithIdentifier(identifier: String?, message: MTMessage?, completionHandler: @escaping () -> Void) {
guard let identifier = identifier,
let message = message,
let categoryId = message.aps.categoryId,
let registeredCategories = MobileMessaging.sharedInstance?.interactiveCategories,
let category = registeredCategories.first(where: {return $0.identifier == categoryId}),
let action = category.actions.first(where: {return $0.identifier == identifier}) else {
completionHandler()
return
}
action.handlingBlock(message, completionHandler)
}
}

extension UIApplication: MMApplication {}
Expand Down
Loading

0 comments on commit c47d186

Please sign in to comment.