Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SFSafariViewControllerDelegate methods not called when assigning delegate to something other than view controller

I have a simple view controller that presents a SFSafariViewController when a link button is tapped.

#import "ViewController.h"
#import "SafariDelegate.h"

@interface ViewController ()

@property(nonatomic, strong) NSString *url;
@property(nonatomic, weak) SafariDelegate *safariDelegate;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.url = @"http://www.google.com";
}

- (IBAction)linkTapped:(id)sender {
    SFSafariViewController *vc = [[SFSafariViewController alloc] initWithURL:[NSURL URLWithString:self.url]];
    SafariDelegate *safariDelegate = [[SafariDelegate alloc] init];
    vc.delegate = safariDelegate;
    [self presentViewController:vc animated:YES completion:nil];
}

@end

SafariDelegate conforms to SFSafariViewControllerDelegate and just logs when the delegate methods fire.

SafariDelegate.h

#import <Foundation/Foundation.h>
#import <SafariServices/SafariServices.h>

@interface SafariDelegate : NSObject <SFSafariViewControllerDelegate>

@end

SafariDelegate.m

#import "SafariDelegate.h"

@implementation SafariDelegate

- (NSArray<UIActivity *> *)safariViewController:(SFSafariViewController *)controller activityItemsForURL:(NSURL *)URL     title:(nullable NSString *)title
{
    NSLog(@"safariViewController activityItemsForURL");

    return @[];
}

- (void)safariViewControllerDidFinish:(SFSafariViewController *)controller
{
    NSLog(@"safariViewControllerDidFinish");
}


- (void)safariViewController:(SFSafariViewController *)controller didCompleteInitialLoad:(BOOL)didLoadSuccessfully
{
    NSLog(@"safariViewController didCompleteInitialLoad");
}

@end

When I tap the button, the safariviewcontroller loads the page up properly but the delegate methods are never called (including when I hit 'Done'). I stuck a break point at the line where the 'vc' is presented and confirmed that the delegate is properly set at that point. What am I missing?

like image 987
Reginald Meow Avatar asked Jan 06 '23 09:01

Reginald Meow


1 Answers

SafariViewController doesn't retain its delegate, so it gets deallocated immediately after your linkTapped: method returns since nothing else has a strong reference to it.

You need to keep a strong reference to it somewhere. You could probably just change the property you have in your current view controller to strong and store it there. You could also keep it in an associated object on the safari view controller.

like image 75
dan Avatar answered Jan 08 '23 21:01

dan