I'm new with Swift and I begin exploring some feature for bridging with Objective-C.
Currently I have a method with NSError
reference which is:
- (BOOL) verifyPersonalizationWithError:(NSError **) error NS_REFINED_FOR_SWIFT;
Now I can access the method in Swift for some refinements, but the return value is lost. The generated method for Swift is:
open func __verifyPersonalization() throws
The error is correctly handled with the do catch but the return value seems to be lost.
Any missing thing for my NS_REFINED_FOR_SWIFT macro?
This is unrelated to the NS_REFINED_FOR_SWIFT
macro. The Objective-C
method
- (BOOL) verifyPersonalizationWithError:(NSError **) error;
is imported to Swift as
open func verifyPersonalization() throws
and the only effect of the NS_REFINED_FOR_SWIFT
macro is to prepend
underscores to the Swift method name
open func __verifyPersonalization() throws
which allows to provide a refined Swift interface in an extension, while keeping the original implementation available to be called from the refined interface (see "Refining Objective-C Declarations" in Swift and Objective-C in the Same Project).
The Swift importer assumes that the boolean return value of the Objective-C method indicates success or failure, which is the common Cocoa pattern as documented in Using and Creating Error Objects:
Important: Success or failure is indicated by the return value of the method. Although Cocoa methods that indirectly return error objects in the Cocoa error domain are guaranteed to return such objects if the method indicates failure by directly returning nil or NO, you should always check that the return value is nil or NO before attempting to do anything with the NSError object.
A typical usage in Objective-C is
NSError *error;
if ([self verifyPersonalizationWithError:&error]) {
NSLog(@"success");
} else {
NSLog(@"failed: %@", error.localizedDescription);
}
The Swift method throws an error on failure, so there is no need for a boolean return value:
do {
try verifyPersonalization()
print("success")
} catch {
print("failed:", error.localizedDescription)
}
If the Objective-C method really indicates failure by leaving
a non-null error in the error parameter (instead of returning false
, which is the usual Cocoa pattern) then you can indicate that
by adding a attribute:
- (BOOL) verifyPersonalizationWithError:(NSError **) error
__attribute__((swift_error(nonnull_error)));
which is imported to Swift as
open func verifyPersonalization() throws -> Bool
The swift_error
attribute is documented at https://github.com/apple/swift-clang/blob/383859a9c4b964af3d127b5cc8abd0a8f11dd164/include/clang/Basic/AttrDocs.td#L1800-L1819
来源:https://stackoverflow.com/questions/45565960/ns-refined-for-swift-and-return-value