UIWebView – prezentacja stron internetowych w aplikacjach IOS

ios_xcode_32

W niektórych projektach związanych z systemem iOS dla urządzeń takich jak iPhone, iPad oraz iPod napotykamy na konieczność wyświetlania zawartości stron internetowych wewnątrz aplikacji. W takim przypadku system iOS pozwala nam użyć gotowego komponentu, jakim jest UIWebView. Chcę pokazać, jak go wykorzystać oraz jak pozyskiwać wyświetlane w nim dane.

Prosta aplikacja wykorzystująca komponent UIWebView

W ramach prezentacji możliwości komponentu stworzymy prosty program wyświetlający stronę internetową wewnątrz naszej aplikacji.

Aby to zrobić, należy przejść przez kilka kroków.

1. Tworzymy nową pustą aplikację w Xcode.

clip_image002

2. Do aplikacji dodajemy element „Objective-C class“ dziedziczący po klasie „UIViewController“, o parametrach jak na poniższym rysunku. Zaznaczenie dodatkowych check-boxów nie jest obowiązkowe i zależy od docelowego urządzenia.

clip_image004

Stworzony element będzie naszym głównym kontrolerem widoku.

3. W pliku „AppDelegate.m“ ustawiamy główny kontroler widoku na dodaną przez nas klasę.

clip_image006

1
[self.window setRootViewController:[ViewController alloc]];

„ViewController“ to nazwa dodanej przez nas klasy.

4. Następnie w pliku „ViewController.m“ edytujemy metodę „viewDidLoad“ według poniższego rysunku:

clip_image008

W zaprezentowanym kodzie inicjujemy komponent UIWebView o rozmiarze okna. W kolejnym kroku uzupełniamy parametry dotyczące żądania, którego wynik chcemy zaprezentować w komponencie. Załadowanie danych do komponentu odbywa się za pomocą polecenia „loadRequest“. Wreszcie ostatnim krokiem jest dodanie naszego komponentu do głównego widoku.

5. Możemy uruchomić naszą aplikację i zaobserwować wynik.

clip_image010

W symulatorze możemy zaobserwować mobilną wersję strony „Blog Technologiczny Atena“.

Sposoby ładowania danych do komponentu UIWebView

Istnieje kilka sposobów pozyskiwania i ładowania danych do komponentu UIWebView. W pierwszym punkcie zaprezentowałem najprostszy sposób załadowania danych do komponentu UIWebView. Jako źródło danych komponent może przyjmować:

· żądanie – przedstawione w punkcie pierwszym – komponent sam analizuje żądanie i pobiera jego odpowiedź;

· dane NSData – dane pozyskane z żądania;

· źródło strony – kod źródłowy strony, która ma być zaprezentowana w komponencie.

Wszystkie dane akceptowane przez komponent możemy pozyskiwać na kilka różnych sposobów.

Żądanie synchroniczne

Pierwszym sposobem pozyskiwania danych dla komponentu jest żądanie synchroniczne.

1
2
3
NSData *responseData = [NSURLConnection
sendSynchronousRequest:request returningResponse:nil error:nil];
[webView loadData:responseData MIMEType:@"text/html" textEncodingName:@"utf-8" baseURL:nil]

Taki sposób pozyskiwania danych wiąże się jednak ze sporymi niedogodnościami:

· brak możliwości anulowania żądania;

· blokada wątku, który uruchomił żądanie – blokada interfejsu użytkownika;

· możliwość ustawienia autentyfikacji tylko przed rozpoczęciem żądania;

· brak możliwości przetwarzania danych w locie;

· dostęp do danych po całkowitym ich przetworzeniu.

Jedynym sposobem ustawienia autentyfikacji dla żądania synchronicznego jest możliwość sprecyzowania „Protection space“ oraz sposobu logowania dla strefy.

Przykład logowania domenowego:

1
2
3
4
5
6
7
8
9
10
11
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc] initWithHost: @"host"
port: 80
protocol: @"http"
realm: @"host"
authenticationMethod:NSURLAuthenticationMethodNTLM];
[[NSURLCredentialStorage sharedCredentialStorage]
setDefaultCredential:[NSURLCredential
credentialWithUser:@"username"
password:@"password"
persistence:NSURLCredentialPersistenceForSession]
forProtectionSpace:protectionSpace];

Ustawienie autentyfikacji musi zostać wykonane przed wysłaniem żądania.

Żądanie asynchroniczne

Drugim, lepszym sposobem pozyskiwania danych jest żądanie asynchroniczne. Oznacza to, że dane możemy pobierać za pomocą wysłania asynchronicznego żądania lub obsłużenie delegatów połączenia.

1. Wysłanie żądania asynchronicznego

1
2
3
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
[webView loadData:data MIMEType:@"text/html" textEncodingName:@"utf-8" baseURL:nil]; }];

2. Obsługa delegatów połączenia

1
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

Delegaty:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
-(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response
{
//Pozyskanie odpowiedzi
webData = [[NSMutableData alloc] init];
}
-(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
//Pozyskiwanie danych w locie <p>[webData appendData:data];
}
-(void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
NSLog(@"%@",[error description]);
}
-(BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
return YES;
}
-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
//Autentyfikacja
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//Zakończenie ładowania
}

Wnioski

Komponent UIWebView można bardzo łatwo wykorzystywać jako przeglądarkę internetową wewnątrz natywnych aplikacji iOS. Sposób dostarczania danych do komponentu zależy od specyfikacji wymagań projektu, jednak zaleca się stosowanie asynchronicznych żądań oraz unikania wielowątkowych żądań synchronicznych.

Na pierwszy rzut oka żądania asynchroniczne wydają się bardziej skomplikowane, jednak ich zalety zrekompensują czas poświęcony na ich wdrożenie.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *