Category: iOS 17

  • 「iOS 17」SwiftUIの新たな19本の機能とビュー(コード例付き)(WWDC 2023)

    目次

    • スクロールビューで特定の位置までスクロール
    • App Storeで購入可能なアイテムを表示
    • App Storeのサブスクリプションを表示
    • 写真がNSFWかどうかを分析
    • データストレージSwiftDataを使用
    • SwiftUIのビュースタイルのためにMetalシェーダーを使用
    • マップにマーカーやその他のコンポーネントを追加
    • SFシンボルの画像エフェクト(パルス、反転、バウンス、スケール、表示/非表示、トランジション)
    • 回転のジェスチャー
    • インスペクタビュー(右側に表示されるサイドバー)
    • 新しい#previewプレビューブロック
    • foregroundStyleスタイルの使用
    • TipKitを使ったヒントの表示
    • Swift Macro

    はじめに

    この記事の多くの部分(例えば、SwiftData、センシティブコンテンツ分析など)については、後ほどQiitaの記事でより詳しい解説を書く予定です。

    ※一般公開されている(一般に開示した情報)WWDC Keynoteの動画と公開Session/Documentationページだけを使ってこの記事を執筆しました。スクリーンショットはWWDCのセッション映像のものを使用しています。Xcodeのベータ版にアクセスできる場合は、自身でコードを実行されることをお勧めします。

    ScrollView内で特定の位置までスクロールする

    ScrollViewとその内部のスタック構造を使用している場合、
    特定の行までビューをスクロールすることができます。

    まず、.scrollTargetLayout()というビューモディファイアを、ScrollView内に主要な繰り返しコンテンツを含むレイアウトコンテナに追加します。これはVStack、LazyHStack、HStack、またはForEachなどになります。

    import SwiftUI
    
    struct ScrollViewToRow: View {
        var body: some View {
            VStack {
                ScrollView {
                    ForEach(1..<30, id: \.self) { number in
                        // ...
                    }
    +                .scrollTargetLayout()
                }
            }
        }
    }
    

    この例では、1から30までのすべての数字をループするためにForEachを使用しています。したがって、このビューモディファイアをForEachに追加します。

    次に、scrollPositionビューモディファイアを使用してスクロール位置をバインドします。このビューモディファイアはScrollViewに添付されます。

    import SwiftUI
    
    struct ScrollViewToRow: View {
    +    @State private var scrollPosition: Int? = 0
        var body: some View {
            VStack {
                ScrollView {
                    ForEach(1..<30, id: \.self) { number in
                        // ...
                    }
                        .scrollTargetLayout()
                }
    +            .scrollPosition(id: $scrollPosition)
            }
        }
    }
    

    オプションのInt型の@State変数を使用します。

    新しい値を割り当てることでスクロール位置を更新することができます。コードをwithAnimationブロック内に配置すると、スクロールアニメーションが表示されます。

    現在のスクロール位置を読み取ることもできます。

    import SwiftUI
    
    struct ScrollViewToRow: View {
        
        @State private var scrollPosition: Int? = 0
        
        var body: some View {
            
            VStack {
                
                Text("currently at \(scrollPosition ?? -1)")
                
                Button("Scroll") {
                    withAnimation {
                        scrollPosition = 10
                    }
                }
                
                ScrollView {
                    ForEach(1..<30, id: \.self) { number in
                        HStack {
                            Text(verbatim: number.formatted())
                            Spacer()
                        }
                        .padding()
                        .foregroundStyle(.white)
                        .background {
                            RoundedRectangle(cornerRadius: 10)
                                .foregroundStyle(.teal)
                        }
                    }
                        .scrollTargetLayout()
                }
                .scrollPosition(id: $scrollPosition)
                
            }
            .padding()
            
        }
        
    }
    
    #Preview {
        ScrollViewToRow()
    }
    

    App Storeのアプリ内購入製品を表示

    IMG_1155.JPG

    このビューでは、1つの製品を表示しています。
    複数の商品を紹介するスクロールビューや水平スタックなどを作成することができます。

    この話題については後で詳しくQiitaの記事を書きます

    App Storeから取得した製品IDを使用して、ProductViewを初期化できます。

    大きな製品ビュー(上記のBox of Nutrition Pelletsのような)を表示するためには、ビューモディファイア .productViewStyle(.large) を使用します。

    ProductView(id: ids.nutritionPelletBox) {
        BoxOfNutritionPelletsIcon()
    }
    .productViewStyle(.large)
    

    ProductViewのコードブロック内では、製品のアイコン(たとえば、Image)を提供できます。

    App Storeのすべてのサブスクリプションを表示

    Appleから提供されるプレスタイルのビューを使用して、App Storeのサブスクリプションを表示することができます。

    これを最も簡単に表示する方法は、SubscriptionStoreView(groupID: birdPassGroupID)を呼び出すだけで、非常にシンプルなビューが表示されます。

    IMG_1156.JPG

    この話題については後で詳しくQiitaの記事を書きます

    このビューはカスタマイズ可能で、カスタムヘッダー、背景、アイコンを表示できます。

    まず、サブスクリプショングループIDを使用してSubscriptionStoreViewを初期化します。visibleRelationshipsでは、アップグレードのみを表示するか、すべてのオプション(ダウングレードオプションを含む)を表示するかを定義できます。

    ブロック内では、PassMarketingContent(オプション)がヘッダーとして表示されます。ここでは、アプリのアイコン、サブスクリプショングループ名、サブスクリプションの利点を簡単に説明できます。

    また、.subscriptionStoreControlIcon(オプション)ビューモディファイアを使用して、各サブスクリプションアイテムのアイコンを定義することもできます。

    SubscriptionStoreView(
        groupID: passGroupID,
        visibleRelationships: showPremiumUpgrade ? .upgrade : .all
    ) {
        PassMarketingContent(showPremiumUpgrade: showPremiumUpgrade)
    #if !os(watchOS)
            .containerBackground(for: .subscriptionStoreFullHeight) {
                SkyBackground()
            }
    #endif
    }
    #if os(iOS)
    .storeButton(.visible, for: .redeemCode)
    #else
    .frame(width: 400, height: 550)
    #endif
    .subscriptionStoreControlIcon { _, subscriptionInfo in
        Group {
            switch PassStatus(levelOfService: subscriptionInfo.groupLevel) {
                case .premium:
                    Image(systemName: "bird")
                case .family:
                    Image(systemName: "person.3.sequence")
                default:
                    Image(systemName: "wallet.pass")
            }
        }
        .foregroundStyle(.accent)
        .symbolVariant(.fill)
    }
    #if !os(watchOS)
    .backgroundStyle(.clear)
    .subscriptionStoreButtonLabel(.multiline)
    .subscriptionStorePickerItemBackground(.thinMaterial)
    #endif
    

    SensitiveContentAnalysisを使用して画像を解析

    https://developer.apple.com/documentation/sensitivecontentanalysis

    この話題については後で詳しくQiitaの記事を書きます

    rendered2x-1683741577.png

    まず、センシティブコンテンツ(NSFW)アナライザーのエンタイトルメントをプロジェクトに追加する必要があります。

    イメージアナライザーを初期化します:

    let analyzer = SCSensitivityAnalyzer()
    

    次に、アプリは、ユーザーがセンシティブコンテンツ分析機能をオンにしているかどうかをチェックします。

    ユーザーは、システム設定(プライバシーセクション内)でこの機能をオンまたはオフにすることができます。この設定がオフの場合、画像の解析はできません。

    switch analyzer.analysisPolicy {
        case .simpleInterventions:
            Label("Simple UI", systemImage: "checkmark")
            Text("Blur the image, and show a button to show the content.")
        case .descriptiveInterventions:
            Label("Detailed UI", systemImage: "checkmark")
            Text("Show a detailed description on how these types of images might affect the user.")
        case .disabled:
            Label("Not enabled", systemImage: "xmark")
            Text("To analyze a photo, turn on the sensitive photo warning first in system settings.")
    }
    

    その後、CGImageオブジェクトに変換することで、画像を解析することができます

    func analyzePhoto(input: CGImage) {
        Task {
            let response = try await analyzer.analyzeImage(input)
            self.isImageSensitive = response.isSensitive
        }
    }
    

    以下は、フォトピッカーも含むSwiftUIのコードです。

    import SwiftUI
    import SensitiveContentAnalysis
    import PhotosUI
    
    struct ContentView: View {
        
        let analyzer = SCSensitivityAnalyzer()
        
        @State private var pickedPhotoToAnalyze: PhotosPickerItem?
        @State private var analyzedImage: UIImage?
        @State private var isImageSensitive: Bool?
        
        var body: some View {
            
            Form {
                
                Section("Status") {
                    
                    VStack(alignment: .leading) {
                        Text("Warning enabled in system settings")
                            .font(.headline)
                        switch analyzer.analysisPolicy {
                            case .simpleInterventions:
                                Label("Simple UI", systemImage: "checkmark")
                                Text("Blur the image, and show a button to show the content.")
                            case .descriptiveInterventions:
                                Label("Detailed UI", systemImage: "checkmark")
                                Text("Show a detailed description on how these types of images might affect the user.")
                            case .disabled:
                                Label("Not enabled", systemImage: "xmark")
                                Text("To analyze a photo, turn on the sensitive photo warning first in system settings.")
                        }
                    }
                    
                }
                .id(analyzer.analysisPolicy.rawValue)
                
                Section("Image analysis") {
                    
                    PhotosPicker("Pick a photo to analyze", selection: $pickedPhotoToAnalyze)
                        .onChange(of: pickedPhotoToAnalyze) { newValue in
                            if let newValue {
                                handlePickedImageItem(newValue)
                            }
                        }
                    
                    if let isImageSensitive {
                        if isImageSensitive {
                            Label("Oh no! What image did you pick?", systemImage: "eye.trianglebadge.exclamationmark")
                                .foregroundStyle(.red)
                        } else {
                            Label("It is OK!", systemImage: "checkmark")
                                .foregroundStyle(.green)
                        }
                    }
                    
                    if let analyzedImage,
                       let isImageSensitive
                    {
                        if isImageSensitive {
                            Image(uiImage: analyzedImage)
                                .resizable()
                                .scaledToFit()
                                .frame(height: 230)
                                .blur(radius: 5.0, opaque: true)
                        } else {
                            Image(uiImage: analyzedImage)
                                .resizable()
                                .scaledToFit()
                                .frame(height: 230)
                        }
                    }
                    
                }
                .disabled(analyzer.analysisPolicy == .disabled)
                
            }
            
        }
        
        func analyzePhoto(input: CGImage) {
            Task {
                let response = try await analyzer.analyzeImage(input)
                self.isImageSensitive = response.isSensitive
            }
        }
        
        func handlePickedImageItem(_ newValue: PhotosPickerItem) {
            self.isImageSensitive = nil
            self.analyzedImage = nil
            newValue.loadTransferable(type: Data.self) { result in
                switch result {
                    case .success(let success):
                        if let success,
                           let imageObj = UIImage(data: success),
                           let cgImageObj = imageObj.cgImage
                        {
                            self.analyzedImage = imageObj
                            self.analyzePhoto(input: cgImageObj)
                        }
                    case .failure(let failure):
                        return
                }
            }
        }
        
    }
    
    #Preview {
        ContentView()
    }
    

    SwiftData

    この話題については後で詳しくQiitaの記事を書きます

    SwiftDataはCore Dataを基盤に構築されています(ただし、Core Dataと組み合わせて使用する場合は、ハッシュをチェックするための追加の手順が必要です)。

    以下の53行のコードで、保存されるデータの構造を定義し、コンテキストを作成し、新しいレコードを追加するためのSwiftUIビュー、レコードを表示し、削除するためのビューを作成しています。

    import SwiftUI
    import SwiftData
    
    @Model
    class Record {
        
        var id: UUID
        var timestamp: Date
        
        init(timestamp: Date) {
            self.id = UUID()
            self.timestamp = timestamp
        }
        
    }
    
    struct SwiftDataDemo: View {
        var body: some View {
            RecordsList()
                .modelContainer(for: [Record.self])
        }
    }
    
    struct RecordsList: View {
        @Environment(\.modelContext) private var modelContext
        
        @Query(sort: \.timestamp, order: .forward, animation: .snappy)
        var storedRecords: [Record]
        
        var body: some View {
            NavigationStack {
                List {
                    ForEach(storedRecords) { record in
                        Text(record.timestamp, format: .dateTime)
                    }
                    .onDelete(perform: { indexSet in
                        indexSet.forEach({ modelContext.delete(storedRecords[$0]) })
                    })
                }
                .toolbar {
                    Button ("Add") {
                        let location = Record(timestamp: Date())
                        modelContext.insert(location)
                    }
                }
            }
        }
    }
    
    #Preview {
        SwiftDataDemo()
    }
    

    上記のコードにおいて、以下のコードでデータ構造を定義しています:

    @Model
    class Record {
        
        var id: UUID
        var timestamp: Date
        
        init(timestamp: Date) {
            self.id = UUID()
            self.timestamp = timestamp
        }
        
    }
    

    ビューにストレージをアタッチします。まだ存在しない場合は、新しいストレージが作成されます。

    struct SwiftDataDemo: View {
        var body: some View {
            RecordsList()
                .modelContainer(for: [Record.self])
        }
    }
    

    上記のビューモディファイアには、さらにinitパラメータがあり、例えば、データを自動的に保存するかどうか、完了時にコードを実行するかどうかなどを制御することができます。

    また、iCloudを有効にし、iCloudコンテナを作成することも可能です。データはiCloudに同期されます

    データのクエリには @Query を使用することができます

    @Query(sort: \.timestamp, order: .forward, animation: .snappy)
    var storedRecords: [Record]
    

    レコードを削除するには、データベースを読む@Environmental変数を作成します。

    @Environment(\.modelContext) private var modelContext
    

    デフォルトでは、変更内容は自動的に保存されます。

    ShaderLibraryを使用して、ビュースタイルにMetalを適用

    Fx82SziaEAE-Fpy.jpeg

    まず、シェーダーの形状を定義する.metal定義ファイルを作成します。

    //  angledFill.metal
    
    #include <metal_stdlib>
    using namespace metal;
    
    [[ stitchable ]] half4
    angledFill(float2 position, float width, float angle, half4 color)
    {
        float pMagnitude = sqrt(position.x * position.x + position.y * position.y);
        float pAngle = angle +
        (position.x == 0.0f ? (M_PI_F / 2.0f) : atan(position.y / position.x));
        float rotatedX = pMagnitude * cos(pAngle);
        float rotatedY = pMagnitude * sin(pAngle);
        return (color + color * fmod(abs(rotatedX + rotatedY), width) / width) / 2;
    }
    
    

    次に、上記の.metal定義内の関数(angleFillと呼ばれる)を参照する新しいShaderシェーダーを作成します。

    var stripes: Shader {
        ShaderLibrary.angledFill(
            .float(10),
            .float(90),
            .color(.blue)
        )
    }
    

    これで、.foregroundStyle ビューモディファイアを使って、テキストにShaderシェーダースタイルを適用できるようになりました。

    Text("Furdinand").font(.system(size: 50).bold()).foregroundStyle(stripes) + Text(" is a good dog.").font(.system(size: 50).bold())
    

    SwiftUIで異なるテキストコンポーネントを連結させることができます。

    .foregroundStyleについて、

    https://developer.apple.com/documentation/swiftui/view/foregroundstyle(_:)

    .foregroundStyleビューモディファイアを使用して、
    SwiftUIビューに色またはMetalスタイルを設定することができます。

    このビューモディファイアはiOS 15から使用可能ですが、iOS 17では入力パラメータとしてシェーダーを使用することができます。

    >= iOS 15

    iOS 15以降、.foregroundStyleを使用してビューの色やグラデーションを設定することができます。

    Text("Furdinand")
        .font(.system(size: 50).bold())
        .foregroundStyle(.blue)
    
    Text("Hello world")
        .foregroundStyle(.linearGradient(colors: [.teal, .blue], startPoint: .top, endPoint: .bottom))
    
    

    .foregroundColor`は非推奨 (will be deprecated) になるようです。

    スクリーンショット 2023-06-17 15.19.27.png
    https://qiita.com/embed-contents/link-card#qiita-embed-content__a82b23a9bd3189450f7f26e4c14933d2

    もしiOS 14以前のデバイス向けのアプリをターゲットにしている場合、カスタムのビューモディファイアを作成することができます。一方、iOS 15以降のデバイス向けのアプリをターゲットにしている場合は、新しいforegroundStyleビューモディファイアにコードを置き換えることができます。

    カスタムのビューモディファイア: https://gist.github.com/mszpro/fb6bb8a95376402daf433220de222389

    >= iOS 17

    iOS 17では入力パラメータとしてシェーダーを使用することができます。

    var stripes: Shader {
        ShaderLibrary.angledFill(
            .float(10),
            .float(90),
            .color(.blue)
        )
    }
    
    Text("Furdinand")
        .font(.system(size: 50).bold())
        .foregroundStyle(stripes)
    

    SwiftUIでMapKitのマップを制御

    以下は、WWDCのセッション動画からのスクリーンショットです。

    Markerや図形(円、折れ線、多角形)を簡単に適用することができます。
    また、@Binding変数を使用することで、現在どのMarkerが選択されているかを確認することができます。

    スクリーンショット 2023-06-16 12.01.12.png
    スクリーンショット 2023-06-16 12.01.19.png
    スクリーンショット 2023-06-16 12.01.52.png

    この話題については後で詳しくQiitaの記事を書きます

    https://developer.apple.com/wwdc23/10043

    SFシンボルエフェクト

    SwiftUIでSFシンボル画像に多くの視覚効果を加えることができる

    パルス

    シンボルの不透明度をアニメーションで表示します。

    Image(systemName: "rectangle.inset.filled.and.person.filled")
                .symbolEffect(.pulse)
                .frame(maxWidth: .infinity)
                .font(.system(size: 50))
                .symbolRenderingMode(.multicolor)
    

    リバーシング

    シンボルをレイヤーごとにアニメーションさせることができます。例えば、WiFi接続のアニメーションを作成することができます。

    Image(systemName: "wifi")
        .symbolEffect(.variableColor.iterative.reversing)
        .font(.system(size: 50))
        .symbolRenderingMode(.multicolor)
    

    バウンス(ハートビート効果)

    画像のスケールをアニメーションで変化させます。画像を拡大し、縮小します。心臓の鼓動のようです。

    Image(systemName: "arrow.down.circle")
        .symbolEffect(.bounce, value: simulatedDownloadPercentage)
        .font(.system(size: 50))
        .symbolRenderingMode(.multicolor)
    

    拡大・縮小

    上記と同様に、bool値を使ってシンボルを拡大・縮小することもできます。以下のサンプルコードでは、simulatedDownloadPercentage が偶数である場合に画像を拡大表示しています。

    Image(systemName: "bubble.left.and.bubble.right.fill")
        .symbolEffect(.scale.up, isActive: simulatedDownloadPercentage % 2 == 0)
        .font(.system(size: 50))
        .symbolRenderingMode(.multicolor)
    

    表示・非表示

    Image(systemName: "cloud.sun.rain.fill")
        .symbolEffect(.disappear, isActive: simulatedDownloadPercentage % 2 == 0)
        .font(.system(size: 50))
        .symbolRenderingMode(.multicolor)
    

    2つのシンボル間のトランジション効果

    1つのシンボルから別のシンボルへの切り替え時に、トランジション効果を追加することができます。例えば、再生ボタンで、再生アイコンと一時停止アイコンを切り替えるような場合に使用できます。

    VStack {
        Image(systemName: runToggle ? "play.fill" : "pause.fill")
            .contentTransition(.symbolEffect(.replace.downUp))
            .font(.system(size: 50))
            .symbolRenderingMode(.multicolor)
        Button("Toggle status") {
            runToggle.toggle()
        }
    }
    

    回転ジェスチャー

    回転ジェスチャーを認識することで、ビューの回転を監視することができます。

    struct RotationTesting: View {
        @State private var angleRotated = Angle(degrees: 0.0)
    
        var body: some View {
            Rectangle()
                .frame(width: 200, height: 200, alignment: .center)
                .rotationEffect(angleRotated)
                .gesture(
                    RotateGesture()
                        .onChanged { value in
                            angleRotated = value.rotation
                        }
                )
        }
    }
    

    インスペクタービュー(右側のサイドバー)を表示

    インスペクターは右側に表示され、通常、ユーザーがアイテムの詳細を表示するために使用されます。

    inspector.jpg
    public struct ContentView: View {
        @State private var state = AppState()
        @State private var presented = true
    
        public var body: some View {
            AnimalTable(state: $state)
                .inspector(isPresented: $presented) {
                    AnimalInspectorForm(animal: $state.binding())
                        .inspectorColumnWidth(
                            min: 200, ideal: 300, max: 400)
                        .toolbar {
                            Spacer()
                            Button {
                                presented.toggle()
                            } label: {
                                Label("Toggle Inspector", systemImage: "info.circle")
                            }
                        }
                }
        }
    }
    

    簡単にプレビュー

    SwiftUIのビューをプレビューするために#previewを記述することができます。
    また、#preview内で変数を直接追加することもできます。

    #Preview {
        ContentView()
    }
    

    TipKitを使ったユーザーへのチップ表示について

    https://qiita.com/mashunzhe/items/016e991fb9020b3eb4c7

    https://developer.apple.com/videos/play/wwdc2023/10229

    TipKitを使って、ユーザーにヒントを表示し、どこにどんな機能があるかを理解させることができます。

    iOSベータ1では、ヒントを表示する際に問題があるかもしれませんが、
    後でコードを更新します。

    https://developer.apple.com/forums/thread/731073

    Fx53LuLakAENWgH.jpeg
    Fx9t6XFX0AElPzo.jpeg

    Macros

    https://qiita.com/embed-contents/link-card#qiita-embed-content__7cc08dca7bcc19b7a5b67b50e4b9dbf0

    お読みいただき、ありがとうございました。

    :relaxed: Twitter @MszPro

    :relaxed: 個人ウェブサイト https://MszPro.com


    上記内容の一部は、Apple社のサンプルコードから引用しています。ライセンスは下記に添付しています:

    Copyright © 2023 Apple Inc.
    
    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
    
    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  • WWDC 2023 基調講演 まとめ(セッションのリンク付き)

    スタートビデオ

    Dream it. Chase it. Code it

    それ(アイデア)を夢見て。それを追い求めて。それをコーディングする。

    wwdc-intro-dream-it-chase-it-code-it.jpg

    Apple Vision Pro ビジョンプロ

    vision-pro.jpg

    手を使って、ビューをコントロールする。

    visionpro-ppt-facetime.jpg

    ホームビューが目の前に。

    vision-pro-home-page.jpg

    インターフェイスは部屋に溶け込むように透明で、部屋に影を落とすことができます。

    vision-pro-transparent.jpg

    デジタルクラウンを使って没入感をコントロールする。
    例えば、すべての部屋を隠して、アプリケーションだけを見るという選択も可能です。

    vision-pro-digital-crown.jpg

    他の人が近くにいるときは目を表示する
    外装にはディスプレイがあります。あなたの目(内側のカメラで撮影したもの)が表示されます。

    vision-pro-display-eye.jpg

    画面に複数のアプリを置くことができる。

    IMG_0082.jpg

    3Dオブジェクトを素早く見ることができます。

    vision-pro-3d-preview.jpg

    iPhoneで撮影したパノラマを拡大表示する

    vision-pro-panorama.jpg

    3Dで撮影することができます。

    vision-pro-3d-photo.jpg

    また、映画鑑賞にも使用できます。

    vision-pro-cinema-mode

    デジタルペルソナ (Digital Persona)

    Vision Proデバイス内のカメラがあなたの顔をスキャンし、ビデオ通話中の表情や手のジェスチャーを作成します。

    アプリを作る

    ARKitやRealityKitなどのフレームワークを使って、Vision Pro用のアプリを作成することができます。

    Unityで作られたアプリケーションやゲームも、
    Vision Proハードウェアの様々な機能に対応することになります。

    https://developer.apple.com/videos/play/wwdc2023-10260

    https://developer.apple.com/videos/play/wwdc2023-10096

    https://developer.apple.com/videos/play/wwdc2023-10080

    https://developer.apple.com/videos/play/wwdc2023-10073

    https://developer.apple.com/videos/play/wwdc2023-10076

    https://developer.apple.com/videos/play/wwdc2023-10203

    https://developer.apple.com/videos/play/wwdc2023-10082

    https://developer.apple.com/videos/play/wwdc2023-10083

    https://developer.apple.com/videos/play/wwdc2023-10109

    https://developer.apple.com/videos/play/wwdc2023-10072

    https://developer.apple.com/videos/play/wwdc2023-10090

    OpticID

    OpticIDを使用して、虹彩データでデバイスのロックを解除します。

    Mac ハードウェアのリリース

    15インチMacBook Air

    Apple Silicon M2チップを搭載した15インチディスプレイ搭載のMacBook Air

    MacBookAir.jpg

    Mac Studio

    新型M2 Maxチップ

    新型M2 Ultraチップ(M2 Maxチップを2つ)

    mac-studio.jpg

    アップルシリコンを搭載したMac Pro

    新しいM2 Ultraチップを搭載
    PCI拡張を可能

    mac-pro.jpg

    iOS 17

    ios-summary.jpg

    電話アプリ

    連絡先ポスター

    他の人があなたの電話を受けたとき、設定した画像を見ることができます。

    画像は、連絡先アプリにも表示されます。

    ポスターは、サードパーティーのアプリがCallKitを使って設定することができます。

    ios-customized-call.jpg

    ライブボイスメール

    応答する前に、通話をリアルタイムで実況中継。
    電話を取るか取らないかは、決めることができます。

    iOS-17-live-voicemail.jpg

    FaceTimeの通話に相手が出なかった場合、ビデオメッセージを録音することができます。

    iMessage

    • よりパワフルな検索
    • 直前の未読メッセージに飛ぶ
    • チェックイン機能:場所に到着した後、自動的に通知を送る
    • iMessageのアプリケーション:テキストボックスの近くに新しい+ボタンがあり、iMessageの機能やiMessageのアプリケーションに簡単にアクセスできます。
    image-sticker.jpg
    • ステッカー:写真からオブジェクトを抽出して、iMessageのステッカーを作ることができます。Live Photosもステッカーとして機能します。
    imsg-obj-sticker.jpg

    AirDrop

    ネームドロップ

    2台のiPhoneの上部をタップすると、自分の名刺と番号を共有することができます。

    namedrop-iphone.jpg

    Apple Watchと組み合わせて、連絡先を共有することもできます。

    namedorp-iphone-watch.jpg

    インターネット経由のAirDrop

    AirDropの範囲から離れた場所に端末を置いても、インターネットを利用して送信を継続します。

    (API) SharePlay API

    他のiPhoneをタップすると、自動的にSharePlay体験が開始されます。

    https://qiita.com/embed-contents/link-card#qiita-embed-content__26169c7a079289a494a83c3de8b3cfe1

    テキスト入力

    オートコレクト

    • Transformerモデルを用いて、キーボードがより良い述語とオートコレクトを行います。文章レベルの自動修正

    ディクテーション(音声からテキストへ)

    ニューラルエンジンを使用したトランスフォーマーベースのスピーチモデルにより、より正確なディクテーションが可能です。

    新しい体験

    Journalアプリ

    iPhoneで日記を書く。 iPhoneは、地図、写真、運動、場所、音楽のデータをもとに、書くべき内容の候補を作成する

    diary-app.jpg

    (API)サジェスチョンAPI

    diary-api.jpg

    スタンバイ

    充電中にiPhoneを横向きにすると、ナイトスタンドやキッチンタイマーのように、まとめて表示することができます。ウィジェット(ホームコントロール、サードパーティーウィジェット、カレンダーイベント)を表示することができます。

    iphone-standby.jpg

    ライブ・アクティビティにも対応しています。

    「Hey Siri」の代わりに「Siri」と言うだけでSiriが起動します。

    オフラインマップ(地図上のエリアをダウンロードしてオフラインで使用することができます。)

    iPadOS

    ipad-summary.jpg

    ウィジェットとロック画面

    ウィジェットで直接(アプリに入らずに)アクションを実行する:例えば、Todoアイテムの完了をチェックするなど

    ipad-widget-check.jpg

    (API)WidgetKit: ウィジェット用のインタラクション

    ロック画面

    iPhoneのようにiPadのロック画面をカスタマイズすることができます。

    iPadで複数のタイマーを設定する

    ipad-multi-timer.jpg

    iPadで健康アプリ

    ipad-health-app.jpg

    PDF

    機械学習を使ってPDF上のフィールド(名前、住所、Eメール)を識別する

    メモアプリでPDFを大きく表示

    MacOS Sonoma

    macos-summary.jpg

    新しいスローモーションビデオのスクリーンセーバー(Apple TVのように)

    macos-wallpaper.jpg

    Macのウィジェット

    ウィジェットをデスクトップ上に持ってくることができる

    macos-widget.jpg

    Continuityを使うと、iPhoneのウィジェットをMacに追加することができます。
    アプリをインストールする必要はありません(iPhoneはWiFiまたは近くの接続を使用してウィジェットを更新します)。

    ゲームモード

    MacOSに搭載されたゲームモード。CPUとGPUのゲームを優先的に処理するモードです。

    小島秀夫さんがWWDCに

    新作ゲーム「Death Stranding」紹介

    ビデオ会議

    プレゼンテーションの際、画面の上にライブカメラの映像を追加することができます。

    avatar-cam-small.jpg

    縮小表示と拡大表示が選べます。

    avatar-cam-big.jpg

    ビデオリアクション

    video-reaction.jpg

    主要なビデオ通話アプリで動作します。
    また、サムズアップ :thumbsup: を上げると花火が表示されます。

    Safari

    パスワードとパスキーの家族パスワード共有

    safari-pass-share.jpg

    プロファイル(仕事、個人) – Cookie、拡張機能

    AirPodとオーディオ

    audio-summary.jpg
    audio.jpg

    アダプティブオーディオ

    環境に応じてノイズキャンセリングモードを動的にブレンドします
    (自転車のベルなど大切な音を聴くときに、ノイズを低減します)。

    他の人と話すときは、自動的に会話モード (Transparency mode) が使用されます。

    AirPlay

    好みに応じて、Airplayを使用するよう提案します。
    Siriに頼んで、Airplayを有効にすることもできます。
    ホテルでもAirplayが使えます。QRコードを読み取ってペアリング。

    tvOS

    • コントロールセンターで設定、カメラ、コントロール、プロファイルにアクセスします。
    • iPhoneでApple TVのリモコンを探す。
    • フォトメモリーを壁紙として使用
    • Apple TVでFaceTime(iPhoneやiPadのContinuityカメラを使う)

    (API)ContinuityカメラAPI

    watchOS

    新しいインターフェース

    時計の壁紙でデジタルクラウンを回して、スマートスタックのウィジェットを表示(会議、カレンダー)

    watch-widgets.jpg

    各種アプリがアップデートされました:世界時計、アクティビティなど

    (API) ワークアウトAPI

    ウォッチ内の加速度センサーなどを利用して、
    新しいタイプのワークアウトを作成することができます。

    https://developer.apple.com/videos/play/wwdc2023-10016


    :relaxed: Twitter @MszPro

    :relaxed: 個人ウェブサイト https://MszPro.com