Kex*_*Kex 27 apple-push-notifications ios swift
撕裂我的头发,以便在iOS10中使用推送通知.目前的设置:
在func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool:
if #available(iOS 10.0, *) {
            let center = UNUserNotificationCenter.current()
            center.delegate = self
            center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
                if error == nil {
                    print("DID REQUEST THE NOTIFICATION")
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
            print("DID SET DELEGATE")
        }
在func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data):
print("DID REGISTER FOR A REMOTE NOTIFICATION AND THE TOKEN IS \(deviceToken.base64EncodedString())"           
let request = UpdatePushNotificationSubscription_Request(deviceToken: deviceToken)
updatePushNotificationSubscriptionWorker.updateSubscription(request)
我已经检查过令牌是否正确地上传到后端,它确实匹配.
我也实施了:
    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        print("GOT A NOTIFICATION")
    }
    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        //This is for the user tapping on the notification
        print("GOT A NOTIFICATION")
    }
我已为所有目标设置权限并启用了推送:
现在当我尝试从后端发送消息时,设备什么都没有收到.代表们没有被召集.不知道我在这里做错了什么.Push适用于iOS9和Android设备.我可能做错了什么指针?
Dav*_*ood 51
这个答案适用于使用该UserNotifications框架的iOS 10+ .
您需要一个符合UNUserNotificationCenterDelegate协议的类.如果您为此创建一个新类,或者将其添加到您的AppDelegate类中,则无关紧要.我建议创建一个专门的课程.出于本答案的目的,我们假设您UserNotificationController为它创建了一个类.
该类可以具有以下方法:
optional func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
optional func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)
然后在您的AppDelegate.application(_:didFinishLaunchingWithOptions:)方法中,您需要delegate将UNUserNotificationCenter.current()对象设置为您的UserNotificationController类的实例.您可能希望使用共享实例.
请求用户授权以使用该UNUserNotificationCenter.requestAuthorization(options:completionHandler:)方法启用通知,并在中completionHandler检查granted值.如果true,通过呼叫注册远程通知UIApplication.shared.registerForRemoteNotifications().
现在,当应用程序收到推送通知时,可能会发生几种不同的情况.我会尝试列出最常见的案例.
本地通知:
如果应用程序位于前台,则应用程序将调用UserNotificationController .userNotificationCenter(_:willPresent:withCompletionHandler:).
如果应用程序在后台(运行与否),则在用户点击通知之前不会调用任何内容,此时应用程序将打开并调用UserNotificationController .userNotificationCenter(_:didReceive:withCompletionHandler:).
远程通知:
有效载荷的内容将影响发生的事情.有效载荷有三种情况,a)正常alert,badge和sound选项b)包括content-available选项(设置为1或true)c)包括mutable-content选项(设置为1或true).此外,技术上d)你有两个content-available和mutable-content,但这只是触发两种情况.
对于)只是alert,sound,badge信息:
这与本地通知相同.
对于b)content-available== true:
如果应用程序位于前台,UserNotificationController .userNotificationCenter(_:willPresent:withCompletionHandler:)则会调用.
如果应用程序在后台(运行与否),AppDelegate.application(_:didReceiveRemoteNotification:fetchCompletionHandler:)则调用,而不是您UserNotificationController班级中的某个方法.
对于c)mutable-content== true:
如果您已UNNotificationServiceExtension在应用程序中添加了a ,它将处理通知并可以修改内容.无论主应用程序的状态如何,都会发生这种情况.如果用户点击(可选地修改的)通知,则其被处理为类似于上面的本地通知.
如果没有a UNNotificationServiceExtension,通知将被视为上面的正常远程通知.
补充说明:
使用时mutable-content,您必须alert在有效负载中包含信息,否则系统会将其视为不可变,而不是调用您的UNNotificationServiceExtension.您修改的通知仍必须包含alert信息,否则将使用原始通知有效内容.遗憾的是,没有办法阻止通知出现在用户身上.
使用时content-available,如果用户上次使用时强制退出应用程序,系统将不会重新启动应用程序或呼叫AppDelegate.application(_:didReceiveRemoteNotification:fetchCompletionHandler:).虽然它仍然会显示任何警报,播放声音,并按照有效负载中的指示更新徽章.
PO *_*son 21
尝试让AppDelegate类实现UNUserNotificationCenterDelegate协议,而不是实现协议的单独类.
我有一个单独的代表类,它没有用.这就是我的代码在我工作时的样子:
import UIKit
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application 
    UIApplication.shared.registerForRemoteNotifications()
    let center = UNUserNotificationCenter.current()
    center.delegate = self //DID NOT WORK WHEN self WAS MyOtherDelegateClass()
    center.requestAuthorization(options: [.alert, .sound, .badge]) {
        (granted, error) in
            // Enable or disable features based on authorization.
            if granted {
                // update application settings
            }
    }
    return true
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
                            willPresent: UNNotification,
                            withCompletionHandler: @escaping (UNNotificationPresentationOptions)->()) {
    withCompletionHandler([.alert, .sound, .badge])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
                            didReceive: UNNotificationResponse,
                            withCompletionHandler: @escaping ()->()) {
    withCompletionHandler()
}
// and so forth for your other AppDelegate stuff
我为此奋斗了一整天。有时我收到通知,有时没有,但是我永远无法userNotificationCenter(_:willPresent:completionHandler:)触发回调。
原来有两个问题。首先,我仍然有些困惑:我的目标部署版本设置为11.0,但我的项目设置为10.0。将项目更改为11.0是第一步。我对此不完全了解,但是通知处理在10.0和11.0之间可能有所不同吗?
第二部分是通知中心代表。我在文档中注意到了Apple的注释:
重要
您必须在应用启动完成之前将委托对象分配给UNUserNotificationCenter对象。例如,在iOS应用中,必须在应用委托的application(:willFinishLaunchingWithOptions :)或application(:didFinishLaunchingWithOptions :)方法中进行分配。在调用这些方法之后分配委托可能会导致您错过传入的通知。
我一直在设置一个单独的“通知管理器”类,在该类中也放置了回调(作为委托协议实现)。我已将其实例化为我的应用程序委托中的实例var,假设它会尽早创建且不会引起问题。
我搞砸了实例化等了一段时间,但是只有当我在application(_:didFinishLaunchingWithOptions:)方法中设置委托并在应用程序委托中实现委托回调时,我才设法修复它。
所以我的代码基本上变成了:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // You MUST do this HERE and nowhere else!
    UNUserNotificationCenter.current().delegate = self
    // other stuff
    return true
}
extension AppDelegate: UNUserNotificationCenterDelegate {
    // These delegate methods MUST live in App Delegate and nowhere else!
    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        if let userInfo = notification.request.content.userInfo as? [String : AnyObject] {
        }
        completionHandler(.alert)
    }
    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        if let userInfo = response.notification.request.content.userInfo as? [String : AnyObject] {
        }
        completionHandler()
    }
}
| 归档时间: | 
 | 
| 查看次数: | 20759 次 | 
| 最近记录: |