Skip to content

Make all synchronous APIs have 'throws' in Swift 2. #162

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 4, 2015

Conversation

nlutsenko
Copy link
Contributor

  • Made all synchronous APIs have throws when used from Swift.
  • Added backward compatible macro PF_SWIFT_UNAVAILABLE, please note that this macro does nothing when compiled with Xcode 6.4, but only works on Xcode 7 (the one that has Swift 2).

After change (Swift 2):

class PFObject : NSObject {
    public func save() throws
}

Before change (Swift 2):

class PFObject : NSObject {
    public func save() -> Bool
    public func save(error: NSErrorPointer) -> Bool
}

Before && After Change (Swift 1.2):

class PFObject : NSObject {
    public func save() -> Bool
    public func save(error: NSErrorPointer) -> Bool
}

closes #152

cc @richardjrossiii

@grantland
Copy link

Looks awesome!

@adonoho
Copy link

adonoho commented Sep 3, 2015

Thank you for doing this. I will import this branch and try it out.

@adonoho
Copy link

adonoho commented Sep 3, 2015

 /*!
  @abstract *Synchronously* fetches the PFObject with the current data from the server.
  */
-- (instancetype)fetch;
+- (instancetype)fetch PF_SWIFT_UNAVAILABLE;
 /*!
  @abstract *Synchronously* fetches the PFObject with the current data from the server and sets an error if it occurs.

  @param error Pointer to an `NSError` that will be set if necessary.
  */
 - (instancetype)fetch:(NSError **)error;

 /*!
  @abstract *Synchronously* fetches the `PFObject` data from the server if <isDataAvailable> is `NO`.
  */
-- (PF_NULLABLE PFObject *)fetchIfNeeded;
+- (PF_NULLABLE PFObject *)fetchIfNeeded PF_SWIFT_UNAVAILABLE;

 /*!
  @abstract *Synchronously* fetches the `PFObject` data from the server if <isDataAvailable> is `NO`.

  @param error Pointer to an `NSError` that will be set if necessary.
  */
 - (PF_NULLABLE PFObject *)fetchIfNeeded:(NSError **)error;

I wish to bring your attention the differences between:

 - (instancetype)fetch:(NSError **)error;

and

 - (PF_NULLABLE PFObject *)fetchIfNeeded:(NSError **)error;

Both are calls that can fail. Forgiving my lack of experience with your framework's patterns,shouldn't they have the same return type that is nullable to ensure that try-catch functions properly? For example:

 - (PF_NULLABLE instancetype)fetch:(NSError **)error;

Should all synchronous methods using try catch return (PF_NULLABLE instancetype)?

Anon,
Andrew

@nlutsenko
Copy link
Contributor Author

Thanks for bringing this up! You are absolutely correct, this is our mistake.
All of these methods should have PF_NULLABLE, since they will actually return nil if there is an error.
Will address in a separate Pull Request.

@adonoho
Copy link

adonoho commented Sep 3, 2015

I suspect you should also consider replacing the PFObject * with instancetype.

@nlutsenko
Copy link
Contributor Author

👍

nlutsenko added a commit that referenced this pull request Sep 4, 2015
Make all synchronous APIs have 'throws' in Swift 2.
@nlutsenko nlutsenko merged commit 2e899eb into master Sep 4, 2015
@nlutsenko nlutsenko deleted the nlutsenko.swift2 branch September 4, 2015 01:28
@anthony-lai
Copy link

Hi, I had a quick question on how to update my xcode 6.4 code to the xcode 7 version.

Old code:

func a()
    item = b()
    if item == nil {..}
    else {..}

func b() -> PFObject?
    let x = PFObject(className: data)
    let success = x.save()
    if success { return x }
    return nil

now that save doesn't return a boolean, I am attempting to accomplish the same result with:

do {
    try x.save()
    return x
} catch {
    return nil
}

Is this the proper syntax / intended method?

@nlutsenko
Copy link
Contributor Author

@anthony-lai, yes that is correct syntax.
Something like this would fit

func b() -> PFObject? {
    let x = PFObject(className: "Yolo")
    do {
        try x.save()
        return x
    } catch let error {
        print(error)
        return nil
    }
}

You could also make the function itself throw, so you can propagate the error further.

func b() throws -> PFObject {
    let x = PFObject(className: "Yolo")
    try x.save()
    return x
}

@richardjrossiii
Copy link
Contributor

@nlutsenko You can also use swift's try? syntax, which will discard the error (as parse will already print it for you), and wrap the optional automatically as well. This prevents an additional do/catch block :D

@anthony-lai
Copy link

@nlutsenko @richardjrossiii Thanks!

@nlutsenko
Copy link
Contributor Author

(-‸ლ) @richardjrossiii you are right... Absolutely forgot about the optional try?.
On this note - I still like the throws and non-optional functions much more 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Swift v2 Error Handling
6 participants