Search code examples
iosobjective-csfsafariviewcontroller

How to add a custom activity to SFSafariViewController?


I want to add a custom activity (UIActivity) to a SFSafariViewController that I am presenting in my app. How can I do this?


Solution

  • 1. Create a subclass of UIActivity.

    Implement all required methods of the class, and when initializing the activity, pass in the URL of the page at that point and initialize your UIViewController, as prepareWithActivityItems: isn't called within the SFSafariViewController context (rdar://24138390). If your activity doesn't show UI, instead save the URL during initialization so you can process it when the user taps the action.

    Full example:

    @interface YourActivity : UIActivity {
        UIViewController *activityViewController;
    }
    - (id)initWithURL:(NSURL *)url;
    @end
    
    
    @implementation YourActivity
    
    - (id)initWithURL:(NSURL *)url
    {
        self = [super init];
        if (self)
        {
            [self prepareWithURL:url];
        }
        return self;
    }
    
    - (NSString *)activityType
    {
        return @"YourTypeName";
    }
    
    - (NSString *)activityTitle
    {
        return @"Perform Action";
    }
    
    - (UIImage *)activityImage
    {
        return [UIImage imageNamed:@"YourActionIcon"];
    }
    
    - (BOOL)canPerformWithActivityItems:(NSArray *)activityItems
    {
        return YES;
    }
    
    - (void)prepareWithActivityItems:(NSArray *)activityItems
    {
        NSURL* url = nil;
        for (NSObject* obj in activityItems)
        {
            if ([obj isKindOfClass:[NSURL class]])
            {
                url = (NSURL*)obj;
            }
        }
        
        [self prepareWithURL:url];
    }
    
    - (void) prepareWithURL:(NSURL*)url
    {
        // initialize your UI using the given URL
        activityViewController = ... // initialize your UI here
    }
    
    - (UIViewController *)activityViewController
    {
        return activityViewController;
    }
    
    + (UIActivityCategory)activityCategory
    {
        return UIActivityCategoryShare;
    }
    
    
    @end
    

    2. Add UIActivity to SFSafariViewController

    Implement the following method in your SFSafariViewControllerDelegate, which initializes the activity and passes in the URL of the page the user is viewing.

    - (NSArray<UIActivity *> *)safariViewController:(SFSafariViewController *)controller
                                activityItemsForURL:(NSURL *)URL
                                              title:(NSString *)title
    {
        YourActivity* activity = [[YourActivity alloc] initWithURL:URL];
        return @[activity];
    }