์๋ ํ์ธ์...
์ค๋์ ๋ค์ด๋๋ฏน ์์ผ๋๋์ ๋ํด ์ค๋๋ง์ ๊ธ์ ์จ๋ณผ๊ฑด๋ฐ,
์ฌ์ค ๋ค์ด๋๋ฏน ์์ผ๋๋๊ฐ ๋์จ ์ง๋ ๊ฝค ๋์ต๋๋ค. 2023๋ ์ด์๋?
๊ทธ๋ฌ๋ ๊ทธ๋์ ๊ด์ฌ์ ๊ฐ์ง ์์์ต๋๋ค.
์๋๋ฉด ์ ํฐ์ ๋ค์ด๋๋ฏน ์์ผ๋๋๋ฅผ ์ง์ํ์ง ์๋ ์์ดํฐ12์๊ธฐ ๋๋ฌธ์ ๋๋ค.ใ ใ ใ
๊ทธ๋ฌ๋,
์ต๊ทผ์ ํฐ์ ๋ฐ๊พธ๊ณ ๋ ํ ๊ฐ์๊ธฐ ์ ๊ฒฝ์ฐ์ด๋๋ผ๊ตฐ์...
๋ค์ด๋๋ฏน ์์ผ๋๋... ๊ท์ฝ๋ค... ๋๋ ํด๋ณผ๊น...? ใ _ใ
์๊ฐ๋ณด๋ค ์ด๋ ต์ง ์์์ต๋๋ค.
์ผ๋จ ์์ ฏ๊ณผ ๊ฐ์ด SwiftUI ๊ธฐ๋ฐ์ผ๋ก ์ด๋ฃจ์ด์ง๋ฉฐ, ์๋ก์ด ํ๊ฒ์ผ๋ก ์ถ๊ฐํด์ค์ผํ๊ณ ,
์ค์๊ฐ ๋ฐ์ดํฐ ๋ณํ๋ ์ฑ์์ ์กฐ์ ํด์ฃผ๋ฉด ๋ฉ๋๋ค.
File > New > Target > 'Widget Extension' ์ผ๋ก ์์ ฏ ์ต์คํ ์ ์ ์ถ๊ฐํด์ฃผ๋๋ฐ,
Include Live Activities๋ฅผ ๊ผญ ์ฒดํฌํด์ค์ผํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ , ์ฑ ํ๊ฒ์์ ๊ฐ๋จํ UI๋ฅผ ๋ง๋ค์ด์ค๋๋ค.
์ ๋ ํผ์ ๋ฐฐ๋ฌ์ ์ฃผ์ ๋ก ์ผ์, ํญ ์ ๋ฐฐ๋ฌ ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ ๋ฒํผ์ ๋์ดํ์ต๋๋ค. ๐
ํผ์๋ฅผ ๋จน๊ธฐ ์ํด์๋ ๋ค์ด๋๋ฏน ์์ผ๋๋๋ก ๋ณด์ฌ์ค Attributes๋ค์ ์ ์ํด์ค์ผํฉ๋๋ค.
struct PizzaDeliveryAttributes: ActivityAttributes {
public struct ContentState: Codable, Hashable {
var deliveryStage: DeliveryStage
/// ...
}
}
๋ค์ด๋๋ฏน ์์ผ๋๋์ UI๋ฅผ ๊พธ๋ฐ๋๋ค.
์ ๋ ์์๋ก ProgressBar๋ก ์ํ๊ฐ ๋ณํ๋ฅผ ์ฝ๊ฒ ๋์ผ๋ก ํ์ธํ ์ ์๊ฒ๋ ํ์์ต๋๋ค.
struct PizzaDeliveryLiveActivity: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: PizzaDeliveryAttributes.self) { context in
// ์ด ๊ณณ์ UI๋ฅผ ๊พธ๋ฐ๋๋ค.
// ์ ๋ ์์๋ก ProgressBar๋ฅผ ์ ์ํด ๋ณด์ฌ์ฃผ์๋ค์ฃ .ใ
VStack(alignment: .leading, spacing: 16) {
ProgressView(value: progress(for: context.state.deliveryStage))
.progressViewStyle(.linear)
.tint(.orange)
.padding(.horizontal, 16)
.padding(.top, 8)
Spacer(minLength: 8)
}
.activityBackgroundTint(.cyan)
.activitySystemActionForegroundColor(.black)
} dynamicIsland: { context in
DynamicIsland {
// Expanded
DynamicIslandExpandedRegion(.leading) {
Text("๐")
}
DynamicIslandExpandedRegion(.trailing) {
Text(context.state.deliveryStageTitle)
}
DynamicIslandExpandedRegion(.bottom) {
ProgressView(value: progress(for: context.state.deliveryStage))
.progressViewStyle(.linear)
.tint(.orange)
.padding(8)
}
} compactLeading: {
Text("๐")
} compactTrailing: {
Text(context.state.deliveryIcon)
} minimal: {
Text("๐")
}
}
}
func progress(for stage: DeliveryStage) -> Double {
switch stage {
case .checking: return 0.1
case .cooking: return 0.4
case .delivering: return 0.8
case .delivered: return 1.0
}
}
}
์ฑ ํ๊ฒ์์ Live Activity๋ฅผ ์์ํ๊ณ + ์ ๋ฐ์ดํธํ๊ณ + ์ข ๋ฃํ๋ ๋ฉ์๋๋ฅผ ์ ์ํฉ๋๋ค.
func startPizzaDeliveryActivity() {
let attributes = PizzaDeliveryAttributes()
let initialContentState = PizzaDeliveryAttributes.ContentState(deliveryStage: .checking)
do {
let _ = try Activity<PizzaDeliveryAttributes>.request(
attributes: attributes,
contentState: initialContentState,
pushType: nil
)
} catch {
print("Failed to start activity: \(error)")
}
}
func updatePizzaDeliveryActivity(to stage: DeliveryStage) async {
for activity in Activity<PizzaDeliveryAttributes>.activities {
await activity.update(using: .init(deliveryStage: stage))
}
}
func endPizzaDeliveryActivity() async {
for activity in Activity<PizzaDeliveryAttributes>.activities {
await activity.end(using: .init(deliveryStage: .delivered), dismissalPolicy: .immediate)
}
}
๊ฒฐ๊ณผ์ ๋๋ค. ์ฌ๊ฐํ๊ฒ ๊ท์ฌ์
์ฐธ๊ณ ๋ก ํผ์๋ ๋ฐ์ง ํผ์๋ก ์ถ์ (?) ์ค์ ๋๋ค. ์ ์งํผํฐ๊ฐ ๋ง๋ค์ด์ค ๊ฒ์ด์ฌ์.
๋ค์ด๋๋ฏน ์์ผ๋๋๊ฐ ์์์ก์ ๋ ์ด๋ ๊ฒ ๋ณด์ ๋๋ค. ๊ท์ฝ๋ค.
'๐ iOS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[iOS/NFC] CoreNFC๋ก NFC ์ฝ๊ธฐ/์ฐ๊ธฐ (0) | 2024.12.29 |
---|---|
Jazzy๋ก ๋ชจ๋ ๋ฌธ์ํ๋ฅผ ํด๋ด ์๋ค. ๐ถ (0) | 2024.11.17 |
[DI] Swinject - ์์กด์ฑ ์ฃผ์ ํด (0) | 2024.11.17 |
Xcode Template์ผ๋ก ๊ฐ๋ฐ์๊ฐ ๋จ์ถํ์ ๐ (0) | 2024.05.15 |
[Tuist] ํธ์์คํธ ์ถ๋ฉด์~๐บ ํ๋ก์ ํธ๋ฅผ ๋ชจ๋ํ ์ํค๊ธฐ (0) | 2024.05.15 |