Загрузка NSURLRequest на webView из другого класса.

Я создал контроллер представления с webView в раскадровке под названием GoogleSearchController. Свойство для webView, конечно же, было объявлено в GoogleSearchController.

Я пытаюсь получить доступ к синтезированному свойству webView, которое является *googleWebView, в MapViewController, чтобы я мог добавить свои точечные аннотации к поиску Google. Вывод здесь правильный. Я получаю добавленный и нужный URL, но мне не удается его загрузить. В конце метода leftButtonAnnotationPressed вы заметите, что я пытаюсь вызвать loadRequest для self.classObj.googleWebView. Что-то идет не так, как должно. Это первый раз, когда я пытался использовать @synthesize, и я открыт для всех предложений.

Мой вопрос состоит из двух частей. A: я использую @synthesize, как это задумано? и B: Если это правильное использование, почему мой webView не загружает запрос?

GoogleSearchController.h

 @interface GoogleSearchController : UIViewController <UIWebViewDelegate>

 @property (strong, nonatomic) IBOutlet UIWebView *googleWebView;

 @end

GoogleSearchController.m

@synthesize googleWebView;

- (void)viewDidLoad {
    [super viewDidLoad];

    self.googleWebView = [[UIWebView alloc] init];
    self.googleWebView.delegate = self;
}

MapViewController.m

@property (nonatomic, strong) GoogleSearchController *classObj;

-(void)leftButtonAnnotationPressed:(UIButton *)sender {
[self performSegueWithIdentifier:@"googleSearch" sender:nil];
self.classObj = [[GoogleSearchController alloc] init]; <--------

MKPointAnnotation *annotation = [self.mapView.selectedAnnotations objectAtIndex:([self.mapView.selectedAnnotations count]) -1];
NSString *appendString = annotation.title;
NSString *googleString = @"http://www.google.com/search?q=";
NSString *appendedUrlString = [googleString stringByAppendingString:appendString];

if ([appendedUrlString containsString:@" "]) {
    appendedUrlString = [appendedUrlString stringByReplacingOccurrencesOfString:@" " withString:@"+"];

    NSURL *url = [NSURL URLWithString:appendedUrlString];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.classObj.googleWebView loadRequest:request];<------

    NSLog(@"appended string: %@", request);

}

2 ответа

Решение

Хранение NSURLRequest в источнике данных казалось довольно простым решением. В DataSource.h все, что мы делали, это объявляли открытое свойство типа NSURLRequest * searchURL.

+(instancetype) sharedInstance;

@property (nonatomic, strong) NSURLRequest *searchURL;

SharedInstance будет использоваться для нашего одноэлементного шаблона, который гарантирует, что мы получим только один экземпляр нашего DataSource. В DataSource.m мы будем реализовывать наш sharedInstance следующим образом: (который для части публикации является учебником).

+ (instancetype) sharedInstance {
    static dispatch_once_t once;
    static id sharedInstance;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });

    return sharedInstance;
}

Это все, что нам нужно для хранения нашего NSURLRequest.

В MapViewController мы используем нашу sharedInstance для доступа к свойству NSURLRequest из DataSource и устанавливаем его равным добавленному NSURLRequest.

- (void) leftAnnotationButtonPressed:(UIButton *)sender {

        MKPointAnnotation *annotation = [self.mapView.selectedAnnotations objectAtIndex:([self.mapView.selectedAnnotations count]) -1];
        NSString *appendString = annotation.title;
        NSString *googleString = @"http://www.google.com/search?q=";
        NSString *appendedUrlString = [googleString stringByAppendingString:appendString];

        if ([appendedUrlString containsString:@" "]) {
            appendedUrlString = [appendedUrlString stringByReplacingOccurrencesOfString:@" " withString:@"+"];

            NSURL *url = [NSURL URLWithString:appendedUrlString];
            NSURLRequest *request = [NSURLRequest requestWithURL:url];
            [DataSource sharedInstance].searchURL = request;  <----
            NSLog(@"appended string: %@", request);
        }

        [self performSegueWithIdentifier:@"googleSearch" sender:nil];
}

Осталось только загрузить webView. Это можно сделать ввиду того, что загрузил в GoogleSearchController, где находится это свойство. (который снимает всю головную боль).

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.googleWebView loadRequest:[DataSource sharedInstance].searchURL];
}

Все, что мы делаем здесь, это просто вызываем loadRequest в нашем веб-представлении с NSURLRequest, который теперь хранится в нашем источнике данных. И мы закончили. Мне нравится этот подход, и я надеюсь, что кто-нибудь еще, читающий это, сделает это. Вы даже получите небольшой урок о синглетах и ​​источнике данных.

@sythesize больше не требуется / обязательно. Без @synthesize iOS/XCode автоматически создаст переменную экземпляра для вас _[propertyName]

Если ваш UIWebView создан в IB, вам не нужно инициализировать его программно. Убедитесь, что ваше webView и свойство ViewController IBOutlet связаны. Этого должно быть достаточно.

Я думаю, что важная причина, по которой ваш запрос не загружается, заключается в том, что вы загружаете URL-адрес в другом экземпляре, чем тот, который отображается в вашем GoogleSearchViewController

Вы делаете это

[self performSegueWithIdentifier:@"googleSearch" sender:nil];
self.classObj = [[GoogleSearchController alloc] init]; <--------

в первой строке вы просите раскадровку выполнить переход. Итак, раскадровка создаст экземпляр контроллера представления с представлениями и всеми подпредставлениями и отображением.

Во второй строке вы создаете свой собственный экземпляр контроллера представления. Кто его отображает? -- Ни один. Никто.

Ваша загрузка URL в неправильном экземпляре.

Хорошо, теперь, как мне получить доступ к отображаемому контроллеру представления?

Xcode / iOS дает вам возможность сделать это с prepareForSegue Вы можете получить доступ к VC и веб-представлению, как показано ниже, чтобы загрузить запрос.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue.identifier isEqualToString:@"googleSearch"]){
        GoogleSearchViewController *vc = nil;
        if([segue.destinationViewController isKindOfClass:[UINavigationController class]]){
            UINavigationController *navVC = (UINavigationController *)segue.destinationViewController;
            vc = (GoogleSearchViewController *)navVC.viewControllers[0];
        }else{
            vc = segue.destinationViewController;
        }
        if(vc){
            NSURL *url = [NSURL URLWithString:appendedUrlString];
            NSURLRequest *request = [NSURLRequest requestWithURL:url];
            [vc.googleWebView loadRequest:request];

        }
    }

}

Было бы интересно узнать, сработало ли это для вас

Другие вопросы по тегам