카카오톡 로그인을 사용하던 중 딥링크 기능을 추가하면서 겪은 문제이다.
안드로이드는 문제없이 작동하는데 iOS에서 카카오톡 간편로그인이 되지 않는 문제이다.
await AccessTokenStore.instance.toStore(await AuthApi.instance
.issueAccessToken(await isKakaoTalkInstalled()
? await AuthCodeClient.instance.requestWithTalk()
: await AuthCodeClient.instance.request()));
문제의 코드이다.
kakao_flutter_sdk의 카톡 로그인 예제 그자체이다. 3번째 줄이 카톡이 깔려있을 때 호출되는 메소드인데 아무런 값을 반환하지 않고 에러를 던지지도 않는다.
AuthCodeClient.instance.requestWithTalk().then((value) => print(value));
이런식으로 로그를 찍어도 봤는데 찍히지도 않는다. 그런데 app_links패키지를 빼고 캐시까지 전부 지우고 다시 실행하면 로그인이 잘된다.
import Flutter
import UIKit
public class SwiftAppLinksPlugin: NSObject, FlutterPlugin {
fileprivate var methodChannel: FlutterMethodChannel
fileprivate var initialLink: String?
fileprivate var latestLink: String?
public static func register(with registrar: FlutterPluginRegistrar) {
let methodChannel = FlutterMethodChannel(name: "com.llfbandit.app_links/messages", binaryMessenger: registrar.messenger())
let instance = SwiftAppLinksPlugin(methodChannel: methodChannel)
registrar.addMethodCallDelegate(instance, channel: methodChannel)
registrar.addApplicationDelegate(instance)
}
init(methodChannel: FlutterMethodChannel) {
self.methodChannel = methodChannel
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "getInitialAppLink":
result(initialLink)
break
case "getLatestAppLink":
result(latestLink)
break
default:
result(FlutterMethodNotImplemented)
break
}
}
// Universal Links
public func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([Any]) -> Void) -> Bool {
switch userActivity.activityType {
case NSUserActivityTypeBrowsingWeb:
guard let url = userActivity.webpageURL else {
return false
}
handleLink(url: url)
return true
default: return false
}
}
// Custom URL schemes
public func application(
_ application: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
handleLink(url: url)
return true
}
fileprivate func handleLink(url: URL) -> Void {
debugPrint("iOS handleLink: \(url.absoluteString)")
if (initialLink == nil) {
initialLink = url.absoluteString
}
latestLink = url.absoluteString
methodChannel.invokeMethod("onAppLink", arguments: latestLink)
}
}
app_links 패키지의 ios 구현 부분이다. 중간의 주석을 보면 universal link와 custom url scheme을 구현한 메소드 이름이 application이다.
앱을 실행할 때 호출되는 메소드가 application이다. 앱이 universal link이나 custom url scheme을 통해 실행될 때 맞는 메소드를 찾아 호출하고 handleLink를 호출하고 메소드 채널을 통해 값을 flutter단으로 전달한다.
Future<void> initDeepLinkSet() async{
final applink = AppLinks(
onAppLink: (uri){
print('🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶🥶 $uri');
}
);
final lastAppLink = await applink.getLatestAppLink();
if(lastAppLink != null)
print('🦧🦧🦧🦧🦧🦧🦧🦧🦧🦧🦧🦧🦧🦧🦧 $lastAppLink');
print('🦞🦞🦞🦞🦞 ${lastAppLink.queryParameters['code']}');
}
딥링크 처리를 위한 메소드이다. 이 메소드를 로그인 페이지가 아닌 그 후에 보여지는 메인 페이지에서 호출해서 왜 안된건지 몰랐던 것이다.
로그인 페이지에서 로그인 버튼을 눌러서 문제의 requestWithTalk()가 호출되면 카톡이 실행되고 카톡에서 로그인을 위한 값을 받아서 우리의 프로젝트를 실행 하는데 이 때 Custom URL schemes방식으로 실행하게 된다. 이 때 우리의 app_links가 카톡에서 받아온 링크를 채갔던 것이다.
그래서 requestWithTalk()메소드는 호출되었으나 코드를 반환하지 않고 에러를 던지지도 않았던것이다.
kakaoa66c327dd11217556028ced9d45cfbe5://oauth?code=카카오톡인증코드
카카오톡 간편로그인을 하면 이렇게 생긴 값을 반환하는데 마지막에 카카오톡 인증코드를 따로 어떻게 처리하면 된다.
카톡 로그인 뿐만 아닌 다른 소셜 로그인도 이러한 문제가 발생할 수 있을 것이다.
굿굿굿