0

Here is my line of code in Swift, it calls a method:

networkManager.postUserProfile(self, onSuccess: {(username: String, userID: NSNumber, recommendedLessons: [AnyObject]) -> Void in
    ... code block
}, onFailure: {(error: NSError) -> Void in
    ... another code block
})

The networkManager class is from Objective-C and is:

- (void)postUserProfile:(Profile *)profile
              onSuccess:(void(^)(NSString *username, NSNumber *userID, NSArray *recommendedLessons))successBlock
              onFailure:(void(^)(NSError *error))failureBlock;

And the error message is:

error: cannot convert value of type (String, NSNumber, [AnyObject]) -> Void to expected argument type ((String!, NSNumber!, [AnyObject]!) -> Void)!

When calling a method, I understand that the ! operator will force-unwrap an optional. However in this situation, what is the meaning of the ! in the expected argument type?

William Entriken
  • 37,208
  • 23
  • 149
  • 195

1 Answers1

2

There are many excellent existing answers (such as these) explaining what implicitly unwrapped optionals are and why they are used, so I won't go into that.

Object pointer types in Objective-C header files are treated as implicitly unwrapped optionals in Swift because the compiler doesn't know if nil is a valid value.

Your code should compile if you add an exclamation mark after each of the types in the block you are passing to postUserProfile:

networkManager.postUserProfile(self, onSuccess: { (username: String!, userID: NSNumber!, recommendedLessons: [AnyObject]!) -> Void in
    ... code block
}, onFailure: { (error: NSError!) -> Void in
    ... another code block
})

However, a better solution is to add nullability annotations to your Objective-C header file. The properties you mark nullable will be regular optionals and the rest will be non-optionals.

Community
  • 1
  • 1
titaniumdecoy
  • 18,900
  • 17
  • 96
  • 133