Curs de programació d’iOS Novembre de 2011
Organitza
9 Navegació (UINaviga=onController) • Les aplicacions que tenen múl5ples pantalles d’informació u5litzen la classe UINaviga=onController • UINaviga=onController és l’encarregat de mantenir una pila de pantalles. • Les vistes, o instancies view, que apareixen a la pantalla pertanyen al UIViewController situat a la part més alta de la pila.
Navegació
Navegació • Quan s’inicialitza una instància de UINaviga=onController se li ha d’especificar un UIViewController arrel. • El UIViewController arrel mostra la primera pantalla que l’usuari veu.
Navegació UINaviga=onController
rootViewController
viewControllers
topViewController
NSArray
UIViewController
UIViewController
Navegació • Quan la pila rep una operació de 5pus pushViewController, s’afegeix un nou controlador a la posició més alta de la pila i es mostra per pantalla la seva corresponent vista.
Navegació (pushViewController)
[[self naviga5onController] pushViewController:viewController animated:YES];
Navegació • Quan la pila rep una operació de 5pus popViewController, s’extreu el controlador situat a la posició més alta (pantalla visible) de la pila i es torna a mostrar la pantalla del controlador anterior.
Navegació (popViewController)
[[self naviga5onController] popViewControllerAnimated:YES];
Navegació
Navegació • UINaviga=onController té almenys dues vistes: • La vista del UIViewController situat a la part més alta de la pila, és a dir, el que s’està mostrant.
• Un UINaviga=onBar (barra superior de navegació)
Navegació UINaviga=onController
topViewController UIViewController
view
UIView
view
naviga=onBar UINaviga=onBar
Exemple 10 #import “CotxesAppDelegate.h" #import “CatalegViewController.h" @implementa5on CotxesAppDelegate @synthesize window = _window; @synthesize viewController = _viewController; -‐ (BOOL)applica=on:(UIApplica=on *)applica=on didFinishLaunchingWithOp=ons:(NSDic=onary *)launchOp=ons { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.viewController = [[[LlistaViewController alloc] initWithNibName:@"LlistaViewController" bundle:nil] autorelease]; UINaviga5onController *navController = [[UINaviga5onController alloc] initWithRootViewController:self.viewController]; self.window.rootViewController = navController; [navController release]; [self.window makeKeyAndVisible]; return YES; } @end
UINaviga=onBar • UINaviga=onBar és la classe encarregada de representar la barra de navegació. • La classe UINaviga=onItem és l’encarregada de proporcionar a la barra de navegació el con5ngut que ha de mostrar. • Els controladors UIViewController tenen la propietat naviga2onItem del 5pus UINaviga=onItem • Quan s’empila un UIViewController, el controlador de navegació UINaviga=onBar u5litza la propietat naviga2onItem per obtenir el con5ngut a mostrar.
UINaviga=onBar
UINaviga=onController
naviga=onBar
Obté les dades que ha de mostrar a par5r de...
topViewController
UIViewController
UINaviga=onBar
naviga=onItem
UINaviga=onItem
UINaviga=onBar UNaviga=onController
naviga=onBar
topViewController
UIViewController
naviga=onItem
UINaviga=onItem 5tle = @”MyApp”
UINaviga=onBar UINaviga=onController
naviga=onBar
topViewController
UIViewController
naviga=onItem
leRBarBuQonItem
UINaviga=onItem
=tleView
rightBarBuQonItem
UIBarBuQonItem
UILabel
UIBarBuQonItem
5tle = @”Cancel”
text = @”New Message”
5tle = @”Send”
10 Interacció amb serveis web • Un servei web és una aplicació que corre sobre un servidor web. • Permeten l’intercanvi d’informació entre el terminal i el servidor. • El format més habitual de les dades que es transfereixen entre un servei web i una aplicació client és XML i JSON.
Obtenir dades des d’una URL • Disposem de tres classes: NSURL, NSURLRequest i NSURLConnec=on
NSURLConnec=on
NSURLRequest request
cachePolicy Timeout hjpHeaders hjpBody
URL
NSURL hjp://www.google.com
Obtenir dades des d’una URL • NSURL: Conté l’adreça URL de l’aplicació web. • NSURLRequest: Les instàncies d’aquesta classe emmagatzemen totes les dades necessàries per a la comunicació amb el servidor web. Configuració de la caché, temps màxim de resposta, capçaleres hjp, etc… • NSURLConnec=on: Les instàncies d’aquesta classe són les responsables de portar a terme la connexió amb el servidor web, enviar i rebre la informació.
Com treballar amb la classe NSURLConnec=on • Es pot connectar a un servidor web de dues maneres: en mode síncron o mode asíncron. • El mode síncron bloqueja l’aplicació mentre no es reben les dades completament. • El mode asíncron no paralitza la l’aplicació durant les transferències. Els callbacks s’invoquen sobre la classe delegadora que implementa NSURLConnec=onDelegate
Exemple de connexió asíncrona • Crea la connexió a un RSS // Composar la URL del servei web NSURL *url = [NSURL URLWithString:@” hjp://www.elpais.com/rss/”]; // Composar el request NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData 5meoutInterval:30]; if(connec5onInProgress) { [connec5onInProgress cancel]; [connec5onInProgress release]; } xmlData = [[NSMutableData alloc] init]; // S’inicia la connexió asíncrona (no-‐bloquejant) connec5onInProgress = [[NSURLConnec5on alloc] initWithRequest:request delegate:self startImmediately:YES];
Exemple de connexió asíncrona • Implementar els mètodes delegats de NSURLConnec=onDelegate • Concatenar les dades que es van rebent. // Composar la URL del servei web // Aquest mètode serà invocat varies vegades a mesura que vagin arribant els fragments de dades -‐ (void) connec5on: (NSURLConnec5on *)connec5on didReceiveData: (NSData *)data { [xmlData appendData:data]; }
• Quan la connexió acaba d’obtenir totes les dades s’invoca el mètode connec=onDidFinishLoading al delegat. -‐ (void)connec5onDidFinishLoading: (NSURLConnec5on *)connec5on { NSString *xmlCheck = [[[NSString alloc] initWithData:xmlData encoding:NSUTF8StringEncoding] autorelease]; NSLog(@”xmlCheck = %@”, xmlCheck); }
Exemple de connexió asíncrona • Hi ha la possibilitat de que la connexió falli. En aquests casos s’invoca el mètode connec2on:didFailWithError -‐ (void)connec5on: (NSURLConnec5on *)connec5on didFailWithError: (NSError *)error { [connec5onInProgress release]; connec5onInProgress = nil; [xmlData release]; xmlData = nil; }
Anàlisis de dades XML • Per processar les dades XML que s’obtenen d’un servei web cal emprar un parser XML. • Per a aquesta tasca disposem de la classe NSXMLParser • A mesura que el parser avança amb la lectura de dades, anirà enviant missatges al seu delegat de 5pus NSXMLParserDelegate el qual l’informarà del progrés. • Parser de 5pus SAX
NSXMLParser // Crear l’objecte parser amb dades rebudes del servei web anterior NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xmlData]; // Cal assignar-‐li el delegate de 5pus NSXMLParserDelegate [parser setDelegate: self]; // Iniciar el parseig. El document XML serà analitzat I formatejat, i el delegate de NSXMLParser rebrà tots els seus missatges // delegats abans de que finalitzi l’execució d’aquesta linia (bloquejant) [parser parse]; // En aquest punt el parser ha finalitzat i ja el podem alliberar [parser release]; // Podem refrescar les dades de la taula [[self tableView] reloadData];
NSXMLParser • Implementació dels mètodes delegats de NSXMLParserDelegate • Mètode per processar els tags d’inici o obertura parser:didStartElement:nameSpaceURI:qualifiedName:aQributes -‐ (void)parser: (NSXMLParser *)parser didStartElement: (NSString *)elementName namespaceURI : (NSString *)namespaceURI qualifiedName: (NSString *)qName ajributes: (NSDic5onary *)ajributeDict { if([elementName isEqual:@”5tle”]) { NSLog(@”TAG <5tle> trobat.”); 5tleString = [[NSMutableString alloc] init]; } }
• Concatenar el text que hi ha entre tag i tag. -‐ (void)parser: (NSXMLParser *)parser foundCharacters: (NSString *)string { [5tleString appendString:string]; }
NSXMLParser • Mètode per processar els tags de tancament parser:didEndElement:nameSpaceURI:qualifiedName
-‐ (void)parser: (NSXMLParser *)parser didEndElement: (NSString *)elementName namespaceURI : (NSString *)namespaceURI qualifiedName: (NSString *)qName { if([elementName isEqual:@”5tle”]) { NSLog(@”TAG </5tle> trobat.”); [object setTitle:5tleString]; [5tleString release]; 5tleString = nil; } }