Xcode Cloud
一般我們的發佈流程為,從寫程式到測試,接著整合後發佈,再來接著收集資訊後再進行下一輪開發。
Xcode Cloud 將這一切整合在同一個服務之中,讓我們可以直接寫完程式之後,建立 workflow 並整合 Git 服務(GitHub, GitLab 等),接著串接 App Store Connect 進行 TestFlight 和發佈。
我們之後就可以從單一的 Xcode Cloud 介面處理完上述的所有事情,而建立這些 CI/CD 只需要一分鐘的時間。
相比之前弄 GitHub action,應該可以算是更加容易許多(?
建構四步驟
- 選擇 product
- 確認 workflow
- 授權相對應的 source code
- 連接 App Store Connect
在 CI/CD 的測試以及 Code Review 上的體驗都會比原先使用其他服務上好很多,畢竟是原生的體驗,在 DEMO 影片上看起來都蠻有趣的。
目前可以透過這個連結來註冊 Beta 使用,若有機會的話再來詳細寫一篇這部分的體驗。
Swift concurrency
async
和 await
的來臨讓我們能夠取代原先的 completion handler
Completion handler
func prepareForShow(completion: @escaping (Result<Scene, Error>) -> Void) {
danceCompany.warmUp(duration: .minutes (45)) { result in
switch result {
case .success (let dancers):
self.crew.fetchStageScenery { scenery in
self.setStage(with: scenery) { openingScene in
dancers.moveToPosition(in: openingScene) { result in
completion(result)
}
}
}
case .failure(let error):
completion(.failure (error))
}
}
}
await
func prepareForShow() async throws -> Scene {
let dancers = try await danceCompany.warmUp (duration: .minutes (45))
let scenery = await crew.fetchStageScenery()
let openingScene = setStage(with: scenery)
return try await dancers.moveToPosition (in: openingScene)
}
不過這邊另一個問題是,Swift Concurrency 只有支援 iOS 15 / macOS 12 以後的版本⋯ 相關的討論串可以看 Will Swift Concurrency deploy back to older OSs?
Structured Concurrency
如果我們想讓 dances 和 scenery 同時進行,便可以改成 async
的方式
func prepareForShow() async throws -> Scene {
async let dancers = danceCompany.warmUp(duration: .minutes (45))
async let scenery = crew.fetchStageScenery()
let openingScene = setStage(with: await scenery)
return try await dancers. moveToPosition(in: openingScene)
}
Actors
class StageManager {
var stage: Stage
let queue = DispatchQueue(label: "stage")
func setStage(with scenery: Scenery, completion: @escaping (Scene) -> Void) {
queue.async {
self.stage.backdrop = scenery.backdrop
for prop in scenery.props {
self.stage.addProp(prop)
}
completion(self.stage. currentScene)
}
}
}
過去我們利用 DispatchQueue
的 async
方式來確保物件不會被同時寫入的問題。
actor StageManager {
var stage: Stage
func setStage(with scenery: Scenery) -> Scene {
stage.backdrop = scenery.backdrop
for prop in scenery.props {
stage.addProp(prop)
}
return stage.currentScene
}
}
現在可以透過改以 Actor 的方式,它能夠達到上述的效果並且自動避免 race conditions;於是我們便不用手動地去執行 sync 的動作。
而如果有特定的 function 必須在 main thread 上執行的話,則可以使用 @MainActor
的方式
@MainActor
func display(scene: Scene)
SwiftUI
現在已經有不少原生的 apps 是使用 SwiftUI 寫出來的(像是天氣.app),而也有越來越多系統的元件也是使用 SwiftUI(如 Apple pay sheet)。
而這一次也更新了許多新的 features 和 api,並支援了 #if else 來依照不同的 statement 也可以在 SwiftUI 上實作。
詳細的內容等其他篇再來一同整理。
Swift Playground 4
Swift Playground 4 將今年上線,使用者可以直接在上頭 build app 並上傳到 App Store 去,意味著只使用 iPad 作為開發者裝置的可行性出現了。
ARKit
過往建立一個模型需要花費上小時的時間,而 Object Capture 可以利用 iPhone 或是 iPad 在幾分鐘的時間內建立一個 3D 模型。
輸出的格式支援 USDZ,且利用 Procedural Geometry API 可以製作出更多新的效果,如食物上的熱氣或是火焰。
Focus
算是勿擾模式的一個延伸,讓使用者有更多客製化的勿擾模式設定,而這些設定也會被套用在所有的平台上。
Notifications
Notifications 分成新的三種等級
- Passive:當使用者正在使用手機的時候,才會看到
- Active:原本的通知方式
- Time sensitive:有時效性的通知,並且 Siri 會透過 AirPods 來告知使用者
可以管理個人化的 summary of notifications,而在新的 iMessage 下,notifications 將會把原先的 app icon 換成那個人的頭像。
Widget
Widgets 支援擺放在 iPad 的主畫面,和 iOS 目前的效果一樣,並且可以設計更大尺寸的 widget。
Share Play API
開放新的 GroupActivities framework,讓使用者在 Facetime 通話中可以 share 自己的播放內容或者一起做某些事(so dome app activity together)。