2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Flutter uni_linksを使っててもURL SchemeをiOSネイティブでハンドルする

Posted at

FlutterでURL Schemeを扱う方法としてはuni_linksをよく使うと思います。
今回、FlutterアプリにFlutterのパッケージでなくネイティブのGoogle Sign Inを追加した所、uni_linksが動かないという状況になりました。

直接的な原因はAppDelegate.swiftに,GoogleSignInのコールバックを受けるために、以下の関数を追加してしまったことです。(公式ドキュメント通りの手順)

AppDelegate.swift
    override func application(
      _ app: UIApplication,
      open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]
    ) -> Bool {
      var handled: Bool

      handled = GIDSignIn.sharedInstance.handle(url)
      if handled {
        return true
      } else {
          return 
      }

      // Handle other custom URL types.

      // If not handled by this app, return false.
      return false
    }

しかし、この関数をオーバーライドしてしまうと、uni_linksが動かなくなります。
理由はAppDelegateのスーパークラスであるFlutterAppDelegateの方の、関数が動かなくなってしまうからpluginで呼ばれるはずの、uni_links関数が実行されなくなってしまうからです。

正しく修正するには、AppDelegate.swift にこの関数を追加せずに、この関数自体をpluginで実行するようにします。

MyAppDelegatePlugin.swift
public class AppDelegatePlugin: NSObject, FlutterPlugin {
    
    public static func register(with registrar: FlutterPluginRegistrar) {
        let instance = AppDelegatePlugin()
        registrar.addApplicationDelegate(instance)
    }
    
    public func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        var handled: Bool
        
        handled = GIDSignIn.sharedInstance.handle(url)
        if handled {
            return true
        }
        
        // ここでハンドルしない場合はuni_linksでハンドルできるようにfalseを返す
        return false
    }
}

application関数の戻り値はGoogleSignInのURLを処理した場合のみtrueを返し、それ以外の場合はfalseを返します。これは複数のPluginからこの関数が登録された場合に、あとに実行されるapplication関数を実行するためです。ちなみにuni_linksを使うとこの関数の戻り値は常にtrueになります。参考。そのためプラグインの追加順は以下のようにする必要があります。

AppDelegate.swift
// uni_linksより先に実行させるためこの位置に追加
AppDelegatePlugin.register(with: registrar(forPlugin: "com.example.AppDelegatePlugin")!)

// uni_linksを含む追加されたライブラリのプラグインが追加される
GeneratedPluginRegistrant.register(with: self)

いかがでしたか?今回はやりたいことがニッチ過ぎましたが、Flutterプラグインの理解が少し深まりました。
例えばURLスキーマを扱うライブラリが複数追加された場合にも、片方が機能しないなどの問題が起きそうな気がします。その場合、プラグインの追加順を調整したり、application関数の戻り値を制御するなどの対応が取れるかもしれません。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?