This past week John Sundell wrote a blog post (Unit testing asynchronous Swift code) about unit testing asynchronous code.
As I was trying to apply some of the techniques when I came across a method I couldn’t mock because I was getting an error.
Objective-C method
addNotificationRequest:withCompletionHandler:
provided by methodadd(_:withCompletionHandler:)
does not match the requirement’s selector (add:withCompletionHandler:
)
Consider the following method for UNUserNotificationCenter
in Swift.
func add(_ request: UNNotificationRequest, withCompletionHandler completionHandler: ((Error?) -> Swift.Void)? = nil)
If you would want to create a Swift protocol to mimic the interface to UNUserNotificationCenter
that would be pretty simple.
@objc
protocol UserNotificationCenter {
func add(_ request: UNNotificationRequest, withCompletionHandler completionHandler: ((Error?) -> Swift.Void)?)
}
The problem is that the method signature in Swift is different from the method signature in Objective-C. Here is the method definition in Objective-C.
- (void)addNotificationRequest:(UNNotificationRequest *)request withCompletionHandler:(nullable void(^)(NSError *__nullable error))completionHandler;
Since the Objective-C method has a different method signature than the Swift version, we have to specify the Objective-C method signature in our protocol.
@objc(addNotificationRequest:withCompletionHandler:)
func add(_ request: UNNotificationRequest, withCompletionHandler completionHandler: ((Error?) -> Swift.Void)?)
Now we can implement that method in our mock object!