Skip to content

Releases: DongLab-DevTools/ScreenNameViewer-For-iOS

v1.2.1

26 May 07:26

Choose a tag to compare

🎯 Highlights

SwiftUI rootView 가 child UIHostingController 케이스에서도 라벨에 노출 — UIViewController 가 UIHostingController 를 child 로 박는 패턴(가장 흔한 인라인 호스팅 방식)에서 SwiftUI View 이름이 자동으로 라벨에 잡히도록 보강.

🐛 Bug fixes

  • UIViewController 가 UIHostingController(rootView: ...) 를 child 로 추가하는 패턴에서 SwiftUI rootView 이름이 라벨에 안 잡히던 회귀 해결
    • 예: SettingsViewController 화면에서 SettingsView 가 라벨에 추가됨
    • 예: ShortsViewControllerShortsNavigationBar, ShortsLegacyProgressView 등 visible SwiftUI host 모두 노출

🛠 Internal

  • SwiftUIIntrospection.extractRootName 이 generic param 파싱 (UIHostingController<T>T) 을 우선 시도하고 Mirror 기반 ivar 접근은 fallback 으로 동작. iOS 내부 ivar (host, _rootView) 이름 변화에 더 견고
  • Tracker.collectVisibleUserDescendants 가 traverse 중 Apple framework host (UIHostingController 등) 를 만나면 SwiftUI rootView 이름도 평면 적층 리스트에 같이 채집

✅ Tests

82 tests passing. 신규 회귀 테스트 3건:

  • testChildHostingControllerExposesRootViewName — child UIHostingController 의 rootView 라벨 노출
  • testExtractRootNameFromGenericHostingController — generic param 파싱 동작
  • testExtractRootNameReturnsNilForNonHostingController — 일반 VC 영향 0

v1.2.0

24 May 10:41

Choose a tag to compare

🎯 Highlights

  • child VC 평면 적층 — 한 화면이 여러 child VC 로 구성된 경우 모두 라벨에 표시. 컨테이너 안의 컨테이너처럼 깊이 무관 traversal.
  • embedded child attach 시 자동 라벨 갱신 — 부모 화면이 떠있는 동안 child 가 attach 되면 (예: 버튼 탭으로 슬라이드 패널) 라벨이 자동으로 새 child 를 잡음.
  • depth 들여쓰기 — child 라벨에 depth 별 들여쓰기. 화면 구조가 한눈에 보임. 옵션으로 끄기 가능.
  • margin 옵션 — safeArea 기준 4방향 UIEdgeInsets 으로 라벨 위치 조정.
  • 서드파티 SDK 거르기excludedClassNamePrefixes 로 노이즈 VC 제외.

⚠️ Breaking changes

  • Configuration.LabelStyle.enabled 제거install(enabled:) 와 의미 중복이라 정리

마이그레이션

// Before
ScreenNameViewer.install { config in
    config.viewController.enabled = true   // ← 컴파일 에러
    config.route.enabled = false
}

// After — 해당 줄 삭제
ScreenNameViewer.install { config in
    // 라벨 표시 자체는 그대로 동작
}

라이브러리 전체를 끄려면 기존처럼 install(enabled: false) 사용.

✨ New features

Configuration.margin

라벨 4방향 inset.

config.margin = UIEdgeInsets(top: 60, left: 16, bottom: 0, right: 16)

verticalPosition 에 해당하는 top/bottom 만 적용. left/right 는 좌측/우측 라벨에 항상 적용.

Configuration.indentByDepth

child 라벨 depth 별 들여쓰기 (기본 true).

ContentDetailViewController
PlayerViewController
ListViewController
  VodDetailViewController                  ← depth 2 → 2 space indent
    HeaderViewController                   ← depth 3 → 4 space indent
TalkViewController

평면 표시 원하면 config.indentByDepth = false.

Configuration.excludedClassNamePrefixes

prefix 매치되는 VC 를 모든 라벨에서 제외.

config.excludedClassNamePrefixes = ["Introspection", "IMA"]

vc / child / introspected 라벨 전부에 적용. SwiftUI introspection 결과에도 동일.

🐛 Bug fixes

  • 부모 화면이 떠있는 동안 child VC 가 attach 되어도 라벨이 갱신되지 않던 회귀 — handleViewDidAppear 가 screen-level 아닌 VC 의 appear 도 render 트리거하도록 보강
  • 중간 컨테이너 VC 의 자식이 라벨에서 누락되던 회귀 — 깊이 무관 평면 traversal 로 전환

🛠 Internal / Refactor

  • DisplaySnapshot.childDisplays[String][(name: String, depth: Int)] 로 변경 (internal API)
  • 전체 소스 주석을 WHY 위주로 압축. 부가 설명 제거
  • OverlayView 의 child 라벨이 동적 pool 재사용 — 매 update 마다 라벨 생성/제거 비용 회피

✅ Tests

79 tests passing. 신규 회귀 테스트 4건 추가:

  • testChildLabelsIndentByDepth — depth 별 들여쓰기 적용
  • testIndentByDepthFalseDisablesIndent — 들여쓰기 끔 옵션
  • testGrandchildIsCollectedFlatly — 깊은 child 평면 적층
  • testEmbeddedChildAddedAfterParentUpdatesChildDisplays — 부모 떠있는 동안 child attach 시 라벨 갱신

📋 RELEASE 빌드 격리

기존과 동일 — 모든 라이브러리 코드 #if DEBUG 보호. 상용에선 런타임 비용 0.

v1.1.1

20 May 05:28

Choose a tag to compare

🎯 Highlights

  • 회전 정책 격리 — 별도 UIWindow 를 만들지 않고 호스트 앱 keyWindow 에 라벨 view 만 직접 주입합니다. iOS multi-window 회전 결정에 라이브러리가 일절 관여하지 않아, portrait 잠금 화면이 풀리거나 수동 전체화면이 안 먹는 회귀를 근본 차단합니다.
  • install API + enabled 파라미터 — 1회 셋업 모델 명확화. 디버그 오버레이 on/off 를 사용자 설정 토글에 연결하면 재시작 시 새 값이 적용됩니다.
  • 셀 임베드 SwiftUI host 가 라벨을 가로채는 회귀 픽스 — 셀이 UIHostingControllercontentView 에만 add 한 경우 라벨이 SwiftUI rootView 이름으로 바뀌어버리던 문제를 차단합니다.

⚠️ Breaking changes

  • ScreenNameViewer.start(_:) ScreenNameViewer.install(enabled:_:) 로 이름 변경
  • ScreenNameViewer.stop() public API 제거 — 1회 설치 모델이라 런타임 종료 API 불필요

마이그레이션

// Before
ScreenNameViewer.start { config in
    config.verticalPosition = .top
}

// After
ScreenNameViewer.install { config in
    config.verticalPosition = .top
}

// 사용자 설정 토글과 연결
ScreenNameViewer.install(
    enabled: UserDefaults.standard.bool(forKey: "debug_overlay_enabled")
) { config in
    // ...
}

enabled: false 면 swizzling 자체가 일어나지 않습니다. 토글 변경 후 앱 재시작 시 새 값이 적용됩니다(재시작은 적용 앱이 처리).

🐛 Bug fixes

  • contentView 에만 add 된 UIHostingController 가 화면 단위 VC 로 잘못 판정되어 라벨이 SwiftUI rootView 이름으로 바뀌는 회귀 차단 (isScreenLevel 가드 강화)
  • 호스트 앱이 portrait 로 잠근 화면에서 라이브러리 적용 시 디바이스가 회전해버리는 회귀 차단
  • 호스트 앱 플레이어의 수동 전체화면 전환 / 전체화면에서 뒤로가기 시 portrait 복귀가 막히는 회귀 차단

🛠 Internal / Refactor

  • OverlayWindow + OverlayViewController 제거 → OverlayView (UIView) 한 클래스로 통합
  • SceneOverlay 가 host keyWindow 를 추적하고 keyWindow 교체 시 자동 이동 (UIWindow.didBecomeKeyNotification)
  • 모달/시트 z-order 는 매 render 사이클마다 bringSubviewToFront 로 유지
  • 라벨 영역 외 모든 터치는 point(inside:with:) → false 로 통과 — 호스트 제스처 영향 0

✅ Tests

68 tests passing. 신규 회귀 테스트 2건 추가:

  • testParentlessAppleHostIsNotScreenLevel — 셀 임베드 host 가 push 되지 않음을 회귀 방지
  • testTouchPassthrough — 라벨 view 가 호스트 터치를 가로채지 않음을 회귀 방지

📋 RELEASE 빌드 격리

  • 모든 라이브러리 코드(swizzling, UIView 생성, NotificationCenter 구독, Tracker 인스턴스화)는 #if DEBUG 보호
  • public API 본문 모두 #if DEBUG 안 → RELEASE 빌드에선 빈 함수로 컴파일되어 런타임 비용 0