개발 slecs

로그인 때마다 앱 뻗던 버그, AppDelegate 방식으로 해결

목차

로그인 버튼을 누르는 순간 앱이 크래시하는 이슈를 겪었다. Apple·Google 소셜 로그인 플러그인을 쓸 때마다 일관되게 터졌는데, 원인은 iOS 생명주기 관리 방식의 충돌이었다. 결국 UIScene 기반 설정을 완전히 제거하고 클래식 AppDelegate 방식으로 복귀해서 해결했다.

iOS 13 이후의 두 갈래 길

iOS 13부터 Apple은 앱의 생명주기를 관리하는 방식을 크게 바꿨다. 기존 AppDelegate 방식에서 벗어나 UIScene을 도입했다. 단순히 말하면:

  • AppDelegate: 앱 전체의 상태를 관리 (시작, 종료, 메모리 경고)
  • UIScene: 개별 윈도우 시나리오를 관리 (멀티윈도우, Split View 같은 고급 기능)

고급 기능이 필요 없는 단일 윈도우 앱이라면 UIScene은 오버킬이다. 하지만 새로운 Xcode 템플릿이 기본으로 SceneDelegate를 만들어내다 보니, 많은 프로젝트가 무의식적으로 두 가지를 동시에 쓰고 있었다.

충돌의 원인: 플러그인이 기대한 세계가 달랐다

Apple·Google 로그인 SDK들은 꽤 오랫동안 AppDelegate 기반으로만 작동했다. 로그인 콜백을 받으려면 AppDelegate 메서드들(application(_:didFinishLaunchingWithOptions:), application(_:open:options:) 등)이 필수였다.

UIScene이 활성화되면 이런 메서드들의 동작이 불명확해진다. 일부 로직은 SceneDelegate로 옮겨지고, 일부는 AppDelegate에 남아있다. 플러그인 입장에서는 예상한 콜백이 제때 오지 않거나, 앱 상태를 잘못 읽어서 크래시가 발생한다.

우리 팀도 처음엔 SDK 버전을 올리거나 코드 패턴을 튜닝해볼 생각을 했다. 하지만 daily-bible은 단순한 단일-윈도우 앱이고, 멀티윈도우 기능을 지원할 계획도 없었다. 결국 "굳이 UIScene을 쓸 이유가 없다"는 결론에 도달했다.

구현: Info.plist에서 UIScene 제거, AppDelegate로 통일

변경 작업은 세 가지 단계였다:

파일 변경 내용 이유
Info.plist UIApplicationSceneManifest 키 제거 iOS에 UIScene을 쓰지 않음을 알림
AppDelegate.swift 모든 로그인 로직 통합, SceneDelegate 관련 코드 제거 단일 진입점으로 통일
pubspec.yaml iOS 배포 설정 정리 불필요한 Scene 관련 의존성 제거

클래식 AppDelegate 구조로 돌아가면서:

func application(
  _ application: UIApplication,
  didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
  // 모든 초기화: 로그인 SDK, 푸시 알림, 분석 등
  // 시스템이 직관적으로 이 메서드를 호출해줌
  return true
}

func application(
  _ app: UIApplication,
  open url: URL,
  options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
  // Apple·Google 로그인 콜백이 여기로 명확하게 들어옴
  return true
}

흐름이 명확해졌다. 더 이상 "이 로직이 SceneDelegate에서 실행될까, AppDelegate에서 실행될까?" 같은 모호함이 없다.

의사결정 회고: 최신 기술이 항상 정답은 아니다

이 이슈를 풀면서 배운 가장 중요한 교훈은 기술 선택의 문제는 보통 아키텍처 복잡도와 실제 필요성의 밸런스라는 것이다.

  • UIScene: 멀티윈도우, iPad Split View, 외부 디스플레이 같은 고급 기능을 지원하려면 필수다.
  • AppDelegate: 단순하고, 플러그인 생태계와의 호환성이 좋고, 대부분의 모바일 앱에는 충분하다.

우리 경우 daily-bible은 "언제나 한 화면, 한 앱" 형태였다. UIScene의 이점을 활용할 여지가 없었고, 대신 호환성 문제만 늘어났다. 팀에서 "새로운 게 더 좋다"는 선입견을 내려놓고, 실제 요구사항에 맞는 선택을 할 수 있었던 게 다행이다.

비슷한 상황이라면:
- 단일 윈도우 + 레거시 SDK 의존 → AppDelegate로 단순하게
- 멀티태스킹이 핵심 피처 → UIScene 도입 (초기부터, 나중에 추가 금지)
- 과도기 상황 → 호환성 테스트가 충분한지 먼저 확인

로그인 플러그인들도 요즘 대부분 UIScene을 지원하지만, 여전히 레거시 환경을 만나는 경우가 많다. 이런 시점에서는 "기술 이식"보다 문제의 근본 원인을 정확히 진단하고 필요에 맞춰 단순화하는 게 가장 빠른 해법이라는 걸 다시 한 번 확인했다.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.