Flutter注册iOS推送

如题所述

第1个回答  2022-06-18
####总结:

Flutter在iOS中AppDelegate继承自FlutterAppDelegate,所以很多方法必须重写父类中的方法。iOS的推送注册流程还是一样的。不一样的是需要给推送设置别名或者将设备的deviceToken上传到推送服务器,这一步可以原生实现也可以flutter实现,但是还是需要和flutter进行交互,这是就需要注册一个通道实现这个。通道也可以增加别的一些例如:信息处理等。

正文:

在进行iOS上开发,发现Flutter创建的项目不走didRegisterForRemoteNotificationsWithDeviceToken,起初以为是没有设置UNUserNotificationCenterDelegate,后来发现AppDelegate是继承于FlutterAppDelegate的,

也就是将原生的UIApplicationDelegate的方法都会被FlutterAppDelegate拦截,即使我们不实现didRegisterForRemoteNotificationsWithDeviceToken,我觉得应该有两种方法可以实现:第一种是需要重写父类的推送方法。第二种就是在dart文件中监听系统代理,通过通道回调appdelegate来实现,

下面是百度云推送,重写父类代理的实现:

在didFinishLaunchingWithOptions launchOptions: 中注册原生交互channel

override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? ) -> Bool {

        //Flutter Plugin插件注册

        GeneratedPluginRegistrant.register(with: self);

        //调用appdelegate 的 设置、注册远程推送

        self.requestAuthorization(application: application);

        //Flutter原生交互通道

        self.BPushChannel();

        //注册BPush通道

        BPush.registerChannel(launchOptions, apiKey: BPushKey, pushMode: BPushMode.development, withFirstAction: "打开", withSecondAction: "关闭", withCategory: nil, useBehaviorTextInput: true, isDebug: true);

        //禁用地理位置信息推送

        BPush.disableLbs();

        return super.application(application, didFinishLaunchingWithOptions: launchOptions);

    }

    //MARK:注册远程推送通知

    func requestAuthorization(application: UIApplication) {

        if #available(iOS 10.0, *) {

            UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate;

            UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .sound, .alert]) { (granted, error) in

                if granted == true {

                    DispatchQueue.main.async {

                        application.registerForRemoteNotifications()

                    }

                }

            }

        } else if #available(iOS 8.0, *) {

            let types:UIUserNotificationType = [.badge , .alert , .sound]

            let settings:UIUserNotificationSettings = UIUserNotificationSettings(types: types, categories: nil)

            application.registerUserNotificationSettings(settings)

        } else {

            let types:UIRemoteNotificationType = [UIRemoteNotificationType.alert, UIRemoteNotificationType.badge, .sound]

            application.registerForRemoteNotifications(matching: types)

        }

    }

    //百度推送通道

    func BPushChannel() -> Void {

        //获取系统的跟控制器

        let controller = self.window.rootViewController

        //建立rootViewController和Flutter的通信通道

        let pushChannel = FlutterMethodChannel.init(name: channelNameForPush, binaryMessenger:controller as! FlutterBinaryMessenger)

        //设置Method回调 FlutterMethodCall包含了method的Name,ID等信息, FlutterResult是给Native和Flutter的通信回调

        pushChannel.setMethodCallHandler { (FlutterMethodCall, FlutterResult) in

            print("pushChannel");

        }

        //绑定channelId到服务器

        let pushBind = FlutterMethodChannel.init(name:channelNameForPushBind, binaryMessenger: controller as! FlutterBinaryMessenger)

        pushBind.setMethodCallHandler { (FlutterMethodCall, FlutterResult) in

            //FlutterResult();结果回调,回调的结果只能为string类型

            if(self.channelId.isEmpty){

                FlutterResult(FlutterMethodNotImplemented);

            } else{

                print("channelId",self.channelId);

                let dic : Dictionary<String,String> = ["channelId":self.channelId];

                let data = try? JSONSerialization.data(withJSONObject: dic, options: [])

                let encodingStr = String(data: data!, encoding: String.Encoding.utf8)!

//将信息传到Flutter,

                FlutterResult(encodingStr);

            }

        }

    }

    // 重写远程推送通知 注册成功

    override func application(_ application: UIApplication , didRegisterForRemoteNotificationsWithDeviceToken deviceToken:Data) {

        //  向云推送注册 device token

        print("deviceToken = %@", deviceToken);

        BPush.registerDeviceToken(deviceToken as Data)

        // 绑定channel.将会在回调中看获得channnelid appid userid 等

        BPush.bindChannel(completeHandler: { (result, error) -> Void in

            if ((result) != nil){

                self.channelId = BPush.getChannelId();

                BPush.setTag("MyTag", withCompleteHandler: { (result, error) -> Void in

                    if ((result) != nil){

                    }

                })

            }

        })

        super.application(application, didRegisterForRemoteNotificationsWithDeviceToken:deviceToken)

    }

// 重写注册失败

    override func application(_ application: UIApplication , didFailToRegisterForRemoteNotificationsWithError error: Error ) {

        print("deviceToken = %@", error)

        super.application(application, didFailToRegisterForRemoteNotificationsWithError: error)

    }

**如果解决了你的问题,点个赞呗!**
相似回答