web-dev-qa-db-ja.com

既存のオブジェクトに拡張子を追加するSwiftファイルに名前を付けるためのベストプラクティスは何ですか?

言語仕様 で説明されているように、拡張機能を使用して、既存のSwiftオブジェクトタイプに拡張機能を追加することができます。

その結果、次のような拡張機能を作成できます。

extension String {
    var utf8data:NSData {
        return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
    }
}

ただし、このような拡張子を含むSwiftソースファイルのベストネーミングプラクティスは何ですか?

以前は、 Objective-Cガイド で説明されているように、Objective-Cタイプにextendedtype+categoryname.mを使用するという規則がありました。ただし、Swiftの例にはカテゴリ名がなく、String.Swiftを呼び出すことは適切ではないようです。

質問は次のとおりです。上記のString拡張子が与えられた場合、Swiftソースファイルは何と呼ばれますか?

142
AlBlue

私が見たほとんどの例は、Objective-Cのアプローチを模倣しています。上記の拡張子の例は次のとおりです。

String+UTF8Data.Swift

利点は、命名規則により、それが拡張であり、どのクラスが拡張されているかを簡単に理解できることです。

Extensions.SwiftまたはStringExtensions.Swiftを使用する場合の問題は、ファイルの内容を見ずに名前でファイルの目的を推測することができないことです。

Javaで使用されるxxxable.Swiftアプローチの使用は、メソッドのみを定義するプロトコルまたは拡張に対しては問題なく機能します。ただし、上記の例では、UTF8Dataable.Swiftが文法的に意味をなさないように属性を定義しています。

168
picciano

Swift規則はありません。複雑にしないでおく:

StringExtensions.Swift

拡張するクラスごとに1つのファイルを作成します。すべての拡張子に単一のファイルを使用すると、すぐにジャングルになります。

5
Mike Taverne

私の好みは、ファイルの先頭に「Extension_」を置くことです。 (関連するすべての拡張子を同じファイルに入れました。)

このように、すべての拡張ファイルは、アプリのディレクトリとXcodeのナビゲーターにアルファベット順にまとめられています。もちろん、ナビゲーターでグループ化することもできます。

したがって、文字列関連の拡張はExtension_String.Swiftに入ります

0
leanne

チームで合意された一般的なその他の拡張機能セットがある場合は、それらをExtensions.Swiftとしてまとめて、Keep-It-Simpleの第1レベルのソリューションとして機能します。ただし、複雑さが増したり、拡張機能がより複雑になると、複雑さをカプセル化するための階層が必要になります。このような状況では、例を挙げて次のプラクティスをお勧めします。

Serverというバックエンドと通信するクラスがありました。 2つの異なるターゲットアプリをカバーするために大きくなり始めました。一部の人々は大きなファイルを好むが、論理的に拡張子で分割されます。私の好みは各ファイルを比較的短くすることであるため、次の解決策を選択しました。 Serverは元々CloudAdapterProtocolに準拠し、そのすべてのメソッドを実装していました。私がやったのは、下位プロトコルを参照することにより、プロトコルを階層に変えることでした:

protocol CloudAdapterProtocol: ReggyCloudProtocol, ProReggyCloudProtocol {
    var server: CloudServer {
        get set
    }
    func getServerApiVersion(handler: @escaping (String?, Error?) -> Swift.Void)
}

Server.Swiftにある

import Foundation
import UIKit
import Alamofire
import AlamofireImage

class Server: CloudAdapterProtocol {
.
.
func getServerApiVersion(handler: @escaping (String?, Error?) -> Swift.Void) {
.
.
}

Server.Swiftは、サーバーを設定してAPIバージョンを取得するためのコアサーバーAPIを実装するだけです。実際の作業は2つのファイルに分割されます。

Server_ReggyCloudProtocol.Swift
Server_ProReggyCloudProtocol.Swift

これらはそれぞれのプロトコルを実装しています。

これは、他のファイル(この例ではAlamofireの場合)にインポート宣言が必要であることを意味しますが、私の見解ではインターフェースを分離するという点ではクリーンなソリューションです。

このアプローチは、外部で指定されたクラスだけでなく、独自のクラスでも同様にうまく機能すると思います。

0
Faisal Memon

ファイルをStringExtensions.SwiftString+utf8Data.Swiftのようなものに分割するためにあまりにも多くのものを追加するまで、String+Encrypt.Swiftを好みます。

もう1つ、似たようなファイルを1つにまとめると、建物がより速くなります。 Optimizing-Swift-Build-Times を参照してください

0
DawnSong