iosobjective-cparse-platformobjective-c-nullability

PF_NULLABLE parse framework difficult to understand, sending Message's to PFUser


With Xcode 6.3 Parse. framework was giving me errors, so I download the updated Parse framework and things started working.

Now, there is something new which I am trying to understand what this method logInWithUsername is. Previously it used to pretty simple. I see more null while writing the code. And at some point I get confused, mainly with pointer to a pointer (i.e NSError).

[PFUser logInWithUsername:(NSString * __nonnull) 
                 password:(NSString * __nonnull) 
                    error:(NSError * __nullable __autoreleasing * __nullable)];

When I jump to definition, it's a quite a different story, the syntax seems to be clear here:

+ (PF_NULLABLE instancetype)logInWithUsername:(NSString *)username
                                     password:(NSString *)password
                                        error:(NSError **)error;

Am I missing something on configuration or setup side for this framework?


Solution

  • From the Objective-C end, you could completely ignore these nullability annotations. These are strictly there for interfacing with Swift and allowing whether Swift should treat the object as an optional or non-optional, rather than treating everything as an implicitly unwrapped optional.

    If we translate your Objective-C method:

    [PFUser logInWithUsername:(NSString * __nonnull) 
                     password:(NSString * __nonnull) 
                        error:(NSError * __nullable __autoreleasing * __nullable)];
    

    The Swift equivalent would be:

    PFUser.logIn(username: String, password: String, error: inout NSError?)
    

    The gist of it is this: The method does not accept nil for the username or password arguments, but it expects an optional reference to an optional error object.

    That is, it doesn't matter if your pointer is nil, or if what it points to is nil (both are allowed to be nil). The method will sort it out.

    If you call the method and pass nil for the error parameter, you are passing a nil pointer. If you pass an uninitialized NSError pointer (NSError *error = nil;), you are passing a non-nil pointer to a nil pointer to an NSError object.

    But again, if you are working with this library from the Objective-C side, you can ignore this completely. It works just like it always did. This only makes an impact from the Swift end where the compiler is strict about the nullability of parameters.

    For more reading on Objective-C nullability annotations, see this Stack Overflow answer.