平台通道在初始运行时未返回快速关闭

时间:2019-03-01 09:14:32

标签: swift flutter closures firebase-cloud-messaging cross-platform

我正在开发Flutter应用程序,在这里我需要为每个平台利用本机Firebase Messaging插件。我已遵循platform channels上Flutter的指南,能够实现本机代码。我的问题是,当我第一次在任何iOS设备上安装应用程序时,平台通道都没有从Swift接收任何信息。该methodCall让我挂了。但是,当重新安装应用程序时,将返回令牌。我对Swift还是比较陌生,显然很难完全掌握如何正确实现闭包和@escaping参数。

我将问题缩小到GeneratedPluginRegistrant.register(with: self)行(这对于Flutter应用程序非常重要)。当该行被忽略时,我每次都会检索令牌,但不会显示启动屏幕(该应用程序停在空白屏幕上,这不是可行的解决方案)。

起初,我认为该应用程序受到以下事实的影响:它请求在初次运行时显示通知的权限,但是即使在重新安装该应用程序之前我不回答弹出窗口,我也获得了令牌。我尝试在不请求显示通知权限的情况下运行该应用程序,但这并没有影响结果。

客户/ Flutter

从initState()中调用以下代码:

  Future<void> getTokenNatively() async {
    print("inside getTokenNatively()");
    try {
      userToken = await getFirebaseTokenChannel.invokeMethod("getTokenNatively");
      print("-- FLUTTER -- userToken: $userToken");
    } catch (error) {
      print("getTokenNatively() resulted in an error: $error");
    } finally {
      print("Finally has run.");
    }
  }

主机/ iOS

didFinishLaunchingWithOptions内调用以下方法

            let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
            let tokenChannel = FlutterMethodChannel(name: "com.example.obscured/getTokenNatively",
                                                    binaryMessenger: controller)

            tokenChannel.setMethodCallHandler({
                [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
                print("just inside our FlutterMethodCall closure")
                guard call.method == "getTokenNatively" else {
                    result(FlutterMethodNotImplemented)
                    return
                }

                print("I will be printed every time")

                InstanceID.instanceID().instanceID(handler: { (res, error) in
                    print("First line after 'in' inside InstanceID.instanceID().instanceID")
                    if let error = error {
                        print("Error fetching remote instance ID: \(error)")
                        result(error.localizedDescription)
                    } else if let res = res {
                        print("Remote instance ID token: \(res.token)")
                        result(res.token)
                    } else {
                        print("neither a error or result. What are you?")
                        result("none of the above")
                    }
                    print("Outside if/else if/else")
                })

                print("That seems to be the case for me as well")
            })

    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

登录以进行全新安装(该应用尚未加载到设备上):

2019-03-29 10:47:39.215103+0100 Runner[2334:1001337] 5.7.0 - [Firebase/Analytics][I-ACS023007] Analytics v.50101000 started
2019-03-29 10:47:39.215323+0100 Runner[2334:1001337] 5.7.0 - [Firebase/Analytics][I-ACS023008] To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see "some fancy google link")
2019-03-29 10:47:39.219380+0100 Runner[2334:1001347] flutter: Observatory listening on http://127.0.0.1:60398/
APNs token retrieved: 32 bytes
2019-03-29 10:47:39.953629+0100 Runner[2334:1001340] flutter: didChangeDependencies() root_page
2019-03-29 10:47:39.959653+0100 Runner[2334:1001340] flutter: getDevice() result: IOS
2019-03-29 10:47:39.960416+0100 Runner[2334:1001340] flutter: inside getTokenNatively()
just inside our FlutterMethodCall closure
I will be printed every time
That seems to be the case for me as well
2019-03-29 10:47:40.177060+0100 Runner[2334:1001340] flutter: _authStatus: AuthStatus.signedIn
2019-03-29 10:47:40.177195+0100 Runner[2334:1001340] flutter: _homeStatus: null
2019-03-29 10:47:41.174878+0100 Runner[2334:1001340] flutter: Has [USER] accepted an invitation? Answer: true
2019-03-29 10:47:41.175041+0100 Runner[2334:1001340] flutter: crudMethods.hasHome(): true
2019-03-29 10:47:43.853516+0100 Runner[2334:1001355] [BoringSSL] nw_protocol_boringssl_get_output_frames(1301) [C4.1:2][0x1133cd2b0] get output frames failed, state 8196
2019-03-29 10:47:43.853858+0100 Runner[2334:1001355] [BoringSSL] nw_protocol_boringssl_get_output_frames(1301) [C4.1:2][0x1133cd2b0] get output frames failed, state 8196
2019-03-29 10:47:43.854425+0100 Runner[2334:1001355] TIC Read Status [4:0x0]: 1:57
2019-03-29 10:47:43.854485+0100 Runner[2334:1001355] TIC Read Status [4:0x0]: 1:57

在将以下行留在GeneratedPluginRegistrant.register(with: self)时记录全新安装:

2019-03-29 10:45:37.212943+0100 Runner[2327:1000780] flutter: Observatory listening on http://127.0.0.1:60265/
2019-03-29 10:45:37.214168+0100 Runner[2327:1000766] 5.7.0 - [Firebase/Analytics][I-ACS023007] Analytics v.50101000 started
2019-03-29 10:45:37.214855+0100 Runner[2327:1000766] 5.7.0 - [Firebase/Analytics][I-ACS023008] To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see "some shortened Google url")
APNs token retrieved: 32 bytes
2019-03-29 10:45:37.636480+0100 Runner[2327:1000772] [VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: MissingPluginException(No implementation found for method Firestore#settings on channel plugins.flutter.io/cloud_firestore)
#0      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:300:7)
<asynchronous suspension>
#1      Firestore.settings (file:///Users/[USER]/Library/flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.9.5+2/lib/src/firestore.dart:145:19)
<asynchronous suspension>
#2      main (package:cue_app/main.dart:31:18)
<asynchronous suspension>
#3      _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:189:25)
#4      _rootRun (dart:async/zone.dart:1124:13)
#5      _CustomZone.run (dart:async/zone.dart:1021:19)
#6      _runZoned (dart:async/zone.dart:1516:10)
#7      runZoned (dart:async/zone.dart:1500:12)
#8      _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:180:5)
#9      _startIsolate.<anonymous closure> (dart:isolate/runtime/lib/isolate_patch.dart:300:19)
#10     _RawReceivePortImpl._handleMessage (dart:isolate/runtime/lib/isolate_patch.dart:171:12)
Firebase registration token: [OMITTED]

然后我获得了令牌,但是该应用程序从未显示启动屏幕(因此,这不是解决方案)。

登录以重新安装(设备上有较早版本的应用程序):

2019-03-29 11:30:28.125256+0100 Runner[2345:1004655] 5.7.0 - [Firebase/Analytics][I-ACS023007] Analytics v.50101000 started
2019-03-29 11:30:28.127196+0100 Runner[2345:1004655] 5.7.0 - [Firebase/Analytics][I-ACS023008] To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see "some google link")
2019-03-29 11:30:28.133468+0100 Runner[2345:1004666] flutter: Observatory listening on http://127.0.0.1:61630/
APNs token retrieved: 32 bytes
2019-03-29 11:30:28.590713+0100 Runner[2345:1004661] flutter: didChangeDependencies() root_page
2019-03-29 11:30:28.595299+0100 Runner[2345:1004661] flutter: getDevice() result: IOS
2019-03-29 11:30:28.596043+0100 Runner[2345:1004661] flutter: inside getTokenNatively()
just inside our FlutterMethodCall closure
I will be printed every time
That seems to be the case for me as well
First line after 'in' inside InstanceID.instanceID().instanceID
Remote instance ID token: [OMITTED]
Outside if/else if/else
2019-03-29 11:30:28.794378+0100 Runner[2345:1004661] flutter: _authStatus: AuthStatus.signedIn
2019-03-29 11:30:28.794446+0100 Runner[2345:1004661] flutter: _homeStatus: null
2019-03-29 11:30:28.796259+0100 Runner[2345:1004661] flutter: -- FLUTTER -- userToken: [OMITTED]
2019-03-29 11:30:28.796293+0100 Runner[2345:1004661] flutter: Finally has run.
2019-03-29 11:30:29.974120+0100 Runner[2345:1004661] flutter: Has [USER] accepted an invitation? Answer: true
2019-03-29 11:30:29.974453+0100 Runner[2345:1004661] flutter: crudMethods.hasHome(): true

更新

我简化了示例。 Swift代码来自Firebase's repo。当我将他们的榜样作为一个独立的作品来运行时,它就是一种魅力。但是,当我尝试将其集成到Flutter项目中时,会破坏上面概述的各种情况。

由于某些原因,不允许代码在第一次运行时在methodChannel内返回代码。我认为这与Swift中的@escaping有关,但是我不知道如何从这里开始。有人知道吗?

0 个答案:

没有答案