반응형
iOS 위젯에서 앱 특정 화면으로 이동하는 방법
iOS에서 Widget을 탭했을 때 앱이 열리며 특정 화면으로 이동하게 하려면, URL Scheme + 딥링크 라우팅 + Widget Link 구성의 세 가지 핵심을 이해해야 합니다.
이 문서는 iOS 17~18 최신 SwiftUI / WidgetKit 구조에 맞춰 정리된 실전 예제입니다.
1. 개념 요약
구성 요소설명
| Widget | 앱의 일부 정보를 홈 화면/잠금화면에 표시 |
| URL Scheme | myapp://home, myapp://detail?id=3 형태로 앱 특정화면 호출 |
| Router | URL을 파싱해 SwiftUI NavigationStack으로 연결 |
| Link / AppIntent | Widget 내부에서 앱을 여는 공식 방법 |
2. URL Scheme 등록 (딥링크 설정)
Info.plist 파일에 아래 항목 추가:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>
→ 이제 myapp://home, myapp://detail?id=3 등을 인식할 수 있습니다.
3. SwiftUI App에서 onOpenURL 처리
import SwiftUI
@main
struct MyApp: App {
@StateObject var router = AppRouter()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(router)
.onOpenURL { url in
router.handleDeepLink(url)
}
}
}
}
4. AppRouter 구현
import Foundation
final class AppRouter: ObservableObject {
@Published var destination: Destination?
enum Destination {
case home
case detail(id: Int)
case settings
}
func handleDeepLink(_ url: URL) {
guard url.scheme == "myapp" else { return }
switch url.host {
case "home":
destination = .home
case "detail":
if let idString = url.queryItems?["id"], let id = Int(idString) {
destination = .detail(id: id)
}
case "settings":
destination = .settings
default:
break
}
}
}
extension URL {
var queryItems: [String: String]? {
URLComponents(string: absoluteString)?.queryItems?
.reduce(into: [String: String]()) { $0[$1.name] = $1.value }
}
}
5. ContentView에서 라우팅 반영
import SwiftUI
struct ContentView: View {
@EnvironmentObject var router: AppRouter
var body: some View {
NavigationStack {
VStack {
NavigationLink("홈으로", value: AppRouter.Destination.home)
NavigationLink("상세로", value: AppRouter.Destination.detail(id: 1))
}
.navigationDestination(for: AppRouter.Destination.self) { destination in
switch destination {
case .home: HomeView()
case .detail(let id): DetailView(id: id)
case .settings: SettingsView()
}
}
}
}
}
6. Widget에서 딥링크로 앱 열기
import WidgetKit
import SwiftUI
struct MyWidgetEntryView: View {
var entry: SimpleEntry
var body: some View {
VStack {
Link(destination: URL(string: "myapp://detail?id=3")!) {
HStack {
Image(systemName: "bell.fill")
Text("3번 상세화면 열기")
}
}
Link(destination: URL(string: "myapp://settings")!) {
Text("설정 화면 열기")
}
}
.padding()
}
}
Link(destination:)은 위젯에서 앱을 여는 공식 API이며, 지정한 URL로 앱이 실행됩니다.
7. AppIntent 기반 (iOS 17+)
struct OpenDetailIntent: AppIntent {
static var title: LocalizedStringResource = "상세화면 열기"
func perform() async throws -> some IntentResult {
guard let url = URL(string: "myapp://detail?id=10") else { return .result() }
await UIApplication.shared.open(url)
return .result()
}
}
Widget 내부에서:
struct MyWidget: Widget {
var body: some WidgetConfiguration {
AppIntentConfiguration(kind: "MyWidget", intent: OpenDetailIntent.self) { entry in
VStack {
Button(intent: OpenDetailIntent()) {
Label("상세 화면 열기", systemImage: "doc.text.magnifyingglass")
}
}
}
}
}
8. 데이터 공유 (App Group)
let defaults = UserDefaults(suiteName: "group.com.mycompany.myapp")
defaults?.set("hello", forKey: "widgetMessage")
앱에서 읽기:
let message = UserDefaults(suiteName: "group.com.mycompany.myapp")?.string(forKey: "widgetMessage")
9. 테스트 명령어
시뮬레이터에서 직접 딥링크 실행:
xcrun simctl openurl booted "myapp://detail?id=3"
→ 해당 화면으로 이동하면 정상 동작입니다.
10. 문제 해결 FAQ
증상원인해결
| 앱은 열리지만 화면이 안 바뀜 | .onOpenURL 누락 | App 구조에 추가 |
| 위젯 터치 작동안함 | Link 영역 누락 | 명시적으로 감싸기 |
| SwiftUI 이동 안됨 | @Published destination미갱신 | Router에서 상태 변경 확인 |
11. 결론
단계설명
| 1단계 | Info.plist에 URL Scheme 등록 (myapp://) |
| 2단계 | .onOpenURL 로 URL 수신 |
| 3단계 | AppRouter로 라우팅 |
| 4단계 | Widget에서 Link() 또는 AppIntent로 호출 |
| 5단계 | 필요 시 App Group으로 데이터 공유 |
→ 이 과정을 적용하면 위젯 → 앱 → 특정 화면 자동 이동이 완벽하게 구현됩니다.
반응형
'Dev Study > iOS' 카테고리의 다른 글
| WKWebView 쿠키(Cookie) 가이드 (0) | 2025.11.10 |
|---|---|
| 화면을 이미지로 전환 (UIView -> UIImage, View -> Image) (0) | 2025.11.06 |
| WKWebView 실전 팁 모음 (iOS 15+) (0) | 2025.11.06 |
| Swift 날짜 포맷(DateFormatter) 치트시트 & 사용법 정리 (iOS) (0) | 2025.11.06 |
| iOS 앱 크래시 발생 시 확인하는 방법 (0) | 2025.11.06 |
| iOS DocC 완전 정복 가이드: Swift 문서화를 위한 최고의 도구 (0) | 2025.11.06 |
| iOS TDD 완벽 가이드: 개념부터 실전까지 (0) | 2025.11.06 |
| iOS 개발자를 위한 Tuist 완벽 가이드 (0) | 2025.11.03 |


