Article

Calling Objective-C APIs Asynchronously Objective-C APIを非同期に呼び出す

Learn how functions and methods that take a completion handler are converted to Swift asynchronous functions. 完了ハンドラをとる関数およびメソッドがどのようにSwift非同期関数へと変換されるかを学んでください。

Overview 概要

In Cocoa, methods that perform asynchronous operations take a completion handler as their last parameter, and the method calls that block after the operation finishes to return a result or an error. Swift 5.5 and later automatically translates Objective-C methods that take completion handlers into asynchronous methods using Swift's native concurrency support, in addition to importing the callback-based version of the method into Swift. Because both Swift methods have the same behavior, they share the same page in the documentation. Cocoaでは、非同期演算を実行するメソッドは、それの最後のパラメータとしてある完了ハンドラを、そして演算が終了する後では遮断するメソッド呼び出しいくつかをとって、結果またはエラーを返します。Swift 5.5以降は、完了ハンドラをとるObjective-Cメソッドを非同期メソッドへとSwiftの生得の並行性サポートを使って自動的に翻訳します、そのメソッドのコールバック基盤バージョンをSwiftへとインポートするのに加えて。両方のSwiftメソッドは同じ挙動を持つことから、それらは文書化において同じページを共有します。

For information about asynchronous functions, see Concurrency in The Swift Programming Language. 非同期関数についての情報として、並行性をThe Swift Programming Languageで見てください。

Understand How Swift Imports Completion Handlers どのようにSwiftが完了ハンドラをインポートするか理解する

Swift imports Objective-C methods that take a completion handler as two related Swift methods: a method that takes a closure, and an asynchronous method that doesn’t take a closure. For example, consider the present(completion:) method from PassKit. In Objective-C, it's declared like this: Swiftは、完了ハンドラをとるObjective-Cメソッドを2つの同族のSwiftメソッド:あるクロージャをとるメソッド、そしてクロージャをとらない非同期メソッドとしてインポートします。例として、PassKit由来のpresent(completion:)メソッドを考えてみてください。Objective-Cでは、それはこのように宣言されます:


- (void)presentWithCompletion:(void (^)(BOOL success))completion;

However, in Swift, it’s imported as two methods: しかしながら、Swiftでは、それは2つのメソッドとしてインポートされます:


func present(completion: ((Bool) -> Void)? = nil)


func present() async -> Bool

The first version, present(completion:), has a return type of Void and takes a completion handler. The second version, present(), returns a Boolean value and is an asynchronous method. 最初のバージョン、present(completion:)は、Voidの戻り型を持ち、そしてある完了ハンドラをとります。2番目のバージョン、present()は、ブール値を返します、そして非同期メソッドです。

Methods whose completion handlers populate a NSError pointer parameter also become throwing methods in Swift, as described in About Imported Cocoa Error Parameters. The NSError parameter on an asynchronous throwing method must also be nullable, which indicates that the parameter is used only to communicate an error. For example, consider the write(_:timeout:completionHandler:) method from URLSessionStreamTask. In Objective-C, it's declared like this: それの持つ完了ハンドラにNSErrorポインタパラメータが入っているメソッドはまた、Swiftではスローするメソッドになります、インポートされるCocoaエラーパラメータについてで記述されるように。非同期スローメソッド上のNSErrorパラメータは、同様にnull可能でなければなりません、それはそのパラメータがエラーとの通信にのみ使われることを指し示します。例えば、URLSessionStreamTask由来のwrite(_:timeout:completionHandler:)メソッドを考えてみてください。Objective-Cでは、それはこのように宣言されます:


- (void)writeData:(NSData *)data
          timeout:(NSTimeInterval)timeout
completionHandler:(void (^) (NSError * _Nullable error))completionHandler;

As in the previous example, Swift imports this Objective-C method as two methods: an asynchronous method that takes a closure, and an asynchronous throwing method. 前の例でのように、SwiftはこのObjective-Cメソッドを2つのメソッドとしてインポートします:クロージャを取る非同期メソッド、そして非同期スローメソッド。


func write(
    _ data: Data, 
    timeout: TimeInterval, 
    completionHandler: @escaping (Error?) -> Void
)


func write(_ data: Data, timeout: TimeInterval) async throws

Methods whose completion handlers take multiple arguments become methods that return a tuple. For example, the sign(_:using:completion:) method from PassKit is declared like this in Objective-C: それの完了ハンドラが複数の引数をとるメソッドは、あるタプルを返すメソッドになります。例えば、PassKit由来のsign(_:using:completion:)メソッドはObjective-Cにおいてこのように宣言されます:


- (void)signData:(NSData *)signData 
withSecureElementPass:(PKSecureElementPass *)secureElementPass 
      completion:(void (^)(NSData *signedData, NSData *signature, NSError *error))completion;

In Swift it‘s imported as two methods, an asychronous method that takes a closure and an asynchronous throwing method that returns a tuple: Swiftではそれは2つのメソッドとしてインポートされます、あるクロージャをとる非同期メソッドそしてあるタプルを返す非同期スローメソッド:


func sign(
    _ signData: Data, 
    using secureElementPass: PKSecureElementPass, 
    completion: @escaping (Data?, Data?, Error?) -> Void
)


func sign(_ signData: Data, 
    using secureElementPass: PKSecureElementPass
) async throws -> (Data, Data)

Understand the Conversion Rules 変換規則を理解する

The method that takes a completion handler must meet the following requirements: 完了ハンドラをとるメソッドは、以下の要件を満たさなければなりません:

  • The method has a void return type. そのメソッドはvoid戻り型を持つ。

  • The block has a void return type. そのブロックはvoid戻り型を持つ。

  • The block is called exactly once, on all possible paths of control flow. そのブロックは、制御の流れの全ての可能な経路上で、厳密に一回だけ呼び出される。

If the method has only one parameter and its selector ends with one of the following suffixes, Swift imports the method as an asynchronous method: メソッドがただ1つのパラメータを持つ、そしてそれのセレクタが以下の接尾辞の1つで終わるならば、Swiftはそのメソッドをある非同期メソッドとしてインポートします:

  • WithCompletion

  • WithCompletionHandler

  • WithCompletionBlock

  • WithReplyTo

  • WithReply

If the method has more than one parameter, and the last parameter's selector piece is one of the following, Swift imports the method as an asynchronous method: メソッドが1つ以上のパラメータを持つ、そして最後のパラメータの持つセレクタ部分が以下の1つであるならば、Swiftはそのメソッドをある非同期メソッドとしてインポートします:

  • completion

  • withCompletion

  • completionHandler

  • withCompletionHandler

  • completionBlock

  • withCompletionBlock

  • replyTo

  • withReplyTo

  • reply

  • replyTo

The name of the Swift method is modified from the Objective-C method as follows: Swiftメソッドの名前は、Objective-Cメソッドから以下のように修正されます:

  • The selector piece for the completion handler is removed. 完了ハンドラのセレクタ部分は、取り除かれます。

  • If the selector starts with get, that prefix is removed and leading initialisms are converted to lowercase. セレクタがgetで始まるならば、その接頭辞は取り除かれます、そして先導している頭文字それらは小文字に変換されます。

  • If the selector ends with Asynchronously, that suffix is removed. セレクタがAsynchronouslyで終わるならば、その接尾辞は取り除かれます。

  • If the method calls its completion handler with a nullable parameter, the asynchronous version in Swift is marked with the @discardableResult attribute. メソッドがそれの完了ハンドラをヌル可能パラメータで呼び出すならば、Swiftでの非同期版は、@discardableResult属性で印されます。

See Also 参照

Language Interoperability 言語互換性