user5812721 user5812721 - 5 months ago 70
Swift Question

I used Swiftify to convert some Obj C code to Swift and got errors that I don't know how to deal with

This is a section of the code that was translated:

Objective C:

[SPTRequest userInformationForUserInSession:session callback:^(NSError *error, SPTUser *user) {
if (error != nil) {
UIAlertView *view = [[UIAlertView alloc] initWithTitle:@"Getting User Info Failed"
message:error.userInfo[NSLocalizedDescriptionKey]
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[view show];
return;
}


Swift:

1 SPTRequest.userInformationForUserInSession(session, callback: {(error: NSError, user: SPTUser) -> Void in
2 if error != nil {
3 var view: UIAlertView = UIAlertView(title: "Getting User Info Failed", message: error.userInfo[NSLocalizedDescriptionKey], delegate: nil, cancelButtonTitle: "OK", otherButtonTitles: "")
4 view.show()
5 return
6 }


Errors:

1:
Cannot convert value of type '(NSError, SPTUser) -> Void' to expected argument type 'SPTRequestCallback!'


2:
Value of type 'NSError' can never be nil, comparison isn't allowed


3:
Cannot subscript a value of the type '[NSObject: AnyObject]' with an index of type 'String'


What I'm most confused about is how Objective C would work but the Swift translation doesn't. My bridging header is set up right as well.

Thanks!

Rob Rob
Answer

It should look something like:

SPTRequest.userInformationForUserInSession(session) { error, user in
    guard error == nil else {
        let alert = UIAlertView(title: "Getting User Info Failed", message: error.localizedDescription, delegate: nil, cancelButtonTitle: "OK", otherButtonTitles: "")
        alert.show()
        return
    }

    // carry on
}

A few observations:

  1. Don't bother specifying types for the error and user types, and let it infer that for you.
  2. I also used trailing closure syntax which eliminates the need for the callback parameter.
  3. I'd also use guard to check for error conditions.
  4. I'd use error.localizedDescription rather than trying to get it out of the userDict. It's more intuitive and easier.

As an aside, nowadays we'd use UIAlertController rather than UIAlert. Furthermore, and more significantly, the whole userInformationForUserInSession appears to be deprecated, so I'm not sure you should be using this method at all.