SlideShare a Scribd company logo
1 of 31
Download to read offline
Swift API Design
Guidelines (Dec 3, 2015)
Takaaki Tanaka, Goichi Hirakawa
About Me
• 田中 孝明 (Takaaki Tanaka)
• @kongmingtrap
• iOS Developer (Swift / Objective-C)
• GyazSquare / GitHub
About Me
• 平川 剛一 (Goichi Hirakawa)
• @gooichi
• OS X / iOSソフトウェアエンジニア(フリー)
• GyazSquare / GitHub
• Mailer、デバイス制御、MDM系など
• Objective-C歴XX年、最近はSwiftにはまる…
Swift is Open Source
• 2015/12/03にオープンソースとして公開
• 2.2リリース:2016年春頃
• 3.0リリース:2016年秋頃
• 3.0の目標の一つ:
API design guidelines: 定義と適用
Agenda
• 2015-12-03版APIガイドラインの紹介
• Fundamentals: 基礎
• Naming: 命名
• Conventions: 規約
• Special instructions: 特記事項
Agenda
• 2015-12-03版APIガイドラインの紹介
• Fundamentals: 基礎
• Naming: 命名
• Conventions: 規約
• Special instructions: 特記事項
Fundamentals
• 利用時の明確さ
• もっとも重要な目標
• 明確さは簡潔さより重要
• 最小の文字数が目標ではない
• ドキュメントコメントを書く
Write a Document Comment
• すべてのメソッドとプロパティ
• MarkDownのSwift方言を使う
/// Returns the first index where `element` appears in `self`,
/// or `nil` if `element` is not found.
///
/// - Complexity: O(`self.count`).
public func indexOf(element: Generator.Element) -> Index? {
Agenda
• 2015-12-03版APIガイドラインの紹介
• Fundamentals: 基礎
• Naming: 命名
• Conventions: 規約
• Special instructions: 特記事項
Naming
• Promote Clear Usage: 明快な語法を推進
• Be Grammatical: 文法に正しく
• Use Terminology Well: 専門用語をうまく使用
Promote Clear Usage
• 曖昧さを避けること

例えば、以下のようなポジションを指定して削除する

メソッドがあった場合、
public mutating func removeAt(position: Index) -> Element
employees.removeAt(x)
Atを省略すると位置を指定するのか、employeesの

要素を指定するのか曖昧になる:
employees.remove(x) // unclear: are we removing x?
Promote Clear Usage
• 不要な単語は省略する

余剰な情報は省略すべき。Elementを管理するオブジェク
トのElementを削除するメソッドに対して、メソッド名に
Elementを含めるのは余剰な情報である:
public mutating func removeElement(member: Element) -> Element?
allViews.removeElement(cancelButton)
以下のようにするのがよい:
public mutating func remove(member: Element) -> Element?
allViews.remove(cancelButton) // clearer
Promote Clear Usage
• パラメータには役割を明確にするための補足情報を追加する

NSObject、Any、AnyObjectや基本的な型(Intや
String)のパラメータは役割を明確にした名前をつける:
func add(observer: NSObject, for keyPath: String)
grid.add(self, for: graphics) // vague
以下のように、selfはObserver、StringはkeyPathと
して使用することを明示する:
func addObserver(_ observer: NSObject, forKeyPath path: String)
grid.addObserver(self, forKeyPath: graphics) // clear
Be Grammatical
• mutatingメソッドには動詞句を使用する
• non-mutatingメソッドには名詞句を使用する
• mutatingメソッドが動詞句の場合、対応する 
non-mutatingメソッドには「ed/ing」をつける
Be Grammatical
• non-mutatingなBooleanメソッド、プロパティは
以下のようにする
x.isEmpty, line1.intersects(line2)
• Protocolは特徴を名詞で記述し、接尾語に
「able」、「ible」、「ing」をつける
• その他の変数、プロパティ、定数は名詞で記述する
Use Terminology Well
• あまり知られてない専門用語は避ける
• 専門用語を使用する場合は確立された意味に従う
• 専門家を驚かせない
• 初心者を惑わせない
Use Terminology Well
• 略語は避ける
• 先例を受け入れる

連続したデータ構造ではListよりもArrayと名前
につける(Arrayはモダン・コンピューティングの
基礎であり、すべてのプログラマが知っている)
Agenda
• 2015-12-03版APIガイドラインの紹介
• Fundamentals: 基礎
• Naming: 命名
• Conventions: 規約
• Special instructions: 特記事項
Conventions
• General Conventions: 一般的な規約
• Parameters: パラメータ
General Conventions
• O(1)ではない計算型プロパティの複雑さは文章化
• フリー関数よりメソッドやプロパティを選択する
• ケース(大文字・小文字)の規約に従う
• 同じ基本的な意味を共有するとき、メソッドは

ベース名を共有できる
Free Functions
• フリー関数は特別な場合のみ使用される:
1.明白な self がないとき
min(x, y, z)
2.関数が制約なく汎用的なとき
print(x)
3.関数の構文が確立されたドメイン表記の一部のとき
sin(x)
Parameters
• デフォルト引数を利用する
• メソッドファミリーの利用より一般的に好ましい
• デフォルトを持つパラメータは最後の方に置く
• 引数ラベルの存在は言語のデフォルト設定に従う
例外:
1.拡張型変換と見られるべきであるイニシャライザ
2.すべてのパラメータが有効に区別できないピアのとき
3.最初の引数がデフォルト設定されたとき
Argument Labels
• メソッドや関数の最初の引数は必須の引数ラベルを
持つべきではない
• メソッドや関数の他のパラメータは必須の引数ラベ
ルを持つべきである
• イニシャライザのすべてのパラメータは必須の引数
ラベルを持つべきである
Exception 1
• 拡張型変換(widening type conversions):

元が取り得るすべての値を許容可能な型への変換
• 縮小型変換(narrowing type conversions):

値の一部を保持できない型への変換
extension UInt32 {
init(_ value: Int16) // widening, so no label
init(truncating bits: UInt64) // narrowing
init(saturating value: UInt64) // narrowing
}
Exception 2
• すべてのパラメータが有効に区別できないピアの

ときのよく知られた例:
min(number1, number2)
zip(sequence1, sequence2)
Exception 3
• 最初の引数がデフォルト設定されたときの例
extension Document {
func close(completionHandler completion: ((Bool) -> Void)? = nil)
}
doc1.close()
doc2.close(completionHandler: app.quit)
extension Document {
func close(completion: ((Bool) -> Void)? = nil)
}
doc.close(app.quit) // Closing the quit function?
extension Document {
func closeWithCompletionHandler(completion: ((Bool) -> Void)? = nil)
}
doc.closeWithCompletionHandler() // What completion handler?
Agenda
• 2015-12-03版APIガイドラインの紹介
• Fundamentals: 基礎
• Naming: 命名
• Conventions: 規約
• Special instructions: 特記事項
Special Instructions
• 制約のない多態性に細心の注意を払うこと
• Any、AnyObjectと制約のないジェネリックパラメータ
• ドキュメントコメントツールフレンドリーにする
• リッチなフォーマットのドキュメントが自動生成
• Xcodeで表示される
• 優れた要約を記述することがより重要である
Unconstrained Polymorphism
• 例えば、以下のオーバーロードのセットを考える:
struct Array {
/// Inserts `newElement` at `self.endIndex`.
public mutating func append(newElement: Element)
/// Inserts the contents of `newElements`, in order, at
/// `self.endIndex`.
public mutating func append<
S : SequenceType where S.Generator.Element == Element
>(newElements: S)
}
ElementがAnyのとき、曖昧になる

(単一のElementがElementのシーケンスと同じ型扱い)
var values: [Any] = [1, "a"]
values.append([2, 3, 4]) // [1, "a", [2, 3, 4]] or [1, "a", 2, 3, 4]?
Unconstrained Polymorphism
• 曖昧さを排除するために2番目のオーバーロードを
より明確に命名する:
struct Array {
/// Inserts `newElement` at `self.endIndex`.
public mutating func append(newElement: Element)
/// Inserts the contents of `newElements`, in order, at
/// `self.endIndex`.
public mutating func appendContentsOf<
S : SequenceType where S.Generator.Element == Element
>(newElements: S)
}
Conclusion
• Swift 3 API Guidelines Review
• GitHubで公開
• Swift 3 API Guidelinesの成果の一部
• Swift 3インポータ自動適用結果が見れる
➡ Swift 2.xでもある程度意識しながらコードを書いた方がよい
• ただし、ガイドラインはあくまでガイドライン(指針)
• 細かな部分はプロジェクトやグループで決めが必要
• ガイドライン自体がGitHub上に欲しい

More Related Content

Similar to Swift api design guidelines (dec 3, 2015)

Azureのサーバーレスで限界を超えよう~スマートスピーカースキル開発を題材に~
Azureのサーバーレスで限界を超えよう~スマートスピーカースキル開発を題材に~Azureのサーバーレスで限界を超えよう~スマートスピーカースキル開発を題材に~
Azureのサーバーレスで限界を超えよう~スマートスピーカースキル開発を題材に~拓将 平林
 
Azure でサーバーレス、 Infrastructure as Code どうしてますか?
Azure でサーバーレス、 Infrastructure as Code どうしてますか?Azure でサーバーレス、 Infrastructure as Code どうしてますか?
Azure でサーバーレス、 Infrastructure as Code どうしてますか?Kazumi IWANAGA
 
『これからの.NETアプリケーション開発』セミナー .NET用アプリケーション フレームワーク Open 棟梁 概説
『これからの.NETアプリケーション開発』セミナー .NET用アプリケーション フレームワーク Open 棟梁 概説『これからの.NETアプリケーション開発』セミナー .NET用アプリケーション フレームワーク Open 棟梁 概説
『これからの.NETアプリケーション開発』セミナー .NET用アプリケーション フレームワーク Open 棟梁 概説Daisuke Nishino
 
Xamarin 概要 @ 2014/11/08 第2回 Japan Xamarin User Group Conference 西日本編
Xamarin 概要 @ 2014/11/08 第2回 Japan Xamarin User Group Conference 西日本編Xamarin 概要 @ 2014/11/08 第2回 Japan Xamarin User Group Conference 西日本編
Xamarin 概要 @ 2014/11/08 第2回 Japan Xamarin User Group Conference 西日本編Yoshito Tabuchi
 
eZ Publish勉強会2013年3月「eZ Publishの構築を簡単に!」
eZ Publish勉強会2013年3月「eZ Publishの構築を簡単に!」eZ Publish勉強会2013年3月「eZ Publishの構築を簡単に!」
eZ Publish勉強会2013年3月「eZ Publishの構築を簡単に!」ericsagnes
 
プログラマが欲しい仕様書とは
プログラマが欲しい仕様書とはプログラマが欲しい仕様書とは
プログラマが欲しい仕様書とはKatsutoshi Makino
 
[CB19] FileInsight-plugins: Decoding toolbox for malware analysis by 萬谷 暢崇
[CB19] FileInsight-plugins: Decoding toolbox for malware analysis by 萬谷 暢崇[CB19] FileInsight-plugins: Decoding toolbox for malware analysis by 萬谷 暢崇
[CB19] FileInsight-plugins: Decoding toolbox for malware analysis by 萬谷 暢崇CODE BLUE
 
技術選択とアーキテクトの役割
技術選択とアーキテクトの役割技術選択とアーキテクトの役割
技術選択とアーキテクトの役割Toru Yamaguchi
 
Python languageupdate (2004)
Python languageupdate (2004)Python languageupdate (2004)
Python languageupdate (2004)泰 増田
 
論理思考とプログラミング 2013f#10
論理思考とプログラミング 2013f#10論理思考とプログラミング 2013f#10
論理思考とプログラミング 2013f#10Noritada Shimizu
 
GitHub Codespaces と Azure でつくる、エンタープライズレベルの開発環境
GitHub Codespaces と Azure でつくる、エンタープライズレベルの開発環境GitHub Codespaces と Azure でつくる、エンタープライズレベルの開発環境
GitHub Codespaces と Azure でつくる、エンタープライズレベルの開発環境Kazumi IWANAGA
 
Macで快適にプログラミング
Macで快適にプログラミングMacで快適にプログラミング
Macで快適にプログラミングYusuke Sakurai
 
俺も受託開発〜準委任契約によるふつうのソフトウェア開発〜
俺も受託開発〜準委任契約によるふつうのソフトウェア開発〜俺も受託開発〜準委任契約によるふつうのソフトウェア開発〜
俺も受託開発〜準委任契約によるふつうのソフトウェア開発〜Koichi ITO
 
Chainerで学ぶdeep learning
Chainerで学ぶdeep learningChainerで学ぶdeep learning
Chainerで学ぶdeep learningRetrieva inc.
 
ARMテンプレートでサーバーレスに挑む!
ARMテンプレートでサーバーレスに挑む!ARMテンプレートでサーバーレスに挑む!
ARMテンプレートでサーバーレスに挑む!Kazumi IWANAGA
 

Similar to Swift api design guidelines (dec 3, 2015) (20)

Azureのサーバーレスで限界を超えよう~スマートスピーカースキル開発を題材に~
Azureのサーバーレスで限界を超えよう~スマートスピーカースキル開発を題材に~Azureのサーバーレスで限界を超えよう~スマートスピーカースキル開発を題材に~
Azureのサーバーレスで限界を超えよう~スマートスピーカースキル開発を題材に~
 
Tizen & Crosswalk
Tizen & CrosswalkTizen & Crosswalk
Tizen & Crosswalk
 
Azure でサーバーレス、 Infrastructure as Code どうしてますか?
Azure でサーバーレス、 Infrastructure as Code どうしてますか?Azure でサーバーレス、 Infrastructure as Code どうしてますか?
Azure でサーバーレス、 Infrastructure as Code どうしてますか?
 
Objective-C Generics
Objective-C GenericsObjective-C Generics
Objective-C Generics
 
『これからの.NETアプリケーション開発』セミナー .NET用アプリケーション フレームワーク Open 棟梁 概説
『これからの.NETアプリケーション開発』セミナー .NET用アプリケーション フレームワーク Open 棟梁 概説『これからの.NETアプリケーション開発』セミナー .NET用アプリケーション フレームワーク Open 棟梁 概説
『これからの.NETアプリケーション開発』セミナー .NET用アプリケーション フレームワーク Open 棟梁 概説
 
Xamarin 概要 @ 2014/11/08 第2回 Japan Xamarin User Group Conference 西日本編
Xamarin 概要 @ 2014/11/08 第2回 Japan Xamarin User Group Conference 西日本編Xamarin 概要 @ 2014/11/08 第2回 Japan Xamarin User Group Conference 西日本編
Xamarin 概要 @ 2014/11/08 第2回 Japan Xamarin User Group Conference 西日本編
 
eZ Publish勉強会2013年3月「eZ Publishの構築を簡単に!」
eZ Publish勉強会2013年3月「eZ Publishの構築を簡単に!」eZ Publish勉強会2013年3月「eZ Publishの構築を簡単に!」
eZ Publish勉強会2013年3月「eZ Publishの構築を簡単に!」
 
プログラマが欲しい仕様書とは
プログラマが欲しい仕様書とはプログラマが欲しい仕様書とは
プログラマが欲しい仕様書とは
 
Java Clientで入門する Apache Kafka #jjug_ccc #ccc_e2
Java Clientで入門する Apache Kafka #jjug_ccc #ccc_e2Java Clientで入門する Apache Kafka #jjug_ccc #ccc_e2
Java Clientで入門する Apache Kafka #jjug_ccc #ccc_e2
 
[CB19] FileInsight-plugins: Decoding toolbox for malware analysis by 萬谷 暢崇
[CB19] FileInsight-plugins: Decoding toolbox for malware analysis by 萬谷 暢崇[CB19] FileInsight-plugins: Decoding toolbox for malware analysis by 萬谷 暢崇
[CB19] FileInsight-plugins: Decoding toolbox for malware analysis by 萬谷 暢崇
 
自由なデータ
自由なデータ自由なデータ
自由なデータ
 
技術選択とアーキテクトの役割
技術選択とアーキテクトの役割技術選択とアーキテクトの役割
技術選択とアーキテクトの役割
 
Python languageupdate (2004)
Python languageupdate (2004)Python languageupdate (2004)
Python languageupdate (2004)
 
論理思考とプログラミング 2013f#10
論理思考とプログラミング 2013f#10論理思考とプログラミング 2013f#10
論理思考とプログラミング 2013f#10
 
GitHub Codespaces と Azure でつくる、エンタープライズレベルの開発環境
GitHub Codespaces と Azure でつくる、エンタープライズレベルの開発環境GitHub Codespaces と Azure でつくる、エンタープライズレベルの開発環境
GitHub Codespaces と Azure でつくる、エンタープライズレベルの開発環境
 
Macで快適にプログラミング
Macで快適にプログラミングMacで快適にプログラミング
Macで快適にプログラミング
 
俺も受託開発〜準委任契約によるふつうのソフトウェア開発〜
俺も受託開発〜準委任契約によるふつうのソフトウェア開発〜俺も受託開発〜準委任契約によるふつうのソフトウェア開発〜
俺も受託開発〜準委任契約によるふつうのソフトウェア開発〜
 
Chainerで学ぶdeep learning
Chainerで学ぶdeep learningChainerで学ぶdeep learning
Chainerで学ぶdeep learning
 
ARMテンプレートでサーバーレスに挑む!
ARMテンプレートでサーバーレスに挑む!ARMテンプレートでサーバーレスに挑む!
ARMテンプレートでサーバーレスに挑む!
 
C# 8
C# 8C# 8
C# 8
 

More from Takaaki Tanaka

Swiftをキめると 気持ちいい!
Swiftをキめると 気持ちいい!Swiftをキめると 気持ちいい!
Swiftをキめると 気持ちいい!Takaaki Tanaka
 
Enumはデキる子 ~ case .Success(let value): ~
 Enumはデキる子 ~ case .Success(let value): ~ Enumはデキる子 ~ case .Success(let value): ~
Enumはデキる子 ~ case .Success(let value): ~Takaaki Tanaka
 
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜Takaaki Tanaka
 
全部見せます!最前線エンジニアが語るBleアプリケーションのハマりどころ(i os)
全部見せます!最前線エンジニアが語るBleアプリケーションのハマりどころ(i os)全部見せます!最前線エンジニアが語るBleアプリケーションのハマりどころ(i os)
全部見せます!最前線エンジニアが語るBleアプリケーションのハマりどころ(i os)Takaaki Tanaka
 
モバイル開発者から見た サーバーレスアーキテクチャ
モバイル開発者から見た サーバーレスアーキテクチャモバイル開発者から見た サーバーレスアーキテクチャ
モバイル開発者から見た サーバーレスアーキテクチャTakaaki Tanaka
 
AddressBook to Contacts
AddressBook to ContactsAddressBook to Contacts
AddressBook to ContactsTakaaki Tanaka
 

More from Takaaki Tanaka (7)

Server Side? Swift
Server Side? SwiftServer Side? Swift
Server Side? Swift
 
Swiftをキめると 気持ちいい!
Swiftをキめると 気持ちいい!Swiftをキめると 気持ちいい!
Swiftをキめると 気持ちいい!
 
Enumはデキる子 ~ case .Success(let value): ~
 Enumはデキる子 ~ case .Success(let value): ~ Enumはデキる子 ~ case .Success(let value): ~
Enumはデキる子 ~ case .Success(let value): ~
 
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜
 
全部見せます!最前線エンジニアが語るBleアプリケーションのハマりどころ(i os)
全部見せます!最前線エンジニアが語るBleアプリケーションのハマりどころ(i os)全部見せます!最前線エンジニアが語るBleアプリケーションのハマりどころ(i os)
全部見せます!最前線エンジニアが語るBleアプリケーションのハマりどころ(i os)
 
モバイル開発者から見た サーバーレスアーキテクチャ
モバイル開発者から見た サーバーレスアーキテクチャモバイル開発者から見た サーバーレスアーキテクチャ
モバイル開発者から見た サーバーレスアーキテクチャ
 
AddressBook to Contacts
AddressBook to ContactsAddressBook to Contacts
AddressBook to Contacts
 

Recently uploaded

Windowsアップデート後の黒い画面を修正する方法|データ復元|ブラックスクリーン
Windowsアップデート後の黒い画面を修正する方法|データ復元|ブラックスクリーンWindowsアップデート後の黒い画面を修正する方法|データ復元|ブラックスクリーン
Windowsアップデート後の黒い画面を修正する方法|データ復元|ブラックスクリーンivanwang53
 
あらゆる通信環境で切れない「ネットモーション」のモバイルアクセス [NetMotion]
あらゆる通信環境で切れない「ネットモーション」のモバイルアクセス [NetMotion]あらゆる通信環境で切れない「ネットモーション」のモバイルアクセス [NetMotion]
あらゆる通信環境で切れない「ネットモーション」のモバイルアクセス [NetMotion]Taka Narita
 
Windows 10、Windows 11の付箋を簡単に復元する6つの方法|データ復元
Windows 10、Windows 11の付箋を簡単に復元する6つの方法|データ復元Windows 10、Windows 11の付箋を簡単に復元する6つの方法|データ復元
Windows 10、Windows 11の付箋を簡単に復元する6つの方法|データ復元ivanwang53
 
動的 & 非同期コンポーネント / Dynamic & Async Components
動的 & 非同期コンポーネント / Dynamic & Async Components動的 & 非同期コンポーネント / Dynamic & Async Components
動的 & 非同期コンポーネント / Dynamic & Async Componentsokitamasashi
 
ダウンロードがダウンロード(Downloads)フォルダに表示されない」問題の対処法
ダウンロードがダウンロード(Downloads)フォルダに表示されない」問題の対処法ダウンロードがダウンロード(Downloads)フォルダに表示されない」問題の対処法
ダウンロードがダウンロード(Downloads)フォルダに表示されない」問題の対処法ivanwang53
 
Windows Defenderのフル・クイック・カスタム・オフラインスキャンを実行する方法.docx
Windows Defenderのフル・クイック・カスタム・オフラインスキャンを実行する方法.docxWindows Defenderのフル・クイック・カスタム・オフラインスキャンを実行する方法.docx
Windows Defenderのフル・クイック・カスタム・オフラインスキャンを実行する方法.docxivanwang53
 

Recently uploaded (6)

Windowsアップデート後の黒い画面を修正する方法|データ復元|ブラックスクリーン
Windowsアップデート後の黒い画面を修正する方法|データ復元|ブラックスクリーンWindowsアップデート後の黒い画面を修正する方法|データ復元|ブラックスクリーン
Windowsアップデート後の黒い画面を修正する方法|データ復元|ブラックスクリーン
 
あらゆる通信環境で切れない「ネットモーション」のモバイルアクセス [NetMotion]
あらゆる通信環境で切れない「ネットモーション」のモバイルアクセス [NetMotion]あらゆる通信環境で切れない「ネットモーション」のモバイルアクセス [NetMotion]
あらゆる通信環境で切れない「ネットモーション」のモバイルアクセス [NetMotion]
 
Windows 10、Windows 11の付箋を簡単に復元する6つの方法|データ復元
Windows 10、Windows 11の付箋を簡単に復元する6つの方法|データ復元Windows 10、Windows 11の付箋を簡単に復元する6つの方法|データ復元
Windows 10、Windows 11の付箋を簡単に復元する6つの方法|データ復元
 
動的 & 非同期コンポーネント / Dynamic & Async Components
動的 & 非同期コンポーネント / Dynamic & Async Components動的 & 非同期コンポーネント / Dynamic & Async Components
動的 & 非同期コンポーネント / Dynamic & Async Components
 
ダウンロードがダウンロード(Downloads)フォルダに表示されない」問題の対処法
ダウンロードがダウンロード(Downloads)フォルダに表示されない」問題の対処法ダウンロードがダウンロード(Downloads)フォルダに表示されない」問題の対処法
ダウンロードがダウンロード(Downloads)フォルダに表示されない」問題の対処法
 
Windows Defenderのフル・クイック・カスタム・オフラインスキャンを実行する方法.docx
Windows Defenderのフル・クイック・カスタム・オフラインスキャンを実行する方法.docxWindows Defenderのフル・クイック・カスタム・オフラインスキャンを実行する方法.docx
Windows Defenderのフル・クイック・カスタム・オフラインスキャンを実行する方法.docx
 

Swift api design guidelines (dec 3, 2015)