현재 진행하는 iOS 프로젝트에서 Firebase Authentication의 OAuthProvider를 사용해 GitHub 로그인을 구현하던 중, 다소 흥미로운 동작을 발견했다.
getCredentialWith 호출 후 아무런 오류도 발생하지 않는데도, completion 블록이 호출되지 않는 현상이 발생한 것이다. 디버거나 런루프 상태를 여러 방식으로 확인하면서 흐름을 추적하던 중, 일부 상황에서는 정상적으로 콜백이 호출되지만, 다른 상황에서는 조용히 호출되지 않는다는 패턴을 발견했다.
문제를 재현하며 런타임 상태를 추적해보니, 공통적으로 다음 특성이 있었다.
문제가 발생한 경우:
OAuthProvider인스턴스를 지역 변수로만 생성하고 메서드가 종료됨정상 동작한 경우: 객체가 유지되는 시점이 길어 completion 시점까지 살아 있음
즉, ARC 메모리 관리 관점에서 보면, OAuthProvider 객체가 completion 블록이 호출되기 전에 메모리에서 해제되고 있었던 것이다.
OAuthProvider는 내부적으로 인증 흐름을 유지해야 하는데, 메서드가 종료되면서 provider가 사라지면 이후의 인증 결과를 받을 수 있는 구조가 유지되지 않는다. 따라서 콜백이 호출되지 않는 현상은 라이브러리의 버그가 아니라,
객체 생명주기 관리가 요구되는 설계적 특성이었다.
해결 방법은 명확하다. OAuthProvider 인스턴스를 함수 안의 지역변수가 아니라 ViewController 레벨의 프로퍼티로 유지하는 것.
class LoginViewController: UIViewController {
private var oauthProvider: OAuthProvider?
@objc func test() {
oauthProvider = OAuthProvider(providerID: "github.com")
oauthProvider?.getCredentialWith(nil) { credential, error in
...
}
}
}객체가 ViewController가 살아있는 동안 보존되기 때문에, 비동기 인증 흐름이 끝날 때까지 안정적으로 유지된다.