0

I've got a share button following

http://www.codingexplorer.com/sharing-swift-app-uiactivityviewcontroller/

this works fine in the simulator, it does a popup from the bottom (iphone6) but of course it doesn't have the facebook and other options, just email and another. when I try this on the ipad though, it gives an error

2015-01-07 12:32:43.173  Clown[2011:2967183] LaunchServices: invalidationHandler called
2015-01-07 12:32:43.185  Clown[2011:2967169] LaunchServices: invalidationHandler called
2015-01-07 12:32:43.766  Clown[2011:2967083] *** Terminating app due to uncaught exception 'NSGenericException', reason: 'UIPopoverPresentationController (<_UIAlertControllerActionSheetRegularPresentationController: 0x1565e7d0>) should have a non-nil sourceView or barButtonItem set before the presentation occurs.'

he does mention in the article that an invalidationHandler will be thrown but to ignore it because everything works fine. but, it doesn't, the app crashes.

seems simliar to

http://stackoverflow.com/questions/26039229/swift-uialtertcontroller-actionsheet-ipad-ios8-crashes

but I tried to add that and my code didn't know what the alertcontroller was. here is the code

@IBAction func handleShareButton(sender: AnyObject) {
    if let detail: AnyObject = self.detailItem {
        let theItem = detail as [String: String]
        let textToShare = "..."

        if let myWebsite = NSURL(string: theItem["image"]!)
        {
            let objectsToShare = [textToShare, myWebsite]
            let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)

            //New Excluded Activities Code
            activityVC.excludedActivityTypes = [UIActivityTypeAirDrop, UIActivityTypeAddToReadingList]

            self.presentViewController(activityVC, animated: true, completion: nil)

        }
    }
}
Jason G
  • 2,395
  • 2
  • 24
  • 34

2 Answers2

2

The problem is that you're trying to present the view controller in an unsupported manner.

Here's the quote from Apple's UIActivityViewController Documentation:

Your app is responsible for configuring, presenting, and dismissing this view controller. Configuration for the view controller involves specifying the data objects on which the view controller should act. (You can also specify the list of custom services your app supports.) When presenting the view controller, you must do so using the appropriate means for the current device. On iPad, you must present the view controller in a popover. On iPhone and iPod touch, you must present it modally.

So, you should put a check in to see which type of device you have an present it differently based upon that. For instance, here's the way to check the device type (written in Obj-C, but should be easy to translate):

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    // The app is running on an iPad, so you have to wrap it in a UIPopOverController
    UIPopoverController *popOver = [[UIPopoverController alloc] initWithContentViewController:activityVC];

    // Option 1: If your "share" button is a UIBarButtonItem
    [popOver presentPopoverFromBarButtonItem:barButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

    // Option 2: If your "share" button is NOT a UIBarButtonItem
    [popOver presentPopoverFromRect:someRect inView:someView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
} else {
    // The app is running on an iPod Touch or iPhone
    // Use the same code you already have here...
    [self presentViewController:activityVC animated:YES completion:nil];
}


Edit: (new code supplied for Swift by naturalc)
if UIDevice.currentDevice().userInterfaceIdiom == .Pad {
    // The app is running on an iPad, so you have to wrap it in a UIPopOverController
    var popOver: UIPopoverController = UIPopoverController(contentViewController: activityVC)

    // if your "share" button is a UIBarButtonItem
    popOver.presentPopoverFromBarButtonItem(self.shareButton, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)

} else { 
    self.presentViewController(activityVC, animated: true, completion: nil)

}
mbm29414
  • 11,558
  • 6
  • 56
  • 87
  • Wish I could give this more upvotes. All examples I've seen neglect to mention the Popover requirement. Helped fix my Xamarin version. – Glenn Jul 07 '15 at 22:24
0

Add next code before row "self.presentViewController(activityVC,.."

if UIDevice.currentDevice().userInterfaceIdiom == .Pad {
activityVC.popoverPresentationController?.sourceView = self.view
}
Włodzimierz Woźniak
  • 3,106
  • 1
  • 26
  • 23