-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRemoteNotificationCondition.swift
More file actions
127 lines (99 loc) · 4.33 KB
/
RemoteNotificationCondition.swift
File metadata and controls
127 lines (99 loc) · 4.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
Copyright (C) 2015 Apple Inc. All Rights Reserved.
See LICENSE.txt for this sample’s licensing information
Abstract:
This file shows an example of implementing the OperationCondition protocol.
*/
#if os(iOS)
import UIKit
private let RemoteNotificationQueue = OperationQueue()
private let RemoteNotificationName = "RemoteNotificationPermissionNotification"
private enum RemoteRegistrationResult {
case Token(NSData)
case Error(NSError)
}
/// A condition for verifying that the app has the ability to receive push notifications.
struct RemoteNotificationCondition: OperationCondition {
static let name = "RemoteNotification"
static let isMutuallyExclusive = false
static func didReceiveNotificationToken(token: NSData) {
NSNotificationCenter.defaultCenter().postNotificationName(RemoteNotificationName, object: nil, userInfo: [
"token": token
])
}
static func didFailToRegister(error: NSError) {
NSNotificationCenter.defaultCenter().postNotificationName(RemoteNotificationName, object: nil, userInfo: [
"error": error
])
}
let application: UIApplication
init(application: UIApplication) {
self.application = application
}
func dependencyForOperation(operation: Operation) -> NSOperation? {
return RemoteNotificationPermissionOperation(application: application, handler: { _ in })
}
func evaluateForOperation(operation: Operation, completion: OperationConditionResult -> Void) {
/*
Since evaluation requires executing an operation, use a private operation
queue.
*/
RemoteNotificationQueue.addOperation(RemoteNotificationPermissionOperation(application: application) { result in
switch result {
case .Token(_):
completion(.Satisfied)
case .Error(let underlyingError):
let error = NSError(code: .ConditionFailed, userInfo: [
OperationConditionKey: self.dynamicType.name,
NSUnderlyingErrorKey: underlyingError
])
completion(.Failed(error))
}
})
}
}
/**
A private `Operation` to request a push notification token from the `UIApplication`.
- note: This operation is used for *both* the generated dependency **and**
condition evaluation, since there is no "easy" way to retrieve the push
notification token other than to ask for it.
- note: This operation requires you to call either `RemoteNotificationCondition.didReceiveNotificationToken(_:)` or
`RemoteNotificationCondition.didFailToRegister(_:)` in the appropriate
`UIApplicationDelegate` method, as shown in the `AppDelegate.swift` file.
*/
private class RemoteNotificationPermissionOperation: Operation {
let application: UIApplication
private let handler: RemoteRegistrationResult -> Void
private init(application: UIApplication, handler: RemoteRegistrationResult -> Void) {
self.application = application
self.handler = handler
super.init()
/*
This operation cannot run at the same time as any other remote notification
permission operation.
*/
addCondition(MutuallyExclusive<RemoteNotificationPermissionOperation>())
}
override func execute() {
dispatch_async(dispatch_get_main_queue()) {
let notificationCenter = NSNotificationCenter.defaultCenter()
notificationCenter.addObserver(self, selector: #selector(RemoteNotificationPermissionOperation.didReceiveResponse(_:)), name: RemoteNotificationName, object: nil)
self.application.registerForRemoteNotifications()
}
}
@objc func didReceiveResponse(notification: NSNotification) {
NSNotificationCenter.defaultCenter().removeObserver(self)
let userInfo = notification.userInfo
if let token = userInfo?["token"] as? NSData {
handler(.Token(token))
}
else if let error = userInfo?["error"] as? NSError {
handler(.Error(error))
}
else {
fatalError("Received a notification without a token and without an error.")
}
finish()
}
}
#endif