日本語教師、プログラマーになる。

韓国に嫁いで日本語を教えていましたが、なんやかんやでiOSアプリ作ってます。

Alamofire5でcustomURLSchemeがリダイレクトできなくてunsupported URLとか言われる

Alamofire5を使っています。

カスタムURLスキームにリダイレクトしたら普通にアプリが立ち上がると思ったらそうでもなかった。カスタムURLスキームってあれね。「myapp://」みたいにするとアプリが起動するやつ。

 

もちろん、Info.plistにはちゃんと登録してある。その証拠にSafariで直接打ち込んだら無事立ち上がるのです。あれれ…。

responseを見ると

error : Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL"

とか言われてしまっています。httpじゃないからよくわかんない!変なもの食べさせないでよ!!って事らしい。もしブラウザ(openURL)だったら勝手にリダイレクトしてくれるんだけど、Alamofireでやりたいんだけど…。

 

Alamofire5にはRedirectorというものがある。すごい便利になったよ!と言われ、便利すぎて逆にここでつまづいてしまった。Redirectorには3つの結末(Behavior)が用意されていて、

  • follow
  • doNotFollow
  • そしてmodifyムニャムニャ

の3種類。当然followでしょと思ったらこれがいけなかった。followを選ぶとそのまんま食えもしない「myapp://」をそのまんま食べようとして食当たりを起こしていた。こうなるとstatusCodeも原因不明(nil)になってしまいなんで泣いているのかわからないのである。

本来ならリダイレクトなのだから「302」が返ってくるはずで、nilって何だよ!?と堂々巡りをしてしまっていた。実はここであえて「doNotFollow」を選ぶと無事「302」が来ていることを確認できるのである。なんなん。どうやらリダイレクト前のURLはいちいちレスポンスを確認しないでそのまま次に行くみたい。前向きだ。

参考(韓国語です):

eunjin3786.tistory.com

 

結論から言うと、ここではfollowではなくmodifyを選ぶ。

modifyも何も何をどうmodifyするんだよという感じだが、ここで割り込んでリダイレクトURLを開きつつ最終的にはnilを返して無視する。つまりこう。

 

let redirector = Redirector(behavior: .modify({ task, request, response in
            DispatchQueue.main.async { //メインスレッドじゃないと怒られる
                UIApplication.shared.open(request.url!, options: [:], completionHandler: nil)
            }
            return nil
        }))

 

このようにして作ったRedirectorをrequestの方にセットする。

 

AF.request(path,
                   method: .post,
                   parameters: params ?? nil,
                   encoding: JSONEncoding.default,
                   headers: headers,
                   interceptor: nil,
                   requestModifier: nil)
        .redirect(using: redirector) //←ここ
        .validate(statusCode: 200..<400)
        .responseData { response in

 

という感じです。なんか裏技みたいでイマイチ気持ち悪いんだけど、間違ってたらすいません。