MKMapSnapshotter initWithOptions nullability

Published by malhal on

MKMapSnapshotter has the following constructor (within NS_ASSUME_NONNULL_BEGIN):

- (instancetype)initWithOptions:(MKMapSnapshotOptions *)options NS_DESIGNATED_INITIALIZER;

Which means an options param must be supplied. However the documentation contradicts this, stating “If you specify nil for this property, the snapshotter uses a set of default options that capture an image of the current user’s country”, thus it should be tagged nullable:

- (instancetype)initWithOptions:(nullable MKMapSnapshotOptions *)options NS_DESIGNATED_INITIALIZER;

This is odd because the MapKit API has been updated for nullability so I think maybe was skipped because it wasn’t straightforward. Using a decompiler we can see the code has problems, rather than the init being disallowed it actually exists and looks like this:

- (instancetype)init{
    return [self initWithOptions:nil];

And the initWithOptions checks for the nil param and creates an instance of MKMapSnapshotOptions (which has all the settings needed in its default states. This is actually not the correct way to implement designated initializers and initWithOptions should actually disallow null and the init should be:

- (instancetype)init{
    return [self initWithOptions:[MKMapSnapshotOptions.alloc init]];

I think the best way to resolve this is just to add init to the header and document that it will use a default MKMapSnapshotOptions and remove the nil options allowed to initWithOptions in the documentation. That is better than making init NS_UNAVAILABLE and adding nullable to initWithOptions because its what coders who understand designated inits expect.