美文网首页
iOS远程推送(Objective-C & Swift)

iOS远程推送(Objective-C & Swift)

作者: 文子飞_ | 来源:发表于2020-12-16 10:05 被阅读0次

    iOS远程推送

    在这里插入图片描述

    APNS远程推送的流程:

    1、app 注册到 APNS。
    2、APNS 下发 devicetoken 给 app。
    3、app 将 device token 发送给 app Server。
    4、app Serve 将[消息+device token]发送给 APNS。
    5、APNS 根据 device token 推送消息给iOS设备上的app。

    实现上述步骤需要一个前提:应用程序的推送证书(开发环境&生产环境两类推送证书)和描述文件(Provisioning Profile)配置完备。苹果会在推送前根据描述文件和 App ID 等信息对应用程序的合法性进行验证。`

    Objective-C相关代码

    //推送相关逻辑
    @interface AppDelegate (AppPush)<UNUserNotificationCenterDelegate>
    
    - (void)registerRemoteNotifications:(UIApplication *)application;
    
    @end
    
    @implementation AppDelegate (AppPush)
    
    - (void)registerRemoteNotifications:(UIApplication *)application {
        
        if (@available(iOS 10, *)) {
            UNUserNotificationCenter *notificationCenter = [UNUserNotificationCenter currentNotificationCenter];
            notificationCenter.delegate = self;
            // 申请权限
            [notificationCenter requestAuthorizationWithOptions:UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound completionHandler:^(BOOL granted, NSError * _Nullable error) {
                NSLog(@"申请权限granted = %d", granted);
                if (!error && granted) {
                    NSLog(@"远程通知注册成功");
                } else {
                    NSLog(@"远程通知注册失败error-%@", error);
                }
            }];
            
            // 获取权限设置 可以获取到用户设定通知的信息
            [notificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
                NSLog(@"settings = %@", settings);
            }];
            
        } else if ([[UIDevice currentDevice] systemVersion].floatValue >= 8.0) {
            [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge categories:nil]];
        }
        
        // 注册远程通知,获得device Token
        [[UIApplication sharedApplication] registerForRemoteNotifications];
        
    }
    
    #pragma mark - <UIApplicationDelegate>
    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
        // 将devicetoken发送给服务端
        NSUInteger length = deviceToken.length;
        const unsigned char *buffer = deviceToken.bytes;
        NSMutableString *token  = [NSMutableString stringWithCapacity:(length * 2)];
        for (int i = 0; i < length; ++i) {
          [token appendFormat:@"%02x", buffer[i]];
        }
        [kUserDefaults setObject:token forKey:kApp_DeviceToken];
        [kUserDefaults synchronize];
        NSLog(@"token = %@ ", token);
    }
    
    // 适配iOS10之前系统
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
        NSLog(@"didReceiveRemoteNotification-userInfo = %@",userInfo);
    }
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
        completionHandler(UIBackgroundFetchResultNewData);
        if (application.applicationState == UIApplicationStateActive) {
            NSLog(@"点击推送唤起app userInfo = %@", userInfo);
        } else {
            NSLog(@"前台收到推送 userInfo = %@", userInfo);
        }
    }
    
    - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
        NSLog(@"didFailToRegisterForRemoteNotificationsWithError-error = %@",error);
    }
    
    #pragma mark - <UNUserNotificationCenterDelegate>
    // app在前台收到通知时触发
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler  API_AVAILABLE(ios(10.0)){
        // 前台收到推送,也是可以跟后台收到推送一样,弹出横幅,播放声音并震动的。这要在completionHandler中传入相应的UNNotificationPresentationOptions
        completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound |UNNotificationPresentationOptionAlert);
    }
    
    // 当用户点击通知时,会触发
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler  API_AVAILABLE(ios(10.0)){
        completionHandler();  // 系统要求执行这个方法
    }
    
    #pragma mark - <private method>
    
    
    @end
    

    Swift相关代码

    extension AppDelegate {
        
        // MARK: - 注册远程推送
        func registerRemoteNotifications(with application: UIApplication) {
            
            let notificationCenter = UNUserNotificationCenter.current()
            notificationCenter.requestAuthorization(options: [.alert,.badge,.sound]) { (isGrand, error) in
                DispatchQueue.main.async {
                    if error != nil && isGrand {
                        print("用户允许了推送权限")
                    }else{
                        print("用户拒绝了推送权限")
                    }
                }
            }
            
            // 适配iOS10以前的设备
            UIApplication.shared.registerUserNotificationSettings(.init(types:[.alert,.badge,.sound], categories:nil))
            
            // 注册远程通知,获得device Token
            UIApplication.shared.registerForRemoteNotifications()
        }
        
        // MARK: iOS10以前的设备 registerUserNotificationSettings会触发notificationSettings
        func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) {
            if notificationSettings.types.isEmpty {
                    print("用户拒绝了推送权限")
            }else{
                    print("用户允许了推送权限")
            }
        }
        
        
        // MARK: - <UIApplicationDelegate>
        func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
            // 将devicetoken发送给服务端
            let deviceTokenString = deviceToken.reduce("",{$0 + String(format:"%02x",$1)})
        }
        
        func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
            print("didFailToRegisterForRemoteNotificationsWithError-error = \(error)")
        }
        // MARK: - 收到推送
        // 适配iOS10之前系统
        func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
            if application.applicationState == .inactive {
                print("点击推送唤起app userInfo=\(userInfo)")
            }else{
                print("前台收到推送 userInfo=\(userInfo)")
            }
        }
        
        
        // MARK: <UNUserNotificationCenterDelegate>
        // MARK: app在前台收到通知时触发
        func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
            // 前台收到推送,也是可以跟后台收到推送一样,弹出横幅,播放声音并震动的。这要在completionHandler中传入相应的UNNotificationPresentationOptions
            completionHandler([.sound,.alert])
        }
        // MARK: 当用户点击通知时,会触发
        func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
            let userInfo = response.notification.request.content.userInfo
            //handleUserResponse(userInfo:userInfo)
            // 系统要求执行这个方法
            completionHandler()
        }
        
    }
    
    // MARK: -  如果app已经被杀死,那么app会被重新启动,我们需要在app加载完成后处理用户的响应。
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        if let removePushUserInfo = launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification]{
            // 处理用户收到推送后的响应
       NotificationUtil.shared.handleUserResponse(userInfo:removePushUserInfo as! [AnyHashable:Any])
        }
        return true
    }
    
    

    相关文章

      网友评论

          本文标题:iOS远程推送(Objective-C & Swift)

          本文链接:https://www.haomeiwen.com/subject/rmswgktx.html