Dynamic Island靈動(dòng)島調(diào)研

1.背景

對(duì)于IoT行業(yè),iPhone14 Pro及Max的靈動(dòng)島可以用于展示設(shè)備的各種動(dòng)作和計(jì)時(shí),在iPhone鎖定屏幕和動(dòng)態(tài)島上顯示App的最新數(shù)據(jù),這讓人們可以一目了然地看到實(shí)時(shí)信息。

2.名詞解釋

詞匯 含義
1 Widget 組件,iOS 14 重磅推出的新功能,使得用戶(hù)可以在主屏幕添加小組件,快速瀏覽 app 提供的重要信息
2 Dynamic Island 靈動(dòng)島,iOS16.1推出的針對(duì)iphone14 pro系列機(jī)型的聯(lián)動(dòng)功能,快速瀏覽 app 提供的重要信息
3 Live Activity 實(shí)時(shí)活動(dòng),展示在靈動(dòng)島和鎖屏界面的信息活動(dòng)

Dynamic Island是ActivitiesKit的一部分,而它是Widget Extension的一部分。

3.配置條件

  • 需要至少Xcode 14.1 Beta版及iOS16.1才能使用ActivityKit 框架,iOS16.1是第一個(gè)開(kāi)放ActivityKit的正式版本。
  • 在主工程的info.plist中加入鍵值NSSupportsLiveActivities ,并將其布爾值設(shè)置為YES
  • 因?yàn)殪`動(dòng)島是屬于小組件的一部分,所以項(xiàng)目中如果沒(méi)有小組件的話(huà)要先創(chuàng)建小組件。有小組件的話(huà)可以添加些代碼即可適配。


    16645173953743.png

4.詳細(xì)介紹

4.1 布局
16645173873665.png
16645182762547.png
Simulator Screen Shot - iPhone 14 Pro Max - 2022-09-30 at 14.15.21.png

上圖依次是

  • 緊湊視圖:分為leading和traling視圖,只有一個(gè)live activity事件時(shí)
  • 最小視圖:兩個(gè)及以上live activity事件時(shí),左右顯示的都是minmal視圖
  • 擴(kuò)展視圖:分為leading、traling、center、bottom
  • 鎖屏視圖:鎖屏的時(shí)候會(huì)展示在鎖屏下方
var body: some WidgetConfiguration {
        ActivityConfiguration(for: GroceryDeliveryAppAttributes.self) { context in
            LockScreenView(context: context) //鎖屏視圖
        } dynamicIsland: { context in
            DynamicIsland {
                 //擴(kuò)展視圖
                 DynamicIslandExpandedRegion(.leading) {
                    dynamicIslandExpandedLeadingView(context: context)
                 }
                 
                 DynamicIslandExpandedRegion(.trailing) {
                     dynamicIslandExpandedTrailingView(context: context)
                 }
                 
                 DynamicIslandExpandedRegion(.center) {
                     dynamicIslandExpandedCenterView(context: context)
                 }
                 
                 DynamicIslandExpandedRegion(.bottom) {
                    dynamicIslandExpandedBottomView(context: context)
                 }
                
              } compactLeading: {//單個(gè)前視圖
                  compactLeadingView(context: context)
              } compactTrailing: {//單個(gè)后視圖
                  compactTrailingView(context: context)
              } minimal: { //最小化視圖
                  minimalView(context: context)
              }
              .keylineTint(.cyan) //靈動(dòng)島邊緣顏色
        }
    }

當(dāng)只有一個(gè)live activity事件時(shí)


16645183250579.png
16645183283279.png

因?yàn)檫@個(gè)靈動(dòng)島左右是對(duì)稱(chēng)的,左邊布局的拉寬會(huì)帶動(dòng)右邊也拉寬,進(jìn)而占據(jù)時(shí)間、信號(hào)、電量等圖標(biāo)。而用戶(hù)肯定會(huì)對(duì)這種占據(jù)過(guò)多空間的live activity深?lèi)和唇^,可能會(huì)立馬干掉。

靈動(dòng)島:只能在App處于前臺(tái)時(shí)從其啟動(dòng)實(shí)時(shí)活動(dòng)。目前最多只能展示兩個(gè)live activity,后來(lái)的不會(huì)顯示,除非用戶(hù)上下滑動(dòng)移除了當(dāng)前顯示的live activity或者在鎖屏界面移除或者代碼調(diào)用移除,后來(lái)的才會(huì)依次展示在上面,因?yàn)橛玫哪M器調(diào)研,不知道系統(tǒng)的打電話(huà)功能是否優(yōu)先級(jí)最高。注意這里的上下滑動(dòng)只是隱藏了當(dāng)前的live activity,他其實(shí)還在,鎖屏的時(shí)候依然會(huì)顯示。

鎖屏: 沒(méi)有靈動(dòng)島的設(shè)備同樣會(huì)展示鎖屏視圖,高度最多顯示160,其余會(huì)被系統(tǒng)裁剪掉。移除鎖屏狀態(tài)的視圖,就相當(dāng)于停止了live activity。

4.2 更新策略

每個(gè)“Live Activity”都在自己的沙盒中運(yùn)行,雖然它是依托于小組件但是與小組件的時(shí)間線(xiàn)timeline更新不同,它無(wú)法訪問(wèn)網(wǎng)絡(luò)或接收位置更新。要更新活動(dòng)現(xiàn)場(chǎng)活動(dòng)的動(dòng)態(tài)數(shù)據(jù),請(qǐng)使用應(yīng)用程序中的ActivityKit框架,或允許您的現(xiàn)場(chǎng)活動(dòng)接收遠(yuǎn)程推送通知。 ActivityKit 更新后和遠(yuǎn)程推送通知更新的動(dòng)態(tài)數(shù)據(jù)大小不得超過(guò) 4KB

4.2.1 live activity更新
  1. 手動(dòng)代碼更新:
    16645187695082.png
  2. 推送通知更新:需要和服務(wù)端配置推送類(lèi)型pushType,詳情可見(jiàn)相關(guān)鏈接。如果通知被用戶(hù)關(guān)閉了權(quán)限,應(yīng)該只能采用手動(dòng)更新來(lái)保證吧。

4.2.2 對(duì)比widget更新

Widget 的刷新方式是很特別的,相當(dāng)?shù)目酥啤R韵抡怨俜轿臋n:
Updating every minute is far too aggressive. Widgets have a limited number of updates and if you were to try to update every minute, you'll quickly run out of updates. While debugging with Xcode these limits are not imposed, but if you're running your app outside of Xcode you'd see the behavior you're describing where your widget would stop updating.
意思是一個(gè)組件一天會(huì)有一定限制的刷新頻次數(shù),超過(guò)這個(gè)次數(shù),系統(tǒng)將不保證刷新是否成功。
WidgetKit通過(guò)以下兩種方式之一要求時(shí)間線(xiàn)條目:

  • 單個(gè)即時(shí)快照,表示小部件的當(dāng)前狀態(tài)。
  • 條目數(shù)組,包括當(dāng)前時(shí)刻,以及(如果已知)小部件狀態(tài)將更改的任何未來(lái)日期。

其實(shí)就是Widget引入了timeline時(shí)間線(xiàn)的概念,如果已知這個(gè)小組件現(xiàn)在及未來(lái)一段時(shí)間的狀態(tài),就可以在getTimeline提供內(nèi)容展示的entry組。并且更新策略選.atEnd就是提供的entry都展示完再去請(qǐng)求新的。
WidgetKit 在一個(gè)單獨(dú)的進(jìn)程中呈現(xiàn)視圖。因此,即使小部件在屏幕上,小部件擴(kuò)展也不會(huì)一直處于活動(dòng)狀態(tài)。盡管小部件并不總是處于活動(dòng)狀態(tài),但可以通過(guò)多種方式使其內(nèi)容保持最新。

被動(dòng):

  • WidgetKit 有時(shí)會(huì)重新加載小部件以幫助保持其內(nèi)容最新。一些常見(jiàn)的場(chǎng)景包括:
  • 如果小部件位于用戶(hù)很少訪問(wèn)的主屏幕頁(yè)面上,則 WidgetKit 可能會(huì)降低該小部件的重新加載頻率。稍后,當(dāng)用戶(hù)查看頁(yè)面時(shí),WidgetKit 可能會(huì)在小部件可見(jiàn)時(shí)重新加載它。
  • 對(duì)于使用位置服務(wù)的小部件,WidgetKit 會(huì)在位置發(fā)生重大變化后重新加載它們。

主動(dòng):
主程序調(diào)用的主動(dòng)刷新:

WidgetCenter.shared.reloadTimelines(ofKind: "com.mygame.character-detail")

官方示例:

如果已知一個(gè)人健康狀態(tài)當(dāng)前為25%,且每小時(shí)固定增長(zhǎng)25%,則可以安排一個(gè)如下計(jì)劃生成timeline

//@escaping修飾則可以進(jìn)行異步網(wǎng)絡(luò)請(qǐng)求,下面的例子是靜態(tài)的時(shí)候的

func getTimeline(in context: Context, completion: @escaping (Timeline<CharacterDetailEntry>) -> Void) {

        var date = Date()

        var healthLevel = 0.25

        var entries: [CharacterDetailEntry] = []       

        while healthLevel <= 1 {

            entries.append(CharacterDetailEntry(date: date, healthLevel: healthLevel))  //添加當(dāng)前狀態(tài)的entry 是要立馬展示出來(lái)的

            healthLevel = min(1, healthLevel + 0.25)                                                        // 每次把健康狀態(tài)升高0.25,最高為1

            date = Calendar.current.date(byAdding: .hour, value: 1, to: date)!                 // TiimeLine提供一段Entry,而entry的最小間隔是1分鐘,及時(shí)設(shè)置成秒也沒(méi)用。

        }

        let timeline = Timeline(entries: entries, policy: .atEnd) // .after   .never

        completion(timeline)

    }
4.3 移除策略

在靈動(dòng)島leading視圖部位上下滑動(dòng)可以隱藏當(dāng)前的live activity , 也可以在應(yīng)用的設(shè)置里面禁止live activity。

  • default:“實(shí)時(shí)活動(dòng)”會(huì)在鎖定屏幕上顯示一段時(shí)間,以便用戶(hù)一目了然地查看手機(jī)以查看最新信息。用戶(hù)可以選擇隨時(shí)刪除“實(shí)時(shí)活動(dòng)”,或者系統(tǒng)會(huì)在“實(shí)時(shí)活動(dòng)”結(jié)束后四小時(shí)自動(dòng)移除它。

  • immediate:立即移除從鎖定屏幕結(jié)束的“實(shí)時(shí)活動(dòng)”

  • after: 系統(tǒng)會(huì)在給定日期后或自“實(shí)時(shí)活動(dòng)”結(jié)束起四小時(shí)后刪除已結(jié)束的現(xiàn)場(chǎng)活動(dòng)——以先到者為準(zhǔn)

除非App主動(dòng)結(jié)束或用戶(hù)手動(dòng)結(jié)束,否則展現(xiàn)在靈動(dòng)島的“l(fā)ive activity”活動(dòng)在不操作的情況下最多可以活躍8小時(shí)。如果在第8小時(shí)的時(shí)候用戶(hù)主動(dòng)關(guān)閉了default或after策略的live activity,鎖定屏幕上的可以再多顯示4個(gè)小時(shí)。所以即實(shí)時(shí)活動(dòng)會(huì)靈動(dòng)上島最多保留八小時(shí),在鎖定屏幕上最多保留十二小時(shí)。 殺死App不會(huì)停止live activity.

歡迎大家交流并指出錯(cuò)誤,謝謝

5. 參考文檔

參考 鏈接
ActivityKit https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities
Live Activity Push Notification https://developer.apple.com/documentation/activitykit/update-and-end-your-live-activity-with-remote-push-notifications
Dynamic Island https://developer.apple.com/documentation/widgetkit/dynamicisland
Code https://github.com/jordibruin/Dynamic-Islands https://github.com/batikansosun/iOSLiveActivitiesLockScreen https://github.com/1998code/iOS16-Live-Activities
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,119評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,382評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,038評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,853評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,616評(píng)論 6 408
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,112評(píng)論 1 323
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,192評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,355評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,869評(píng)論 1 334
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,727評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,928評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,467評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,165評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,570評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,813評(píng)論 1 282
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,585評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,892評(píng)論 2 372

推薦閱讀更多精彩內(nèi)容