Help us understand the problem. What is going on with this article?

SwiftのExtensionをより分かりやすく -TargetedExtension-

はじめに

本記事はCyberAgent 20新卒 Advent Calendar 2019の13日目の記事です!
もうすこしでクリスマスですね🎅🎄

// TODO: 追記します!
- 昨日の投稿は, Ayumuくんの「Lottieを使ったAndroidのアニメーション実装」でした!
- そして, 14日目の投稿はdragon_taroくんの「」です!
ぜひこちらもご覧ください!!

本日(アドベントカレンダー13日目)の記事は, よだだよ!or ヨーダが担当します!
普段から触っている技術はiOSで, 最近は研究や受託開発等でARKitを使うことが多いです.

しかし,
今回はSwiftExtensionの記事を書こうと思います!

※実は, 「ARKitを使って, クリスマスぽいお絵かきARアプリを作ってみよう!🎄🎨」というタイトルで書こうと思ってましたが, 間に合わなそうなのでテーマを急遽変更しました!
時間のあるときにでも, お絵かきAR作ってみる記事は書こうと思います.

SwiftのExtensionとは...

  1. クラスや構造体, 列挙体の拡張
  2. プロトコル拡張(デフォルト実装)
  3. クラスや構造体, 列挙体をプロトコルに適合させる
Extension+String.swift
extension String {
  // 追加するメソッド等
  func printHoge() {
    print("hoge")
  }
}

// 呼び出し
String().printHoge()

↑例えばこのように拡張することはあるかと思いますが,
もとからあるのもなのか, それとも拡張され追加されたものなのかを判別するのは分からないと言う問題があります.

そこで, 拡張され追加されたものには, プレフィックスを付けます.
そのようにすることによって, 拡張されたものであることが明示的になると同時に, プロパティの衝突も避けることができます.

では, ここから実際にTargetedExtensionを実装していきます!

Extensions実装

今回は例として, FileManagerを拡張してみたいと思います!
ちなみに, このメソッドは指定パスにあるファイルを一覧を表示するものです.

下のものは, 単純にFileManagerを拡張したものになります.

FileManager+Extensions.swift
import Foundation

public extension FileManager {
    /// List local files (specified path)
    func listupLocalFiles(path: String) {
        do {
            // Get all file name strings in path
            let files = try FileManager().contentsOfDirectory(atPath: path)
            // Get file name as String array
            print(files)
        }
        catch let error {
            // Error : If path doesn't exist
            print(error)
        }
    }
}

// Usage: Temp Directory
let fm = FileManager()
fm.listupLocalFiles(path: NSTemporaryDirectory())

普通に拡張すると, fm.listupLocalFiles(path: NSTemporaryDirectory())になり,
最初に挙げたように, 元からあるものなのか, 追加されたものなのかが分かりません.

Targeted Extensionsで実装

FileManager+Extensions.swift
import Foundation

public protocol FileManagerComapatible {
    associatedtype CompatibleType

    var ex: CompatibleType { get }
}

public final class FileManagerExtension<Base> {
    private let base: Base
    public init(_ base: Base) {
        self.base = base
    }
}

public extension FileManagerComapatible {
    var ex: FileManagerExtension<Self> {
        return FileManagerExtension(self)
    }
}

extension FileManager: FileManagerComapatible { }

extension FileManagerExtension where Base == FileManager {
    /// ローカルファイル(指定パス)のリストアップ
    func listupLocalFiles(path: String) {
        do {
            // Get all file name strings in path
            let files = try FileManager().contentsOfDirectory(atPath: path)
            // Get file name as String array
            print(files)
        }
        catch let error {
            // Error : If path doesn't exist
            print(error)
        }
    }
}

// Usage:
// let fm = FileManager()
// fm.ex.listupLocalFiles(path: NSTemporaryDirectory())

TargetedExtension呼ばれる形で実装することで,fm.ex.listupLocalFiles(path: NSTemporaryDirectory())といった形にすることができます.

メソッドの前に, exを挟むことで, 「これは追加されたもの」なんだと理解することができます!

// TODO: コードの説明の追加

まとめ

  • TargetedExtension呼ばれるにすることで, Extensionであることが明示的になる
  • また, 名前の衝突も避けることができるというメリットが生まれます.

※後で, #TargetedExtension部分は, コードの説明を交えて丁寧なものにしたいと思います.

参考

告知

今年もサイバーエージェントの本選考がやってきたみたいです!
興味ある方は, 以下のURLからチェックしてみてください!!
https://www.cyberagent.co.jp/careers/special/engineer2021/

  • 早期選考で内定となった場合, 長期実務インターンをすることができます!
  • #cypitch をつけてTwitterに呟くと, それが会社説明資料になるみたいです!

僕自身がCyberAgentを選んだ理由はたくさんありますが,
その1つとして「人の良さ」です!!
「人の良さ」ってのを言葉で正確に伝えるのは難しいので, Zehi社員さんに会ってみてください!(勿論, 内定者でも大丈夫です!)
きっとこの言葉の意味が感じられるような気がします!

最後まで読んでくださり, ありがとうございました🙇‍♂️

yodaaa
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした