Edited at

【Swift】エクステンション


エクステンションとは?

エクステンションとは、すでに存在しているプロパティやメソッド、イニシャライザなどを型を構成する要素に追加する事を可能にする構文です。


定義方法

エクステンションはextensionで宣言でき、{}内に対象の型に追加したい要素を追加できます。

extension エクステンションを定義する対象の型(既存の型) {

追加したい要素
}


追加可能な要素


メソッド

エクステンションにはメソッドを追加することが可能で、通常のメソッドと同じように使用できます。

下記サンプルコードの通り、追加したメソッドを普通に使用しています。

//String型に新しいメソッドを追加

extension String {
func printSelf() {
print(self)
}
}

let string = "abc"
string.printSelf()

//実行結果
abc


コンピューテッドプロパティの追加

エクステンションで気をつけなければいけないのが、ストアドプロパティの追加はできず、しかしコンピューテッドプロパティの追加はできるという点です。

コンピューテッドプロパティを使用することで既存の型に対して頻繁に行われる処理を型自身に定義でき、メソッドと同じく既存のプロパティと同じように使用することが可能です。

extension String {

 //コンピューテッドプロパティのため値を保持しない
var enclosedString: String {
return "【\(self)】"
}
}

let title = "重要".enclosedString + "今日は休み"

//実行結果
【重要】今日は休み


イニシャライザの追加

エクステンションではイニシャライザを追加することも可能です。

そして既存の型にイニシャライザを追加することで、そのアプリ独自の情報から既存の型でのインスタンス生成も可能にします。

次のサンプルコードを見てください。

import UIKit

//アプリケーション独自のエラー(固有の情報)
enum WebAPIError : Error {
case connectionError(Error)
case fatalError

var title: String {
switch self {
case .connectionError:
return "通信エラー"
case .fatalError:
return "致命的エラー"
}
}
var message: String {
switch self {
case .connectionError(let underlyingError):
return underlyingError.locaizedDescription
+ "再試行してください"
case .fatalError:
return "サポート窓口に連絡してください"
}
}
}

extension UIAlertController {
//イニシャライザの引数にwebAPIError型の値をとる
convenience init(webAPIError: WebAPIError) {
  
self.init(title: webAPIError .title,
message: webAPIError.message,
preferredStyle: .alert
}
}

let error = WebAPIError.fatalError
let alertController = UIAlertController(webAPIError: error)

上記のコードはアプリケーションでエラーが発生した際に出すアラート画面の実装処理を表しています。

最初に定義されたWebAPIError型内では発生したエラーが何エラーでそれに対応したアラート文を分岐処理で返り値を返しています。

次にエクステンションされているUIAlertControllerですが、これはアラート画面を表示するCocoa TouchのUIAlertControllerというクラスでありSwift既存の用意されたクラスになります。それに対してイニシャライザを追加し、引数に先ほどのWebAPIErrorの分岐処理の結果を引数に与えることで、任意の文字列をアラート画面として出力することを可能にしました。

イニシャライザの追加は以上のように使用することができます。

参考にUIAlertControolerの公式リファレンスを記載しておきます。

https://developer.apple.com/documentation/uikit/uialertcontroller