En los tutoriales anteriores, exploramos los fundamentos de la SESIÓN
API. Hay otra característica de la SESIÓN
API que aún no hemos examinado, es decir, subidas y descargas fuera de proceso. En los siguientes dos tutoriales, te mostraré cómo crear un cliente de podcast muy simple que permita descargas en segundo plano..
El cliente de podcast que estamos a punto de crear no será realmente tan funcional. Le permitirá al usuario consultar la API de búsqueda de iTunes para obtener una lista de podcasts, seleccionar un podcast y descargar episodios. Ya que nos estamos enfocando en el SESIÓN
API, no entraremos a reproducir los episodios que descarga la aplicación..
Sin embargo, el proyecto le enseñará cómo usar tareas de datos y descargar tareas en una aplicación del mundo real. El cliente de podcast también habilitará descargas en segundo plano para las que aprovecharemos SESIÓN
API fuera de proceso. Tenemos algunas cosas que hacer, así que no perdamos tiempo y comencemos..
Encienda el Xcode 5, seleccione Nuevo> Proyecto ... desde el Expediente menú, y elija la Solicitud de vista única Plantilla de la lista de plantillas de aplicaciones iOS. Nombra la aplicación Singlecast, selecciona el Familia de dispositivos a iPhone, y dile a Xcode dónde te gustaría guardar el proyecto. Golpear Crear para crear el proyecto.
Lo primero que debemos hacer es editar el guión gráfico principal del proyecto. Abierto Main.storyboard, Seleccione el único controlador de vista del guión gráfico y elija Insertar en> Controlador de navegación desde el Editor menú. La razón para incrustar el controlador de vista en un controlador de navegación se aclarará más adelante en este tutorial..
Como mencioné en la introducción, para mantener las cosas simples, el usuario solo podrá suscribirse a un podcast. Vamos a empezar por crear el controlador de vista de búsqueda. Seleccionar Nuevo> Archivo ... desde el Expediente menú y elegir Clase objetiva-c De las opciones de la derecha. Nombra la clase MTSearchViewController
y convertirlo en una subclase de UIViewController
. Deje la casilla marcada Con XIB para la interfaz de usuario. desenfrenado. Dile a Xcode dónde quieres guardar los archivos de clase y pulsa Crear.
Antes de crear la interfaz de usuario, abra el archivo de encabezado del controlador de vista y actualice la interfaz de la clase como se muestra a continuación. Especificamos que la MTSearchViewController
clase se ajusta a la UITableViewDataSource
, UITableViewDelegate
, y UISearchBarDelegate
Protocolos, declaramos dos salidas., barra de búsqueda
y tableView
así como una acción, cancelar
, para descartar el controlador de vista de búsqueda.
#importar@interface MTSearchViewController: UIViewController @ propiedad (débil, no atómica) IBOutlet UISearchBar * searchBar; @ propiedad (débil, no atómica) IBOutlet UITableView * tableView; - (IBAction) cancelar: (id) remitente; @fin
Revise el guión gráfico principal del proyecto y arrastre un nuevo controlador de vista desde el Biblioteca de objetos a la derecha. Seleccione el nuevo controlador de vista, abra el Inspector de identidad a la derecha, y configura la clase del controlador de vista a MTSearchViewController
. Con el nuevo controlador de vista aún seleccionado, abra el Editor menú y elegir Insertar en> Controlador de navegación. Arrastre una vista de tabla a la vista del controlador de vista y conecte la vista de tabla fuente de datos
y delegar
puntos de venta con el controlador de vista de búsqueda.
Con la vista de tabla aún seleccionada, abra el Inspector de atributos, y establecer el número de células prototipo para 1
. Seleccione la celda prototipo y establezca su propiedad de estilo en Subtitular y su identificador a SearchCell
.
Arrastre una barra de búsqueda de la Biblioteca de objetos y agregarlo a la vista de encabezado de la vista de tabla. Selecciona la barra de búsqueda y conecta su delegar
toma de corriente con el controlador de vista.
Seleccione el controlador de vista y conecte su barra de búsqueda
y tableView
Outlets con la barra de búsqueda y vista de tabla respectivamente. Hay algunas otras cosas que debemos hacer antes de que terminemos con el guión gráfico.
Abre el Biblioteca de objetos y arrastre un elemento del botón de la barra a la barra de navegación. Seleccione el elemento del botón de la barra, conéctelo con el cancelar:
Acción que declaramos en la interfaz del controlador de vista de búsqueda, y cambiamos su Identificador en el Inspector de atributos a Cancelar.
Arrastre un elemento del botón de la barra a la barra de navegación del controlador de vista (no del controlador de vista de búsqueda) y cambie su Identificador en el Inspector de atributos a Añadir. Controle el arrastre desde el elemento del botón de la barra al controlador de navegación del controlador de vista de búsqueda y seleccione modal Del menú que aparece. Esto crea un segmento del controlador de vista al controlador de navegación del controlador de vista de búsqueda.
Si tuviera que controlar el arrastre desde el elemento del botón de la barra del controlador de la vista directamente al controlador de la vista de búsqueda en lugar de su controlador de navegación, el controlador de navegación nunca se instanciará y no verá una barra de navegación en la parte superior del controlador de la vista de búsqueda.Antes de implementar el UITableViewDataSource
y UITableViewDelegate
protocolos en el MTSearchViewController
Clase, debemos declarar una propiedad que almacena los resultados de búsqueda que obtendremos de la API de búsqueda de iTunes. Nombra la propiedad podcasts
Como se muestra abajo. También declaramos una cadena estática que servirá como un identificador de reutilización de celda. Corresponde al identificador que configuramos en la celda prototipo hace unos momentos..
#importar "MTSearchViewController.h" @interface MTSearchViewController () @property (strong, nonatomic) NSMutableArray * podcasts; @fin
NSString estático * SearchCell = @ "SearchCell";
La implementación de numberOfSectionsInTableView:
Es tan fácil como es posible. Regresamos 1
Si self.podcasts
no es nulo
y 0
si esto es. La implementación de tableView: numberOfRowsInSection:
Es bastante similar como se puede ver a continuación. En tableView: cellForRowAtIndexPath:
, solicitamos a la vista de tabla una celda pasando el identificador de reutilización de celda, que declaramos anteriormente, y indexPath
. Obtenemos el artículo correspondiente de la podcasts
fuente de datos y actualizar la celda de vista de tabla. Ambos tableView: canEditRowAtIndexPath:
y tableView: canMoveRowAtIndexPath:
regreso NO
.
- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return self.podcasts? 1: 0;
- (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) section return self.podcasts? self.podcasts.count: 0;
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: SearchCell forIndexPath: indexPath]; // Fetch Podcast NSDictionary * podcast = [self.podcasts objectAtIndex: indexPath.row]; // Configurar la celda de vista de tabla [cell.textLabel setText: [podcast objectForKey: @ "collectionName"]]; [cell.detailTextLabel setText: [podcast objectForKey: @ "artistName"]]; celda de retorno
- (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath return NO;
- (BOOL) tableView: (UITableView *) tableView canMoveRowAtIndexPath: (NSIndexPath *) indexPath return NO;
Antes de ejecutar la aplicación, implementar el cancelar:
Acción en la que descartamos el controlador de vista de búsqueda..
- (IBAction) cancel: (id) sender [self dismissViewControllerAnimated: YES completed: nil];
Genere el proyecto y ejecute la aplicación para asegurarse de que la base funciona como se espera. Es hora de empezar a usar el SESIÓN
API para consultar la API de búsqueda de iTunes.
Comencemos por declarar dos propiedades privadas adicionales en el MTSearchViewController
clase, sesión
y Tarea de datos
. los sesión
variable se utiliza para almacenar una referencia a la SESIÓN
Instancia que usaremos para consultar la API de Apple. También mantenemos una referencia a la tarea de datos que utilizaremos para la solicitud. Esto nos permitirá cancelar la tarea de datos si el usuario actualiza la consulta de búsqueda antes de que recibamos una respuesta de la API. Si tiene un ojo para los detalles, puede haber notado que el MTSearchViewController
clase también se ajusta a la UIScrollViewDelegate
protocolo. El motivo de esto quedará claro en unos minutos..
#import "MTSearchViewController.h" @interface MTSearchViewController ()@property (strong, nonatomic) NSURLSession * session; @property (strong, nonatomic) NSURLSessionDataTask * dataTask; @property (strong, nonatomic) NSMutableArray * podcasts; @fin
La sesión se crea en su método getter como se puede ver a continuación. Su implementación no debería contener sorpresas si has leído los tutoriales anteriores. Anulamos el método getter del sesión
propiedad para cargar perezosamente la sesión y limitar la creación de instancias y la configuración de la sesión en su método getter. Esto hace que para código limpio y elegante.
- (NSURLSession *) session if (! _Session) // Inicializar configuración de sesión NSURLSessionConfiguration * sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; // Configurar la configuración de la sesión [sessionConfiguration setHTTPAdditionalHeaders: @ @ "Aceptar": @ "application / json"]; // Inicializar sesión _session = [NSURLSession sessionWithConfiguration: sessionConfiguration]; return _session;
Para responder a la entrada del usuario en la barra de búsqueda, implementamos searchBar: textDidChange:
del UISearchBarDelegate
protocolo. La implementación es simple. Si buscar texto
es nulo
, El método regresa temprano. Si la longitud de buscar texto
tiene menos de cuatro caracteres, restablecemos la búsqueda invocando reiniciarBuscar
. Si la consulta es de cuatro caracteres o más, realizamos una búsqueda llamando realizarBúsqueda
en el controlador de vista de búsqueda.
- (void) searchBar: (UISearchBar *) searchBar textDidChange: (NSString *) searchText if (! searchText) return; si (searchText.length <= 3) [self resetSearch]; else [self performSearch];
Antes de inspeccionar realizarBúsqueda
, echemos un vistazo rápido a reiniciarBuscar
. Todo lo que hacemos en reiniciarBuscar
está limpiando el contenido de podcasts
y recargando la vista de tabla.
- (void) resetSearch // Actualizar fuente de datos [self.podcasts removeAllObjects]; // Actualizar vista de tabla [self.tableView reloadData];
El levantamiento de pesas se realiza en realizarBúsqueda
. Después de almacenar la entrada del usuario en una variable llamada consulta
, comprobamos si Tarea de datos
Está establecido. Si está configurado, llamamos cancelar
en eso. Esto es importante ya que no queremos recibir una respuesta de un antiguo Solicitud que ya no puede ser relevante para el usuario. Esta es también la razón por la que solo tenemos una tarea de datos activa a la vez. No hay ninguna ventaja en enviar múltiples solicitudes a la API.
A continuación, solicitamos a la sesión una nueva instancia de tarea de datos al pasarla NSURL
instancia y un controlador de finalización. Recuerda que la sesión es la fábrica que crea tareas. Nunca debes crear tareas tú mismo. Si obtenemos una tarea de datos válida de la sesión, llamamos currículum
en él como vimos en los tutoriales anteriores.
La lógica dentro del controlador de finalización es interesante por decir lo menos. los error
El objeto es importante para nosotros por varias razones. No solo nos dirá si algo salió mal con la solicitud, sino que también es útil para determinar si la tarea de datos se canceló. Si obtenemos un objeto de error, verificamos si su código de error es igual a -999
. Este código de error indica que la tarea de datos fue cancelada. Si obtenemos otro código de error, registramos el error en la consola. En una aplicación real, necesitaría mejorar el manejo de errores y notificar al usuario cuando se produce un error.
Si no se pasó ningún error al controlador de finalización, creamos un diccionario desde el NSData
instancia que se pasó al controlador de finalización y extraemos los resultados de ella. Si tenemos una serie de resultados con los que trabajar, se lo pasamos a procesoResultados:
. ¿Notaste que invocamos? procesoResultados:
en un bloque GCD (Grand Central Dispatch)? ¿Por qué hicimos eso? Espero que lo recuerden, porque es un detalle muy importante. No tenemos ninguna garantía de que el controlador de finalización se invoque en el subproceso principal. Dado que necesitamos actualizar la vista de tabla en el subproceso principal, debemos asegurarnos de que procesoResultados:
se llama en el hilo principal.
- (void) performSearch NSString * query = self.searchBar.text; if (self.dataTask) [self.dataTask cancel]; self.dataTask = [self.session dataTaskWithURL: [self urlForQuery: query] completedHandler: ^ (NSData * data, NSURLResponse * response, NSError * error) if (error) if (error.code! = -999) NSLog (@ "% @", error); else else NSDictionary * result = [NSJSONSerialization JSONObjectWithData: opciones de datos: 0 error: nil]; NSArray * resultados = [resultado objectForKey: @ "resultados"]; dispatch_async (dispatch_get_main_queue (), ^ if (results) [self ProcessResults: results];); ]; if (self.dataTask) [self.dataTask resume];
Antes de ver la implementación de procesoResultados:
, Quiero mostrarte rápidamente lo que pasa en urlForQuery:
, El método auxiliar que usamos en realizarBúsqueda
. En urlForQuery:
, reemplazamos cualquier espacio con un +
firme para asegurarse de que la API de búsqueda de iTunes esté de acuerdo con lo que le enviamos. Entonces creamos un NSURL
instancia con él y devuélvalo.
- (NSURL *) urlForQuery: (NSString *) query query = [query stringByReplacingOccurrencesOfString: @ "" withString: @ "+"]; return [NSURL URLWithString: [NSString stringWithFormat: @ "https://itunes.apple.com/search?media=podcast&entity=podcast&term=%@", consulta]];
En procesoResultados:
, la podcasts
Se borra la variable, se rellena con los contenidos de resultados
, y los resultados se muestran en la vista de tabla..
- (void) processResults: (NSArray *) resulta if (! self.podcasts) self.podcasts = [NSMutableArray array]; // Actualizar fuente de datos [self.podcasts removeAllObjects]; [self.podcasts addObjectsFromArray: resultados]; // Actualizar vista de tabla [self.tableView reloadData];
Cuando el usuario toca una fila en la vista de tabla para seleccionar un podcast, tableView: didSelectRowAtIndexPath:
del UITableViewDelegate
Se invoca el protocolo. Su implementación puede parecer extraña al principio, así que déjame explicarte lo que está pasando. Seleccionamos el podcast que corresponde con la selección del usuario, lo almacenamos en la base de datos predeterminada de usuario de la aplicación y descartamos el controlador de vista de búsqueda. ¿No notificamos a nadie sobre esto? Por qué hacemos esto quedará claro una vez que continuemos implementando el MTViewController
clase.
- (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath [tableView deselectRowAtIndexPath: indexPath animated: YES]; // Fetch Podcast NSDictionary * podcast = [self.podcasts objectAtIndex: indexPath.row]; // Actualizar User Defatuls NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; [ud setObject: podcast forKey: @ "MTPodcast"]; [ud sincronizar]; // Descartar controlador de vista [self dismissViewControllerAnimated: YES completed: nil];
Hay dos detalles de los que quiero hablar antes de volver a la MTViewController
clase. Cuando el controlador de la vista de búsqueda se presenta al usuario, está claro que quiere buscar podcasts. Por lo tanto, es una buena idea presentar inmediatamente el teclado. Hacemos esto en viewDidAppear:
Como se muestra abajo.
- (void) viewDidAppear: (BOOL) animated [super viewDidAppear: animated]; // Mostrar teclado [self.searchBar becomeFirstResponder];
El teclado debe ocultar el momento en que el usuario comienza a desplazarse por los resultados de búsqueda. Para lograr esto, implementamos scrollViewDidScroll:
del UIScrollViewDelegate
protocolo. Esto explica porque MTSearchViewController
se ajusta a la UIScrollViewDelegate
protocolo. Echa un vistazo a la implementación de scrollViewDidScroll:
mostrado a continuación.
- (void) scrollViewDidScroll: (UIScrollView *) scrollView if ([self.searchBar isFirstResponder]) [self.searchBar resignFirstResponder];los
UITableView
clase es una subclase de UIScrollView
, ¿Cuál es la razón por la que funciona el enfoque anterior. Como vimos anteriormente, almacenamos la selección del usuario en la base de datos predeterminada de usuario de la aplicación. Necesitamos actualizar el MTViewController
Clase para hacer uso de la selección del usuario en el controlador de vista de búsqueda. En el controlador de vista viewDidLoad
Método, cargamos el podcast desde la base de datos de valores predeterminados del usuario y agregamos el controlador de vista como observador de la base de datos de valores predeterminados del usuario para la ruta clave MTPodcast
para que el controlador de vista sea notificado cuando el valor para MTPodcast
cambios.
- (void) viewDidLoad [super viewDidLoad]; // Load Podcast [self loadPodcast]; // Agregar Observer [[NSUserDefaults standardUserDefaults] addObserver: self forKeyPath: @ Opciones de "MTPodcast": NSKeyValueObservingOptionNew context: NULL];
Todo lo que hacemos en loadPodcast
está almacenando el valor para MTPodcast
desde la base de datos predeterminada de usuario en el controlador de vista podcast
propiedad. Este valor será nulo
Si la base de datos predeterminada del usuario no contiene una entrada para MTPodcast
. El controlador de vista manejará con gracia esto por nosotros. Recuerde que, en Objective-C, puede enviar mensajes a nulo
sin que todo el infierno se desate. Esto tiene sus desventajas, pero ciertamente tiene sus ventajas para.
- (void) loadPodcast NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; self.podcast = [ud objectForKey: @ "MTPodcast"];
Esto también significa que necesitamos declarar una propiedad llamada podcast
en el archivo de implementación del controlador de vista.
#import "MTViewController.h" @interface MTViewController () @property (strong, nonatomic) NSDictionary * podcast; @fin
Echemos también un vistazo rápido a setPodcast:
y updateView
.
- (void) setPodcast: (NSDictionary *) podcast if (_podcast! = podcast) _podcast = podcast; // Vista de actualización [self updateView];
- (void) updateView // Update View self.title = [self.podcast objectForKey: @ "collectionName"];
Cuando el valor en la base de datos predeterminada del usuario cambia para la clave MTPodcast
, El controlador de vista puede responder a este cambio en observeValueForKeyPath: ofObject: change: context:
. Así es como funciona el valor clave de la observación. Todo lo que hacemos en este método es actualizar el valor del controlador de vista. podcast
propiedad.
- (void) observeValueForKeyPath: (NSString *) keyPath ofObject: (id) cambio de objeto: (NSDictionary *) cambia el contexto: (void *) context if ([keyPath isEqualToString: @ "MTPodcast"]) self.podcast = [object objectForKey: @ "MTPodcast"];
Cuando se trabaja con la observación de valores clave, es fundamental conocer la gestión de la memoria y retener los ciclos. En este caso, significa que debemos eliminar el controlador de vista como observador cuando el controlador de vista está desasignado.
- (void) dealloc [[NSUserDefaults standardUserDefaults] removeObserver: self forKeyPath: @ "MTPodcast"];
La respuesta que recibimos de la API de búsqueda de iTunes incluye un URL para el canal
Atributo para cada podcast. Podríamos obtener el feed manualmente y analizarlo. Sin embargo, para ahorrar algo de tiempo, haremos uso de MWFeedParser, una biblioteca popular que puede hacer esto por nosotros. Puede descargar manualmente e incluir la biblioteca en su proyecto, pero voy a optar por Cocoapods. Prefiero Cocoapods para administrar dependencias en proyectos iOS y OS X. Puedes leer más sobre Cocoapods en su sitio web o en Mobiletuts+.
Salga de Xcode, navegue hasta la raíz de su proyecto de Xcode y cree un archivo llamado Podfile. Abra este archivo en el editor de texto que prefiera y agregue las siguientes tres líneas de código. En la primera línea, especificamos la plataforma y el destino de la implementación, que es iOS 7 en este ejemplo. Las siguientes dos líneas especifican una dependencia de nuestro proyecto Xcode. El primero es el MWFeedParser biblioteca y también he incluido el popular SVProgressHUD biblioteca, que será útil un poco más tarde.
plataforma: ios, '7' pod 'MWFeedParser' pod 'SVProgressHUD'
Abra una ventana de Terminal, navegue hasta la raíz de su proyecto Xcode y ejecute el comando instalación de la vaina
. Esto debería instalar las dependencias y crear un espacio de trabajo de Xcode.. Cuando Cocoapods termina de instalar las dependencias del proyecto, le indica que use el espacio de trabajo que creó para usted. Esto es importante, así que no ignore este consejo.. En la raíz de su proyecto Xcode, verá que Cocoapods ha creado un espacio de trabajo Xcode para usted. Haga doble clic en este archivo y debería estar listo para ir.
Abra el archivo de implementación del MTViewController
clase, agregue una declaración de importación para MWFeedParser y SVProgressHUD, y declarar dos propiedades, episodios
y feedParser
. También necesitamos hacer MTViewController
conforme a la MWFeedParserDelegate
protocolo.
#import "MTViewController.h" #import "MWFeedParser.h" #import "SVProgressHUD.h" @interface MTViewController ()@property (fuerte, no atómico) NSDictionary * podcast; Episodios de NSMutableArray * de @property (strong, nonatomic); @property (strong, nonatomic) MWFeedParser * feedParser; @fin
A continuación, actualizamos setPodcast:
invocando fetchAndParseFeed
, Un método de ayuda en el que usamos el MWFeedParser
clase para buscar y analizar el feed del podcast.
- (void) setPodcast: (NSDictionary *) podcast if (_podcast! = podcast) _podcast = podcast; // Vista de actualización [self updateView]; // Fetch and Parse Feed [self fetchAndParseFeed];
En fetchAndParseFeed
, Nos deshacemos de nuestra corriente MWFeedParser
instancia si tenemos una e inicializamos una nueva instancia con la URL del feed del podcast. Establecemos el feedParseType
propiedad a ParseTypeFull
y configura el controlador de vista como el delegado del analizador de fuentes. Antes de buscar el feed, utilizamos SVProgressHUD
mostrar un HUD de progreso al usuario.
- (void) fetchAndParseFeed if (! self.podcast) return; NSURL * url = [NSURL URLWithString: [self.podcast objectForKey: @ "feedUrl"]]; si (! url) regresa; if (self.feedParser) [self.feedParser stopParsing]; [self.feedParser setDelegate: nil]; [self setFeedParser: nil]; // Borrar episodios si (self.episodes) [self setEpisodes: nil]; // Inicializar Feed Parser self.feedParser = [[MWFeedParser alloc] initWithFeedURL: url]; // Configurar Feed Parser [self.feedParser setFeedParseType: ParseTypeFull]; [self.feedParser setDelegate: self]; // Mostrar progreso HUD [SVProgress HUD showWithMaskType: SVProgressHUDMaskTypeGradient]; // Iniciar el análisis [self.feedParser parse];
También necesitamos implementar dos métodos de MWFeedParserDelegate
protocolo, feedParser: didParseFeedItem:
y feedParserDidFinish:
. En feedParser: didParseFeedItem:
, inicializamos el episodios
propiedad si es necesario y pásele el elemento de feed que el analizador de feed nos entrega.
- (void) feedParser: (MWFeedParser *) parser didParseFeedItem: (MWFeedItem *) item if (! self.episodes) self.episodes = [array NSMutableArray]; [self.episodes addObject: item];
En feedParserDidFinish:
, descartamos el progreso HUD y actualizamos la vista de tabla. ¿Dijiste la vista de tabla? Está bien. Necesitamos agregar una vista de tabla e implementar lo necesario. UITableViewDataSource
métodos de protocolo.
- (void) feedParserDidFinish: (MWFeedParser *) parser // Descartar progreso HUD [SVProgress HUD despedir]; // Vista de actualización [self.tableView reloadData];
Antes de actualizar la interfaz de usuario, abra MTViewController.h
, declarar una salida para la vista de tabla y decirle al compilador MTViewController
clase se ajusta a la UITableViewDataSource
y UITableViewDelegate
protocolos.
#importar@interface MTViewController: UIViewController @ propiedad (débil, no atómica) IBOutlet UITableView * tableView; @fin
Abra el guión gráfico una vez más y agregue una vista de tabla a la vista del controlador de vista. Conecte la vista de tabla fuente de datos
y delegar
salidas con el controlador de vista y conecte el controlador de vista tableView
Salida con la vista de la mesa. Seleccione la vista de tabla, abra el Inspector de atributos, y establecer el número de células prototipo para 1
. Seleccione la celda prototipo, establezca su estilo en Subtitular, y darle un identificador de EpisodioCell.
Antes de implementar el UITableViewDataSource
protocolo, declarar una cadena estática llamada EpisodioCell
en MTViewController.m. Esto se corresponde con el identificador que configuramos para la celda prototipo en el guión gráfico..
static NSString * EpisodeCell = @ "EpisodeCell";
Implementando el UITableViewDataSource
El protocolo es simple como circular y muy similar a cómo implementamos el protocolo en el controlador de vista de búsqueda. La única diferencia es que la episodios
variable contiene instancias de la MWFeedItem
clase en lugar de NSDiccionario
instancias.
- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return self.episodes? 1: 0;
- (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) section return self.episodes? self.episodes.count: 0;
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: EpisodeCell forIndexPath: indexPath]; // Fetch Feed Item MWFeedItem * feedItem = [self.episodes objectAtIndex: indexPath.row]; // Configurar la celda de vista de tabla [cell.textLabel setText: feedItem.title]; [cell.detailTextLabel setText: [NSString stringWithFormat: @ "% @", feedItem.date]]; celda de retorno
- (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath return NO;
- (BOOL) tableView: (UITableView *) tableView canMoveRowAtIndexPath: (NSIndexPath *) indexPath return NO;
Ejecute la aplicación en el simulador de iOS o en un dispositivo físico y ejecútelo a su ritmo. Ahora debería poder buscar podcasts, seleccionar un podcast de la lista y ver sus episodios.
Hemos hecho mucho en este tutorial, pero aún tenemos mucho trabajo por delante. En el siguiente tutorial, hacemos zoom en la descarga de episodios de la fuente y analizaremos las descargas en segundo plano o fuera de proceso. Manténganse al tanto.