20200919のiOSに関する記事は15件です。

iOSアプリのリバースエンジニアリング-[ツール編]

はじめに

この記事は随時追記していきます。時々思い出した頃に見に来てください。ストックかLGTMで多分更新時に通知がいくようにするのでみたい人はお願いします

ツールたち

LLDB

LLVM(Xcodeでも使われているコンパイラ)のプロジェクトの一部として開発された高性能な動的デバッガ。
以下のサイトはgdb to lldbのチートシートであるが、普通にlldbのコマンドを調べるためにも役に立つ。
http://lldb.llvm.org/use/map.html
こちらは純粋なlldbのチートシート
https://www.nesono.com/sites/default/files/lldb%20cheat%20sheet.pdf

breakpointはもちろん、bt(バックトレース)やimage lookup --address、thread returnなどをよく使ってる。
XcodeからでなくコマンドラインでLLDBを使うようになってから、普通のiOSアプリの開発においてもコマンドから使ったりするようになった。

あんまり実用性はないけどGUIも用意されてたりする。
スクリーンショット 2020-09-19 22.07.20.png

otool

いくつかの用法がある。

ライブラリの依存関係を調べる

lddみたいな使い方

otool -L ファイル名

nm

シンボルを抽出して表示する。使用されているクラス名などを調べることができる。

nm ファイル名

strings

ファイルから文字列の部分を抽出する。例えば、pirntf("aaaa");としていれば、aaaaが見つかる。
このコマンドから見つからないようにする方法も今度記事にしようと思っています。

strings ファイル名

dsdump

Hopper Disassembler V4

Ghidra

frida

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iOSDC2020の HomeKit のセッションが面白かった

iOSDC2020 の HomeKit に関するセッションが面白かったので、セッションで聞いた内容含め簡単にまとめておこうかと思います。暇があったら何か作ってみたい?

HomeKit とは?

image.png

iOS、iPadOS、macOS、watchOS などの Apple製品からデバイスを管理・コントロールできるようにするための IoT アプリケーションの枠組みです。また、そのような HomeKit 対応のアプリケーションを対応する機器をコントロールするアプリとして Apple から Home というアプリが標準で提供されていますが、HomeKitFramework という Framework を使うことで独自にアプリを作ることも可能です。

HomeKit Accessory Protocol(HAP) とは?

HomeKit Accessory Protocol(HAP) は、サードパーティー製アクセサリ(証明やドアロックなど)と Apple製品とが相互に通信するためのプロトコルで、商用目的ではない場合は自由にアクセサリに HAP を実装できますが、商用目的の場合は、MFi プログラムに基づく HomeKit 認定を完了する必要があるみたいです。

Homebridge とは?

Homebridge は、iOS HomeKit API の挙動を HomeKit に対応していないアクセサリを動かすために使用される、ホームネットワークで実行できる軽量のサーバーです。また、それら HomeKit デバイスを制御する Homebridge プラグインが2000以上あるそうです。詳しくはこちら を参照してください。

セッションでは、Homebridge の代表例として、Philips hue の Bridge が消化されていました。この Bridge により他の Philips Hue で提供されているアクセサリーが実質 Home App で使用できるようになっているようです。

https://www.philips-hue.com/ja-jp/p/hue-bridge/8718696562260

HomeKit ADK とは?

HomeKit Accessory DevelopmentKit の略でアクセサリーメーカーが HomeKit に対応したデバイスを作成するための Apple から提供されている開発コードのようです。つまり、前述の Bridge とは違い Home App で直接的にアクセサリを操作できるようにするための DevelopmentKit のようですね。

https://github.com/apple/HomeKitADK

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[iOS]ipaファイル中身解析

とりあえず簡易的にまとめる。ipaファイルは中身はただのzipファイルなので、拡張子を.zipに変更した後ダブルクリックなどをすると解凍できる。

中身にペイロードがあるが、これをチェックする方法・ツールはいくつかある。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SwiftUIやってて出てきたGeometryReaderって

はじめに

SwiftUIでサイドメニューを実装しようと

[https://swiswiswift.com/2020-02-20/:title]

こちらのサイトをみていたら
GeometryReader
という記述がありました。

SwiftUIのおそらくグラフとかアニメーションのTutorialで出てきたと思うのですが、自分は最初はそこは必要ないと思い飛ばしていました。

なので今回は自分が調べた内容を備忘録としてまとめます。

公式の定義

GeometryReaderの説明は独自のサイズと座標空間の関数としてコンテンツを定義するコンテナービュー。

親レイアウトに柔軟な優先サイズを返します。

とあります。



親のViewのサイズや座標空間を取得して子のViewで使えるって感じですかね。

サイドメニューの参考サイトの場合は画面のサイズを取得するため
body下で利用したのでBodyのサイズ、つまり画面サイズが取得できたと。

画面サイズの取得の仕方としては

UIScreen.main.boundsでも取得はできそうです。

逆に親Viewを指定というか選ぶ場合は

.background(指定したい親View)をすればいけるみたい。

他にも参考サイト先で面白い内容があるのでもう少し勉強しようと思います。

参考サイト

[https://qiita.com/masa7351/items/0567969f93cc88d714ac:title]

Apple公式Doc

[https://blog.personal-factory.com/2019/12/08/how-to-know-coorginate-space-by-geometryreader/:title]

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

なんとなく気になったdYSM調べた

はじめに

なんとなくdYCMという言葉を見つけて

そういえば、コレってなんなのかなーと思ったので調べました。

dYCMとは

dSYMはクラッシュレポートのメモリアドレスに

対応するシンボル(クラス名やメソッド名)を持っているとの事なので

バイナリファイルにシンボル情報が入っているそうです。

どういう時に使うの?

結論から言うと

「iOSのクラッシュログをSymbolicate(復元)するため」

です。



生のクラッシュログはアドレスで表記されているため

そのままだと分かりません。(制約の警告とはちょっと違うけどあんな感じ)

アプリのdSYMファイルを用いてシンボル化(Symbolicate)することで

どこで落ちてるか見ることができるようになります。

詳しいやり方は、以下の参考サイトに書かれていました。

参考サイト

[https://qiita.com/ruwatana/items/cc470eb229d267d693b0:title]

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

App Storeのレビューで表示するスクリーンショットの作成

はじめに

今回はApp Storeのレビューで表示するスクリーンショットについて

勉強していたのでそちらの備忘録&まとめです。

以前、勉強がてら冷蔵庫の中身を管理するアプリを初めて作成しました。

「Rakko」

この時はぶっちゃけ仕事と並行して3ヶ月以内に

作成しようと思い、画像の作成やスクリーンショットについては

ほぼ勉強していませんでした。

なので、今回新しくSwiftUIでアプリを作ってみるということで

今度はそれ並行しつつはもう少し勉強しようと。。笑


必要な画像のサイズ

必要なのスクリーンショットのサイズは5.5インチ6.5インチです。(2020年9月現在

アプリのスクリーンショットのサイズを間違えて一度リジェクトをされたことがありました。

なのでここら辺はしっかり調べてやりました。


枠付きのスクショを撮る方法

アプリのレビュー用の画像にどのようなアプリかを載せるために

シミュレータを利用して枠付きのスクショを撮って利用しました。

やり方は

「cmd」+「shift」+「4」+「space」→ 対象のウィンドウをクリック

でできます。


スクリーンショットを作る時に参考にした物

まずは、同じような冷蔵庫管理アプリがどのような画像をやっているか

参考にしました。



次に、ダイアログとかのサービスをしている「Reporo」さんの

スクリーンショット作成術のデザインなどを参考にしました。



他にもいろいろネットで探しましたが、ここら辺は自分で調べた方が

頭に残りやすいと思うのであえて載せませんがたくさんありました。

[https://repro.io/contents/the-ultimate-guide-for-itunes-connect-screenshots/:title]

最終的なレビュー用画像

こんな感じになりました。

んーなんだか安っぽい感じがまだ抜け出ないですが、

コレは単に自分のセンスとデザインの勉強不足ですね。(/ _ ; )

一個前のやつはこんな感じです。



  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

FlutterでGoogle sign in使おうとしたら、iOSでクラッシュし続ける

iOSでFlutterのgoogle_sign_inが動かない...

Flutterのfirebase_authgoogle_sign_inで、Google sing inを実装していた。
Android側は問題なく動いたが、iOSがどうにも動かない。

GoogleSignIn().signIn()signIn()でクラッシュする。

FlutterFireのiOS Installationを舐めるように読み返してみても解決しない。

  • google_sign_in: 4.5.3
  • iOS: 10.3.1

解決策

GoogleSignIn( scopes: ['email', 'profile'], hostedDomain: '', clientId: '',).signIn();

GitHub issueで解決策見つけた。
https://github.com/flutter/flutter/issues/44564#issuecomment-575883100
どうやらライブラリで、パラメータのnullチェックが足りてないらしい。

もっと少ないパラメータで大丈夫だった人も。
https://github.com/flutter/flutter/issues/44564#issuecomment-655884103

他のハマりポイント

先のissueをみてると、設定漏れでハマってる人もちらほら。

https://pub.dev/packages/google_sign_in#ios-integration
ここにある通り、
1. GoogleService-Info.plistをFirebaseコンソールからDLして、[my_project]/ios/Runnerに追加する。
2. CFBundleURLTypesInfo.plistに追記する。
3. この時、stringタグの中身を、先のGoogleService-Info.plistに書いてあるREVERSED_CLIENT_IDで置き換える。

...のをお忘れなく。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】@escaping 丸わかり?

@escaping

image.png

@escapingとは?

  • Swiftの 属性(= attribute)の1つ
  • @escaping属性は、クロージャに対して指定する追加情報
  • 関数に引数として渡されたクロージャが、関数のスコープ外で保持される可能性があることを示す

この記事分かりやすいです?

var array = [()->Void]()

func testEscaping(arg: @escaping ()->Void) {
    //関数のスコープ外の配列に追加
    //クロージャが関数外で保持されることになるので、@escaping属性が必要
    array.append(arg)
}
testEscaping {print("玄邪 一郎")}
testEscaping {print("玄邪 二郎")}

array.forEach { $0() } //Swiftではクロージャの引数に自動的に$0、$1、$2…と順に名前が付与されます。

属性(= attribute)とは?

  • コンパイラに対し、宣言や型の補足情報を伝えるもの
  • @を使う。

@escapingを、 使う理由

複数のタスクを、非同期で並列処理させるため。

どんな時に、 必要か

  • クロージャが、スコープ外で強参照されるとき (= プロパティとして保持されるとき)
  • クロージャを、非同期で実行するとき (= メソッド内ですぐに実行されないとき)

こちら参考

クロージャをすぐに実行し、どこからも強参照されない場合は、
@escaping は必要ありません。

よくある例

非同期処理をする、完了ハンドラとしてのクロージャ。

// NG: コンパイルエラー
func someAsyncMethod(completion: () -> Void) {
    DispatchQueue.main.async {
       completion()
    }
}

// OK
func someAsyncMethod(completion: @escaping () -> Void) {
    DispatchQueue.main.async {
       completion()
    }
}
// completionHandler -> クエリが完了したときに実行される
// DispatchQueue -> 処理待ちタスクを追加するためのキュー

DispatchQueueについて

「循環参照」 に 気を付けよう?

@escapingなクロージャは、どこか から強参照される可能性があります。
その参照元をクロージャ内で強参照すると、循環参照になります...

おしまい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

@escaping覚書?【Swift】

 @escaping

image.png

 @escapingとは?

  • Swiftの 属性(= attribute)の1つ
  • @escaping属性は、クロージャに対して指定する追加情報
  • 関数に引数として渡されたクロージャが、関数のスコープ外で保持される可能性があることを示す

 この記事分かりやすいです?

var array = [()->Void]()

func testEscaping(arg: @escaping ()->Void) {
    //関数のスコープ外の配列に追加
    //クロージャが関数外で保持されることになるので、@escaping属性が必要
    array.append(arg)
}
testEscaping {print("玄邪 一郎")}
testEscaping {print("玄邪 二郎")}

array.forEach { $0() } //Swiftではクロージャの引数に自動的に$0、$1、$2…と順に名前が付与されます。

 属性(= attribute)とは?

  • コンパイラに対し、宣言や型の補足情報を伝えるもの
  • @を使う。

 @escapingを、 使う理由

 複数のタスクを、非同期で並列処理させるため。

 どんな時に、 必要か

  • クロージャが、スコープ外で強参照されるとき (= プロパティとして保持されるとき)
  • クロージャを、非同期で実行するとき (= メソッド内ですぐに実行されないとき)

 こちら参考

クロージャをすぐに実行し、どこからも強参照されない場合は、
@escaping は必要ありません。

 よくある例

 非同期処理をする、完了ハンドラとしてのクロージャ。

// NG: コンパイルエラー
func someAsyncMethod(completion: () -> Void) {
    DispatchQueue.main.async {
       completion()
    }
}

// OK
func someAsyncMethod(completion: @escaping () -> Void) {
    DispatchQueue.main.async {
       completion()
    }
}
// completionHandler -> クエリが完了したときに実行される
// DispatchQueue -> 処理待ちタスクを追加するためのキュー

 DispatchQueueについて

 「循環参照」 に 気を付けよう?

 @escapingなクロージャは、どこか から強参照される可能性があります。
 その参照元をクロージャ内で強参照すると、循環参照になります...

 おしまい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】クロージャー 丸わかり?

image.png

 クロージャ

 使い方

変数引数に、関数の処理を直接代入する。

 使う理由

最近のプログラミング言語では、
引数に関数を入れるとか、戻り値に関数を入れるとかが当たり前になっているので、
そういうときにクロージャを使うと綺麗に記述できるので、みんな嬉しい。

  • 引数として使うパターンが多い

 名前の由来

Closure closes over var.

 コード

 let, varに、関数の処理を直接代入

// MARK: - let, varに、関数の処理を直接代入

// 定数closureが、恰も関数のように扱える
let closure = { () -> () in print("Hello World!")}
closure()

let closure_2 = { () -> Void in print("hamburger")}
closure_2()
// 戻り値がVoid型、引数がない場合は、(引数) -> 戻り値の型 in を省略可
let closure_3 = { print("Yeah!") }
closure_3()

// 型を指定
let closure_4: (Int, Int) -> Void = { (num1: Int, num2: Int) -> Void in print(num1 + num2) }
// 型推論ってやつ
let closure_5 = { (num1: Int, num2: Int) -> Void in print(num1 + num2) }
closure_4(100, 199)
closure_5(100, 199)

// 因みに、closure_4 は num1, num2を省略可。

// 内部引数名を省略 -> 「$」を使用。
// $0 は最初の引数を表し、$1 は2番目の引数を表します。
let closure_6: (Int, Int, Int, Int) -> Void = {
    print ($0 - $1 + $2 + $3)
}
closure_6(30, 20, 100, 10) // 120

 型推論とは?

型の指定をしなくても、代入した値に応じて値の型を推論してくれる機能。
つまり、Swiftは変数の宣言時に型の指定を省略できる。( -> むしろ推奨。)


 クロージャを引数として、関数を実行

  • 引数として使うパターンが多い
// MARK: - クロージャを引数として、関数を実行

func closureTest(num1: Int, num2: Int, closure: (Int, Int) -> Int) { print(closure(num1, num2)) }

// return文が1行のみの場合には「return」は省略可
closureTest(num1: 300, num2: 5000, closure: { (num1, num2) -> Int in return num1 + num2 })
closureTest(num1: 300, num2: 5000, closure: { (num1, num2) -> Int in num1 + num2 })

// 引数の型を入力しないと、こうなるので注意。
// closureTest(<#T##<<error type>>#>, <#T##<<error type>>#>, <#T##<<error type>>#>)

// トレーリング クロージャ (= Trailing Closure)
closureTest(num1: 100, num2: 400) { (num1, num2) -> Int in
    num1 + num2 // return省略
}

 Trailing Closureとは?

関数の引数のうち 最後の引数がクロージャの場合、
クロージャを( )の外に書くことができる。

func testprint(str1: String, closure: (String) -> Void) {
    closure("僕の名前は\(str1)です。")
}

// トレーリングクロージャの場合 -> 美しい
testprint(str1: "玄邪 太郎") { string in
    print(string)   
}

// 通常のクロージャの場合 -> 可読性が悪い...
testprint(str1: "玄邪 太郎",{ string in
    print(string)   
})
  • クロージャが引数だと、{ }の外に( )を包まないといけないので、 可読性が悪くなる。(-> そこで、Trailing Closureが考案)

 クロージャの、基本的な性質2つ

  • ?クロージャーは関数の引数変数として使える
  • ?クロージャーは自分が定義されたスコープをキャプチャする

【Swift】クロージャの理解

 引数としてのクロージャ、利点?

  • コードが綺麗になる。
  • 呼び出し側で、処理が記述できる

呼び出され側は、クロージャに引数として値を渡し、
「値は渡すから、その値はそちらで好きに料理してね」という具合です。

class Foo {
    let val:Int = 10

    func testClosure(closure: (Int) -> Void) {
        closure(self.val) // self
    }
}

class Bar {
    let foo = Foo()

    // 引数の値を倍にする
    func twice() {
        foo.testClosure{ arg in print(arg * 2) } // arg = argument = 引数
    }

    // 引数の値を半分にする
    func half() {
        foo.testClosure{ arg in print(arg / 2) }
    }
}

let bar = Bar()
bar.twice()    // 20
bar.half() // 5

 クロージャによる、 変数と定数のキャプチャ?

  • ローカルスコープ(= scope_1)で定義された変数や定数は、
    ローカルスコープ内でしか使用できませんが、(= scope_2では使用不可)

  • クロージャが参照している変数や定数は、
    クロージャが実行されるスコープ(= scope_4)が
    変数や定数が定義されたローカルスコープ以外(= scope_3以外)であっても、
    クロージャの実行時に使用できます。

これは、クロージャが 自身の定義されたスコープ(= scope_3) の
 変数や定数への参照を保持している為で、この機能をキャプチャと言います。

class Foo {
    // scope_2関数は、普通の関数scope_1を2回実行しています。
    func scope_1() {
        var toto = 1
        toto += 1 // toto = toto + 1 と同義 (= 変数totoの値を更新)
        print(toto)
    }

    func scope_2() {
        scope_1()
        scope_1()
    }

    // scope_4関数は、scope_3関数から返されたクロージャを2回実行しています。
    func scope_3() -> () -> Void {
        var tete = 10
        let closure = { tete += 1
            print(tete)
        }
        return closure
    }

    func scope_4() {
        let tutu = self.scope_3()
        tutu()
        tutu()
    }
}

let test = Foo()
test.scope_2() // 2, 2
test.scope_4() // 11, 12

// scope_2関数は、普通の関数scope_1を2回実行しています。

普通の関数は、実行後はリセットされるので、
1回目の実行で「2」と表示されても、実行後ローカル変数totoの値は「1」に戻ります。

なので2回目の実行でも「2」と表示されます。

// scope_4関数は、scope_3関数から返されたクロージャを2回実行しています。

クロージャが、scope_3関数のローカル変数teteを参照しているので、
1回目の実行で「11」、2回目の実行では1回目の参照を保持しているので「12」となります。


 キャプチャとは?

 自身の定義されたスコープの変数や定数への、参照を「保持」する機能。
 クロージャ特有の機能。

 クロージャにて、self を使う理由

 明示的なselfには、循環参照 が存在しないよう確認を促す役割がある。

(Escaping Closuresは)循環参照を起こす危険性があるので、
(プログラマにそれを意識させるために)クロージャーの中で親スコープを強参照するときは、selfをつける。

selfを付けることが、循環参照を防ぐことに直結しているわけではなくて
コードの意図が明確になり、循環参照しないかにプログラマが意識を向けて書くようになる。

 おしまい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

クロージャー覚書?【Swift】

image.png

 クロージャ

 使い方

変数引数に、関数の処理を直接代入する。

 使う理由

最近のプログラミング言語では、
引数に関数を入れるとか、戻り値に関数を入れるとかが当たり前になっているので、
そういうときにクロージャを使うと綺麗に記述できるので、みんな嬉しい。

  • 引数として使うパターンが多い

 名前の由来

Closure closes over var.

 コード

 let, varに、関数の処理を直接代入

// MARK: - let, varに、関数の処理を直接代入

// 定数closureが、恰も関数のように扱える
let closure = { () -> () in print("Hello World!")}
closure()

let closure_2 = { () -> Void in print("hamburger")}
closure_2()
// 戻り値がVoid型、引数がない場合は、(引数) -> 戻り値の型 in を省略可
let closure_3 = { print("Yeah!") }
closure_3()

// 型を指定
let closure_4: (Int, Int) -> Void = { (num1: Int, num2: Int) -> Void in print(num1 + num2) }
// 型推論ってやつ
let closure_5 = { (num1: Int, num2: Int) -> Void in print(num1 + num2) }
closure_4(100, 199)
closure_5(100, 199)

// 因みに、closure_4 は num1, num2を省略可。

// 内部引数名を省略 -> 「$」を使用。
// $0 は最初の引数を表し、$1 は2番目の引数を表します。
let closure_6: (Int, Int, Int, Int) -> Void = {
    print ($0 - $1 + $2 + $3)
}
closure_6(30, 20, 100, 10) // 120

 型推論とは?

型の指定をしなくても、代入した値に応じて値の型を推論してくれる機能。
つまり、Swiftは変数の宣言時に型の指定を省略できる。( -> むしろ推奨。)

 内部引数とは?

 関数を呼び出すときは、外部引数名を利用します。

 普段 私たちは、内部引数名外部引数名として、関数を呼び出しています。
 違いはこちら


 クロージャを引数として、関数を実行

  • 引数として使うパターンが多い
// MARK: - クロージャを引数として、関数を実行

func closureTest(num1: Int, num2: Int, closure: (Int, Int) -> Int) { print(closure(num1, num2)) }

// return文が1行のみの場合には「return」は省略可
closureTest(num1: 300, num2: 5000, closure: { (num1, num2) -> Int in return num1 + num2 })
closureTest(num1: 300, num2: 5000, closure: { (num1, num2) -> Int in num1 + num2 })

// 引数の型を入力しないと、こうなるので注意。
// closureTest(<#T##<<error type>>#>, <#T##<<error type>>#>, <#T##<<error type>>#>)

// トレーリング クロージャ (= Trailing Closure)
closureTest(num1: 100, num2: 400) { (num1, num2) -> Int in
    num1 + num2 // return省略
}

 Trailing Closureとは?

関数の引数のうち 最後の引数がクロージャの場合、
クロージャを( )の外に書くことができる。

func testprint(str1: String, closure: (String) -> Void) {
    closure("僕の名前は\(str1)です。")
}

// トレーリングクロージャの場合 -> 美しい
testprint(str1: "玄邪 太郎") { string in
    print(string)   
}

// 通常のクロージャの場合 -> 可読性が悪い...
testprint(str1: "玄邪 太郎",{ string in
    print(string)   
})
  • クロージャが引数だと、{ }の外に( )を包まないといけないので、 可読性が悪くなる。(-> そこで、Trailing Closureが考案)

 クロージャの、基本的な性質2つ

  • ?クロージャーは関数の引数変数として使える
  • ?クロージャーは自分が定義されたスコープをキャプチャする

【Swift】クロージャの理解

 引数としてのクロージャ、利点?

  • コードが綺麗になる。
  • 呼び出し側で、処理が記述できる

呼び出され側は、クロージャに引数として値を渡し、
「値は渡すから、その値はそちらで好きに料理してね」という具合です。

class Foo {
    let val:Int = 10

    func testClosure(closure: (Int) -> Void) {
        closure(self.val) // self
    }
}

class Bar {
    let foo = Foo()

    // 引数の値を倍にする
    func twice() {
        foo.testClosure{ arg in print(arg * 2) } // arg = argument = 引数
    }

    // 引数の値を半分にする
    func half() {
        foo.testClosure{ arg in print(arg / 2) }
    }
}

let bar = Bar()
bar.twice()    // 20
bar.half() // 5

 クロージャによる、 変数と定数のキャプチャ?

  • ローカルスコープ(= scope_1)で定義された変数や定数は、
    ローカルスコープ内でしか使用できませんが、(= scope_2では使用不可)

  • クロージャが参照している変数や定数は、
    クロージャが実行されるスコープ(= scope_4)が
    変数や定数が定義されたローカルスコープ以外(= scope_3以外)であっても、
    クロージャの実行時に使用できます。

これは、クロージャが 自身の定義されたスコープ(= scope_3) の
 変数や定数への参照を保持している為で、この機能をキャプチャと言います。

class Foo {
    // scope_2関数は、普通の関数scope_1を2回実行しています。
    func scope_1() {
        var toto = 1
        toto += 1 // toto = toto + 1 と同義 (= 変数totoの値を更新)
        print(toto)
    }

    func scope_2() {
        scope_1()
        scope_1()
    }

    // scope_4関数は、scope_3関数から返されたクロージャを2回実行しています。
    func scope_3() -> () -> Void {
        var tete = 10
        let closure = { tete += 1
            print(tete)
        }
        return closure
    }

    func scope_4() {
        let tutu = self.scope_3()
        tutu()
        tutu()
    }
}

let test = Foo()
test.scope_2() // 2, 2
test.scope_4() // 11, 12

// scope_2関数は、普通の関数scope_1を2回実行しています。

普通の関数は、実行後はリセットされるので、
1回目の実行で「2」と表示されても、実行後ローカル変数totoの値は「1」に戻ります。

なので2回目の実行でも「2」と表示されます。

// scope_4関数は、scope_3関数から返されたクロージャを2回実行しています。

クロージャが、scope_3関数のローカル変数teteを参照しているので、
1回目の実行で「11」、2回目の実行では1回目の参照を保持しているので「12」となります。


 キャプチャとは?

 自身の定義されたスコープの変数や定数への、参照を「保持」する機能。
 クロージャ特有の機能。

 クロージャにて、self を使う理由

 明示的なselfには、循環参照 が存在しないよう確認を促す役割がある。

(Escaping Closuresは)循環参照を起こす危険性があるので、
(プログラマにそれを意識させるために)クロージャーの中で親スコープを強参照するときは、selfをつける。

selfを付けることが、循環参照を防ぐことに直結しているわけではなくて
コードの意図が明確になり、循環参照しないかにプログラマが意識を向けて書くようになる。

 おしまい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iOSのUIガイドライン Human Interface Guidelines を読んでみる part5

はじめに

これでいよいよ最終パートです。

今回はiOSのUIKitが提供するUIについてがメインです。

コントロール

ボタン

ボタンは、アプリ固有のアクションを開始し、カスタマイズ可能な背景があり、タイトルまたはアイコンを含めることができます。
システムには、ほとんどの使用例に対応する定義済みのボタンスタイルが多数用意されています。
完全にカスタムボタンをデザインすることもできます。

タイトルには動詞を使用する

アクション固有のタイトルは、ボタンがインタラクティブであることを示し、タップすると何が起こるかを示しています。

タイトルにはtitle-case(font)を使用します。

記事、調整語彙、4文字以下の前置詞を除くすべての単語を大文字にします。

タイトルは短く

テキストが長すぎると、インターフェースが混雑し、小さい画面では切り捨てられる場合があります。

必要な場合にのみ、境界線または背景を追加する

デフォルトでは、システムボタンには境界線や背景がありません。
ただし、一部のコンテンツ領域では、双方向性を示すために境界線または背景が必要です。
電話アプリでは、ボーダー付きの数字キーが電話をかけるという従来のモデルを強化し、[通話]ボタンの背景は、簡単にヒットできる目を引くターゲットを提供します。

※これはナビゲーションバーなどに当てはまりますが、コンテンツ内のボタンは影をつけたり押し感の分かるボタンが良いと思います。

カラーウェルズ

タップすると、カラーウェルにシステム提供のカラーピッカーが表示されます。
ユーザーはカラーピッカーを使用して、テキスト、図形、マーキングツール、およびその他の要素の色を選択できます。

開発者向けガイダンスについては、UIColorWellおよびUIColorPickerViewControllerを参照してください。

iPadメインなので割愛

コンテキストメニュー

iOS 13以降では、コンテキストメニューを使用して、インターフェイスを煩雑にすることなく、
画面上のアイテムに関連する追加機能にアクセスできます。

コンテキストメニューは、ピークとポップに似ていますが、2つの重要な違いがあります。

  • コンテキストメニューは、iOS 13以降を実行しているすべてのデバイスで使用できます。
    Peek and Popは、3D Touchをサポートするデバイスでのみ使用できます。

  • コンテキストメニューには、コンテキストに関連するコマンドがすぐに表示されます。
    ピークとポップでは、コマンドを表示するために上にスワイプする必要があります。

コンテキストメニューを表示するには、システム定義のタッチアンドホールドジェスチャーまたは3Dタッチを使用できます。

コンテキストメニューの利用に一貫性を持たせる

一部の場所ではアイテムのコンテキストメニューを提供し、他の場所では提供しない場合
機能をどこで使用できるかがユーザーは分からずに、アプリに問題があると思われる場合があります。

コンテキストメニューの各コマンドにグリフを含める

グリフ(画像でいう機能をイメージしたアイコン)はコマンドの意味を強調し、人々がその機能を即座に理解できるようにします。

MenuEdit

ユーザーは、テキストフィールド、テキストビュー、Webビュー、またはイメージビューの要素を押し続けるかダブルタップして、
コンテンツを選択し、コピーや貼り付けなどの編集オプションを表示できます。

割愛します。
詳細は
https://developer.apple.com/design/human-interface-guidelines/ios/controls/edit-menus/
UIMenuController

ラベル

ラベルは、画面上のインターフェイス要素を説明するか、短いメッセージを提供します。
ラベルを編集することはできませんが、ラベルの内容をコピーできる場合があります。

ラベルを読みやすく

ラベルには、プレーンテキストまたはスタイル付きテキストを含めることができます。
ラベルのスタイルを調整したり、カスタムフォントを使用したりする場合は、読みやすさを犠牲にしないでください。
ユーザーがデバイスでテキストサイズを変更してもラベルが適切に表示されるように、ダイナミックタイプを採用することをお勧めします。

※全般的に言えますが、ここで述べられていることは全年齢の全世界のiOSユーザーを想定していて、
AppleとしてのUI/UX向上の指針なのでもちろんプロダクトごとに良いものは違います。

ページコントロール

割愛します

ピッカー

ピッカーは、ユーザーが選択できる個別の値の1つ以上のスクロール可能なリストを表示できます。
iOS 14以降では、日付ピッカーは、カレンダービューでの日付の選択や、テンキーを使用した日付と時刻の入力など、
値を選択する追加の方法をサポートしています(ガイダンスについては、日付ピッカーを参照してください)。
どちらのタイプのピッカーでも、単一またはマルチパートの値を選択することにより、人々が情報を簡単に入力できるようにします。

ピッカーを使用して、中程度のリストに向いている

選択肢のかなり短いリストを表示する必要がある場合は、ピッカーの代わりにプルダウンメニューの使用を検討してください。
ピッカーを使用すると、多くの項目をすばやく簡単にスクロールできますが、項目の短いリストに視覚的な重みが追加されることがあります。
一方、非常に大きなアイテムのセットを提示する必要がある場合は、リストまたはテーブルの使用を検討してください。
リストとテーブルは高さを調整でき、テーブルにはインデックスを含めることができます。

予測可能で論理的に順序付けられた値

スクロール可能なリストが固定されている場合、ピッカーの多くの値が非表示になることがあります。
国のアルファベット順リストなど、ユーザーが非表示の値を予測できるようにして、アイテム間をすばやく移動できるようにするのが最適です。

画面を切り替えてピッカーを表示しない

ピッカーは、編集中のフィールドの下または近くにコンテキストで表示するとうまく機能します。
ピッカーは通常、画面の下部またはポップオーバーに表示されます。

開発者向けガイダンスについては、UIPickerViewを参照してください。

日付ピッカー

日付ピッカーは、タッチ、キーボード、またはポインティングデバイスを使用して、
特定の日付、時刻、またはその両方を選択するための効率的なインターフェイスです。
次のいずれかのスタイルで日付ピッカーを表示できます。

  • インライン—リストやテーブル行などの小さなスペースに収まり、展開して編集ビューを表示する編集可能なフィールド
  • コンパクト—展開してモーダルコンテキストで編集ビューを表示するラベル
  • ホイール—従来のスクロールホイールのセット

自動スタイルを選択して、システムが現在のプラットフォームと日付ピッカーモードを使用して適切な表示スタイルを決定することもできます。

■インラインピッカー

日付ピッカーには4つのモードがあり、それぞれに選択可能な値の異なるセットが表示されます。

  • 日付。月、日、年を表示します。
  • 時間。時間、分、および(オプションで)AM / PM指定を表示します。
  • 日時。日付、時間、分、および(オプションで)AM / PM指定を表示します。
  • カウントダウンタイマー。最大23時間59分までの時間と分を表示します。このモードはコンパクトスタイルでは使用できません。

日付ピッカーに表示される正確な値とその順序は、ユーザーのロケールによって異なります。

スペースが限られている場合は、コンパクトな日付ピッカーを検討

折りたたむと、コンパクトスタイルには、アプリのアクセントカラーで現在の値を示すボタンが表示されます。
ボタンをタップすると、日付ピッカーがモーダルビューに展開され、
使い慣れたカレンダースタイルのエディターと時間ピッカーにアクセスできます。
モーダルビュー内では、日付と時刻を複数回編集してから、ビューの外側をタップして選択を確認できます。

分を指定する場合は、粒度を低くする

デフォルトでは、分リストには60個の値(0〜59)が含まれています。
60分に均等に分割される限り、オプションで分間隔を増やすことができます。
たとえば、15分間隔(0、15、30、および45)が必要になる場合があります。

開発者向けガイダンスについては、UIDatePickerを参照してください。

進捗インジケーター

アプリがコンテンツをロードしたり、長時間のデータ処理操作を実行したりするのを待つ静的な画面を見つめている人を置かないでください。
アクティビティインジケーターとプログレスバーを使用して、アプリが停止していないことをユーザーに知らせ、待機時間を知らせます。

ロードも参照してください。

活動指標

複雑なデータの読み込みや同期などの定量化できないタスクが実行されている間、アクティビティインジケーターが回転します。
タスクが完了すると消えます。
アクティビティインジケータは非インタラクティブです。

※iOS標準のものもありますが、基本的には独自でViewをカスタムしてデザイナーさんのものに合わせるか
ライブラリで色々出ているのでそちらを使います。

タスクが完了するのを待つ間に役立つ情報を提供する

追加のコンテキストを提供するために、アクティビティインジケーターの上にラベルを含めます。
ロードや認証などのあいまいな用語は、通常は値を追加しないため、避けてください。

プログレスバー

進行状況バーには、左から右へと進むトラックが含まれており、期間がわかっているタスクの進行状況を示します。
プログレスバーは非インタラクティブですが、対応する操作をキャンセルするためのボタンが付いていることがよくあります。

ナビゲーションバーとツールバーのトラックの未入力部分を非表示に

デフォルトでは、プログレスバーのトラックには、塗りつぶされた部分と塗りつぶされていない部分の両方が含まれます。
ページの読み込みを示すなどのナビゲーションバーまたはツールバーで使用する場合、
進行状況バーを構成して、トラックの埋められていない部分を非表示にする必要があります。

アプリに合わせてプログレスバーの外観をカスタマイズする

プログレスバーの外観は、アプリのデザインに合わせて調整できます。
たとえば、トラックと塗りつぶしの両方にカスタムティントまたはイメージを指定できます。

プルダウンメニュー

iOS 14以降では、ボタンにプルダウンメニューを表示して、ユーザーが選択できる項目またはアクションを一覧表示できます。
プルダウンメニュー(または単にメニュー)を使用して、ボタンのアクションに直接関連するアイテムを提供したり、
現在のコンテキストで役立つアクションのリストを提供したりできます。

メニューには、アクションシート、コンテキストメニュー、ポップオーバーに比べていくつかの利点があります。

例えば

  • メニューが表示されるボタンのすぐ近くにメニューが開くので、メニューの項目と実行しているアクションの関係をすぐに理解できます。
  • メニューには、アクションのリストに加えて、ユーザーが主要なアクションに影響を与えるために使用できる選択を提供できます。
  • メニューはすばやくアニメーション表示され、表示されたときに画面を暗くすることがないため、移行と全体的なエクスペリエンスの両方に軽量感があります。

開発者向けガイダンスについては、UIMenuを参照してください。

すべてのアクションをメニューに配置しない

メニューを使用すると、インターフェースを煩雑にすることなくさまざまなアイテムを提供できますが、
すべてのアクションをメニューに配置することは、ユーザーが何かをするために少なくとも2回タップする必要があることを意味します。
メインインターフェイスに最も重要なアクションを配置し続け、メニューを使用して補足アイテムを提供します。
たとえば、新しいメッセージの作成は、人々がメッセージで行う最も一般的なアクションであるため、
[作成]ボタンはメインインターフェイスで目立つように機能しています。
ユーザーに便利な編集オプションのセットを提供するために、
メッセージはメインインターフェイスにオプションを表示する代わりに、[編集]ボタンにメニューを添付します。

セパレータを使用して、関連するメニュー項目を視覚的にグループ化する

視覚的なグループを作成すると、ユーザーがメニューをすばやくスキャンできるようになります。
たとえば、ファイルアプリの[その他]メニューでは、区切り記号を使用して、
コンテンツに影響を与えるアクションと表示や並べ替えに関連するアイテムを区別できるようにしています。
メニューで4つ以上のグループを使用すると、解析が困難に見える場合があります。

意味がある場合は、メニュータイトルを表示

アクションを実行するためにボタンをタップするとメニューが即座に表示されるため、
ほとんどの場合、人々はメニューのアイテムのコンテキストを理解します。
必要に応じて、メニューの上部に表示する簡潔なタイトルを指定できます。

コンテンツコントロールの更新

リフレッシュコントロールは手動で開始され、次の自動コンテンツ更新の発生を待たずに、
通常はテーブルビューでコンテンツをすぐに再読み込みします。
更新コントロールは特殊なタイプのアクティビティインジケーターであり、
デフォルトでは非表示になっており、再読み込みするビューを下にドラッグすると表示されます。

自動コンテンツ更新を実行

人々はすぐにコンテンツの更新をトリガーできることを高く評価していますが、
自動更新が定期的に行われることも期待しています。
すべての更新を開始する責任をユーザーに与えないでください。

付加価値がある場合にのみ、短いタイトルを入力してください

オプションで、更新コントロールにタイトルを含めることができます。
コントロールのアニメーションがコンテンツの読み込みを示しているため、ほとんどの場合、これは不要です。
タイトルを含めた場合、それを使用して更新を実行する方法を説明しないでください。
代わりに、更新されるコンテンツに関する価値のある情報を提供します。
たとえば、ポッドキャストの更新コントロールでは、タイトルを使用して、ポッドキャストの最後の更新がいつ行われたかをユーザーに知らせます。

開発者向けガイダンスについては、UIRefreshControlを参照してください。

セグメントコントロール

セグメントコントロールは、2つ以上のセグメントの線形セットであり、それぞれが相互に排他的なボタンとして機能します。
コントロール内では、すべてのセグメントの幅が同じです。
ボタンと同様に、セグメントにはテキストや画像を含めることができます。
セグメントコントロールは、さまざまなビューを表示するためによく使用されます。

使いやすさを向上させるために、セグメントの数を制限する

幅の広いセグメントほどタップが簡単です。
iPhoneでは、セグメントコントロールは5つ以下のセグメントを持つ必要があります。

セグメントコンテンツのサイズを一定に保つ

すべてのセグメントの幅が等しくないと見栄えがよくありません。

セグメントコントロールでテキストと画像を同時に使わない

個々のセグメントにはテキストまたは画像を含めることができますが、2つを1つのコントロールに混在させると、
インターフェースが切断されて混乱する可能性があります。

スライダー

スライダーは、コントロール付きの水平トラックであり、指でスライドして、
メディアの再生中の画面の明るさのレベルや位置などの最小値と最大値の間を移動できます。
スライダーの値が変化すると、最小値とつまみの間のトラック部分が色で塗りつぶされます。
スライダーは、最小値と最大値の意味を示す左と右のアイコンをオプションで表示できます。

開発者向けガイダンスについては、 UISliderを参照してください。

ステッパー

ステッパーは、増分値を増減するために使用される2セグメントコントロールです。
デフォルトでは、ステッパーの1つのセグメントにプラス記号が表示され、もう1つのセグメントにマイナス記号が表示されます。
これらのシンボルは、必要に応じてカスタムイメージに置き換えることができます。

ステッパーの影響を受ける値を明確にします。

ステッパー自体には値が表示されないため、ステッパーを使用するときに変更する値をユーザーに知らせてください。

大きな値の変更が予想される場合は、ステッパーを使用しない

ステッパーは、数回のタップを必要とする小さな変更を加えるのに適しています。
たとえば、印刷画面では、ステッパーを使用して部数を設定することは理にかなっています。
これは、この設定をあまり変更しないためです。
一方、妥当なページ範囲でも多くのタップが必要になるため、ステッパーを使用してページ範囲を選択することは意味がありません。

開発者向けガイダンスについては、UIStepperを参照してください。

スイッチ

スイッチは、2つの相互に排他的な状態(オンとオフ)を視覚的に切り替えます。

アプリのスタイルに合わせてスイッチに色を付けることを検討する

アプリで問題なく機能する場合は、スイッチの色をオンとオフの状態で変更できます。

テーブルの行でのみスイッチを使用する

スイッチは、オンとオフを切り替えることができる設定のリストなどのテーブルで使用するためのものです。
ツールバーまたはナビゲーションバーで同様の機能が必要な場合は、代わりにボタンを使用し、状態を伝える2つの異なるアイコンを利用します。

スイッチの値を説明するラベルを追加しない

スイッチはオンまたはオフです。これらの状態を説明するラベルを提供することは冗長であり、インターフェースが煩雑になります。

テキストフィールド

テキストフィールドは、高さが1行の固定高さのフィールドで、多くの場合、角が丸められており、
ユーザーがタップするとキーボードが自動的に表示されます。
テキストフィールドを使用して、メールアドレスなどの少量の情報をリクエストします。

必要に応じて、セキュリティで保護されたテキストフィールドを使用

アプリがパスワードなどの機密データを要求する場合は、常に安全なテキストフィールドを使用してください。

画像とボタンを使用して、テキストフィールドに明確さと機能を提供する

テキストフィールドの左側または右側にカスタム画像を表示したり、ブックマークボタンなどのシステム提供のボタンを追加したりできます。通常、テキストフィールドの左端を使用してフィールドの目的を示し、右端を使用してブックマークなどの追加機能の存在を示します。

開発者向けガイダンスについては、UITextFieldを参照してください。

キーボード

適切なキーボードタイプを表示します。iOSはいくつかの異なるキーボードタイプを提供し、

それぞれが異なるタイプの入力を容易にするように設計されています。
データ入力を効率化するには、テキストフィールドの編集時に表示されるキーボードが、
フィールドのコンテンツのタイプに適している必要があります。
使用可能なキーボードタイプの完全なリストについては、UIKeyboardTypeの一定のUITextInputTraitsを。

■メールキーボード

■電話キーボード

関連するガイダンスについては、「カスタムキーボード」を参照してください。

カスタムキーボード

標準キーボードを置き換えるキーボード拡張を作成することにより、カスタムキーボードを提供できます。
ユーザーが[設定]でカスタムキーボードを有効にすると、
セキュリティで保護されたテキストフィールドと電話番号フィールドを編集する場合を除いて、アプリ内のテキスト入力にそれを使用できます。
ユーザーは複数のカスタムキーボードを有効にして、いつでも切り替えることができます。

カスタムキーボードが本当に必要かどうかを確認

カスタムキーボードは、テキストを入力する新しい方法やiOSでサポートされていない言語で入力する機能など、
システム全体に固有のキーボード機能を公開する場合に適しています。
アプリ内でのみ使用できるカスタムキーボードを提供する場合は、代わりにカスタム入力ビューを作成することを検討してください。

カスタム入力ビュー
カスタム入力ビューは、標準キーボードをカスタムキーボードに置き換えますが、システム全体ではなく、アプリ内のみです。カスタム入力ビューを使用して、独自の効率的なデータ入力方法を提供します。たとえば、数値は、スプレッドシートの編集中に数値を入力するためのカスタム入力ビューを実装します。

開発者向けガイダンスについては、カスタムキーボードの作成を参照してください。

入力中に標準のキーボードクリック音が鳴る

入力ビューでカスタムコントロールをタップすると、標準サウンドが生成されます。
このサウンドは、表示されているカスタム入力ビューでのみ使用でき、
ユーザーは[設定]> [サウンド]でシステム全体のサウンドを無効にできることに注意してください。
開発者向けガイダンスについては、UIDeviceのplayInputClickメソッドを参照してください。

システム機能

評価とレビュー

評価とレビューは、アプリを試してみるかどうかを検討する際に、情報に基づいた決定を行うのに役立ちます。
肯定的な評価とレビューは、アプリのダウンロードが増えることを意味します。
顧客からのフィードバックにより、実際の使用状況についての洞察が得られ、将来の開発作業に役立ちます。

優れた全体的なエクスペリエンスを提供することは、肯定的な評価とレビューを促進するための最良の方法ですが、
適切なタイミングでフィードバックを求めることも重要です。
アプリを評価するようユーザーに求めるときは、これらの考慮事項に留意してください。

ユーザーがアプリへのエンゲージメントを示した後にのみ、評価を求める

たとえば、ゲームレベルや生産性タスクの完了時にユーザーにプロンプ​​トを表示します。
初回起動時またはオンボーディング中に評価を要求しないでください。意見を述べるのに十分な時間を見込んでください。

特に時間に敏感な、またはストレスの多いタスクを実行しているときはユーザーを邪魔しない

評価リクエストが最も意味のある論理的な一時停止または停止ポイントを探します。

害虫にならないで

評価のプロンプトが繰り返されるとイライラするだけでなく、ユーザーのアプリに対する意見に悪影響を与えることさえあります。
レーティングリクエストの間隔は少なくとも1〜2週間とし、
ユーザーがアプリでさらにエンゲージメントを示した後にのみプロンプトを表示します。
システムは、プロンプトの表示を365日の期間内にアプリごとに3回まで自動的に制限します。

最後に

長々と書いてきましたが、これで終わりになります。

色々調べている中で、参考になった言葉がありまして、

  • 開発で大事なことはプラットフォームを知ることで、そのためにUIガイドラインを読む。

です。

これを知ってからiOSというプラットフォームを知るためにも

Human Interface Guidelinesを読むことが大事なのだと思っています。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iOSのUIガイドライン Human Interface Guidelines を読んでみる part4

バー

ナビゲーションバー

ナビゲーションバーは、アプリ画面の上部、ステータスバーの下に表示され、一連の階層画面をナビゲートできます。
新しい画面が表示されると、前の画面のタイトルが付けられた戻るボタンがバーの左側に表示されます。
場合によっては、ナビゲーションバーの右側に、
アクティブなビュー内のコンテンツを管理するための[編集]ボタンや[完了]ボタンなどのコントロールが含まれています。
分割ビューでは、分割バーの1つのペインにナビゲーションバーが表示される場合があります。
ナビゲーションバーは半透明で、背景の色合いがあり、キーボードが画面上にあるとき、ジェスチャーが発生したとき、またはビューのサイズが変更されたときに非表示になるように構成できます。

全画面コンテンツを表示するときは、ナビゲーションバーを一時的に非表示にすることを検討する

コンテンツに集中したい場合、ナビゲーションバーが邪魔になることがあります。
バーを一時的に非表示にして、より没入型のエクスペリエンスを提供します。
写真は、フルスクリーンの写真を表示するときに、ナビゲーションバーやその他のインターフェイス要素を非表示にします。
このタイプの動作を実装する場合、タップなどの簡単なジェスチャーでナビゲーションバーを復元できるようにします。

開発者向けガイダンスについては、UINavigationBarを参照してください。

ナビゲーションバーのタイトル

ナビゲーションバーに現在のビューのタイトルを表示することを検討してください。
ほとんどの場合、タイトルは人々が自分が見ているものを理解するのに役立ちます。
ただし、ナビゲーションバーにタイトルを付けるのが冗長に思われる場合は、タイトルを空白のままにすることができます。
たとえば、コンテンツの最初の行は必要なすべてのコンテキストを提供するため、メモアプリは現在のノートにタイトルを付けません。

■標準タイトル

■大きなタイトル

コンテキストを特に強調したい場合は、大きなタイトルを使用

大きなタイトルはコンテンツと競合するべきではありませんが、
一部のアプリでは、大きなタイトルの大きくて太字のテキストが、ユーザーが閲覧および検索する際の方向付けに役立ちます。
たとえば、タブ付きレイアウトでは、大きなタイトルはアクティブなタブを明確にし、
ユーザーがいつ一番上までスクロールしたかを示すのに役立ちます。
電話アプリはこのアプローチを使用していますが、
ミュージックは大きなタイトルを使用して、アルバム、アーティスト、プレイリスト、ラジオなどのコンテンツ領域を区別しています。
iOS 13以降では、大きなタイトルナビゲーションバーには、デフォルトで背景素材や影が含まれていません。
また、大きなタイトルは、コンテンツをスクロールし始めると標準のタイトルに変わります。
開発者向けガイダンスについては、prefersLargeTitlesを参照してください。

大きなタイトルのナビゲーションバーの境界線を非表示にする

iOS 13以降では、バーの影を取り除くことで、ナビゲーションバーの下の境界線を非表示にできます。
(ユーザーがコンテンツ領域をスクロールすると、境界線は自動的に再表示されます)。
ボーダレススタイルは、タイトルとコンテンツのつながりを強化するため、大きなタイトルのナビゲーションバーでうまく機能します。
ただし、標準のタイトルのナビゲーションバーでは、ボーダーレススタイルはうまく機能しない可能性があります。
バーのタイトルとボタンを区別するのが難しい場合があるためです。
これの例外は、iPadの分割ビューです。
両方でボーダーレススタイルを使用して、プライマリビューとセカンダリビューの一貫性を維持することができます。

ナビゲーションバーコントロール

コントロールの数が多すぎるナビゲーションバーを混雑させないようにします。
一般に、ナビゲーションバーには、ビューの現在のタイトル、戻るボタン、およびビューのコンテンツを管理する1つで十分です。
ナビゲーションバーでセグメント化されたコントロールを使用する場合、
バーにはタイトルやセグメント化されたコントロール以外のコントロールを含めないでください。

標準の戻るボタン

標準の戻るボタンを使用すると、情報の階層をたどってステップをたどることができます。
ただし、カスタムの戻るボタンを実装する場合は、

  • 戻るボタンのように見え
  • 直感的に動作し
  • 他のインターフェースと一致し
  • アプリ全体に一貫して実装されていること

を確認してください。
システム提供の戻るボタンシェブロンをカスタムイメージに置き換える場合は、カスタムマスクイメージも指定してください。
iOSはこのマスクを使用して、遷移中にボタンのタイトルをアニメーション化します。

複数セグメントのパンくずリストを含めないでください。

戻るボタンは常に単一のアクションを実行し、前の画面に戻ります。
現在の画面への完全なパスがないと人々が迷子になる可能性があると思われる場合は、
アプリの階層をフラット化することを検討してください。

テキスト付きのボタンに十分なスペースを与えます。

ナビゲーションバーに複数のテキストボタンが含まれている場合、
間隔がないとボタンが区別しにくくなることがあります。
ボタンの間に固定スペースアイテムを挿入して、分離を追加します。
開発者のガイダンスについては、参照UIBarButtonSystemItemFixedSpaceのではUIBarButtonItemを参照してください。

ナビゲーションバーでセグメント化されたコントロールを使用して、アプリの情報階層を平坦化することを検討してください。

ナビゲーションバーでセグメント化されたコントロールを使用する場合は、階層の最上位レベルでのみ使用し、
下位レベルで正確な戻るボタンのタイトルを選択してください。
追加のガイダンスについては、「セグメント化されたコントロール」を参照してください。

※こちらはあまり最近のアプリで利用されていることを見ない気がします。
基本的にはタイトルや戻るボタンのあるナビゲーションバーが最上位にあるイメージです。
タブで階層が深くない場合はこういうのも良いのでしょうか。

検索バー

検索バーを使用すると、フィールドにテキストを入力して、値の大きなコレクションを検索できます。
検索バーは、単独で、またはナビゲーションバーやコンテンツビューに表示できます。

検索を実装するには、テキストフィールドの代わりに検索バーを使用

テキストフィールドには、ユーザーが期待する標準の検索バーの外観がありません。

[クリア]ボタンを有効に

ほとんどの検索バーには、フィールドの内容を消去する[クリア]ボタンが含まれています。

必要に応じて[キャンセル]ボタンを有効に

ほとんどの専用検索バーには、検索をすぐに終了する[キャンセル]ボタンがあります。

必要に応じて、検索バーにヒントを

検索バーのフィールドには、検索対象を思い出させるために、
「衣類、靴、アクセサリーの検索」または単に「検索」などのプレースホルダーテキストを含めることができます。

検索バーの下に便利なショートカットやその他のコンテンツを提供することを検討

検索バーの下の領域を使用すると、コンテンツにすばやくアクセスできます。
たとえばSafariでは、検索フィールドをタップするとすぐにブックマークが表示されます。
いずれかを選択すると、検索語句を入力せずにその場所に移動します。

いわゆる絞り込みであったり良くあるものを素早くアクセスさせてUXを良くするってことですよね。
開発者向けガイダンスについては、UISearchControllerおよびUISearchBarを参照してください。

自分UISearchController使ったことないので勉強してみよう。

スコープバー

スコープバーを検索バーに追加すると、検索の範囲を絞り込むことができます。

サイドバー

サイドバーは、アプリレベルのナビゲーションと、アプリ内のコンテンツのトップレベルコレクションへのクイックアクセスを提供します。
サイドバーの項目を選択すると、特定のコンテンツに移動できます。

サイドバーに正しい外観を適用する

サイドバーを作成するには、コレクションビューリストレイアウトのサイドバーの外観を使用します。
開発者向けガイダンスについては、UICollectionLayoutListConfiguration.Appearanceを参照してください。

サイドバーを隠せるようにしてください

ユーザーがサイドバーを非表示にしてコンテンツのスペースを増やし、組み込みのエッジスワイプジェスチャーを使用して
サイドバーを再度表示できるようにします。
デフォルトでサイドバーを非表示にしないでください。

サイドバーのタイトルは明確かつ簡潔にしてください。

不要で冗長な単語は省略します。

一般に、サイドバー内で2レベルを超える階層を公開しない

データ階層が2レベルよりも深い場合は、分割ビューインターフェイスの補足列でリストビューを使用します。
開発者向けガイダンスについては、UICollectionLayoutListConfigurationを参照してください。

ステータスバー

ステータスバーは画面の上端に沿って表示され、時間、携帯通信会社、バッテリーレベルなど、
デバイスの現在の状態に関する有用な情報を表示します。
ステータスバーに表示される実際の情報は、デバイスとシステム構成によって異なります。

システム提供のステータスバーを使用します。
ステータスバーがシステム全体で一貫していることを期待しています。
カスタムステータスバーに置き換えないでください。

ステータスバーの下にある不明瞭なコンテンツ

デフォルトでは、ステータスバーの背景は透明で、下のコンテンツが透けて見えます。
ステータスバーを読みやすくし、その背後にあるコンテンツがインタラクティブであることを示唆しないでください。
これを行うには、いくつかの一般的な手法があります。

  • アプリのナビゲーションバーを使用すると、ステータスバーの背景が自動的に表示され、
    コンテンツがステータスバーの下に表示されなくなります。

  • ステータスバーの背後に、グラデーションや単色などのカスタム画像を表示します。

  • ステータスバーの後ろにぼかしたビューを配置します。

開発者向けガイダンスについては、UIBlurEffectを参照してください。

フルスクリーンメディアを表示するときは、ステータスバーを一時的に非表示にすることを検討してください。

ユーザーがメディアに集中しようとすると、ステータスバーが邪魔になることがあります。
これらの要素を一時的に非表示にして、より没入型のエクスペリエンスを提供します。
たとえば、写真アプリでは、ユーザーが全画面の写真を閲覧すると、ステータスバーやその他のインターフェイス要素が非表示になります。

タブバー

アプリ画面の下部にタブバーが表示され、アプリのさまざまなセクションをすばやく切り替えることができます。
タブバーは半透明で、背景の色合いがあり、すべての画面方向で同じ高さを維持し、キーボードが表示されているときは非表示になっています。
タブバーには任意の数のタブを含めることができますが、表示されるタブの数はデバイスのサイズと向きによって異なります。
水平方向のスペースが限られているために一部のタブを表示できない場合、最後に表示されるタブは[追加]タブになり、別の画面のリストに追加のタブが表示されます。

タブバーを使用して、アクセスを容易に

タブバーは、情報階層を平坦化し、複数のピア情報カテゴリまたはモードへのアクセスを一度に提供するための良い方法です。

ナビゲーションを目的としてタブバーを使用する

アクションを実行するためにタブバーボタンを使用しないでください。
現在のビューの要素に作用するコントロールを提供する必要がある場合は、代わりにツールバーを使用してください。

タブが多すぎないように

タブを追加するたびに、タブを選択するためのタップ可能な領域が減り、アプリの複雑さが増し、情報の検索が難しくなります。
[その他]タブでは追加のタブを表示できますが、これにはタップの回数が増え、スペースの使用率が低くなります。
必須のタブのみを含め、情報階層に必要な最小限のタブを使用してください。
タブが少なすぎると、インターフェースが切断されたように見えるため、問題になる可能性があります。
一般的に、iPhoneでは3〜5個のタブを使用します。iPadでは、さらにいくつかを使用できます。

アプリ内の別の領域に移動するときにタブバーを非表示にしないでください。

タブバーはアプリのグローバルナビゲーションを有効にするため、どこにでも表示されたままにする必要があります。
これの例外は、モーダルビューです。
モーダルビューは、終了時にユーザーが閉じる別のエクスペリエンスを提供するため、アプリの全体的なナビゲーションの一部ではありません。

機能が利用できないときは、タブを削除したり無効にしたりしないでください

タブが使用可能な場合とそうでない場合がある場合、アプリのインターフェースは不安定になり、予測できなくなります。
すべてのタブが常に有効になっていることを確認し、タブのコンテンツが使用できない理由を説明します。

※例えばコンテンツが使えない場合は「データがありません」などの使用できない理由のラベルがのったビューを表示させるなど。

バッジを使用する

新しい情報がそのビューまたはモードに関連付けられていることを示すために、
バッジ(白いテキストと数字または感嘆符のいずれかを含む赤い楕円)をタブに表示できます。

ツールバー

ツールバーはアプリ画面の下部に表示され、
現在のビューまたはその中のコンテンツに関連するアクションを実行するためのボタンが含まれています。
ツールバーは半透明で、背景の色合いがあり、多くの場合、ユーザーが必要としない場合は非表示になります。
たとえば、Safariでは、ページをスクロールし始めると、読んでいる可能性が高いため、ツールバーが非表示になります。

アイコンまたはテキストタイトルのボタンがアプリに適しているかどうか

4つ以上のツールバーボタンが必要な場合、アイコンは適切に機能します。
ボタンが3つ以下の場合、テキストがより鮮明になることがあります。

テキスト付きのボタンに十分なスペースを持たせる

ツールバーに複数のボタンが含まれている場合、
それらのボタンのテキストが一緒に実行されているように見えて、ボタンを区別できなくなる場合があります。
ボタン間に固定スペースを挿入して、分離を追加します。
開発者のガイダンスについては、UIBarButtonSystemItemFixedSpaceを参照してください。

アクションシート

アクションシートは、コントロールまたはアクションに応答して表示される特定のスタイルのアラートであり、
現在のコンテキストに関連する2つ以上の選択肢のセットを提示します。
アクションシートを使用して、タスクを開始したり、キャンセルのような操作を実行する前に確認を要求したりできます。
小さい画面では、アクションシートが画面の下から上にスライドします。
大きな画面では、アクションシートがポップオーバーとして一度に表示されます。

わかりやすくする場合は、[キャンセル]ボタンを提供する

[キャンセル]ボタンは、ユーザーがタスクを放棄しているときに自信を与えます。
キャンセルボタンは、常に画面下部のアクションシートに含める必要があります。

破壊的な選択を目立たせます。

破壊的または危険なアクションを実行するボタンには赤を使用し、アクションシートの上部にこれらのボタンを表示します。

アクションシートでスクロールを有効にしない

アクションシートのオプションが多すぎる場合、人々はスクロールしてすべての選択肢を見る必要があります。
スクロールは、選択を行うために余分な時間を必要とし、不注意でボタンをタップしてしまうかもしれないので有効にしないでください。

アラート

アラートは、重要な情報を伝え、多くの場合フィードバックを要求します。
アラートは、タイトル、メッセージ、1つ以上のボタン、および入力を収集するためのオプションのテキストフィールドで構成されます。
これらの構成可能な要素を除いて、アラートの視覚的な外観は静的であり、カスタマイズできません。

アラートを最小限に抑える

アラートはユーザーエクスペリエンスを混乱させるため、購入の確認や破壊的なアクション(削除など)、
または問題の通知などの重要な状況でのみ使用する必要があります。
頻度の低いアラートは、人々がアラートを真剣に受け止めるのに役立ちます。

両方の方向でアラートの外観をテスト

アラートは、横長モードと縦長モードで異なって表示される場合があります。
アラートテキストを最適化して、スクロールせずにどの方向でも読みやすくします。

開発者向けガイダンスについては、UIAlertControllerを参照してください。

アラートのタイトルとメッセージ

短く説明的なマルチワードのアラートタイトルを作成します。

画面上で読む必要があるテキストが少なければ少ないほど良いです。
質問するか短い文章を使用することを検討してください。
タイトルは可能な限り1行にしてください。
タイトルが完全な文である場合は、文スタイルの大文字と適切な末尾の句読点を使用します。
タイトルが文の断片である場合は、タイトルスタイルの大文字を使用し、末尾に句読点を追加しないでください。

メッセージを提供する必要がある場合は、短く

スクロールしないように、メッセージを1行または2行に収まるように短くしてください。

非難、批判的、または侮辱的な発言は避ける

アラートは問題や危険な状況について通知することを知っています。
親しみのある口調を使うよりネガティブでダイレクトな方がいいです。
ただし、あなた、あなた、私、私のような代名詞は避けてください。

警告ボタン

最大2つのボタンのアラートを使用する

2ボタンのアラートにより、2つの選択肢から簡単に選択できます。
ボタン1つでアラートが通知されますが、状況を制御できません。
3つ以上のボタンを持つアラートは複雑になり、スクロールが必要になる場合があります。
これはユーザーエクスペリエンスの低下です。
3つ以上の選択肢が必要な場合は、代わりにアクションシートの使用を検討してください。

警告ボタンに簡潔なタイトルを

最適なボタンのタイトルは、ボタンを選択した結果を説明する単語で構成されます。
すべてのボタンタイトルと同様に、タイトルスタイルの大文字を使用し、句読点を使わないでください。
可能な限り、アラートのタイトルとメッセージに直接関連する動詞と動詞句を使用します(たとえば、すべて表示、返信、または無視)。
OKを使用して単純に受け入れます。
はいといいえの使用は避けてください。

人々が期待する場所にボタンを配置します。

一般的に、人々がタップする可能性が最も高いボタンは右側にある必要があります。
キャンセルボタンは常に左側にある必要があります。
キャンセルボタンに適切にラベルを付けます。
アラートのアクションをキャンセルするボタンには、常に「キャンセル」というラベルを付ける必要があります。

破壊的なボタンを定義する

アラートボタンの結果、コンテンツの削除などの破壊的なアクションが発生する場合は、
ボタンのスタイルをDestructiveに設定して、システムが適切なフォーマットを取得できるようにします。
開発者のガイダンスについては、UIAlertActionStyleDestructiveの定数UIAlertActionを参照してください。

ホーム画面に戻って、アラートをキャンセルできるようにします。アラートが表示されているときにホーム画面にアクセスすると、アプリが終了します。また、[キャンセル]ボタンをタップするのと同じ効果が得られるはずです。つまり、アラートはアクションを実行せずに閉じられます。アラートに[キャンセル]ボタンがない場合は、誰かがアプリを終了したときに実行されるキャンセルアクションをコードに実装することを検討してください。

コレクション(ビュー)

コレクションは、一連の写真などのコンテンツの順序付けされたセットを管理し、
カスタマイズ可能な高度に視覚的なレイアウトで表示します。
コレクションは厳密な線形形式を強制しないため、サイズの異なるアイテムを表示するのに特に適しています。
一般的に言えば、コレクションは画像ベースのコンテンツを表示するために理想的です。
オプションで背景やその他の装飾ビューを実装して、アイテムのサブセットを視覚的に区別できます。

コレクション(ビュー)は対話性とアニメーションの両方をサポートする

デフォルトでは、タップして選択したり、押し続けて編集したり、スワイプしてスクロールしたりできます。
アプリで必要な場合は、カスタムアクションを実行するためのジェスチャーをさらに追加できます。
コレクション内では、アイテムが挿入、削除、または並べ替えられるたびにアニメーションを有効にできます。

標準の行またはグリッドレイアウトで十分な場合は、根本的な新しいデザインを作成しない

コレクションはユーザーエクスペリエンスを向上させるものであり、注目の的になるものではありません。
アイテムを選択しやすくします。
コレクション内のアイテムをタップするのが難しい場合、ユーザーは不満をもち、目的のコンテンツに到達する前に興味を失います。
コンテンツの周りに適切なパディングを使用して、レイアウトをきれいに保ち、コンテンツの重複を防ぎます。

テキストのコレクションではなくテーブルの使用を検討する

スクロール可能なリストに表示されている場合、テキスト情報を表示して要約する方が一般的には簡単で効率的です。

動的なレイアウト変更を行うときは注意

コレクションのレイアウトはいつでも変更できます。
人々がそれを表示して操作しているときにレイアウトを動的に変更する場合は、変更が意味をなし、追跡が容易であることを確認してください。

ページ

ページビューコントローラーは、ドキュメント、ブック、メモ帳、カレンダーなど
コンテンツのページ間の線形ナビゲーションを実装する方法を提供します。
ページビューコントローラーは、2つのスタイルの1つを使用して、
ナビゲーション中のページ間の遷移(スクロールまたはページカール)を管理します。
スクロール遷移には特定の外観はありません。
ページは次から次へとスムーズにスクロールします。
ページカールの遷移により、画面をスワイプすると、ページがカールして、物理的な本のページのようにめくります。

■ページカール

ポップオーバー

ポップオーバーは、コントロールまたは領域をタップしたときに画面上の他のコンテンツの上に表示される一時的なビューです。
通常、ポップオーバーには、それが出現した場所を指す矢印が含まれています。
ポップオーバーは非モーダルまたはモーダルにすることができます。
非モーダルポップオーバーは、画面の別の部分またはポップオーバーのボタンをタップすることによって閉じられます。
モーダルポップオーバーは、ポップオーバーの[キャンセル]または他のボタンをタップすることによって閉じられます。

iPhoneでは使用しない

通常、ポップオーバーはiPadアプリで使用するために予約する必要があります。
iPhoneアプリでは、ポップオーバーではなく全画面のモーダルビューで情報を表示することにより、
利用可能なすべての画面スペースを利用します。

スクロールビュー

スクロールビューを使用すると、ドキュメント内のテキストや画像のコレクションなど、
表示領域よりも大きなコンテンツを閲覧できます。
人々がスワイプ、フリック、ドラッグ、タップ、ピンチすると、スクロールビューがジェスチャーに追従し、
自然な方法でコンテンツを表示またはズームします。
スクロールビュー自体には外観はありませんが、ユーザーが操作するときに一時的なスクロールインジケーターが表示されます。
スクロールビューは、ページングモードで動作するように構成することもできます。
スクロールすると、現在のページを移動するのではなく、コンテンツのまったく新しいページが表示されます。

スクロールビューを別のスクロールビュー内に配置しない

これを行うと、制御が困難な予測不可能なインターフェースが作成されます。

一度に1つのスクロールビューを表示

人々はスクロール時に大きなスワイプジェスチャーを行うことが多く、
同じ画面上の隣接するスクロールビューとの対話を避けるのが難しい場合があります。
1つの画面に2つのスクロールビューを配置する必要がある場合は、1つのジェスチャーが両方のビューに影響する可能性が低くなるように、
スクロールビューを異なる方向にスクロールできるようにすることを検討してください。

テーブル(ビュー)

テーブル(ビュー)は、セクションまたはグループに分割できる、スクロールする単一列リストです。
一般的に、テーブルはテキストベースのコンテンツに最適であり、関連するコンテンツが反対側に表示された状態で、
分割ビューの片側にナビゲーション手段として表示されることがよくあります。

iOSは
- プレーン
- グループ化
- インセットグループ化

の3つのスタイルのテーブルを提供します。

プレーン

行はラベル付きセクションに分割でき、
セクションの最初の項目の前にヘッダーを表示でき、最後の項目の後にフッターを表示できます。

グループ化

行はグループで表示され、ヘッダーの前にフッターを付けることができます。
このスタイルのテーブルには常に少なくとも1つのグループが含まれ、各グループには常に少なくとも1つの行が含まれます。

インセットグループ

行は、角が丸く、親ビューの端からはめ込まれたグループで表示されます。
構成はグループ化と同じ特性を持ち合わせています。
インセットのグループ化されたスタイルは、通常の幅の環境で最適に機能します。

テーブルのコンテンツが素早く表示される

画面上の行にテキストデータをすぐに入力し、画像などのより複雑なデータが利用可能になったら表示します。
これによって人々にすぐに役立つ情報を提供し、アプリの知覚される応答性を高めます。

コンテンツの読み込み時に進行状況を伝えます。テーブルのデータの読み込みに時間がかかる場合は、進行状況バーまたは回転アクティビティインジケーターを表示して、アプリがまだ実行中であることをユーザーに知らせます。

コンテンツを最新の状態に

新しいデータを反映するために、テーブルのコンテンツを定期的に更新することを検討してください。
スクロール位置は勝手に変更してはいけないです。
代わりに、コンテンツをテーブルの最初または最後に追加し、準備ができたらスクロールできるようにします。

テーブルセル

基本的に4種類のスタイルが用意されています。

  • Basic (Default)
  • Subtitle
  • Right Detail (Value 1)
  • Left Detail (Value 2)

詳しくはhttps://developer.apple.com/design/human-interface-guidelines/ios/views/tables/

選択時のフィードバック

コンテンツがタップされたときに、行が短時間ハイライト表示されることを期待しています。
次に、選択が行われたことを示すチェックマークが表示されるなど、新しいビューが表示されるか何かが変更されることを期待します。

Webビュー

Webビューは、埋め込みHTMLやWebサイトなどのリッチWebコンテンツをアプリ内に直接ロードして表示します。
例えば、メールアプリはWebビューを使用して、メッセージにHTMLコンテンツを表示します。

Webビューのみでアプリを構築しない

Webビューを使用して、アプリのコンテキストを離れることなくWebサイトに簡単にアクセスできるようにすることは問題ありませんが、
iOSでWebを閲覧する主な方法はSafariです。
Safariの機能をアプリに複製することは不要であり、お勧めできません。

最後に

part5へ続く...

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iOSアプリケーションのクラッシュログを見つける方法とiOSのクラッシュログをシンボル化する方法

概要

あなたはXcodeに接続せずに携帯電話でアプリケーションをテストしていますか?あなたはAppleに対してバグレポートを提出していて、Appleはクラッシュログを要求しましたか?この記事では、クラッシュログをフェッチする方法をいくつかご紹介します。

1) お使いのデバイスをXcodeに接続してデバッグする(インタラクティブ)
2) お使いのコンピューター上のクラッシュログにアクセスする(シンボル化)
3) お使いのデバイス上のクラッシュログにアクセスする(シンボル化されていない)

この記事でもシンボル化されたクラッシュログの解析方法について説明します。

シンボル化されたクラッシュログは、クラッシュの原因となった特定のコードを表示します。

App Storeのレビュー担当から提供されたログファイルを使用し、クラッシュが発生した場所を把握するときに重要となります。

4) Xcodeでクラッシュログをシンボル化する
5) symbolicatecrash ツールでクラッシュログをシンボル化する
6) atos ツールでクラッシュログをシンボル化する

既にApp Storeで公開されているアプリケーションのクラッシュログを解析する方法については、こちらをクリックして別の記事を参照してください。

クラッシュレポートの取得方法

デバイスをXcodeに接続する(シンボル化済み)

最も簡単な方法は、デバイスをMacBookに接続し、コンピュータに接続されたスマートフォンでアプリケーションを実行することです。

Xcodeでクラッシュログにアクセスします(シンボル化済み)

まず、スマートフォンをコンピュータに接続します。次に、Xcodeアプリケーションを開きます。

上部にある Window メニューをクリックし、Devices and Simulators を選択します

image

次に、左側で Device タブを選択します

image

ウィンドウの右側にある View Device Logs をクリックします

スクリーンショット 0002-09-18 13.28.32.png

これでログメッセージの一覧が見られるようになり、検索ボックスにアプリケーションの名前を入力することで特定のクラッシュログを探せるようになりました。また、All Logs ボタンをクリックしてすべてのログを閲覧することも可能です。

デバイス上でクラッシュログ (シンボル化されていない状態) にアクセスする

クラッシュログにはiPhoneまたはiPadから直接アクセスできます。
1. 設定 を開く
2. プライバシー を開く

image

解析および改善 を開く

image

解析データ を開く

image

すると、全てのクラッシュログの閲覧表が表示されます。下へスクロールすると、検索バーが出てきます。そこへアプリケーション名を入力すると、そのアプリのクラッシュログのリストがみられます。

image

クリックしてログへ入ると、それをコンピューターへエアドロップできます。

ログファイルをシンボル化

Xcodeの中

最初に、クラッシュファイルのファイル拡張子が .crash になっているかどうか確認してください。もしそうなっていなければ、拡張子を .crash に変更してください。

Xcodeを開いて、Devices and Simulators ウィンドウを開いてください。View Device Logs(デバイスログを閲覧)をクリックしてください。表が完全にロードしたら、クラッシュファイルをウィンドウの左パネルへドラッグしてください。

コマンドラインで

コマンドラインを使って各アドレスをシンボル化することも可能です

まず、 dSYM ファイルを見つけます

App Storeにアップロードされているアプリの場合、Xcode の Organizer を開くことで dSYM ファイルをフェッチできます。アプリを見つけ、バージョンの上で右クリックしてください。

スクリーンショット 0002-09-18 13.59.12.png

これで、Xcodeのアーカイブされたファイルを Finder アプリ内で閲覧できるようになります。 そのアーカイブ上で右クリックして、パッケージの内容を表示 をクリックしてください。

スクリーンショット 0002-09-18 13.59.45.png

これで Folder 内で dSYM ファイルが見られるようになります。

スクリーンショット 0002-09-18 14.00.06.png

dSYM ファイルの検索

ID を一致させて dSYM ファイルを検索することもできます。

最初に ID を見つけます

アプリケーションの ID はクラッシュレポートの Binary Images セクションで見つかります

スクリーンショット 0002-09-18 14.21.02.png

その後、以下のコマンドを入力し、所定のUUIDのdSYMファイルを検索します。

mdfind "com_apple_xcode_dsym_uuids == <UUID>"

symbolicatecrash ツールの利用

まず最初にファイルパスを定義します:

export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer

その後、コマンドを実行します

/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash -d <path_to_dsym> -o <output file> <path_to_crash_report>

: あなたのdSYMファイルのファイルパス
: 出力場所
: オリジナルのクラッシュレポートへのファイルパス

atos ツールの利用

atos -arch <binary architecture> -o <dSYM file path> -l <Load address> <Stack Address>

binary architecture: クラッシュレポートのバイナリイメージ Binary Image の一行目にあります。

スクリーンショット 0002-09-18 14.16.35.png

Load address: クラッシュレポートのバイナリイメージ Binary Image の一行目にあります。

スクリーンショット 0002-09-18 14.12.48.png

Stack Address: これは、そのファイルの行に一番最初に表示されるアドレスです。

スクリーンショット 0002-09-18 14.14.45.png

従ってこの場合、実行するコマンドラインは:

atos -arch arm64 -o <dSYM file path> -l 0x10237c000 0x000000010243bd64

上記のコマンドの出力には、異常終了が起きた場所のコード行が表示されているはずです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iOSのUIガイドライン Human Interface Guidelines を読んでみる part3

ビュジュアルデザイン

適応性とレイアウト

iOSアプリでは、iPadでのマルチタスク中、分割ビュー、画面の回転時などに、
さまざまなデバイスの形状とサイズを自動的に変更するようにインターフェイス要素とレイアウトを構成できます。
あらゆる環境で優れたエクスペリエンスを提供する、適応可能なインターフェースを設計することが重要です。

デバイスの画面サイズと向き

iOSデバイスにはさまざまな画面サイズがあり、縦向きでも横向きでも使用できます。
iPhone XやiPad Proなどの端から端までのデバイスでは、ディスプレイの角が丸くなっており、
デバイスの全体的な寸法とほぼ一致しています。
iPhone SEやiPad Airなどの他のデバイスには、長方形のディスプレイがあります。

アプリが特定のデバイスで実行される場合は、そのデバイスのすべての画面サイズで実行されることを確認してください。
つまり、iPhone専用アプリはすべてのiPhone画面サイズで実行する必要があり、iPad専用アプリはすべてのiPad画面サイズで実行する必要があります。

端末 寸法(縦)
12.9インチiPad Pro 1024pt×1366pt(2048px×2732px @ 2x)
11インチiPad Pro 834pt×1194pt(1668px×2388px @ 2x)
10.5インチiPad Pro 834pt×1194pt(1668px×2388px @ 2x)
9.7インチiPad Pro 768pt×1024pt(153​​6px×2048px @ 2x)
7.9インチiPad mini 768pt×1024pt(153​​6px×2048px @ 2x)
10.5インチiPad Air 834pt×1112pt(1668px×2224px @ 2x)
9.7インチiPad Air 768pt×1024pt(153​​6px×2048px @ 2x)
10.2インチiPad 810pt×1080pt(1620px×2160px @ 2x)
9.7インチiPad 768pt×1024pt(153​​6px×2048px @ 2x)
iPhone 11 Pro Max 414pt×896pt(1242px×2688px @ 3x)
iPhone 11 Pro 375pt×812pt(1125px×2436px @ 3x)
iPhone 11 414pt×896pt(828px×1792px @ 2x)
iPhone X S Max 414pt×896pt(1242px×2688px @ 3x)
iPhone X S 375pt×812pt(1125px×2436px @ 3x)
iPhone X R 414pt×896pt(828px×1792px @ 2x)
iPhone X 375pt×812pt(1125px×2436px @ 3x)
iPhone 8 Plus 414pt×736pt(1080px×1920px @ 3x)
iPhone 8 375pt×667pt(750px×1334px @ 2x)
iPhone 7 Plus 414pt×736pt(1080px×1920px @ 3x)
iPhone 7 375pt×667pt(750px×1334px @ 2x)
iPhone 6s Plus 414pt×736pt(1080px×1920px @ 3x)
iPhone 6s 375pt×667pt(750px×1334px @ 2x)
iPhone 6 Plus 414pt×736pt(1080px×1920px @ 3x)
iphone 6 375pt×667pt(750px×1334px @ 2x)
4.7インチiPhone SE 375pt×667pt(750px×1334px @ 2x)
4インチiPhone SE 320pt×568pt(640px×1136px @ 2x)
iPod touch第5世代以降 320pt×568pt(640px×1136px @ 2x)

AutoLayout

Auto Layoutは、アダプティブインターフェイスを構築するための開発ツールです。
Auto Layoutを使用すると、アプリのコンテンツを制御するルール(制約と呼ばれる)を定義できます。
たとえば、使用可能な画面スペースに関係なく、ボタンを常に水平方向の中央に配置し、
画像の下に8ポイント配置するようにボタンを制限できます。

Auto Layoutは、指定された制約に従ってレイアウトを自動的に再調整します。
次のようなさまざまな特性に動的に適応するようにアプリを設定できます。

  • さまざまなデバイスの画面サイズ、解像度、色域(sRGB / P3)
  • さまざまなデバイスの向き(縦/横)
  • 分割ビュー

etc...

詳しくはAuto Layout Guideを参照してください。

Layout GuideとSafe Area

Layout Guideは、実際には画面上に表示されない長方形の領域を定義します。
これらのLayout Guideは、デバイスとコンテキストに基づいて適切なインセットを保証します。
Safe Areaは、コンテンツがステータスバー、ナビゲーションバー、ツールバー、タブバーと重ならないようにします。
システムが提供する標準のビューでは、自動的にSafe Areaが採用されます。

詳しくはUILayoutGuidelayoutMarginsGuidereadableContentGuide、およびsafeAreaLayoutGuideを参照してください。

Size Class

サイズクラスは、サイズに基づいてコンテンツ領域に自動的に割り当てられる特性です。
OSはビューの高さと幅を表す2つのサイズクラス、
- Regular(拡張スペースを表す)と
- Compact(制約付きスペースを表す)を定義します。

ビューはサイズクラスの任意の組み合わせを持つことができます。

  • Regular width, regular height
  • Compact width, compact height
  • Regular width, compact height
  • Compact width, regular height

※単純に横向きと縦向きそれぞれの高さを定義しているってことです。
例えば、iPhone 11 Pro Maxは縦向きはコンパクトな幅、通常の高さと認識され、横向きは通常の幅、コンパクトな高さとなります。

マルチタスクサイズクラスというのが分割ビューの登場により出てきました。ここはとりあえず割愛します。

レイアウトに関する一般的な考慮事項

視覚的な重みとバランスの考慮

大きなアイテムは目を引き、小さなものよりも重要に見えます。
大きいアイテムはタップするのも簡単です。
アプリがキッチンやジムなどの周囲の注意散漫に使用される場合、特に重要です。
基本的に主要なアイテムは画面の上半分に、左から右に読む場合は画面の左側に配置します。

※ただ、デバイスが大きくなっていることもあり右下に押しやすい、よく押すボタンを置くというのもUXの向上に繋がります。(個人的意見)

配置を有効に利用する

アラインメントにより、アプリがすっきりと整理された外観になり、
スクロール中にユーザーが集中できるようになり、情報を見つけやすくなります。
インデントと配置は、コンテンツのグループがどのように関連しているかを示すこともできます。

テキストサイズの変更に対応する

OSの設定画面からフォントサイズを変更できるので、調整する必要がある場合があります。
アプリでのテキストの使用の詳細については、タイポグラフィを参照してください。

 

タップ可能領域 

すべてのコントロールの最小タップ可能領域を44pt x 44ptに維持するようにしてください。

フルスクリーンエクスペリエンスの設計

どちらのタイプのiOSデバイスでもアプリを実行できる柔軟性があることを高く評価しています。
アプリの特定の機能でテレフォニーなどのiPhone固有のハードウェアが必要な場合は、
iPadでそれらの機能を非表示にするか無効にして、アプリの他の機能を使用できるようにすることを検討してください。

画面の一番下や隅にインタラクティブなコントロールを明示的に配置しないでください。

ユーザーはディスプレイの下端でスワイプジェスチャーを使用して、ホーム画面やアプリスイッチャーなどの機能にアクセスします。
これらのジェスチャーは、この領域に実装するカスタムジェスチャーをキャンセルする場合があります。
画面の隅は、人々が快適に到達するのが難しい領域になる可能性があります。

※Safe Areaにかからなければ基本的には大丈夫です。iPhone8などは注意が必要ですね。

クリッピングを防ぐために必須コンテンツを挿入する

一般に、コンテンツは中央に配置され、対称的にはめ込まれているため、
どの方向でも見栄えがよく、角の丸い部分で切り取られたり、
ホーム画面にアクセスするためのインジケーターで隠れたりしません。
最良の結果を得るには、標準のシステム提供のインターフェース要素とAuto Layoutを使用してインターフェースを構築し、
Layout GuideとSafe Areaに準拠するべきです。

■正解

■不正解

はめ込み全角ボタン

画面の端まで延びるボタンは、ボタンのように見えない場合があります。
全幅ボタンの両側にある標準のUIKitマージンを尊重してください。
画面の下部に表示される全幅のボタンは、角が丸く、安全領域の下部と揃っているときに最適に見えます。

ステータスバーの高さに注意

フルスクリーンのiPhoneモデルでは、ステータスバーが他のモデルよりも高くなっています。
アプリがステータスバーの下にコンテンツを配置するために固定のステータスバーの高さを想定している場合は、
現在のデバイスに基づいてコンテンツを動的に配置するようにアプリを更新する必要があります。

現在ステータスバーを非表示にしている場合は、アプリをフルスクリーンのiPhoneで実行するときにその決定を再検討してください。

他のモデルよりもコンテンツの垂直方向のスペースが多く、ステータスバーは、アプリが十分に活用できない画面の領域を占めます。
ステータスバーには、人々が役立つと思う情報も表示されます。付加価値と引き換えにのみ非表示にする必要があります。

アニメーション

iOS全体の美しく繊細なアニメーションは、画面上の人とコンテンツ間の視覚的なつながりを構築します。
アニメーションを適切に使用すると、ステータスを伝え、フィードバックを提供し、直接操作の感覚を高め、
ユーザーがアクションの結果を視覚化するのに役立ちます。

アニメーションとモーションエフェクトは慎重に使用すること

過度または不必要なアニメーションは、特に没入型のエクスペリエンスを提供しないアプリで、
人々が途切れたり気が散ったりするように感じる可能性があります。
モーションエフェクトを実装する場合は、常に結果をテストして、それらが適切に機能することを確認してください。

リアリズムと信頼性に努める

物理的な法則に反するように見えるとき、ユーザーは混乱します。
たとえば、誰かが画面の上から下にスライドしてビューを表示した場合、上にスライドしてビューを閉じることができるはずです。

ブランディング

ブランディングを成功させるには、スマートなフォント、色、画像の決定を通じて、
独自のブランドアイデンティティを表現します。

洗練された控えめなブランディング

最高のエクスペリエンスを実現するには、アプリのデザインにブランドを微妙に取り入れます。
インターフェイス全体でアプリアイコンの色を使用することは、アプリにコンテキストを提供するための1つの優れた方法です。

ブランディングよりコンテンツを優先する

画面の上部にブランドアセットを表示するだけの永続的なバーを表示すると、コンテンツを表示する余地が少なくなります。
代わりに、カスタムの配色やフォントを使用したり、背景を微妙にカスタマイズしたりするなど、
ブランドを実装する邪魔にならない方法を検討してください。

アプリ全体にロゴを表示するという誘惑に負けないで

コンテキストを提供する必要がない限り、ロゴをアプリ全体に表示しないでください。
これは、タイトルがより役立つナビゲーションバーで特に重要です。

誘惑に負けないでって言葉、なんだか面白いですねw

Appleの商標ガイドラインに従う

Appleの商標をアプリ名や画像に表示しないでください。
アップルの商標リストおよびアップルの商標の使用に関するガイドラインを参照してください。

色は、活力を与え、視覚的な連続性を提供し、ステータス情報を伝え、ユーザーのアクションに応じてフィードバックを提供し、人々がデータを視覚化するのに役立つ優れた方法です。

注意を引く色

重要な情報に注意を引く色の力は、控えめに使用すると高まります。たとえば、重大な問題を警告する赤い三角形は、重大でない理由でアプリの他の場所で赤を使用すると効果が低下します。

アプリのロゴと調和する限られたカラーパレットを選択する

色を緻密に使用することは、ブランドを伝える優れた方法です。

アプリ全体のインタラクティブ性を示す

メモアプリでは、インタラクティブな要素は黄色です。
カレンダーアプリでは、インタラクティブな要素は赤です。
インタラクティビティを表すティントカラーを定義する場合は、他のカラーがそれと競合しないことを確認してください。

ティントカラーでライトモードとダークモードに対応

ティントカラーにシステムカラーを使用すると、ハイコントラストが自動的にサポートされます。

インタラクティブ要素と非インタラクティブ要素に同じ色を使用しないでください。

インタラクティブ要素と非インタラクティブ要素の色が同じ場合、タップする場所を人々が知るのは困難です。

半透明性が近くの色にどのように影響するかを検討する

半透明要素の背後に配置したり、ツールバーなどの半透明要素に適用したりすると、色が異なって表示される場合があります。

さまざまな照明条件下でアプリの配色をテスト

部屋の雰囲気、時間帯、天候などに基づいて、照明は屋内と屋外の両方で大きく異なります。
アプリが現実の世界で使用されている場合、コンピューターに表示される色は常に同じとは限りません。
晴れた日の屋外など、さまざまな照明条件下でアプリを常にプレビューして、色がどのように表示されるかを確認してください。

True Toneディスプレイが色にどのように影響するか

True Toneディスプレイを利用すると環境光センサーを使用して、その場の環境の照明条件に適応します。
読書、写真、ビデオ、およびゲームに主に焦点を当てたアプリは、ホワイトポイントのアダプティブスタイルを指定することで、
この効果を強化または弱めることができます。
開発者向けガイダンスについては、UIWhitePointAdaptivityStyleを参照してください。

コンテンツを認識しにくい色の使用は避ける

たとえば、色覚異常の人は一部の色の組み合わせを区別できない場合があり、
コントラストが不十分な場合、アイコンとテキストが背景に溶け込み、コンテンツが読みにくくなることがあります。
ガイダンスについては色とコントラストを参照ください。

システムカラー

アプリでシステムカラー値をハードコードしないこと

実際の色の値は、さまざまな環境変数に基づいて、リリースごとに変動する可能性があります。
システムカラーを適用するには、常にAPIを使用してください。開発者向けガイダンスについては、UIColorを参照してください。

iOS 13では、半透明がうまく機能しないまれなケースで使用できる6種類の不透明な灰色も導入されています。
たとえば、交差する要素や重なり合う要素(グリッドの線や棒など)は、不透明度を使用すると見栄えがよくなります。
基本的に、UI要素には意味的に定義されたシステムカラーを使用します。

ダイナミックシステムカラー

濃淡の色に加えて、iOSは意味的に定義されたシステムカラーも提供します。
これは、ライトモードとダークモードの両方に自動的に適応します。
セマンティックカラーは、その目的ではなく、背景領域と前景コンテンツで使用する色を定義しています。
たとえば、iOSでは、ラベル、セパレーター、塗りつぶしなど。

ダークモード

iOS 13.0以降では、システム全体で暗いモードと呼ばれる暗い外観を採用することを選択できます。
ダークモードでは、システムはすべての画面、ビュー、メニュー、コントロールに暗いカラーパレットを使用し、
より鮮やかな色を使用して、前景のコンテンツを暗い背景に対して目立たせます。
ダークモードは、すべてのユーザー補助機能をサポートしています。

設定で選択した外観モードに準拠する

システム全体の外観の選択に適応しない場合、アプリが壊れているとユーザーは思うかもしれません。
選択された外観を元に調整するか、どちらかのモードをアプリで強制的に選択する必要があります。

色のコントラストを調整

システム定義の色を使用すると、前景コンテンツと背景コンテンツの適切なコントラスト比が保証されます。
カスタムカラーの場合、特に小さいテキストの場合は、7:1のコントラスト比を目指します。
ガイダンスについては、「ダイナミックシステムカラー」を参照してください。

白い背景の色を柔らかく

ダークモードの場合は、背景が周囲の暗いコンテンツに対して光らないように、少し暗い白を選択します。

 Materials

鮮やかさは、暗い背景のテキストのコントラストを維持するのに役立ちます。

 システム提供のラベルの色を使用する場合

一次、二次、三次、および四次のラベルの色は、明るい外観と暗い外観に自動的に適応します。
関連するガイダンスについては、「タイポグラフィ」を参照してください。

ぼかし効果

iOSは、奥行き感を出すために半透明の効果を作成するぼかし効果を提供します。
これにより、前景のコンテンツに邪魔されることなく、ビューとコントロールが背景のコンテンツの見栄えを良くします。
この効果を生み出すために、マテリアルは背景の色情報がフロントのビューを通過できるようにし、
同時に背景のコンテキストをぼかして読みやすさを維持します。

用語

親しみやすく理解しやすい語句を使用する

技術的なことは受け入れがたいかもしれません。
人々が理解できないかもしれない頭字語や専門用語を避けてください。
基本的に誰にでも勧められるアプリは、高度に技術的な言葉を避けなければなりません。
専門的な言語は、より高度な、または技術的な群衆を対象とするアプリに適している場合があります。

インターフェイスのテキストは明確かつ簡潔に

ユーザーは短い直接のテキストを好み、タスクを完了するために長い文章を読むことは避けたいと思います。
最も重要な情報を特定し、簡潔に表現し、目立つように提示することで、
ユーザーが次に何をすべきかを理解しやすくさせます。

インタラクティブな要素を適切に

要素が何をするのかがひと目でわかるようにすべきです。
ボタンやその他のインタラクティブな要素にラベルを付ける場合は、接続、送信、追加などのアクション動詞を使用します。

ひいきに聞こえるかもしれない言葉は避ける

私たち、私、などの表現を避けてください、(例えば、「チュートリアル」ではなく「私のトレーニングを」)。
ユーザーは時々不快に解釈されます。

ユーモアを使うときは注意する

ユーザーはあなたのインターフェースのテキストを何度も読む可能性が高く、
最初は良いと思われるかもしれないものの、時間の経過とともに苛立たしいものになる可能性があることを覚えておいてください。
また、ある文化のユーモアは、必ずしも他の文化にうまく翻訳できるとは限らないことも覚えておいてください。

日付を正確に表現する

今日や明日のようなわかりやすい用語を使用するのが適切ですが、
現在のロケールを考慮に入れないと、これらの用語は混乱したり不正確になったりする可能性があります。
真夜中に始まるイベントを考えてみましょう。
1つのタイムゾーンで、イベントが今日開始される場合があります。
別のタイムゾーンで、同じイベントが昨日開始された可能性があります。
通常、日付はイベントを表示する人のタイムゾーンを反映する必要があります。
ただし、フライト追跡アプリなどの一部のケースでは、フライトの出発地である開始日とタイムゾーンを明示的に示す方が明確な場合があります。

タイポグラフィ

Appleは、iOSアプリで使用できる2つのタイプファミリーを提供しています。

サンフランシスコ(SF)。

サンフランシスコは、SF Pro、SF Pro Rounded、SF Mono、SF Compact、SF Compact Roundedを含むサンセリフタイプファミリーです。SF Proは、iOS、macOS、tvOSのシステムフォントです。
SF Compactは、watchOSのシステムフォントです。
プラットフォームUIの視覚的な明快さに一致するように設計されたシステムフォントは、読みやすく中立です。

ニューヨーク

ニューヨークは、インターフェースで使用したり、従来の読書体験を提供したりできる、古典的なセリフ書体です。

NYは以下をサポートします:

ラテン語、ギリシャ語、キリル文字のスクリプトを使用する100以上の言語
レギュラーからブラックまで、アップライトとイタリックの6つのウェイト
テキストのサイズに基づいて自動的に調整される可変文字間隔
小、中、大、および特大の個別の光学サイズに加えて、動的光学サイズ

ダイナミックタイプサイズ

ダイナミックタイプは、読者が好みのテキストサイズを選択できるようにすることで、さらに柔軟性を提供します。
以下は、異なるダイナミックタイプサイズでの各テキストスタイルの重み、サイズ、および先行値です。

より大きなアクセシビリティタイプサイズ

標準の動的タイプサイズに加えて、システムは、アクセシビリティが必要なユーザー向けに、さらに多くのサイズを提供します。
これは、より大きなアクセシビリティタイプサイズでの各テキストスタイルの重み、サイズ、および先行値です。

アイコンとサイズ

画像サイズと解像度

iOSがコンテンツを画面に配置するためにiOSが使用する座標系は、
ディスプレイのピクセルにマッピングされるポイントの測定に基づいています。
標準解像度ディスプレイのピクセル密度は1:1(@ 1x)で、1ピクセルは1ポイントに相当します高解像度ディスプレイはより高いピクセル密度を持ち、2.0または3.0の倍率を提供します(@ 2xおよび@ 3xと呼ばれます)。
その結果、高解像度ディスプレイには、より多くのピクセルを持つ画像が必要になります。

たとえば、100px×100pxの標準解像度(@ 1x)の画像があるとします。この画像の@ 2xバージョンは200px×200px、@ 3xバージョンは300px×300pxになります。

アプリアイコン

すべてのアプリには、App Storeで注目を集め、ホーム画面で目立つ、美しく思い出に残るアイコンが必要です。
アイコンは、一目でアプリの目的を伝える最初の機会です。また、設定や検索結果など、システム全体に表示されます。

シンプルさ

アプリの本質を捉えた単一の要素を見つけ、その要素をシンプルでユニークな形で表現します。
より修飾する場合は慎重に検討する必要があります。
アイコンのサイズが小さい場合、詳細を識別しにくい場合があります。

わかりやすいアイコンを心がける

アイコンが何を表しているのか、詳しく理科してもらう必要はありません。
たとえば、メールアプリのアイコンは、メールに広く関連付けられているエンベロープを使用します。
時間をかけて、アプリの目的を芸術的に表す美しく魅力的な抽象的なアイコンをデザインしてください。

※芸術的に表す美しく魅力的な抽象的なアイコンってサラッと書いてあるけど難しいような。。

背景をシンプルに、透明度の高いものは避ける

アイコンが不透明で、背景が乱雑にならないようにしてください。
近くにある他のアプリのアイコンを邪魔しないように背景をシンプルにします。
ただし、アイコン全体をコンテンツで埋める必要はありません。

単語は、ロゴが不可欠またはロゴの一部である場合にのみ使用する

アプリの名前がホーム画面のアイコンの下に表示されます。
名前を繰り返す、重要でない汎用的な単語を含めないでください。
デザインにテキストが含まれている場合は、アプリが提供する実際のコンテンツに関連する単語を強調します。

写真は含めない

写真の細部は、小さなサイズでは非常に見にくい場合があります。

Appleハードウェア製品の複製を使用しない

Apple製品は著作権で保護されており、アイコンや画像に複製することはできません。

さまざまな壁紙に対してアイコンをテストする

ユーザーがホーム画面用に選択する壁紙を予測することはできないため、
明るい色または暗い色に対してアプリをテストするだけではいけません。
さまざまな写真でどのように見えるかを確認してください。

スポットライト、設定、通知アイコン

※スポットライト、設定、通知アイコンで使用するアイコンを提供しないといけないということが書かれていますが、
Assetsに全てのサイズ入れれば良いので割愛。

開発者向けガイダンスについては、UIApplicationのsetAlternateIconNameメソッドを参照してください。

カスタムアイコン

iOS 13以降では、SFシンボルを使用することがお勧めされています。
アプリがiOS12以前で実行されている場合、またはカスタムビットマップアイコンを作成する必要がある場合はこちらのガイダンスを一読しておくと良いです。

簡素化されたデザイン

ディテールが凝りすぎていないユニバーサルなデザインを目指します。
良いアイコンの要素の一つとして、使い慣れた視覚的なメタファーがあります。

グリフ

グリフ(テンプレートイメージとも呼ばれます)は、マスクを使用して形状を定義する、
透明度、アンチエイリアス、およびドロップシャドウのない単色イメージです。
グリフは、コンテキストとユーザーインタラクションに基づいて、
適切な外観(カラーリング、ハイライト、鮮やかさなど)を自動的に受け取ります。
ナビゲーションバー、タブバー、ツールバー、ホーム画面のクイックアクションなど、
さまざまな標準インターフェイス要素がグリフをサポートしています。

アイコンの読みやすさ

一般に、塗りつぶされたアイコンは、輪郭を描かれたアイコンよりも明確になる傾向があります。
アイコンに線を含める必要がある場合は、他のアイコンやアプリのタイポグラフィと重さを調整してください。

色を使用して、選択状態と選択解除状態を伝える

ソリッドバージョンとアウトラインバージョンのように、2つの異なるアイコンデザインを切り替えないでください。

アイコンにテキストを含めない

テキストが必要な場合は、アイコンの下にラベルを表示し、それに応じて配置を調整します。

カスタムアイコンサイズ

何よりも、アプリのアイコンファミリーのサイズは視覚的に一貫している必要があります。個々のアイコンのデザインの重さが異なる場合、この効果を実現するには、一部のアイコンを他のアイコンよりも少し大きくする必要がある場合があります。

サイズ一覧など詳細はhttps://developer.apple.com/design/human-interface-guidelines/ios/icons-and-images/custom-icons/で。

システムアイコン

システムが提供するすべてのイメージには、特定のよく知られた意味があります。
ユーザーの混乱を避けるために、各画像はその意味と推奨される使用法に従って使用することが不可欠です。
もし意図したイメージを表すアイコンがない場合は自分でアイコンを作成します。

システムアイコンの意味と使用方法については以下を参考にしてください。

システムアイコンについて

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む