UIActivityItemProvider's item property should be nullable

Originator:robotspacer
Number:rdar://28394697 Date Originated:20-Sep-2016 05:58 PM
Status:Open Resolved:
Product:iOS SDK Product Version:iOS 10.0.1
Classification:Enhancemnt Reproducible:N/A
 
Summary:
When I first started using UIActivityItemProvider I had no idea the item method was supposed to return a nonnull value. This was before things were explicitly marked as such, and the documentation doesn't say anything about it. Moreover, it seemed to work fine, and gave me the result I was after: I could customize which items were shared based on the activity, by returning nil to exclude a particular item. Or if there was an error generating the content, I could return nil to skip that item.

It looks like it was marked as nonnull a while back, and Xcode 8 finally started giving me an error about it. I've tried to find a different solution to my problem but the API seems deficient. The UIActivityItemSource protocol allows you to return a nil value from activityViewController:itemForActivityType:, so it seemed simple enough to just use that instead. But activityViewController:itemForActivityType: is called on the main thread, and expects a return value immediately. This is causing other problems for me that seem impossible to work around: http://stackoverflow.com/q/39592642/813247

Steps to Reproduce:
Do something like this to set up an activity view controller:

JUNActivityProvider *fileProvider = [[JUNActivityProvider alloc] initWithPlaceholderItem:[NSObject new]];
fileProvider.objectID = objectID;
fileProvider.fileURL = fileURL;

JUNActivityProvider *textProvider = [[JUNActivityProvider alloc] initWithPlaceholderItem:[NSString new]];
textProvider.objectID = objectID;

...

UIActivityViewController *activityController = [[UIActivityViewController alloc]
    initWithActivityItems:@[fileProvider,imageProvider,textProvider,urlProvider,printFormatter]
    applicationActivities:nil];

Then in JUNActivityProvider (a UIActivityItemProvider subclass), create an item method that customizes the return value based on the activityType:

- (id)item {

    if (self.fileURL) {

        if ([self.activityType isEqualToString:UIActivityTypeAirDrop]) {

            // Create the file
            return url;

        }

    } else if ([self.placeholderItem isKindOfClass:[UIImage class]]) {

        if ([self.activityType isEqualToString:UIActivityTypeAirDrop] == NO &&
            [self.activityType isEqualToString:UIActivityTypeMail] == NO &&
            [self.activityType isEqualToString:UIActivityTypePrint] == NO) {

            // Create the image
            return image;

        }

    } else if ([self.placeholderItem isKindOfClass:[NSString class]]) {

        if ([self.activityType isEqualToString:UIActivityTypeMail]) {

            return @"example one";

        } else if ([self.activityType isEqualToString:UIActivityTypeMessage] ||
            [self.activityType isEqualToString:UIActivityTypeCopyToPasteboard]) {

            return @"example two";

        }

    }

    return nil;

}

The idea here is that certain items are not appropriate for certain methods of sharing. In the context of my app, it makes sense to send a file representing the item over AirDrop—but not an image or text.

Expected Results:
I'd expect the documentation, header files, and actual behavior to match up more. Given that returning nil has worked fine for years and the documentation doesn't mention the nonnull requirement, I didn't expect the header file to say otherwise. Generally I'd expect a crash if I return a nil value where it's not expected.

Directly implementing the UIActivityItemSource protocol is both limiting and requires more work. In my case it seems to be impossible to use it to do what I want. So I'd prefer to see the nullability of the item property changed to allow more flexibility.

Actual Results:
Everything works fine, but since the item property is defined as nonnull, Xcode 8 gives an appropriate error when you choose Product > Analyze.

Version:
iOS 10.0.1, Xcode 8

Notes:


Configuration:
iPhone 7, 256GB, AT&T

Attachments:

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!