Skip to content
This repository has been archived by the owner on May 4, 2024. It is now read-only.

Commit

Permalink
Merge pull request #8 from square/federman/fixRemoteNotificationAlert…
Browse files Browse the repository at this point in the history
…_0.8

RemoteNotification should search for values in "aps" dictionary instead of top level
  • Loading branch information
dfed committed Jul 16, 2016
2 parents d4fce51 + 2fdabf4 commit d012505
Show file tree
Hide file tree
Showing 5 changed files with 229 additions and 135 deletions.
1 change: 1 addition & 0 deletions Gemfile
@@ -1,3 +1,4 @@
source 'https://rubygems.org' do
gem 'cocoapods', '1.0.0'
gem 'activesupport', '~> 4.0'
end
65 changes: 43 additions & 22 deletions Sources/RemoteNotification.swift
Expand Up @@ -22,7 +22,7 @@ import Foundation


public struct RemoteNotification: CustomStringConvertible, Equatable {
/// An object representing the user-facing alert. Derived from userInfo["alert"]
/// An object representing the user-facing alert. Derived from userInfo["aps"]["alert"]
public let alert: Alert?
/// The badge set on the remote notification. Derived from userInfo["badge"]
public let badge: Int?
Expand All @@ -42,19 +42,19 @@ public struct RemoteNotification: CustomStringConvertible, Equatable {
return nil
}

// Parse the notification payload.
// See https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/TheNotificationPayload.html for more information on expected values.
alert = Alert(remoteNotification: remoteNotification)
badge = remoteNotification[badgeKey] as? Int
sound = remoteNotification[soundKey] as? String
contentAvailable = remoteNotification[contentAvailableKey] != nil
categoryIdentifier = remoteNotification[categoryKey] as? String

let apnsDictionary = remoteNotification[APSServiceKey] as? [String : AnyObject]
badge = apnsDictionary?[badgeKey] as? Int
sound = apnsDictionary?[soundKey] as? String
contentAvailable = apnsDictionary?[contentAvailableKey] != nil
categoryIdentifier = apnsDictionary?[categoryKey] as? String
remoteNotificationDictionary = remoteNotification

var customFields = remoteNotification
customFields.removeValueForKey(alertKey)
customFields.removeValueForKey(badgeKey)
customFields.removeValueForKey(soundKey)
customFields.removeValueForKey(contentAvailableKey)
customFields.removeValueForKey(categoryKey)
customFields.removeValueForKey(APSServiceKey)

userInfo = customFields
}
Expand All @@ -68,29 +68,44 @@ public struct RemoteNotification: CustomStringConvertible, Equatable {
// MARK: Alert

public struct Alert: Equatable {
/// The alert message text. Derived from userInfo["alert"]["body"]
/// The alert message text. Derived from userInfo["aps"]["alert"]["body"] or userInfo["aps"]["alert"]
public let body: String?
/// The localization key for the alert message text. Derived from userInfo["alert"]["loc-key"]
/// The localization key for the alert message text. Derived from userInfo["aps"]["alert"]["loc-key"]
public let bodyLocalizationKey: String?
/// The localization arguments for the alert message text. Derived from userInfo["alert"]["loc-args"]
/// The localization arguments for the alert message text. Derived from userInfo["aps"]["alert"]["loc-args"]
public let bodyLocalizationArguments: [String]?

/// The localization key for the alert action button. Derived from userInfo["alert"]["action-loc-key"]
/// The localization key for the alert action button. Derived from userInfo["aps"]["alert"]["action-loc-key"]
public let actionLocalizationKey: String?

/// The filename of an image file in teh app bundle, with or without the filename extension. Derived from userInfo["alert"]["launch-image"]
/// The filename of an image file in the app bundle, with or without the filename extension. Derived from userInfo["aps"]["alert"]["launch-image"]
public let launchImageName: String?

/// The title shown on the Apple Watch. Derived from userInfo["alert"]["title"]
/// The title shown on the Apple Watch. Derived from userInfo["aps"]["alert"]["title"]
public let wearableTitle: String?
/// The localization key for the title shown on the Apple Watch. Derived from userInfo["alert"]["title-loc-key"]
/// The localization key for the title shown on the Apple Watch. Derived from userInfo["aps"]["alert"]["title-loc-key"]
public let wearableTitleLocalizationKey: String?
/// The localization arguments for the title shown on the Apple Watch. Derived from userInfo["alert"]["title-loc-args"]
/// The localization arguments for the title shown on the Apple Watch. Derived from userInfo["aps"]["alert"]["title-loc-args"]
public let wearableTitleLocalizationArguments: [String]?

init?(remoteNotification: [String : AnyObject]) {
guard let alert = remoteNotification[alertKey] else {
return nil
// Alert is represented as either a dictionary or a single string.
guard let alert = remoteNotification[APSServiceKey]?[alertKey] as? [String : AnyObject] else {
guard let body = remoteNotification[APSServiceKey]?[alertKey] as? String else {
return nil
}

self.body = body

bodyLocalizationKey = nil
bodyLocalizationArguments = nil
actionLocalizationKey = nil
launchImageName = nil
wearableTitle = nil
wearableTitleLocalizationKey = nil
wearableTitleLocalizationArguments = nil

return
}

body = alert[alertBodyKey] as? String
Expand Down Expand Up @@ -202,7 +217,13 @@ public func ==(lhs: RemoteNotification.Alert, rhs: RemoteNotification.Alert) ->
}


// MARK: Top Level APNS Keys
// MARK: Top Level APS Keys


let APSServiceKey = "aps"


// MARK: APS Keys


let alertKey = "alert"
Expand All @@ -212,7 +233,7 @@ let contentAvailableKey = "content-available"
let categoryKey = "category"


// MARK: Alert APNS Keys
// MARK: Alert Keys


let alertBodyKey = "body"
Expand Down
2 changes: 1 addition & 1 deletion SuperDelegate.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'SuperDelegate'
s.version = '0.8.0'
s.version = '0.8.1'
s.license = 'Apache License, Version 2.0'
s.summary = 'SuperDelegate provides a clean application delegate interface and protects you from bugs in the application lifecycle.'
s.homepage = 'https://github.com/square/SuperDelegate'
Expand Down
100 changes: 79 additions & 21 deletions Tests/RemoteNotificationTests.swift
Expand Up @@ -25,20 +25,22 @@ class RemoteNotificationTests: XCTestCase {

func test_RemoteNotification_initWithFullRemoteNotificationDictionary() {
let remoteNotificationDictionary: [NSObject : AnyObject] = [
alertKey : [
alertBodyKey : alertBody,
alertBodyLocKey : alertBodyLocalizationKey,
alertBodyLocArgsKey : alertBodyLocalizationArgs,
alertActionLocKey : alertActionLocalizationKey,
alertLaunchImageKey : alertLaunchImageName,
alertWearableTitleKey : alertWearableTitle,
alertWearableTitleLocKey : alertWearableTitleLocalizationKey,
alertWearableTitleLocArgsKey : alertWearableTitleLocalizationArgs
APSServiceKey : [
alertKey : [
alertBodyKey : alertBody,
alertBodyLocKey : alertBodyLocalizationKey,
alertBodyLocArgsKey : alertBodyLocalizationArgs,
alertActionLocKey : alertActionLocalizationKey,
alertLaunchImageKey : alertLaunchImageName,
alertWearableTitleKey : alertWearableTitle,
alertWearableTitleLocKey : alertWearableTitleLocalizationKey,
alertWearableTitleLocArgsKey : alertWearableTitleLocalizationArgs
],
badgeKey : badge,
soundKey : sound,
contentAvailableKey : contentAvailable,
categoryKey : categoryIdentifier,
],
badgeKey : badge,
soundKey : sound,
contentAvailableKey : contentAvailable,
categoryKey : categoryIdentifier,
userInfoCustomKey1 : userInfoCustomValue1,
userInfoCustomKey2 : userInfoCustomValue2,
userInfoCustomKey3 : userInfoCustomValue3
Expand Down Expand Up @@ -85,12 +87,56 @@ class RemoteNotificationTests: XCTestCase {
XCTAssertNotEqual(remoteNotification, RemoteNotification(remoteNotification: differentRemoteNotificationDictionary))
}

func test_RemoteNotification_initWithSimpleAlertRemoteNotificationDictionary() {
let remoteNotificationDictionary: [NSObject : AnyObject] = [
APSServiceKey : [
alertKey : alertBody,
badgeKey : badge,
soundKey : sound,
contentAvailableKey : contentAvailable,
categoryKey : categoryIdentifier,
],
userInfoCustomKey1 : userInfoCustomValue1,
userInfoCustomKey2 : userInfoCustomValue2,
userInfoCustomKey3 : userInfoCustomValue3
]

guard let remoteNotification = RemoteNotification(remoteNotification: remoteNotificationDictionary) else {
XCTFail()
return
}

XCTAssertEqual(alertBody, remoteNotification.alert?.body)
XCTAssertEqual(nil, remoteNotification.alert?.bodyLocalizationKey)
XCTAssertEqual(nil, remoteNotification.alert?.bodyLocalizationArguments?.first)
XCTAssertEqual(nil, remoteNotification.alert?.launchImageName)
XCTAssertEqual(nil, remoteNotification.alert?.wearableTitle)
XCTAssertEqual(nil, remoteNotification.alert?.wearableTitleLocalizationKey)
XCTAssertEqual(nil, remoteNotification.alert?.wearableTitleLocalizationArguments?.first)

XCTAssertEqual(badge, remoteNotification.badge)
XCTAssertEqual(sound, remoteNotification.sound)
XCTAssertTrue(remoteNotification.contentAvailable)
XCTAssertEqual(categoryIdentifier, remoteNotification.categoryIdentifier)
XCTAssertEqual(remoteNotification.userInfo.count, 3)
XCTAssertEqual(remoteNotification.userInfo[userInfoCustomKey1] as? String, userInfoCustomValue1)
XCTAssertEqual(remoteNotification.userInfo[userInfoCustomKey2] as? String, userInfoCustomValue2)
XCTAssertEqual(remoteNotification.userInfo[userInfoCustomKey3] as? Int, userInfoCustomValue3)

XCTAssertTrue(remoteNotification == RemoteNotification(remoteNotification: remoteNotificationDictionary)!)
var differentRemoteNotificationDictionary = remoteNotificationDictionary
differentRemoteNotificationDictionary[userInfoCustomKey3 + "many different"] = "wow"
XCTAssertNotEqual(remoteNotification, RemoteNotification(remoteNotification: differentRemoteNotificationDictionary))
}

func test_RemoteNotification_initWithSilentRemoteNotificationDictionary() {
let remoteNotificationDictionary: [NSObject : AnyObject] = [
badgeKey : badge,
soundKey : sound,
contentAvailableKey : contentAvailable,
categoryKey : categoryIdentifier,
APSServiceKey : [
badgeKey : badge,
soundKey : sound,
contentAvailableKey : contentAvailable,
categoryKey : categoryIdentifier,
],
userInfoCustomKey1 : userInfoCustomValue1,
userInfoCustomKey2 : userInfoCustomValue2,
userInfoCustomKey3 : userInfoCustomValue3
Expand Down Expand Up @@ -119,15 +165,27 @@ class RemoteNotificationTests: XCTestCase {
XCTAssertEqual(remoteNotification.userInfo[userInfoCustomKey3] as? Int, userInfoCustomValue3)

XCTAssertTrue(remoteNotification == RemoteNotification(remoteNotification: remoteNotificationDictionary)!)
var differentRemoteNotificationDictionary = remoteNotificationDictionary
differentRemoteNotificationDictionary.removeValueForKey(categoryKey)
let differentRemoteNotificationDictionary: [NSObject : AnyObject] = [
APSServiceKey : [
badgeKey : badge,
soundKey : sound,
contentAvailableKey : contentAvailable,
// Note that categoryKey is missing.
],
userInfoCustomKey1 : userInfoCustomValue1,
userInfoCustomKey2 : userInfoCustomValue2,
userInfoCustomKey3 : userInfoCustomValue3
]

XCTAssertNotEqual(remoteNotification, RemoteNotification(remoteNotification: differentRemoteNotificationDictionary))
}

func test_RemoteNotification_initWithBadgeChangeRemoteNotificationDictionary() {
let remoteNotificationDictionary: [NSObject : AnyObject] = [
badgeKey : badge,
soundKey : sound,
APSServiceKey : [
badgeKey : badge,
soundKey : sound,
],
]

guard let remoteNotification = RemoteNotification(remoteNotification: remoteNotificationDictionary) else {
Expand Down

0 comments on commit d012505

Please sign in to comment.