FRMSKI開発ブログ

プログラミング、UI / UX、仕事、読書のことなど、日々の記録を綴ります

Human Interface Guidelines⑦ - App Architecture / Requesting Permission 和訳&まとめ

iOSのHuman Interface Guidelines 、Request Permissionについての翻訳です。

Request Permission

 ユーザーは、現在の場所、カレンダー、連絡先情報、リマインダー、写真など、個人情報にアクセスするための許可をアプリケーションに与える必要があります。この情報にアクセスできるアプリの利便性は高く、プライベートデータを管理することも期待できます。たとえば、写真を物理的な場所に自動的にタグ付けしたり、近くの友人を見つけたりすることが好きな人もいますが、そのような機能を無効にするオプションも必要です。

アプリが明らかに必要とする時にだけ、個人データを要求してください

 個人情報の要求が疑わしいのは当然です。必要性が明白でない場合は特にそうです。個人データがはっきりと必要な機能を人々が使用している場合にのみ、許可要求が出されるようにしてください。たとえば、アプリは、位置追跡機能をアクティブにする時にのみ、現在の場所へのアクセスを要求することができます。

アプリが情報を必要とする理由を説明してください

 システムの許可要求アラートに表示するためのカスタムテキスト(目的の文字列または使用の説明文字列)を提供し、例を含めます。テキストを短く、具体的に保ち、文例を使用し、人々が圧迫感を感じないように丁寧にしてください。アプリ名を含める必要はありません。システムはすでにアプリを識別しています。

起動時にアプリが機能するために必要な時にのみアクセス許可をリクエストしてください

 あなたのアプリが操作するために自分の個人情報に依存していることが明らかな場合、ユーザーはこの要請に煩わされることはありません。

不必要に位置情報を要求しないでください

 場所情報にアクセスする前に、システムをチェックして、Location Servicesが有効かどうかを確認してください。この知識により機能が本当に必要とするまでアラートを遅らせることができます。アラートを完全に回避することもできます。位置情報機能の実装方法については「MapKit | Apple Developer Documentation」と「About Location Services and Maps」を参照してください。

Human Interface Guidelines⑦ - App Architecture / Onboarding 和訳&まとめ

今回は起動時のオンボーディングについての和訳です。

Onboarding(オンボーディング)

起動時間は、新しいユーザーを研修、または再来したユーザーと改めて接する最初の機会です。速く、楽しく、教育的なローンチ体験をデザインしましょう。

起動画面を提供する

 アプリ起動時に起動画面が表示され、初期のコンテンツの読み込みを行いながらも、アプリが速く反応しやすいという印象を与えます。この画面はすぐにアプリの最初の画面に置き換えられるため、ローカライズ可能なテキストやインタラクティブな要素を除いて、二つは似ているはずです。

適切な方向に起動する

 アプリがポートレートモードとランドスケープモードの両方をサポートしている場合は、デバイスの現在の方向を使用して起動する必要があります。あなたのアプリが1つの向きでしか動かない場合は、常にその向きで起動し、必要に応じて人々がデバイスを回転させるようにしてください。そうしなければならない魅力的な理由がない限り、横長モードのアプリは、デバイスが左右に回転しているかどうかにかかわらず、正しく動くはずです。

すぐに行動に移る

 スプラッシュスクリーン、メニューなどによって、アプリの使用開始やコンテンツへのアクセスに時間がかかるような手順は表示しないようにします。あなたのアプリにチュートリアルやイントロシークエンスが必要な場合は、それらをスキップするなどユーザーを離脱させない方法を提供してください。

助けの必要性を予期する

 人々が立ち往生している時間を積極的に探します。例えば、ゲームは、一時停止したときや、キャラクターが前進していないときに、気軽に役立つヒントを表示することができます。ユーザーが初めて何かを逃した場合に備えて、チュートリアルを再生できるようにします。

チュートリアルの必需品にこだわる

 初心者のための指導を提供するのはうれしいですが、教育は優れたアプリデザインの代用品ではありません。まず、あなたのアプリを直感的にしてください。あまりにも多くの指導が必要な場合は、アプリのデザインを見直してください。

学習を楽しく、発見可能にする

 実行することによって学ぶことは、指示のリストを読むことよりもはるかに楽しく効果的です。アニメーションとインタラクティビティを使用して、徐々にコンテキストを教えましょう。インタラクティブに表示されるスクリーンショットは表示しないようにします。

セットアップ情報の入力を求めない

 人々はアプリにただ働くことを期待しています。過半数のためのアプリを設計し、別の設定が欲しい少数の人々には彼らのニーズを満たすために設定の調整は任せてください。可能な限り、デバイスの設定とデフォルトから、またはiCloudなどの同期サービスを通じて設定情報を取得します。セットアップ情報を尋ねる必要がある場合は、最初にアプリ内で表示し、後でユーザーがアプリの設定でそれを変更できるようにします。

アプリ内ライセンス契約や免責事項の表示を避ける

 あなたのアプリがダウンロードされる前にApp Storeに同意と破棄を表示させてください。これらのアイテムをアプリに含める必要がある場合は、ユーザーエクスペリエンスを損なわないバランスの取れた方法でそれらのアイテムを統合します。

アプリの再起動時に以前の状態に戻す

 人々があなたのアプリの前の場所に到達するための手順を遡るようにしないでください。アプリケーションの状態を保持して復元し、中断したところから続けることができます。

過度に速く頻繁に評価するように依頼しない

 評価をすぐに、または頻繁に行うことは迷惑であり、受け取った有用なフィードバックの量は減少します。十分に考慮されたフィードバックを奨励するために、評価を求める前に、人々にあなたのアプリについて意見を書く時間を与えてください。評価のプロンプトを表示しないようにして、ユーザーにアプリの評価を強制しないでください。

再起動を奨励しない

 再起動には時間がかかり、アプリの信頼性が低く、使いにくいように見えます。あなたのアプリがメモリやその他の問題を抱えていて、システムがちょうど起動していないなど、実行が困難になった場合に限り、それらの問題に対処する必要があります。

Human Interface Guidelines⑥ - App Architecture / Navigation 和訳&まとめ

App ArchitectureのNavigationについての和訳です。

Navigation(ナビゲーション)

 人々は、期待を満たさなくなるまでアプリのナビゲーションに気づかない傾向があります。あなたの仕事は、注意を喚起せずにアプリの構造と目的をサポートする方法でナビゲーションを実装することです。
ナビゲーションは自然で親しみを感じるべきであり、インターフェースを支配したり、コンテンツからフォーカスを引き離したりしてはなりません。 iOSでは、3つの主要なナビゲーションスタイルがあります。

  • 階層的ナビゲーション
    あなたが目的地に達するまで画面ごとに1つずつ選択します。別の目的地に行くには、あなたのステップをリトレースするか、最初からやり直して別の選択肢を作る必要があります。設定とメールはこのナビゲーションスタイルを使用します。

  • フラットナビゲーション
    複数のコンテンツカテゴリを切り替えます。音楽とApp Storeはこのナビゲーションスタイルを使用します。

  • コンテンツ駆動またはエクスペリエンスドリブンナビゲーション
    コンテンツを自由に移動するか、コンテンツ自体がナビゲーションを定義します。ゲーム、書籍、その他の没入型アプリでは、一般にこのナビゲーションスタイルが使用されます。



いくつかのアプリは複数のナビゲーションスタイルを組み合わせています。たとえば、フラットナビゲーションを使用するアプリは、各カテゴリ内で階層ナビゲーションを実装できます。

常に明確な経路を提供する

人々はいつもあなたのアプリのどこにいるのか、次の目的地に行く方法を知っておくべきです。ナビゲーションスタイルにかかわらず、コンテンツの経路は論理的で予測可能であり、追跡が容易であることが不可欠です。一般に各スクリーンに1つのパスを人に与えます。複数のコンテキストで画面を表示する必要がある場合は、アクションシート、アラート、ポップオーバー、またはモーダルビューの使用を検討してください。

コンテンツに素早く簡単にアクセスできる情報構造を設計する

タップ、スワイプ、およびスクリーンの最小数が必要な方法で情報構造を整理します。

流動性をつくるためにタッチジェスチャーを使用する

最低限の摩擦でインターフェイスを簡単に移動できます。たとえば、画面の横からスワイプして前の画面に戻すことができます。

標準ナビゲーションコンポーネントを使用する

可能な限り、ページコントロール、タブバー、セグメントコントロール、テーブルビュー、コレクションビュー、分割ビューなどの標準のナビゲーションコントロールを使用します。ユーザーは既にこれらのコントロールに精通しており、直感的にアプリを回避する方法を知ることができます。

ナビゲーションバーを使用してデータの階層を横断する

ナビゲーションバーのタイトルに階層内の現在の位置が表示され、戻るボタンで前の場所に戻ることが容易になります。

タブバーを使用してコンテンツまたは機能のピアカテゴリを表示する

タブバーを使用すると現在の場所に関係なく、カテゴリをすばやく簡単に切り替えることができます。

同じ種類のコンテンツのページが複数ある場合はページコントロールを使用する

ページコントロールは利用可能なページ数と現在アクティブなページ数を明確に伝えます。天気アプリケーションは、ページコントロールを使用して場所固有の天気のページを表示します。

JSONEncoderで小数点以下が正確な数値にエンコードされない問題の解決法

JSONEncoderで文字列を出力する時に、Doubleで値を持つと小数点以下の桁数が正確に出力されない場合があります。こういった問題はDecimal型で出力すると解決できます。 下記のソースはDouble型で出力した例です。

struct SaveData{
        save_number:Double
}
    
class Test{
        func testEncode(){
            let number:Double = 12.345678
            let savedata:SaveData = SaveData(
                save_number:number
            )
            let encoder = JSONEncoder()
            let data = encoder.encode(savedata)
            let str:String(data,encoding:.utf8)
            print(str) //出力 { "number" : 12.34567800000000002 }
        }
}

本来小数点以下は6桁のはずが0000~と不要な数字が入っています。
解決策としては、下記のようにStringからDecimal型に変換することで正確に出力されます。

struct SaveData{
        save_number:Decimal
}
    
class Test{
        func testEncode(){
            let number:String = "12.345678"
            let savedata:SaveData = SaveData(
                save_number:Decimal(string:number)
            )
            let encoder = JSONEncoder()
            let data = encoder.encode(savedata)
            let str:String(data,encoding:.utf8)
            print(str) //出力 { "number" : 12.345678 }
        }
}

Double型は2の累乗を用いて値を表すため、10進数の小数を扱うと誤差が出ます。 Decimal型は10の累乗を用いて値を表すため、10進数を誤差なく表すことができます。
小数点以下を正確に表示する場合はDecimal型を使いましょう。

Human Interface Guidelines⑤ - App Architecture / Modality 和訳&まとめ

Modalityについての和訳です。

Modality(モダリティ)

 モダリティは、人々がタスクを完了したりメッセージや表示内容を却下するまで、他のことをやることを防ぎ、集中させます。アクションシート、アラート、およびアクティビティビューはモーダルエクスペリエンスを提供します。モーダルビューが画面上に現れるとき、ユーザはボタンをタップするかモーダルエクスペリエンスを終了することによって選択を行わなければならない。
 一部のアプリでは、カレンダーでイベントを編集するときやSafariでブックマークを選択するときなど、モーダルビューが実装されています。モーダルビューは、画面全体、ポップオーバーなどの親ビュー全体、または画面の一部を占有することができます。モーダルビューには通常、ビューを終了する完了ボタンとキャンセルボタンが含まれます。

f:id:frmski:20181014152226p:plain:w250 ←モーダリティビュー

モダリティの使用を最小限に

 一般に、人々は非線形の方法でアプリとやり取りすることを好みます。誰かの注意を引くことが重要な場合、アプリケーションの使用を続けるためにタスクを完了または放棄する必要がある場合、または重要なデータを保存する場合にのみ、モーダルコンテキストを作成することを検討してください。

明らかで安全な方法を提供する

 モーダルビューを却下したときに、人々が行動の結果を常に把握していることを確認してください。

簡単に、短く、焦点を絞った状態に保つ

 アプリ内にアプリを作成しないでください。モーダルタスクが複雑すぎると、モーダルコンテキストに入ったときに中断したタスクを見失う可能性があります。ユーザーは迷子になり、手順を辿る方法を忘れることがあるため、ビューの階層を含むモーダルタスクを作成することに特に注意してください。モーダルタスクにサブビューが含まれている必要がある場合は、階層を通る単一のパスと完了までの明確なパスを指定します。タスクを完了する以外の目的では、完了ボタンを使用しないでください。

必要に応じて、タスクを識別するタイトルを表示

 ビューをより完全に説明するために、ビューの他の部分にテキストを提供することもできます。

理想的に実行可能な情報を提供するためのアラート

 アラートはその経験を中断させ却下するためのタップを必要とするため、侵入が正当であると感じることが重要です。

通知設定を尊重する

 [設定]では、アプリから通知を受け取る方法を指定します。これらの設定を遵守することによって、ユーザーはアプリの通知を完全に無効にするようなことはしないでしょう。

ポップオーバーの上にモーダルビューを表示しない

 アラートを除いて、ポップオーバーには何も表示されません。モダルビューを表示する前にポップオーバーを閉じてください。

モーダルビューの外観を調整

 モーダルビューは、例えばナビゲーションバーを含むことができます。このような場合は、アプリのナビゲーションバーと同じ外観を使用します。

モーダルビューの種類

  • 全画面表示
    画面全体をカバーします。モーダルビューのコンテキスト内で完了できる潜在的に複雑なタスクに使用します。
  • ページシート
    横長方向に保持されているより大きなデバイスの基礎となるコンテンツを部分的にカバーします。すべてのカバーされていない領域は、それらとの相互作用を防ぐために淡色表示されます。小さなデバイスと縦向きの画面全体をカバーします。モーダルビューのコンテキスト内で完了できる潜在的に複雑なタスクに使用します。
  • フォームシート
    画面の中央に表示されますが、キーボードが表示されている場合は再配置されます。すべてのカバーされていない領域は、それらとの相互作用を防ぐために淡色表示されます。小さなデバイスで画面全体を覆うことがあります。情報の収集に使用します。
  • カレントコンテキスト
    親ビューと同じサイズで表示されます。スプリットビューペイン、ポップオーバー、またはフルスクリーンではない他のビュー内にモーダルコンテンツを表示するために使用します。

適切なトランジションスタイルを選択

 アプリと連携して一時的なコンテキストシフトの意識を高めるトランジションスタイルを使用します。デフォルトの遷移は、モーダルビューを画面の下から垂直方向にスライドさせ、一旦解除すると元に戻します。フリップスタイルのトランジションは、ビューを水平方向に反転させてモーダルビューを表示します。視覚的には、モーダルビューは現在のビューの背面に似ています。それは一旦解雇されたときに戻ってくる。アプリ全体を通して一貫したモーダルトランジションスタイルを使用します。

RxSwiftのbindでテキストフィールドと変数の値を直結させる

RxSwiftのbindを使えばテキストフィールドの値を変更したタイミングで変数を書き換える処理を簡単に実装することができます。

//TestViewController.swift側

@IBOutlet var testTextField : UITextField!
let model = TestModel()
let disposeBag = DisposeBag()

func viewDidLoad{

 testTextField.rx.text.orEmpty
            .bind(to: model.testText)
            .disposed(by: disposeBag)
}

上記ソースではRxSwiftとRxCocoaのimportも記述してください。orEmptyを入れることで空文字とnilはオブザーブしません。disposeBagは自動的に解放するために格納しておきます。

//TestModel.swift側
let testText = Variable<String>("")

このようにModel側で変数を定義してViewControllerでbindします。

Human Interface Guidelines④ - App Architecture / Loading 和訳&まとめ

前回のアクセシビリティに続いて今回はLoadingについての和訳です。

Loading(ローディング)

コンテンツが読み込まれると、空白の画面や静的な画面では、アプリがフリーズしているように見えることがあり、混乱と不満を招き、ユーザーがアプリを離れる可能性があります。

ローディングの発生を明確に

少なくとも、何かが起こっていることを示すアクティビティスピナーを表示します。さらに良いことに、明示的な進捗状況を表示して、ユーザーが待機する時間を測定できるようにします。できるだけ早くコンテンツを表示する。彼らが期待している画面を見る前に、コンテンツが読み込まれるのを待たせないようにしてください。

プレースホルダ要素を用いる

すぐに画面を表示し、プレースホルダテキスト、グラフィックス、またはアニメーションを使用して、コンテンツがまだ利用できない場所を特定します。コンテンツの読み込み時にこれらのプレースホルダ要素を置き換えます。可能であれば、アニメーションが再生されている間、またはユーザーがレベルまたはメニューをナビゲートしている間など、バックグラウンドで今後のコンテンツをプリロードしてください。
ローディング時間を用いて人々を教育したり、楽しんでください。ゲームプレイ、面白いビデオシーケンス、興味深いプレースホルダグラフィックに関するヒントを表示することを検討してください。

画面の読み込みをカスタマイズ

標準的な進捗インジケータは通常はOKですが、状況によって変わります。アプリやゲームのスタイルに合ったカスタムアニメーションや要素を使って、より没入感のある体験をデザインすることを検討してください。