ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
スケーラブルなエンタープライズAppスイートのビルド
連携して機能する集中型エンタープライズAppのビルド方法を学びましょう。本セッションでは、従業員が顧客とやり取りし、業務を追跡し、店舗を管理し、接続状態を保つのに役立つ、Apple RetailのエンタープライズAppスイートをご紹介します。Apple RetailがSwift PackagesとAppのスケーラビリティのテストを導入して一元化された一連のAppをどのように作り上げたかをご覧ください。また、コンフィギュレーションによる製作中のAppの管理が、異なる地域やロケーションに合わせてAppスイートを調整するのに役立つ仕組みもご覧ください。
リソース
関連ビデオ
WWDC20
WWDC19
WWDC18
-
ダウンロード
こんにちは WWDCへようこそ “スケーラブルな エンタープライズAppスイートのビルド” 私はエリック 同僚のピナールと― 販売店向けモバイルアプリチームを 指揮しています エラーに強く柔軟で保守しやすい 企業向けアプリの開発を説明します 500以上あるAppleの店舗は 日々の業務体験を分析しています 小売業の中心的役割を担う販売員を サポートするために開発したアプリは 店の予約や製品カタログ管理から 店のレイアウトまでを支援します 店舗を円滑に運営するため すべてのアプリは連携して動きます 我々の役割が少し理解できましたね 続いて開発の実践方法と あなたの事業に どんな利点があるかを説明します アプリの新規作成時と既存版の再構築時に 両者を共有させるための設計技法と その際に考慮すべき基本原則を取り上げます 開発後に行うテストも説明します 最後はピナールが 運用開始後の アプリの管理についてお伝えします iOSには複数のアプリをうまく連携させる 多くの機能がありますが ここでは― App Gropsの有効化やSwiftパッケージの利点 優れたパッケージ候補の検出方を説明します App Groupsは開発に有効な iOSの代表的機能の1つです 有効化すると UserDefaultsや共有ファイルを 経由し複数のデータ共有が可能です すべての設定はXcode内プロジェクトファイルの 署名と権限で次のように行われます 権限追加をクリックしApp Groupを選択すると 新しいグループパネルが追加されます パネル内の“+”ボタンを押せば 新しいApp Groupが追加でき 開発者ポータルに追加すれば 同じポータル内の他のアプリへアクセスできます Xcodeのグループができれば データ共有は簡単です UserDefaultsを使った共有を 例に説明します まずUserDefaultsインスタンスを作成し App Groupで初期化します この後の作業は 値の設定はsetメソッドを 呼び出すのと同様に簡単で 値の読取りも文字列 整数 ブール変数など named typeメソッドのように容易にできます 次に説明するSwiftパッケージは 新しいアプリの 開発や既存アプリの再構築にも有効です 特に重複コードの削減に絶大な効果を発揮し 開発時間と人為的ミスを軽減するため アプリの信頼性が高まります 多くのコードベースが既に共有されるため 組織の柔軟性が向上し― チーム間の人の移動が簡単になります またパッケージ開発専門チームも立ち上げ より難解な問題を解決する機能を研究しています iOS アプリ開発後は 有効活用できる対象を探しました Appleもアプリケーションに 標準の認証方法を使いますから “認証”を選んだのは正しい選択でした URLSession上で認証アプリを構築すると エンジニアの負担がなくなり 彼らは認証を意識せず サーバーにアクセスできます もう1つのネットワーク関連パッケージは 画像キャッシュと取り出しパッケージで 画像をキューに入れておき 必要に応じ保存ができます ネットワーク接続や画像データの入手先も 無理なく特定できます 開発はすべてUIKitベースで行いました 整合性確保のためパッケージ化したカスタム テーブルビューのセルや製品詳細ビューでは 複数のアプリで同じUIを使います 我々のアプリには顧客 予約 製品など 似たオブジェクトがあります これらモデルオブジェクトはSwiftパッケージで 展開しアプリで共有する優先的な候補で 標準化モデルとして定義されます 最後に説明するスキャンパッケージは VisionとAVFoundation上で開発したため アプリ間でのバーコードやQR 文字認識を― 我々のコードと同じ感覚で行えます 実際に見てみましょう Visionフレームワークでは PDF417やDataMatrix QR code等の記号をスキャンできます テキストデータも取り込めて リアルタイムのOCRも可能です また補足のUIビューを表示したレイヤーを作成し ユーザーのカメラの目標設定やフラッシュ制御 共通APIへの設定などを簡素化します 例えば バーコードやテキストの スキャンには同じコードパターンを使います ビューコントローラを初期化し設定オプションの 構造体へデリゲートを割り当てる簡単な設定です デリゲートがスキャンプロセスの成否についての メッセージに対処します 例を見てみましょう
スキャンパッケージ内で設定を保持する構造体の スキャンオプションのインスタンスを作ります そして新しいバーコードスキャナービュー コントローラを同じ設定で初期化します この設定と初期化パターンにより各アプリ間で それらを簡単に保存し再利用できます 次は最初の例に似ていますが バーコードをスキャンせずコントローラでビュー エリア内の文字列をスキャンし認識できます 設定と初期化のパターンをバーコードに揃え それぞれのパッケージの利用を容易にします 両方のパッケージでAPIはデフォルトUIを提供し 各アプリに応じた変更やカスタマイズが可能です これによりすべてのアプリのUIで 整合性を保つのが容易になります App GroupとSwiftパッケージの話は以上です 次はテストについて説明しましょう アプリ開発後は期待通りに動作するかを 確認するテストを行う必要があります テストに多くの人員を割くこともできますが それよりもっと効率的な方法があります よく行われるのが単体テスト UIテスト 性能テストの3種類です
単体テストは我々のテスト戦略の最初の一歩で エンジニアリングチームと共に行います アプリを動かすクラスや機能を書く際は 単体テストを作ることが重要です 各コードのパスで予想値を返すか 確認するためです XcodeはXCTestフレームワークで単体テストを 補助し素早く動作確認コードを書いて走らせます より詳細な情報向けの セッションは多数ありますが “Testing in Xcode"と“Testing Tips and Tricks"がおすすめです
UIテストもできるだけ多く行って 実際の効率化を確認します UIテストは品質評価チームが作成した手作業での テストケースを使い Swiftでコード化します Xcodeはテストを作成し 実行するための構造を 提供するXCUITestを備えています
これらのテストを作成後 重要度に従って分類します それによって 重要なテストに より多く時間を割くことが可能になります 実行回数が多いほど不具合を早期発見できるため チェックイン時 日単位 週単位で行います WWDCの“UI Testing in Xcode 7”セッションは たくさんの情報を得られます
iOSデバイスの性能テストで注目すべきは レンダリング性能とバッテリー性能の2点です 最新iOSデバイスのCPUとGPUは強力ですが 各アプリの相互作用の性能にまだ注力が必要です ユーザーは画面操作がスムーズでないと フラストレーションが溜まりますからね デバイスは1日中店舗の売り場にあるため バッテリーにも高い性能が求められます 販売員が充電のために接客から離れると 生産性が低下しますから 予備のデバイスを持っておくことも重要です エンジニアの作業を簡潔にする 優れたツールがInstrumentsです このツールはXcodeにも組み込まれており 時間のかかるアプリの分析に役立ちます メモリやバッテリー容量は とても高機能です Instrumentsに関する詳細は“Practical Approaches to Great App Performance”と “Improving Battery Life and Performance”のセッションをご確認ください 次はピナールが アプリの管理について説明します エリック ありがとう 彼が紹介したすばらしい情報について 実際のアプリでどのように管理するのか 説明します 最初に アプリ構成を考慮した 開発について説明します 次に下位互換性とユーザーへの 強制アップデートについてお話しします 当社のアプリケーションは同時に 2つの構成をサポートしています クライアントベースとサーバーベースの 構成ファイルです ブール値は当社のサーバーから ダウンロードしています 最初にクライアント構成についてお話します 弊社クライアントでベイクされ サーバー上で ホストされている構成ファイルによって アプリのユーザーエクスペリエンスの 柔軟性と適合性を高めています 各地域やマーケットレベルで 要素を管理することができ― Apple販売店での管理が可能です 実稼働での属性の変更は コードの変更に一切左右されないため 新しいクライアントビルドが不要です 変化するビジネスニーズに対応可能な 適応性の高いアプリケーションです サーバー構成を適所に保持し アプリの動作を促進しています サーバーからのデータにより 特定の要素を表示しています
特定の地域やマーケットにおいて 使用しない機能がある場合でも 柔軟に対応することができます 世界市場に合わせて 機能のオンオフを切り替えることが可能です
強固なクライアント構成と同様に サーバー上での値の変更において コードの変更は不要です サーバーに設定値がデプロイされると 変更は自動的にアプリケーションに反映されます
運用チームが設定値を単独で制御できる場合は サーバー構成の公開も可能です ビジネスニーズに応じて 機能の切り替えができます この連携により 開発者はアプリの管理ではなく 開発に集中することができるのです
アプリケーションで 構成が どのように機能するかを示した図です クライアント構成で属性を設定した PLISTファイルの作成が可能です このファイルはJSON形式でホストできます 起動シーケンス中に 設定した属性はダウンロードされます 生産中に属性の値を変更する場合は PLISTファイルで変更し 新しいバージョンの設定を サーバーにアップロードすれば完了です アプリケーションを再起動すると変更されます これらの工程を 数分で行う仕組みを紹介します サーバー構成ではビジネスチームや 運用チームが値の設定を完全に制御できます これにより グローバルレベルでの 機能の切り替えを可能とし― マーケットニーズに応じた値への 変更ができるのです iOSアプリケーションで サービスAPIの取得も可能です 属性設定後のフラグが アプリケーションの動作を促進します
次は クライアント構成の例を紹介します これらは顧客フォームに定義したい項目です 氏名 Eメール 電話番号などの情報を 顧客から収集したい場合
これらの属性をクライアントコードに関連付け 関数定義で汎用的にすることで PLISTファイルの操作を可能とします 運用環境でのアプリケーションのUIにおける フォームの外観です 例えば 顧客のEメールを 今後収集する必要がなくなった場合 UIからフィールドの削除を行います
PLISTファイルの構成から “Eメール”フィールドを削除し― 新しい構成をサーバーにアップロードします アプリケーションを再起動すると Eメールの項目は表示されなくなります コードの変更や新たなクライアントビルドも 必要ありません
顧客の電話番号を収集する必要がなく 迅速な変更が必要となった場合も 同じ工程を行い 新しい構成をサーバーにアップロードすれば
電話番号のフィールドは表示されなくなります このようなコンフィギュレーション駆動型の ユーザーエクスペリエンスにより 実稼働でのアプリケーション管理が可能です サーバーとクライアントが連携し 緊密なオーケストレーションで動作する場合 下位互換性には常に留意する必要があります 古いクライアントではサーバー変更が 反映されない場合があるのです 当社は構成バージョンを適所に保持することで 不具合が解消されると考えました アプリケーションは起動時にサーバーや クライアント構成のバージョンを確認します どのユーザーエクスペリエンスを表示するか 決定することができます ユーザーにアプリケーションの バージョン更新を強制するケースも生じます 更新をしないと 新しい機能を確認できないからです ある属性に対して 新しい値がクライアントに追加されても サーバーに新しい値への マッピングがない場合 サーバーもクライアントも 連携することができません そのような場合は ユーザーに強制的に更新していただきます 今回はアプリグループ 共有フレームワーク テストについてお話ししました そして コンフィギュレーション駆動型の ユーザーエクスペリエンスの活用の説明 最後に 下位互換性の必要性と ユーザーに更新を強制する必要性を 説明しました ご視聴ありがとうございました iOS 14で進化するアプリを 楽しみにしております 今年のWWDCを お楽しみいただけますよう願っています
-
-
2:02 - App Groups
let sharedDefaults = UserDefaults(suiteName: “group.com.apple.myappgroup")! sharedDefaults.set("My Cool Value", forKey: "MyKeyName") let myKeyNameValue = sharedDefaults.string(forKey: "MyKeyName")
-
5:04 - BarcodeScannerViewController
import RetailScanner let scanOptions = BarcodeScanOptions() scanOptions.scanRegion = .regular scanOptions.shouldAddSupplementaryView = false scanOptions.shouldShowBarcodeDetector = true let barcodeViewController = BarcodeScannerViewController(scanOptions: scanOptions) barcodeViewController.delegate = self
-
5:29 - OCRScannerViewController
import RetailScanner let scanOptions = OCRScanOptions( scanRegion: .custom(CGSize(width: 400, height: 100)), accessibilityBehavior: .vibrate, shouldAddSupplementaryView: true, validation: nil, shouldShowResultView: true ) scanOptions.recognitionLevel = .fast let ocrViewController = OCRScannerViewController( scanOptions: scanOptions ) ocrViewController.delegate = self
-
12:26 - Config-driven UI - Client based configuration hosted by server
func configuredCellForLabel(for customerInfoField: CustomerInfoField, at indexPath: IndexPath) -> UITableViewCell { . . . } func configuredCellForPhoneNumber(for customerInfoField: CustomerInfoField, at indexPath: IndexPath) -> UITableViewCell { . . . }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。