일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Timer
- WeatherManager
- RunningTimer
- xcode로 날씨앱 만들기
- MKMapItem
- swift
- Xcode
- SwiftUI Boolean 값
- CoreLocation
- 서체관리자
- 러닝기록앱
- dispatchsource
- 한국어 개인정보처리방침
- Protocol
- Startign Assignments
- weak var
- UICollectionViewFlowLayout
- 클로저의 캡슐화
- font book
- 단일 책임원칙
- UIAlertAction
- 러닝타이머
- weatherKit
- 영문 개인정보처리방침
- App Store Connect
- AnyObject
- MKMapViewDelegate
- CLLocationManagerDelegate
- addannotation
- Required Reason API
- Today
- Total
VesselWheel
ActivityKit & WidgetKit 본문
https://developer.apple.com/videos/play/wwdc2023/10184
https://developer.apple.com/documentation/widgetkit/
https://developer.apple.com/wwdc22/10050
https://gyuios.tistory.com/226
widgetkit에 대한 설명 블로그
widgetkit의 공식문서 예시
//
// RunItWidget.swift
// RunItWidget
//
// Created by Jason Yang on 4/11/24.
//
import WidgetKit
import SwiftUI
// struct Provider의 정체
// 위젯을 업데이트 할 시기를 WidgetKit에 알리는 역할
// SimpleEntry를 포함하여, 본격적으로 위젯에 표시될 placeholder, 데이터를 가져와서 표출해주는 getSnapshot, 타임라인 설정 관련된 getTimeLine이 존재
struct Provider: AppIntentTimelineProvider {
// 데이터를 불러오기 전(getSnapshot)에 보여줄 placeholder
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), // *TimelineEntry를 준수하는 구조체, *TimelineEntry: 위젯을 표시할 Date를 정하고, 그 Data에 표시할 데이터를 나타냄
configuration: ConfigurationAppIntent())
}
// 위젯 갤러리에서 위젯을 고를 때 보이는 샘플 데이터를 보여줄때 해당 메소드 호출
// API를 통해서 데이터를 fetch하여 보여줄때 딜레이가 있는 경우 여기서 샘플 데이터를 하드코딩해서 보여주는 작업도 가능
// context.isPreview가 true인 경우 위젯 갤러리에 위젯이 표출되는 상태
func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry {
SimpleEntry(date: Date(), configuration: configuration)
}
// 홈화면에 있는 위젯을 언제 업데이트 시킬것인지 구현하는 부분
func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<SimpleEntry> {
var entries: [SimpleEntry] = []
// Generate a timeline consisting of five entries an hour apart, starting from the current date.
let currentDate = Date()
for hourOffset in 0 ..< 5 {
// 1시간뒤, 2시간뒤, ... 4시간뒤 entry 값으로 업데이트 하라는 코드
let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
let entry = SimpleEntry(date: entryDate, configuration: configuration)
entries.append(entry)
}
// (4시간뒤에 다시 타임라인을 새로 다시 불러옴)
return Timeline(entries: entries, policy: .atEnd)
// .atEnd: 마지막 date가 끝난 후 타임라인 reloading
// .after: 다음 data가 지난 후 타임라인 reloading
// .never: 즉시 타임라인 reloading
}
func recommendations() -> [AppIntentRecommendation<ConfigurationAppIntent>] {
// Create an array with all the preconfigured widgets to show.
[AppIntentRecommendation(intent: ConfigurationAppIntent(), description: "Example Widget")]
}
}
struct SimpleEntry: TimelineEntry {
let date: Date
let configuration: ConfigurationAppIntent
}
struct RunItWidgetEntryView : View {
@Environment(\.widgetFamily) var family: WidgetFamily
var entry: Provider.Entry
var body: some View {
VStack {
HStack {
Text("Time:")
Text(entry.date, style: .time)
}
Text("Favorite Emoji:")
Text(entry.configuration.favoriteEmoji)
}
}
}
@main
struct RunItWidget: Widget {
let kind: String = "RunItWidget"
// body 안에 사용하는 Configuration
// IntentConfiguration: 사용자가 위젯에서 Edit을 통해 위젯에 보여지는 내용 변경이 가능
// StaticConfiguration: 사용자가 변경 불가능한 정적 데이터 표출
var body: some WidgetConfiguration {
AppIntentConfiguration(
kind: kind,
intent: ConfigurationAppIntent.self, // 사용자가 설정하는 컨피그
provider: Provider() // 위젯 생성자 (타이밍 설정도 가능)
) { entry in // 위젯에 표출될 뷰
RunItWidgetEntryView(entry: entry)
.containerBackground(.fill.tertiary, for: .widget)
}
}
}
extension ConfigurationAppIntent {
fileprivate static var smiley: ConfigurationAppIntent {
let intent = ConfigurationAppIntent()
intent.favoriteEmoji = "😀"
return intent
}
fileprivate static var starEyes: ConfigurationAppIntent {
let intent = ConfigurationAppIntent()
intent.favoriteEmoji = "🤩"
return intent
}
}
#Preview(as: .accessoryRectangular) {
RunItWidget()
} timeline: {
SimpleEntry(date: .now, configuration: .smiley)
SimpleEntry(date: .now, configuration: .starEyes)
}
코드 설명
**RunItWidget 코드 설명**
이 코드는 SwiftUI를 사용하여 iOS 위젯을 만드는 방법을 보여줍니다. 위젯은 사용자의 홈 화면에 작은 정보 조각을 제공하며, 이 코드는 위젯의 기본 구조와 기능을 설명합니다. 📱
---
### Provider 구조체
- **역할**: 위젯의 데이터를 관리하고, 위젯이 언제 업데이트될지 WidgetKit에 알립니다.
- **주요 메소드**:
- `placeholder`: 데이터 로딩 전에 임시로 보여줄 내용을 정의합니다.
- `snapshot`: 위젯 갤러리에서 샘플 데이터를 보여줄 때 사용합니다. 실제 데이터 로딩에 딜레이가 있을 때 샘플 데이터를 표시할 수 있습니다.
- `timeline`: 위젯의 업데이트 타이밍을 결정합니다. 여기서는 현재 시간부터 시작하여 1시간 간격으로 5개의 엔트리를 생성하고, 마지막 엔트리 이후에 타임라인을 다시 로딩합니다.
### SimpleEntry 구조체
- **목적**: 위젯에 표시될 데이터를 정의합니다.
- **특징**: `TimelineEntry` 프로토콜을 준수하며, 위젯에 표시될 날짜와 설정을 포함합니다.
### RunItWidgetEntryView 구조체
- **기능**: 위젯의 UI를 정의합니다.
- **디자인**: 사용자가 선택한 이모지와 현재 시간을 표시합니다.
### RunItWidget 구조체
- **설정**: 위젯의 메인 구조를 정의합니다.
- **Configuration 타입**:
- `AppIntentConfiguration`: 사용자가 위젯의 내용을 변경할 수 있게 해주는 설정입니다.
- `Provider`: 위젯의 데이터와 업데이트 타이밍을 관리합니다.
### ConfigurationAppIntent 확장
- **목적**: 사용자가 위젯에서 선택할 수 있는 이모지를 미리 설정합니다.
- **예시**: "😀"와 "🤩" 이모지를 선택할 수 있게 해줍니다.
---
이 코드는 SwiftUI와 WidgetKit을 사용하여 사용자 정의 가능한 iOS 위젯을 만드는 방법을 보여줍니다. 위젯을 통해 사용자는 자신의 홈 화면에서 유용한 정보를 빠르게 확인할 수 있습니다. 더 자세한 정보는 [Apple Developer 문서](https://developer.apple.com/tutorials/swiftui-concepts/exploring-the-structure-of-a-swiftui-app)에서 확인할 수 있습니다. 📚
위젯 개발에 관한 더 궁금한 점이 있다면 언제든지 물어보세요! 😊
이런 자료를 참고했어요.
[1] Apple Developer - Exploring the structure of a SwiftUI app (https://developer.apple.com/tutorials/swiftui-concepts/exploring-the-structure-of-a-swiftui-app)
[2] Apple Developer - Creating and combining views — SwiftUI Tutorials (https://developer.apple.com/tutorials/swiftui/creating-and-combining-views)
'Xcode Study' 카테고리의 다른 글
[ReFactoring]Weather777(URLSession -> async/await) (0) | 2024.04.27 |
---|---|
[트러블 슈팅] [런 잇] 디바운스(Debounce)와 Combine을 활용한 Throttle 적용하기 그리고 Caching을 통한 디버깅 (0) | 2024.04.01 |
Required Reason API(from App Store Connect) (0) | 2024.03.26 |
앱 심사 요청 후 reject (0) | 2024.03.22 |
Swift Font 사용하기 (0) | 2024.03.19 |