[iOS] appcode에서 xcode처럼 코드변경시마다 화면 자동 적용되게 만들기
- defrecated/iOS
- 2021. 7. 14. 16:31
ios 개발하면서 xcode 쓸까 appcode 쓸까 고민하다가 appcode 라이선스도 있으니 그냥 appcode로 해보기로 했다. 하다가 안되면 바꾸지 뭐 ㅋㅋ
근데 시작부터 말썽인게, xcode의 경우 에디터에 preview화면이 있어서 코드 바뀔 때마다 화면이 어떻게 변하는지 알 수 있는 반면, appcode에는 preview가 없다.
검색해보니 appcode에서는 에뮬레이터를 키고 따로 플러그인을 설치해야 preview처럼 화면이 자동으로 변경되는 걸 구현할 수 있다고 한다.
xcode에서는 그냥 되는걸 이것저것 설치해야한다고 하니까 그냥 xcode로 할까... 고민하다가 이왕 시작한 거 한번 해보자~ 해서 jetbrain에서 가이드해주는 내용대로 따라 했다.
가이드 원문 : https://blog.jetbrains.com/objc/2020/05/tutorial-swiftui/
가장 먼저 injectlll이라는 툴을 설치해줘야 한다. 해당 프로그램 github에 들어가면 다운받을 수 있다.
https://github.com/johnno1962/InjectionIII
앱을 다운로드하고 설치하고 실행하면 상태바에 injectionlll 프로그램이 떠있게 된다.
프로그램을 누르고 open project를 누르고 현재 개발 중인 ios 프로젝트를 선택하면 된다.
이것만 하면 되는 건 아니고 프로젝트에 몇 가지 설정을 더해줘야 되는데, 일단 커맨드 + ; 을 눌러서 프로젝트 설정에 간 다음 Build Settings에 Other Linker Flags 값에 "-Xlinker -interposable"를 추가한다.
그다음 SwiftUI를 하기로 했기 때문에 아래 코드에서 AppDelegate 클래스를 {프로젝트명} APP.swift에 추가한다.
//
// JinFirstAppApp.swift
// JinFirstApp
//
// Created by KYUJIN on 2021/07/14.
//
//
import SwiftUI
import UIKit
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
#if DEBUG
var injectionBundlePath = "/Applications/InjectionIII.app/Contents/Resources"
#if targetEnvironment(macCatalyst)
injectionBundlePath = "\(injectionBundlePath)/macOSInjection.bundle"
#elseif os(iOS)
injectionBundlePath = "\(injectionBundlePath)/iOSInjection.bundle"
#endif
Bundle(path: injectionBundlePath)?.load()
#endif
return true
}
}
@main
struct JinFirstAppApp: App {
let persistenceController = PersistenceController.shared
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
}
}
}
마지막으로 preview를 사용할 View.swift에 가서 sturct XXXX_Previews로 되어있는걸 아래처럼 바꿔주면 된다.
class ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
}
#if DEBUG
@objc class func injected() {
UIApplication.shared.windows.first?.rootViewController =
UIHostingController(rootView: ContentView())
}
#endif
}
struct -> class로 바꿔주고 #if 문 있는 코드를 추가하면 됨.
이걸 한다고 xcode처럼 preview창이 뜨는 건 아니고, 에뮬레이터를 켜면 소스가 변경될 때마다 에뮬레이터에 소스를 반영해준다.
실행 한번 해보자.
그냥 실행하면 안 되네..
실행하기 전에 injectionlll에서 prepare project를 눌러줘야 된다.
누르면 뭐라 뭐라 나오는데 Go Ahead를 눌러주면 된다.
그럼 코드에 자동으로 뭐가 막 생기는걸 알 수 있는데, Injection을 위한 코드니까 그러려니 생각하면 된다.
이제 다시 실행시켜보면 코드를 바꾸고 저장을 누를 때마다 에뮬레이터가 바뀌는 걸 볼 수 있다.
이걸 프로젝트할 때마다 해줘야 할 것 같다.
그냥 Xcode쓸까..? ㅋㅋㅋ