пятница, 10 июня 2016 г.

39. WebView

После долгого перерыва, продолжаю проходить IOS Developer Course от Алексея Скутаренко.
39 урок  посвящен UIWebView - вью для просмотра веб страниц, html файлов/строк, файлов популярных приложений (PDF, Excel, Word и др).
Как всегда начинаем новый проект с создания File -> New ->Project -> Single View Application.

В связи с нововведениями безопасности в новых версиях ios, старые проекты и новые проект(в которых не произведены действия описываемые ниже)  перестают работать с сетью
Для того, чтобы работали взаимодействия с сетью для этого (и других проектов). Нужно
провести некоторые манипуляции с info.plist файлом проекта:
1. В корневой список добавляем  NSDictionary - App Transport Security Settings .
2. Внутрь App Transport Security Settings добавляем BOOL  Allow Arbitrary Loads и выставляем Yes.

Теперь  наша WebView сможет получить доступ в интернет.

В проекте не используется Navigation Controller. Все контролы добавляются в автоматически созданный контроллер.
Добавляем ToolBar, WebView и АктивитиИндикатор расставляем констрейнты.
На тулбар добавляем кнопки навигации - назад, вперед и перезагрузить.
WebView вытягиваем на контроллер и объявляем делегатом и вытягиваем на аутлет.
Кнопки назад и вперед вытягиваем на аутлеты, т.к. они будут отключиться  и так же от всех кнопок вытягиваем экшены.

Получилось следующее:

@interface ViewController ()
{
    __weak IBOutlet UIWebView *webView;
    __weak IBOutlet UIBarButtonItem *buttonBack;
    __weak IBOutlet UIBarButtonItem *buttonForward;
    __weak IBOutlet UIBarButtonItem *buttonReload;
    __weak IBOutlet UIActivityIndicatorView *activityIndicator;
    
}

@end


Определяем действия для кнопок:


#pragma mark - action

- (IBAction) actionButtonBack:(UIBarButtonItem *) sender
{
    if (webView.canGoBack) {
        [webView stopLoading];
        [webView goBack];
    }
}

- (IBAction)actionButtonForward:(UIBarButtonItem *)sender
{
    if (webView.canGoForward) {
        [webView stopLoading];
        [webView goForward];
    }
    
}

- (IBAction)actionButtonReload:(UIBarButtonItem *)sender
{
    [webView reload];

}

Так как наш контроллер является делегатом для WebView, вставляем  методы делегата:

#pragma mark - UIWebViewDelegate

// Метод вызывается при переходе на ссылку (можно не переходить, если возвратить NO).

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSLog(@"shouldStartLoadWithRequest.Request: %@. Navigation Type %@",request, @(navigationType));
    
    return YES;
}

// Начало загрузки включаем индикаторы активности

- (void)webViewDidStartLoad:(UIWebView *)webView
{
    [activityIndicator startAnimating];
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
}

// Окончание загрузки  выключаем индикатор  и отключаем/включаем кнопки навигации

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    [activityIndicator stopAnimating];
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    [self setButtons];
}

// Тоже самое, только если возникла ошибка 

- (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error
{
    [activityIndicator stopAnimating];
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    [self setButtons];

}

Функция включения / отключения кнопок навигации в зависимости от возможности перехода на странице загруженной во WebView.

#pragma mark - utilites

- (void)setButtons
{
    buttonBack.enabled = webView.canGoBack;
    buttonForward.enabled = webView.canGoForward;
}

Для загрузки страницы в WebView с помощью строки - web-адреса , определяем NSURL  по url-строке, создаем запрос и загружаем запрос в webView:

    
    NSURL *url = [NSURL URLWithString:@"http://yandex.ru"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [webView loadRequest:request];

Для загрузки  из файла например PDF файла существует несколько способов. 
При этом способе не работают внешние переходы из документа:

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"schengen" ofType:@"pdf"];
    
    NSData *dataFile = [NSData dataWithContentsOfFile:filePath];

    [webView loadData:dataFile MIMEType:@"application/pdf" textEncodingName:@"UTF-8" baseURL:NULL];

При этом  способе работают все ссылки и переходы:

    NSURL *urlLocal = [NSURL fileURLWithPath:filePath];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:urlLocal];

    [webView loadRequest:urlRequest];

Для загрузки в вебвью HTML кода из строки:

    NSString *strHtml = @"<html>"
                            "<body>"
                                "<h1>"
                                    "Lesson 39 webView"
                                "</h1>"
                                "<h2>"
                                    "<a href = \"cmd:PDF\">PDF Document</a>"
                                "</h2>"
                                "<h2>"
                                    "<a href = \"http://yandex.ru\">Yandex.RU</a>"
                                "</h2>"
                                "<h2>"
                                    "<a href = \"cmd:Alert\">Alert</a>"
                                "</h2>"

                            "</body>"
                        "</html>";
    [webView loadHTMLString:strHtml baseURL:nil];

  
Для обработки переходов по ссылке  расширим метод  shouldStartLoadWithRequest в который приходит ссылка для перехода:

- (BOOL)webView:(UIWebView *)webView1 shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSLog(@"shouldStartLoadWithRequest.Request: %@. Navigation Type %@",request, @(navigationType));
    
    NSString *urlString = [request.URL absoluteString];
    if ([urlString hasPrefix:@"cmd:"]) {
        NSString *strCommand = [urlString substringFromIndex:4];
        if ([strCommand isEqualToString:@"Alert"]) {
            [self showAlertMessage:@"showAlert"];
        }
        if ([strCommand isEqualToString:@"PDF"]) {
            NSString *strPathPDF = [[NSBundle mainBundle] pathForResource:@"schengen" ofType:@"pdf"];
            [webView1 loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:strPathPDF]]];
        }
        return NO;
    }
    return YES;
}

Так же для вывода алерта в этом проекте использую следующую функцию:

#pragma mark - UIAlert

- (void)showAlertMessage:(NSString *)message;
{
    NSLog(@"Show Alert");
        UIAlertController * alert=   [UIAlertController
                                      alertControllerWithTitle:@"Alert Title"
                                      message:message
                                      preferredStyle:UIAlertControllerStyleAlert];
        
        UIAlertAction *button = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil];
        [alert addAction:button];
        [[[[UIApplication sharedApplication] keyWindow] rootViewController] presentViewController:alert animated:YES completion:^{
        }];
}

Исходный код к этому уроку.

Домашнее задание:

Задание следующее:

1. Сделайте один контроллер с таблицей, в ней две секции: pdf и url
2. Присоедините к проекту парочку pdf файлов, их имена должны быть в таблице
3. Добавьте парочку web сайтов во вторую секцию
4. Когда я нажимаю на ячейку, то через пуш навигейшн должен отобразиться либо пдф либо web
5. Надеюсь понятно что для загрузки того либо другого мы используем один и тот же контроллев с UIWebView и иницианизируем его нужным NSURL
6. На веб вью должна быть крутилка, а в навигейшине кнопки назад и вперед


Комментариев нет:

Отправить комментарий