본문 바로가기

IOS

Xcode - SwiftUI 모든 이벤트가 동작하지 않을때

얼마전 레거시 프로젝트 중에 UIKit -> SwiftUI 로 변환 작업중에 모든 SwiftUI 코드가 읽혀지지 않는 문제가 발생 

View는 그려지지만 @State, @Binding 등등 값을 변환 하기위한 모든 이벤트가 동작하질 않는다.

일단 UIKit -> SwiftUI 로 변환 하기 위해서는 다음과 같은 절차를 따른다


1.  각종 파일 삭제

기존 스토리보드와, 뷰 컨트롤러 제거와 동시에 info.plist 파일 에 해당 내용까지 삭제 처리 한다.

 

 

SwiftUI 의 메인을 연결하는 방법은 여러가지가 있는데, 필자는 AppDelegate, SceneDelegate 로 처리 하였고

App 파일에서 처리 하는 방법까지 작성 해놓겠습니다

AppDelegate -> SceneDelegate -> View 연결

Appdelegate 에서 SceneDelegate 를 연결하고 SceneDelegate 상에서 SwiftUI View 를 Root 처리 하는 방법입니다.

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        let sceneConfig = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
        sceneConfig.delegateClass = SceneDelegate.self
        return sceneConfig
    }
}
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    
    	guard let windowScene = (scene as? UIWindowScene) else { return }
    	self.window = UIWindow(windowScene: windowScene)
        
        self.window?.rootViewController = UIHostingController(rootView: ContentView())
        self.window?.makeKeyAndVisible()
    }
}

 

많은 내용이 생략된 부분이 있지만,  연결 하기 위한 핵심 부분만 추가 했습니다.

 

App -> @main -> View 연결

너무너무 쉬운 방법이며, 요즘 App 단에서도 이벤트를 받거나 ScenePhase 를 이용해 App 의 생명주기도 파악 할수 있다.

@main 키워드를 추가하여 진행한다

 

만약 SceneDelegate 와 설정이 겹칠경우 ContentView 가 두번 호출 될수 있다. 필자 같은경우 

@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate

을 추가하고 TestApp 에 있는 ContentView 를 호출하지 않도록 처리 하였다.

 

@main
struct TestApp: App {
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    var body: some View {
        VStack {
            Text("asdcasdc")
        }
    }
}

 


이러한 방법은 여러 포스팅에 있으나, 최근 레거시 프로젝트 변환시 문제가 발생 (최상단 문제점)

Project -> Build Settings -> Swift Compiler - General -> Reflection Metadata Level 값을 None -> All 로 변경

Reflection Metadata Level 에 대해 정확히 알고 싶었으나, 찾기가 어려워서 필자가 해결한 방법 토대로 작성 했습니다. (사실 기존 SwiftUI 프로젝트와 일일히 비교해가면서 찾은 결과..) 꼭 아시는분은 댓글 부탁 드립니다!!