# Live Activities บน iOS

<Aside type="tip">
ดูวิดีโอเกี่ยวกับ Live Activities บน iOS
<YouTube id="jRrDh_pIZCE" playlabel="วิดีโอ Youtube: Live Activities บน iOS" /> 
</Aside>


[Live Activities](https://developer.apple.com/design/human-interface-guidelines/live-activities) จะแสดงข้อมูลล่าสุดของแอปของคุณบนหน้าจอล็อกของ iPhone หรือ iPad และใน Dynamic Island ฟีเจอร์นี้ช่วยให้ผู้ใช้สามารถดูข้อมูลสดได้อย่างรวดเร็วและดำเนินการด่วนที่เกี่ยวข้องกับข้อมูลที่แสดง

นี่คือตัวอย่างบางส่วนของการใช้ Live Activities:

*   แสดงสถานะการสั่งซื้อในแอปเดลิเวอรี่
*   แสดงการนับถอยหลังแบบเรียลไทม์ในแอปฝึกซ้อม
*   แสดงข้อมูลการติดตามในแอปแท็กซี่
*   แสดงสถิติเกมและคะแนนปัจจุบันในแอปพลิเคชันกีฬา
*   แสดงพยากรณ์อากาศรายชั่วโมงในแอปสภาพอากาศ

คุณสามารถเปิดใช้งาน Live Activities โดยใช้ Pushwoosh iOS SDK ตามที่อธิบายไว้ด้านล่าง หากต้องการจัดการ Live Activities และอัปเดตเนื้อหา ให้ใช้เมธอด [/updateLiveActivity](/th/developer/api-reference/ios-live-activities-api#updateliveactivity)



## การตั้งค่า
<Aside type="caution" title="สำคัญ" >
Live Activities ใน Pushwoosh รองรับเฉพาะ [การกำหนดค่าโดยใช้โทเค็น (token-based configuration)](/th/developer/first-steps/connect-messaging-services/ios-configuration/ios-token-based-configuration/) เท่านั้น ไม่รองรับ [การกำหนดค่าโดยใช้ใบรับรอง (certificate-based configuration)](/th/developer/first-steps/connect-messaging-services/ios-configuration/ios-platform-configuration/)
</Aside> 

### เพิ่ม Widget Extension

1. สร้าง target ใหม่

ไปที่ **File > New > Target** และเลือก **Widget Extension**

<img src="/ios-push-notifications-ios-live-activities-1.webp" alt=""/>

2. การกำหนดค่า Widget Extension
โปรดป้อนชื่อและตรวจสอบให้แน่ใจว่าได้เลือก **Include Live Activity** แล้วคลิก **Finish**

<img src="/ios-push-notifications-ios-live-activities-2.webp" alt=""/>

###  การกำหนดค่า Info.plist
ค้นหาไฟล์ Info.plist ใน target หลัก แทรกคีย์ "Supports Live Activities" และตั้งค่าเป็น YES

```xml
	<key>NSSupportsLiveActivities</key>
	<true/>
```

###  การเปิดใช้งาน Live Activities จากแอป
หากต้องการเปิดใช้งาน Live Activities ให้เพิ่มโค้ดลงใน widget extension ที่มีอยู่ของคุณ หรือสร้างใหม่หากแอปของคุณยังไม่มี Live Activities ใช้ฟังก์ชันการทำงานของ [SwiftUI](https://developer.apple.com/documentation/SwiftUI) และ [WidgetKit](https://developer.apple.com/documentation/WidgetKit) สำหรับอินเทอร์เฟซผู้ใช้ ActivityKit จะจัดการวงจรชีวิตของแต่ละ Live Activity: API ของมันใช้เพื่อร้องขอ อัปเดต และสิ้นสุด Live Activity และเพื่อรับการแจ้งเตือนแบบพุชของ ActivityKit คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับ Live Activities ได้ใน [เอกสารของ Apple](https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities)

 1. ไปที่ไฟล์ ContentView ของโปรเจกต์ของคุณใน Xcode และสร้าง Button

```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack(spacing: 20) {

            Button(action: {
                LiveActivityManager.shared.startActivity()
            }, label: {
                Text("Start Live Activity")
                    .foregroundColor(.white)
                    .padding()
                    .background(Color.blue)
                    .cornerRadius(10)
            })
        }
        .padding()
    }
}

#Preview {
    ContentView()
}
```
<img src="/ios-push-notifications-ios-live-activities-4.webp" alt=""/>

 2. สร้างไฟล์ LiveActivityManager.swift เพื่อจัดการ Live Activities

```swift
import Foundation
import ActivityKit
import UIKit
import PushwooshFramework
import PushwooshLiveActivities

class LiveActivityManager: NSObject, ObservableObject {
    public static let shared: LiveActivityManager = LiveActivityManager()

    private var currentActivity: Activity<FoodDeliveryAttributes>? = nil

    override init() {
        super.init()
    }

    func startActivity() {
        guard ActivityAuthorizationInfo().areActivitiesEnabled else {
            print("You can't start live activity.")
            return
        }
        do {
            let pushwooshData = PushwooshLiveActivityAttributeData(activityId: "activity_id")
            let atttribute = FoodDeliveryAttributes(orderNumber: "1234567", pushwoosh: pushwooshData)
            let initialState = FoodDeliveryAttributes.ContentState(
                status: "Preparing your meal",
                estimatedTime: "25 min",
                emoji: "👨‍🍳",
                pushwoosh: nil
            )
            let activity = try Activity<FoodDeliveryAttributes>.request(
                attributes: atttribute,
                content: .init(state:initialState , staleDate: nil),
                pushType: .token
            )
            self.currentActivity = activity

            Task {
                for await pushToken in activity.pushTokenUpdates {
                    let pushTokenString = pushToken.reduce("") {
                        $0 + String(format: "%02x", $1)
                    }
                    print("Activity:\(activity.id) push token: \(pushTokenString)")

                    // MARK: - Send Push Token to Pushwoosh
                    Pushwoosh.LiveActivities.startLiveActivity(
                        token: pushTokenString,
                        activityId: "activity_id"
                    )
                }
            }
        } catch {
            print("Start Activity Error: \(error.localizedDescription)")
        }
    }
}

```

 3. เท่านี้ก็เรียบร้อย ตอนนี้เรารันโปรเจกต์และกดปุ่ม 'Start Live Activity' จากนั้นไปที่หน้าจอล็อกและดู Live Activity ที่สร้างขึ้น


<img src="/live-activities-1.webp" alt=""/>

### เริ่มต้น Live Activity ด้วย Remote push notification

1. ในการเริ่มต้น Live Activity ผ่าน Remote Push Notification คุณต้องส่งโทเค็น pushToStartTokenUpdates ไปยัง Pushwoosh

```swift
func getPushToStartToken() {
    if #available(iOS 17.2, *) {
        Task {
            for await data in Activity<LiveActivityAttributes>.pushToStartTokenUpdates {
                let token = data.map {String(format: "%02x", $0)}.joined()
                print("Activity PushToStart Token: \(token)")

                // Send `pushToStartTokenUpdates` token to Pushwoosh
                try await Pushwoosh.LiveActivities.sendPushToStartLiveActivity(token: token)
            }
        }
    }
}
```
2. เริ่มต้น Live Activity ด้วย Remote Push Notification

<Aside type="tip">
 ทำตาม [เอกสารอ้างอิง Pushwoosh API](/th/developer/api-reference/ios-live-activities-api#startliveactivity) ของเราสำหรับคำแนะนำและตัวอย่างในการส่งคำขอเพื่อเริ่ม Live Activity จากระยะไกล
</Aside>

### การจัดการ Live Activities 

Pushwoosh iOS SDK มีเมธอดต่อไปนี้สำหรับทำงานกับ Live Activities:

```swift
// Send Live Activity Push To Start Token to Pushwoosh
static func sendPushToStartLiveActivity(token: String)
static func sendPushToStartLiveActivity(token: String, completion: @escaping (Error?) -> Void)

// Start Live Activity Methods with Activity ID
static func startLiveActivity(token: String, activityId: String)
static func startLiveActivity(token: String, activityId: String, completion: @escaping (Error?) -> Void)

// Stop Live Activity Methods
static func stopLiveActivity()
static func stopLiveActivity(completion: @escaping (Error?) -> Void)

static func stopLiveActivity(activityId: String)
static func stopLiveActivity(activityId: String, completion: @escaping (Error?) -> Void)

// Schedule a Live Activity to start at a future date (iOS 26.0+)
static func schedule<Attributes: PushwooshLiveActivityAttributes>(attributes: Attributes, contentState: Attributes.ContentState, at startDate: Date, alertTitle: String, alertBody: String) throws -> Activity<Attributes>

// Cancel a scheduled or running Live Activity by its Activity ID (iOS 16.2+)
static func cancel<Attributes: PushwooshLiveActivityAttributes>(_ activityType: Attributes.Type, activityId: String)

```

คุณยังสามารถอัปเดต Live Activities ตามเซกเมนต์โดยใช้พารามิเตอร์ Activity ID เมื่อสร้างกิจกรรม คุณต้องส่งพารามิเตอร์ Activity ID ที่ไม่ซ้ำกันในเมธอด ซึ่งจะเกี่ยวข้องกับเซกเมนต์ผู้ใช้ที่เฉพาะเจาะจง

ตัวอย่างเช่น ผู้ใช้ N คนได้สมัครรับข้อมูลเหตุการณ์เดียวกันใน Live Activity จำเป็นที่พารามิเตอร์ Activity ID จะต้องไม่ซ้ำกันสำหรับผู้ใช้ N คนทั้งหมดนี้

เมื่อคุณทำงานกับ Live Activity เสร็จแล้ว ให้ใช้เมธอดเหล่านี้:
```swift
static func stopLiveActivity()
static func stopLiveActivity(completion: @escaping (Error?) -> Void)
```
<Aside type="note">
 คุณสามารถจัดการ Live Activities บน iOS ผ่าน [Pushwoosh API](/th/developer/api-reference/ios-live-activities-api)
</Aside>

### การกำหนดเวลา Live Activity ให้เริ่มในอนาคต

<Aside type="note">
ต้องใช้ iOS 26.0+
</Aside>

แทนที่จะเริ่ม Live Activity ทันที คุณสามารถกำหนดเวลาให้เริ่มในอนาคตได้ `alertTitle` และ `alertBody` จะแสดงให้ผู้ใช้เห็นในการแจ้งเตือนแบบ local notification ที่จะปรากฏขึ้นเมื่อกิจกรรมที่กำหนดเวลาไว้เริ่มทำงานจริง:

```swift
if #available(iOS 26.0, *) {
    let startDate = Date().addingTimeInterval(3600) // starts in 1 hour

    do {
        let activity = try Pushwoosh.LiveActivities.schedule(
            attributes: atttribute,
            contentState: initialState,
            at: startDate,
            alertTitle: "Game starting!",
            alertBody: "The match is about to begin"
        )
        self.currentActivity = activity
    } catch {
        print("Schedule Activity Error: \(error.localizedDescription)")
    }
}
```

`startDate` ต้องเป็นเวลาในอนาคต มิฉะนั้นการเรียกจะเกิดข้อผิดพลาด เรียก `schedule` บน main thread ในขณะที่แอปอยู่ในเบื้องหน้า ไม่มีการส่งคำขอไปยัง Pushwoosh ณ เวลาที่กำหนดเวลา: เซิร์ฟเวอร์จะรับรู้เกี่ยวกับกิจกรรมเมื่อมันเริ่มทำงานจริงและได้รับ push token ผ่าน token observer เดียวกันที่ติดตั้งโดยเมธอด `setup()` (ดูด้านล่าง)

### การยกเลิก Live Activity ด้วย Activity ID

<Aside type="note">
ต้องใช้ iOS 16.2+
</Aside>

ใช้ `cancel(_:activityId:)` เพื่อยกเลิก Live Activity ด้วย Activity ID โดยไม่ต้องอ้างอิงถึงอินสแตนซ์ของ `Activity`:

```swift
if #available(iOS 16.2, *) {
    Pushwoosh.LiveActivities.cancel(FoodDeliveryAttributes.self, activityId: "activity_id")
}
```

`cancel` จะสิ้นสุดกิจกรรมบนอุปกรณ์ทันทีและแจ้งเตือนเซิร์ฟเวอร์ Pushwoosh ซึ่งแตกต่างจาก `stopLiveActivity(activityId:)` ซึ่งจะแจ้งเตือนเซิร์ฟเวอร์เท่านั้นและไม่สิ้นสุดกิจกรรมบนอุปกรณ์โดยตรง `cancel` ยังทำงานสำหรับ Live Activity ที่ถูกกำหนดเวลาด้วย `schedule` แต่ยังไม่ได้เริ่ม — มันจะถูกยกเลิกก่อนที่จะเริ่ม

### เมธอด `Setup()`
Pushwoosh ทำให้การถ่ายโอน activity ID ง่ายขึ้นโดยการแนะนำฟังก์ชัน `PushwooshLiveActivities.setup` ซึ่งจัดการวงจรชีวิตทั้งหมดของ Live Activity ภายในแอปพลิเคชัน ฟังก์ชันนี้จะคอยฟังการอัปเดตโทเค็นทั้ง `pushToStart` และ `pushToUpdate` โดยอัตโนมัติ การใช้วิธีนี้ทำให้แอปพลิเคชันไม่จำเป็นต้องติดตามการเริ่มต้นของ Live Activities หรือจัดการการอัปเดตโทเค็นสำหรับกิจกรรมด้วยตนเองอีกต่อไป

เราขอแนะนำให้ใช้วิธีนี้เนื่องจากจะจัดการการจัดการโทเค็นทั้งหมดในฝั่งของเรา ซึ่งช่วยลดปริมาณโค้ดที่คุณต้องดูแลในฝั่งของคุณ สิ่งนี้ทำให้การผสานรวมง่ายขึ้นและรับประกันประสบการณ์ที่ราบรื่นและมีประสิทธิภาพมากขึ้นสำหรับแอปของคุณ

ใน AppDelegate ตรวจสอบให้แน่ใจว่าคุณได้ import `PushwooshFramework` และ `PushwooshLiveActivities` และเรียกเมธอด `setup` จากโมดูล `Pushwoosh.LiveActivities`

**AppDelegate.swift**
```swift
if #available(iOS 16.1, *) {
    Pushwoosh.LiveActivities.setup(FoodDeliveryAttributes.self)
}
```
**FoodDeliveryAttributes**

```swift
import WidgetKit
import SwiftUI
import ActivityKit
import PushwooshFramework
import PushwooshLiveActivities

struct FoodDeliveryAttributes: PushwooshLiveActivityAttributes {
    public struct ContentState: PushwooshLiveActivityContentState {
        var status: String
        var estimatedTime: String
        var emoji: String
        var pushwoosh: PushwooshLiveActivityContentStateData?
    }

    var orderNumber: String
    var pushwoosh: PushwooshLiveActivityAttributeData
}
```
`FoodDeliveryAttributes`: โครงสร้างนี้สอดคล้องกับโปรโตคอล `PushwooshLiveActivityAttributes` ใช้เพื่อกำหนดแอตทริบิวต์ของ Live Activity ภายในแอป

<Aside type="note">
 คุณสามารถจัดการ Live Activities และอัปเดตเนื้อหาโดยใช้เมธอด /updateLiveActivity ของ Pushwoosh API สำหรับข้อมูลเพิ่มเติม โปรดอ่าน [คู่มือนี้](/th/developer/api-reference/ios-live-activities-api)
</Aside>

## คู่มือการย้ายข้อมูล

ตั้งแต่ Pushwoosh iOS SDK เวอร์ชัน 6.8.0 เป็นต้นไป เราได้อัปเดตโครงสร้าง SDK ตอนนี้เมธอด Live Activities จะเข้าถึงได้ผ่านโมดูล `PushwooshLiveActivities`

หากคุณใช้ Pushwoosh iOS SDK เวอร์ชันก่อน 6.8.0 และเคยเรียกใช้เมธอดที่ระบุไว้ด้านล่าง และได้อัปเดตเป็นเวอร์ชัน 6.8.0 หรือใหม่กว่า โปรดทราบการเปลี่ยนแปลงต่อไปนี้:

```swift
static func setup<Attributes: PushwooshLiveActivityAttributes>(_ activityType: Attributes.Type)
static func defaultSetup()
static func defaultStart(_ activityId: String, attributes: [String: Any], content: [String: Any])
```

ตอนนี้ หากต้องการเข้าถึงเมธอดเหล่านี้ คุณควรใช้โมดูล LiveActivity

```swift
import PushwooshFramework
import PushwooshLiveActivities

```

```swift
Pushwoosh.LiveActivities.setup(FoodDeliveryAttributes.self)
Pushwoosh.LiveActivities.defaultSetup()
Pushwoosh.LiveActivities.defaultStart("activity_id",
                            attributes: ["key_attribute": "value_attribute"],
                            content: ["key_content": "value_content"])
```

เรายังคงรองรับเมธอดเหล่านี้ผ่าน `Pushwoosh.sharedInstance()` ตามที่ระบุไว้ด้านล่าง แต่โปรดทราบว่าเมธอดเหล่านี้จะถูกเลิกใช้งานในอนาคต

``` swift
// Send Live Activity Push To Start Token to Pushwoosh
static func sendPushToStartLiveActivity(token: String)
static func sendPushToStartLiveActivity(token: String, completion: @escaping (Error?) -> Void)

// Start Live Activity Methods with Activity ID
static func startLiveActivity(token: String, activityId: String)
static func startLiveActivity(token: String, activityId: String, completion: @escaping (Error?) -> Void)

// Stop Live Activity Methods
static func stopLiveActivity()
static func stopLiveActivity(completion: @escaping (Error?) -> Void)

static func stopLiveActivity(activityId: String)
static func stopLiveActivity(activityId: String, completion: @escaping (Error?) -> Void)
```