十年網站開發(fā)經驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網站問題一站解決
如果要在殺掉app情況下收到推送,需要在不同的手機渠道商處注冊
創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務領域包括:成都做網站、網站制作、企業(yè)官網、英文網站、手機端網站、網站推廣等服務,滿足客戶于互聯(lián)網時代的天涯網站設計、移動媒體設計的需求,幫助企業(yè)找到有效的互聯(lián)網解決方案。努力成為您成熟可靠的網絡建設合作伙伴!
gRPC是谷歌開發(fā)的一款遠程過程調用系統(tǒng),可以讓客戶端像調用本地對象一樣使用服務端應用的方法,使用protocol buffers接口定義語言來定義服務方法,protocol buffer定義參數和返回類型。
protobuf類似json,是一種數據結構協(xié)議,在android studio中安裝Protobuf Support,方便查看編寫的proto文件
dart使用proto插件將proto文件生成對應的dart文件,使用如下步驟
1、安裝flutter之后,再flutter的下面路徑中有pub命令,需要將命令加入到path中。
可以vi ~/.zshrc,在文件中加入source ~/.bash_profile,然后在vi ~/.bash_profile文件中加入下面路徑(:分割不同的路徑)
export PATH=/Users/webull/app/flutter/bin:/Users/webull/app/flutter/bin/cache/dart-sdk/bin:/Users/webull/.pub-cache/bin:$PATH
其中fluter/bin是flutter的命令路徑,dart-sdk/bin中包含了pub和其他dart命令,.pub-cache/bin是之后運行pub之后建立的路徑,里面包含了proto-gen-dart命令,用來將proto文件轉換為dart的命令
2、使用下面的命令安裝proto插件
$ pub global activate protoc_plugin
安裝完成后,上面的用戶目錄中的.pub-cache目錄才會有proto-gen-dart文件。
1、其中/Users/webull是我的用戶目錄 app/flutter是flutter的安裝目錄
參考:
1、gRPC介紹
2、gRPC配置
####總結:
Flutter在iOS中AppDelegate繼承自FlutterAppDelegate,所以很多方法必須重寫父類中的方法。iOS的推送注冊流程還是一樣的。不一樣的是需要給推送設置別名或者將設備的deviceToken上傳到推送服務器,這一步可以原生實現也可以flutter實現,但是還是需要和flutter進行交互,這是就需要注冊一個通道實現這個。通道也可以增加別的一些例如:信息處理等。
正文:
在進行iOS上開發(fā),發(fā)現Flutter創(chuàng)建的項目不走didRegisterForRemoteNotificationsWithDeviceToken,起初以為是沒有設置UNUserNotificationCenterDelegate,后來發(fā)現AppDelegate是繼承于FlutterAppDelegate的,
也就是將原生的UIApplicationDelegate的方法都會被FlutterAppDelegate攔截,即使我們不實現didRegisterForRemoteNotificationsWithDeviceToken,我覺得應該有兩種方法可以實現:第一種是需要重寫父類的推送方法。第二種就是在dart文件中監(jiān)聽系統(tǒng)代理,通過通道回調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 {
? ? //獲取系統(tǒng)的跟控制器
? ? 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 : DictionaryString,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)
}
**如果解決了你的問題,點個贊唄!**