Trabajando con iCloud Almacenamiento de valor-clave

Mantener los datos de la aplicación sincronizados entre dispositivos es una tarea compleja y desalentadora. Afortunadamente, esa es exactamente la razón por la que Apple construyó iCloud. En esta serie Tuts + Premium, aprenderá cómo funciona iCloud y cómo sus aplicaciones pueden compartir datos a la perfección en múltiples dispositivos.


También disponible en esta serie:

  1. Trabajando con iCloud: Introducción
  2. Trabajando con iCloud: Almacenamiento de valor-clave
  3. Trabajando con iCloud: Almacenamiento de documentos
  4. Trabajando con iCloud: Core Data Integration

En la primera entrega de esta serie, di una introducción a iCloud y me centré en iCloud Storage en particular. Dos tipos de almacenamiento de iCloud están disponibles para los desarrolladores, Almacenamiento de valor-clave y Almacenamiento de documento. Key-Value Storage será el tema central de este tutorial..

Comenzaremos este tutorial analizando de cerca el proceso de configuración de una aplicación para usar con iCloud. Con nuestra aplicación correctamente configurada, utilizaremos el almacenamiento de valor clave de iCloud para mantener los datos de nuestra aplicación sincronizados en múltiples dispositivos.


Antes de que comencemos

No podemos probar la sincronización de datos con un solo dispositivo. Para completar este tutorial, deberá tener al menos dos dispositivos iOS que ejecuten iOS 5 o superior. Desafortunadamente, el simulador de iOS no se puede usar para probar el almacenamiento de iCloud.

La aplicación que estamos a punto de construir será una sencilla aplicación para iOS, lo que significa que podrás ejecutarla en cualquier iPhone, iPod Touch o iPad con iOS 5 o superior. La lectura de este tutorial aún valdrá la pena incluso si no tiene dos dispositivos iOS separados para usar en las pruebas. Le enseñará cómo se configura iCloud y cómo puede usar Key-Value Storage de iCloud para mejorar sus propias aplicaciones..


Paso 1: Configuración del proyecto

Comenzaré guiándole a través del proceso de configuración de nuestra aplicación para usar iCloud Storage. Sin embargo, primero necesitamos configurar nuestro proyecto Xcode.

Crea un nuevo proyecto en Xcode seleccionando el Solicitud de vista única modelo. Nombra tu aplicación Nublado, entrar a identificación de compañía, conjunto iPhone Para la familia de dispositivos, y compruebe Utilice el conteo automático de referencias. Las casillas de verificación restantes deben estar sin marcar. Dile a Xcode dónde quieres guardar tu proyecto y pulsa Crear.



Es clave que elijas cuidadosamente el nombre del producto y identificación de compañía para este proyecto. La combinación de estos dos elementos forma el identificador de paquete (junto con el identificador de inicialización del paquete) de su aplicación, que iCloud utilizará para identificar de forma única su aplicación. Revise cuidadosamente su ortografía, ya que el identificador del paquete distingue entre mayúsculas y minúsculas.


Paso 2: Configuración de iCloud

Como mencioné en el primer artículo de esta serie Tuts + Premium, configurar una aplicación para usar iCloud es fácil e implica solo dos pasos. Déjame guiarte a través del proceso paso a paso.

Paso 2A: Portal de Aprovisionamiento

Abra su navegador favorito y diríjase al Centro de desarrollo de iOS de Apple. Inicie sesión en su cuenta de desarrollador de iOS y haga clic en Portal de aprovisionamiento de iOS enlace a la derecha.


Primero, necesitamos crear un ID de aplicación para nuestra aplicación. Abre el ID de aplicaciones pestaña a la izquierda y haga clic en el Nueva ID de aplicación botón en la parte superior derecha. Asigne a su ID de aplicación un nombre descriptivo para identificarlo fácilmente más adelante. A continuación, ingrese el identificador del paquete del que hablé hace unos momentos. El identificador de paquete es la combinación del identificador de su empresa, com.mobiletuts en nuestro ejemplo, y el nombre del producto, Nublado en nuestro ejemplo Puede dejar el identificador de inicialización del paquete establecido en Usar identificación del equipo, lo cual está bien para nuestra aplicación.

Comprueba que el identificador de tu paquete esté escrito correctamente. Como mencioné anteriormente, el identificador de confusión es sensible a mayúsculas y minúsculas. Haga clic en el botón enviar para crear su ID de aplicación.


Su ID de aplicación recién creada ahora debe estar presente en la lista de ID de aplicación. Notará que iCloud está deshabilitado de forma predeterminada para cada ID de aplicación recién creada. Vamos a cambiar eso. A la derecha de su ID de aplicación, haga clic en Configurar botón. En la parte inferior de la página, debería ver una casilla de verificación que dice Habilitar para iCloud. Marque la casilla de verificación y haga clic en Hecho. Nuestra ID de aplicación ahora está configurada para trabajar con iCloud. Hay una cosa más de la que debemos cuidar mientras estamos en el Portal de aprovisionamiento.



Para garantizar que nuestra aplicación pueda ejecutarse en nuestros dispositivos, debemos crear un perfil de aprovisionamiento. Aún en el Portal de Provisioning de iOS, abre el Aprovisionamiento pestaña a la izquierda y seleccione la Desarrollo pestaña en la parte superior. Haga clic en el Nuevo perfil en la parte superior derecha e ingrese un nombre descriptivo para su nuevo perfil. A continuación, seleccione el certificado de desarrollo al que desea asociar el perfil y elija la ID de aplicación correcta en la lista desplegable. Finalmente, seleccione los dispositivos que utilizará para realizar pruebas en la lista que se encuentra en la parte inferior de la página..


Después de hacer clic en el botón Enviar en la parte inferior derecha, notará que su perfil de aprovisionamiento tiene un estado de Pendiente. Después de volver a cargar la página, el estado del perfil debería haberse actualizado a Activo. Haga clic en el botón de descarga junto a su perfil de aprovisionamiento y haga doble clic en el perfil. Xcode instalará automáticamente el perfil por ti..



Paso 2B: Derechos

Muchos desarrolladores se estremecen cuando escuchan la palabra derechos. Los derechos no tienen nada que temer una vez que entiendas para qué sirven. Los derechos otorgan capacidades específicas o permisos de seguridad a una aplicación. Eso es todo lo que hay que hacer. Es una lista simple de pares clave-valor que le dicen al sistema operativo lo que su aplicación puede y no puede hacer, y qué aplicaciones tienen acceso a los datos de su aplicación. Este último es especialmente importante cuando se trabaja con iCloud..

En nuestro ejemplo, los derechos de iCloud nos permiten habilitar el almacenamiento de iCloud para nuestra aplicación. Para configurar los derechos de nuestra aplicación, nos dirigimos al editor de destino de Xcode.

Haga clic en nuestro proyecto en el Navegador de proyectos y seleccione nuestro objetivo de la lista de objetivos. Con el Resumen pestaña seleccionada, deberías ver una sección llamada Derechos en el fondo. Marque la primera casilla de verificación para habilitar los derechos para nuestra aplicación. Esta opción creará un archivo de derechos para nuestra aplicación. El campo de texto debajo de la casilla de verificación debe ser completado previamente por usted. Ahora tenemos la opción de habilitar iCloud Key-Value Storage y iCloud Document Storage.


En este tutorial, solo hablaré sobre iCloud Key-Value Storage, así que marque la casilla junto a iCloud Key-Value Store. Nuevamente, Xcode rellena previamente el campo de texto junto a la casilla de verificación con su identificador de paquete de aplicación (sin el identificador de semilla de paquete). Verifique que este identificador de paquete se corresponda con el que ingresó en el portal de aprovisionamiento cuando creó su ID de aplicación. Hablaré sobre iCloud Containers en el siguiente tutorial relacionado con el almacenamiento de documentos de iCloud..

En la parte inferior de la sección de derechos, ve Grupos de acceso de llavero. Esta lista especifica qué aplicaciones tienen acceso a los elementos de su llavero de aplicaciones. Puedes dejar esa sección sin tocar por ahora..

Antes de ensuciarnos las manos con las API de iCloud, debemos configurar nuestros ajustes de compilación. Todavía en el editor de destino de Xcode, seleccione el Configuraciones de compilación pestaña y desplácese hacia abajo hasta la Firma de código sección. Establecer la identidad de firma de código para el Depurar y Lanzamiento configuraciones para que coincida con el perfil que acabamos de crear en el Portal de aprovisionamiento de iOS.



Paso 3: Interfaz de usuario

Este tutorial es un tanto avanzado y, por lo tanto, asumo que está familiarizado con los conceptos básicos del desarrollo de iOS. Esto significa que me moveré un poco más rápido de lo normal, ya que tenemos mucho terreno por recorrer..

La aplicación que estamos a punto de construir será un simple administrador de marcadores. Podemos agregar y eliminar marcadores, y nuestros marcadores se sincronizarán en nuestros dispositivos. ¿Cuan genial es eso? Empecemos.

Abra el archivo de encabezado de nuestro controlador de vista y cree una variable de instancia (ivar) de tipo NSMutableArray con un nombre de marcadores. El ivar almacenará nuestros marcadores. Los marcadores se mostrarán en una vista de tabla. Cree una salida para la vista de tabla en nuestro archivo de encabezado del controlador de vista y asegúrese de que nuestro controlador de vista se ajuste a la fuente de datos de vista de tabla y a los protocolos delegados. Además, no olvide sintetizar los accesores para ambas propiedades en el archivo de implementación de nuestro controlador de vista. A continuación, agregue dos acciones a ViewController.h, editBookmarks: y añadir marcador:. Listo? Dirígete a la ViewController.xib archivo para cablear todo.

 #importar  @interface ViewController: UIViewController  NSMutableArray * _bookmarks; __weak UITableView * _tableView;  @property (no atómico, fuerte) NSMutableArray * marcadores; @ propiedad (no atómica, débil) IBOutlet UITableView * tableView; - (IBAction) editBookmarks: (id) remitente; - (IBAction) addBookmark: (id) remitente; @fin

Comience arrastrando una barra de navegación a la vista de nuestro controlador de vista y colóquela en la parte superior. Arrastra una instancia de UIBarButtonItem a la izquierda de la barra de navegación y establezca su identificador en el Inspector de atributos a Editar. Control de arrastrar desde el botón editar a nuestro Propietario del archivo y seleccione el editBookmarks: método. Arrastre un elemento del botón de la segunda barra a la derecha de la barra de navegación y asígnele un identificador de Añadir. Control de arrastrar desde el botón Agregar a nuestro Propietario del archivo y seleccione el añadir marcador: método. Finalmente, arrastre una instancia de UITableView a la vista de nuestro controlador de vista y conecte su fuente de datos y delegar salidas a la Propietario del archivo objeto. Hecho.


La implementación de los protocolos de origen de datos y delegados de nuestra vista de tabla es simple y directa. En el numberOfSectionsInTableView: método, verificamos si nuestra fuente de datos, es decir, nuestros marcadores, no es nula. Si es nulo, devolvemos 1. Si no, devolvemos 0. El tableView: numberOfRowsInSection: El método es casi idéntico. En cambio, si nuestra fuente de datos no es nula, devolvemos el número de elementos que contiene. Si nuestra fuente de datos es nula, devolvemos 0.

 - (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView if (self.bookmarks) return 1;  else return 0;  - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) sección if (! Self.bookmarks) return 0;  else return self.bookmarks.count; 

En el tableView: cellForRowAtIndexPath: Para comenzar, declaramos un identificador de celda estático con el fin de reutilizar la celda y luego pedimos a la vista de tabla una celda reutilizable con el identificador de celda que acabamos de declarar. Si no se devolvió una celda reutilizable, inicializamos una nueva celda con un estilo de UITableViewCellStyleSubtitle y pasamos nuestro identificador celular para la reutilización celular. A continuación, obtenemos el marcador correcto del origen de datos. Cada marcador será un diccionario con dos pares clave-valor, un nombre y un URL. Configuramos la celda configurando su etiqueta y etiqueta de detalle con el nombre del marcador y la URL, respectivamente.

 - (UITableViewCell *) tableView: (UITableView *) aTableView cellForRowAtIndexPath: (NSIndexPath *) indexPath static NSString * CellIdentifier = @ "Cell Identifier"; UITableViewCell * cell = [aTableView dequeueReusableCellWithIdentifier: CellIdentifier]; if (cell == nil) cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: CellIdentifier];  // Fetch Bookmark NSDictionary * bookmark = [self.bookmarks objectAtIndex: indexPath.row]; // Configurar celda cell.textLabel.text = [bookmark objectForKey: @ "name"]; cell.detailTextLabel.text = [bookmark objectForKey: @ "url"]; celda de retorno 

El usuario también tiene la opción de editar sus marcadores. En el tableView: canEditRowAtIndexPath: método volvemos . los tableView: commitEditingStyle: forRowAtIndexPath: Es un poco más complejo. Comenzamos por verificar que el estilo de edición de la celda sea igual a UITableViewCellEditingStyleDelete, es decir, se eliminó un marcador. Primero, actualizamos nuestra fuente de datos eliminando el marcador de la matriz de marcadores. Luego guardamos la fuente de datos enviando a nuestro controlador de vista un guardar marcadores mensaje y finalmente actualizamos la vista de tabla para reflejar los cambios que hicimos en el origen de datos.

 - (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath return YES;  - (void) tableView: (UITableView *) aTableView commitEditingStyle: (UITableViewCellEditingStyle) editingStyle forRowAtIndexPath: (NSIndexCatPPPPPPPPGRATETHEATLATETCLE) EstadoPad.p.P.P.P.P.P.P. // Guardar marcadores [self saveBookmarks]; // Actualizar vista de tabla [aTableView deleteRowsAtIndexPaths: [NSArray arrayWithObject: indexPath] withRowAnimation: UITableViewRowAnimationFade]; 

Echemos un vistazo a nuestras acciones ahora. los editBookmarks: El método no podría ser más fácil. Alternamos el estado de edición de la vista de tabla de forma animada..

 - (IBAction) editBookmarks: (id) sender [self.tableView setEditing:! Self.tableView.editing animated: YES]; 

los añadir marcador: El método requiere un poco más de trabajo. Inicializamos una nueva instancia de Añadir BookmarkViewController, un controlador de vista que crearemos en breve, y establecemos su propiedad de controlador de vista en yo. Luego presentamos el controlador de vista recién creado de manera modal. Como su nombre lo indica, Añadir BookmarkViewController Se encarga de crear nuevos marcadores. Echemos un vistazo más de cerca a Añadir BookmarkViewController.

 - (IBAction) addBookmark: (id) sender // Inicializar Agregar marcador Ver controlador AddBookmarkViewController * vc = [[AddBookmarkViewController alloc] initWithNibName: @ paquete "AddBookmarkViewController": [NSBundle mainBundle]]; vc.viewController = self; // Presentar el controlador de vista Modally [self presentViewController: vc animated: YES completed: nil]; 

Paso 4: Agregar marcadores

La implementación de Añadir BookmarkViewController Es muy sencillo, así que no voy a entrar en demasiados detalles. El controlador de vista tiene una referencia débil a nuestro controlador de vista principal. Esto le permite notificar a nuestro controlador de vista principal cuando se crea un nuevo marcador. Además cuenta con dos salidas de tipo. UITextField, que permite al usuario ingresar un nombre y una URL para cada marcador.

 #importar  @class ViewController; @interface AddBookmarkViewController: UIViewController __weak ViewController * _viewController; __weak UITextField * _nameField; __weak UITextField * _urlField;  @property (no atómico, débil) ViewController * viewController; @ propiedad (no atómica, débil) IBOutlet UITextField * nameField; @ propiedad (no atómica, débil) IBOutlet UITextField * urlField; @fin

El archivo XIB contiene una barra de navegación en la parte superior con un cancelar y un salvar botón. La vista en sí contiene los campos de texto de nombre y URL que acabo de mencionar. Los botones de cancelar y guardar están conectados a un cancelar: y un salvar: Acción, respectivamente. los cancelar: La acción simplemente despide nuestro controlador de vista modal. los salvar: La acción es igual de simple. Creamos un nuevo marcador (es decir, una instancia de NSDiccionario) con los datos que el usuario ha ingresado en los campos de texto e informe a nuestro controlador de vista principal sobre el nuevo marcador. Es importante tener en cuenta que esta no es la mejor solución para que nuestro controlador de vista principal sepa cuándo un marcador nuevo fue creado por nuestro Añadir BookmarkViewController. Este enfoque introduce un acoplamiento apretado, que debe evitarse tanto como sea posible. Un mejor enfoque sería adoptar el patrón de delegación..


 - (IBAction) cancel: (id) sender [self dismissViewControllerAnimated: YES completed: nil];  - (IBAction) guardar: (id) remitente NSString * name = self.nameField.text; NSString * url = self.urlField.text; NSDictionary * bookmark = [[NSDictionary alloc] initWithObjectsAndKeys: name, @ "name", url, @ "url", nil]; [self.viewController saveBookmark: marcador]; [self dismissViewControllerAnimated: YES complete: nil]; 

Estamos casi listos, pero todavía necesitamos implementar eso. saveBookmark: Método en nuestro controlador de vista principal. Comience declarando este método en nuestro archivo de encabezado del controlador de vista y luego diríjase a su archivo de implementación. La implementación es mínima. Añadimos el marcador creado recientemente a nuestra fuente de datos, guardamos el origen de datos y luego volvemos a cargar la vista de tabla para mostrar el marcador que acabamos de agregar..

 - (nulo) saveBookmark: (NSDictionary *) marcador // Agregar marcador a marcadores [self.bookmarks addObject: bookmark]; // Guardar marcadores [self saveBookmarks]; // Reload Table View [self.tableView reloadData]; 

Paso 5: Cargando y Guardando

Nuestra aplicación no es muy útil si los marcadores del usuario no se guardan en el disco. El usuario perdería sus marcadores cada vez que se cierra la aplicación. Mala experiencia de usuario. Vamos a arreglar esto.

En nuestro viewDidLoad: Método, enviamos a nuestro controlador una vista cargar marcadores mensaje. Echemos un vistazo a la cargar marcadores método. Almacenaremos los marcadores del usuario en el base de datos predeterminada de usuario. Primero verificamos si ya hay una entrada en la base de datos predeterminada del usuario con la clave marcadores. Si este es el caso, inicializamos nuestros marcadores con el contenido del objeto almacenado. Si este no es el caso, inicializamos nuestros marcadores con una matriz mutable vacía y la almacenamos en la base de datos predeterminada del usuario. Sencillo. Derecha?

 - (void) viewDidLoad [super viewDidLoad]; // Cargar marcadores [selfloadBookmarks]; 
 - (void) loadBookmarks NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; if ([ud objectForKey: @ "bookmarks"]! = nil) // Load Local Copy self.bookmarks = [NSMutableArray arrayWithArray: [ud objectForKey: @ "bookmarks"]];  else // Inicializar marcadores self.bookmarks = [[NSMutableArray alloc] init]; // Guardar copia local [ud setObject: self.bookmarks forKey: @ "bookmarks"]; 

Guardar los marcadores es aún más simple. Almacenamos nuestro objeto de marcadores en la base de datos por defecto del usuario usando la clave marcadores. Eso es todo al respecto.

 - (void) saveBookmarks NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; [ud setObject: self.bookmarks forKey: @ "bookmarks"]; 

Eso fue bastante trabajo. Ahora puedes construir y ejecutar tu aplicación. Debes poder agregar marcadores y eliminar marcadores. Los marcadores se guardan en el disco para que no pierda ningún dato cuando salga de la aplicación.


Paso 6: Sincronización de marcadores

Para que nuestra aplicación brille realmente, usaremos iCloud para mantener nuestros marcadores sincronizados en nuestros dispositivos. Te sorprenderá lo fácil que es esto. Como mencioné en el tutorial anterior de esta serie, el almacenamiento de Key-Value de iCloud funciona de manera muy similar a NSUserDefaults, es decir, almacena pares clave-valor. En la terminología de iCloud la tienda se llama NSUbiquitousKeyValueStore. Comencemos por guardar nuestros marcadores no solo localmente, sino también en iCloud.

Dirígete a nuestro Guardar marcadores: Método y modifique nuestro método para que se parezca al de abajo. Comenzamos por buscar una referencia al almacén predeterminado llamando tienda por defecto sobre el NSUbiquitousKeyValueStore clase. Una vez más, esto es muy similar a NSUserDefaults. Si nuestra referencia a la tienda no es nula, almacenamos nuestro objeto de marcadores en la tienda con la misma clave que usamos para almacenar nuestros marcadores en la base de datos predeterminada del usuario. Finalmente, sincronizamos la tienda..

 - (void) saveBookmarks // Save Local Copy NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; [ud setObject: self.bookmarks forKey: @ "bookmarks"]; // Guardar en iCloud NSUbiquitousKeyValueStore * store = [NSUbiquitousKeyValueStore defaultStore]; if (store! = nil) [store setObject: self.bookmarks forKey: @ "bookmarks"]; [sincronizar tienda]; 

Vocación sincronizar en la instancia de la tienda se sincronizan las claves y los valores en memoria con los que se guardaron en el disco. Puede pensar que este método obliga a que se envíen nuevos pares clave-valor a iCloud, pero este no es el caso. Al guardar las claves en la memoria en el disco, se notifica a iCloud que hay nuevos pares clave-valor disponibles para sincronizar. Sin embargo, es el sistema operativo el que finalmente decide cuándo es apropiado sincronizar los pares clave-valor recién agregados con iCloud. Es importante tener esto en cuenta y esta es también la razón por la que los cambios realizados en un dispositivo no serán visibles en otro dispositivo inmediatamente.

Además, a pesar de que llamamos a la sincronizado Método en la instancia de la tienda, esto no es necesario en la mayoría de las situaciones. El sistema operativo hace esto por usted en momentos apropiados. Sabía usted que NSUserDefaults tiene un sincronizar método también que funciona casi idénticamente?

Quizás se esté preguntando cómo sabe nuestra aplicación cuándo otro dispositivo ha actualizado Key-Value Store en iCloud y cómo puede introducir esos cambios. Esta es una muy buena pregunta y esta es la pieza final del rompecabezas..

Cada vez que se cambia el Key-Value Store, se envía una notificación y nuestra aplicación puede registrarse como observador para estas notificaciones. Es importante que se registre para recibir dichas notificaciones lo antes posible en el ciclo de vida de su aplicación..

Vamos a ver cómo funciona esto. En nuestro viewDidLoad Método hacemos cuatro cosas. Primero, obtenemos una referencia a Key-Value Store. En segundo lugar, agregamos nuestro controlador de vista como observador para cualquier notificación con un nombre de NSUbiquitousKeyValueStoreDidChangeExternallyNotification enviado por la Key-Value Store. Cuando recibamos dicha notificación, manejaremos esta notificación en nuestro updateKeyValuePairs: Método (que escribiremos en un momento). A continuación, enviamos a la tienda un mensaje de sincronizar. Finalmente, cargamos nuestros marcadores como hicimos antes..

 - (void) viewDidLoad [super viewDidLoad]; NSUbiquitousKeyValueStore * store = [NSUbiquitousKeyValueStore defaultStore]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector (updateKeyValuePairs :) nombre: NSUbiquitousKeyValueStoreDidChangeExternallyNotification object: store]; // Sincronizar tienda [store sincronizar]; // Cargar marcadores [selfloadBookmarks]; 

Todo lo que nos queda por hacer es implementar el updateKeyValuePairs: método. Vamos a hacer eso ahora mismo. La notificación de Información de usuario diccionario contiene dos pares clave-valor importantes, (1) el razón por qué se envió la notificación y (2) la claves en el Key-Value Store cuyos valores fueron cambiados. Comenzamos por analizar más detenidamente el motivo de la notificación. Primero nos aseguramos de que se haya especificado un motivo y se devuelva si no se ha especificado ninguno. Si se especificó un motivo, solo procederemos si el motivo fue un cambio en el servidor (NSUbiquitousKeyValueStoreServerChange) o los cambios locales se descartaron debido a una sincronización inicial con el servidor (NSUbiquitousKeyValueStoreInitialSyncChange). Si se cumple alguno de estos criterios, extraemos el conjunto de claves que se modificaron e iteramos las claves para ver si la clave de marcadores está entre ellas. Si este es el caso, tomamos el valor asociado con la clave y actualizamos nuestra fuente de datos, así como la base de datos predeterminada del usuario con este valor. Finalmente, volvemos a cargar la vista de tabla para reflejar los cambios..

 - (void) updateKeyValuePairs: (NSNotification *) notificación NSDictionary * userInfo = [notification userInfo]; NSNumber * changeReason = [userInfo objectForKey: NSUbiquitousKeyValueStoreChangeReasonKey]; Razón NSInteger = -1; // ¿Se especifica una razón? if (! changeReason) return;  else reason = [changeReason integerValue];  // Continuar si la razón era (1) Cambios en el servidor o (2) Inicialización de sincronización si ((razón == NSUbiquitousKeyValueStoreServerChange) || (razón == NSUbiquitousKeyValueStore en las cosas de las cosas de los animales: las cosas de las partes de las cosas de las cosas de los animales: la NSArray NSUbiquitousKeyValueStore * store = [NSUbiquitousKeyValueStore defaultStore]; // Buscar claves para "marcadores" Clave para (NSString * clave en changedKeys) if ([key isEqualToString: @ "bookmarks"]) // Actualizar origen de datos self.bookmarks = [NSMutableArray arrayWithArray: [store objectForKey: key] ]; // Guardar copia local NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; [ud setObject: self.bookmarks forKey: @ "bookmarks"]; // Reload Table View [self.tableView reloadData]; 

Hay dos puntos que requieren especial atención. Primero, como vimos en la implementación de updateKeyValuePairs:, recibimos una matriz que contiene todas las claves en Key-Value Store con los valores que se cambiaron. Esta es una opción para evitar que iCloud tenga que enviar una notificación por cada par de clave-valor que haya cambiado. En segundo lugar, se recomienda encarecidamente que almacene los datos de Key-Value Store de forma local. La base de datos predeterminada de usuario es adecuada para este propósito, pero usted es libre de elegir cualquier solución que se ajuste a sus necesidades. El motivo para almacenar una copia local es no depender de iCloud para el almacenamiento de datos. No todos los usuarios tendrán una cuenta de iCloud o tendrán habilitado iCloud en su dispositivo.

Con este último fragmento de código en su lugar, nuestra aplicación ahora está habilitada para iCloud. Cree y ejecute su aplicación en dos dispositivos y pruébelo usted mismo. Tenga en cuenta que los cambios no son instantáneos. Los cambios deben sincronizarse con los servidores de iCloud y, posteriormente, enviarse a los dispositivos apropiados que requieren actualización.

Aunque este tutorial es largo, la implementación de iCloud Key-Value Storage no requirió mucho código extra. Como escribí en el tutorial anterior, adoptar Key-Value Storage es fácil, directo y requiere muy pocos gastos generales de su parte..


Conclusión

Antes de terminar este tutorial, quiero reiterar las ventajas y desventajas de iCloud Key-Value Storage, ya que es importante tenerlas en cuenta. Los pros son obvios a estas alturas, es fácil de adoptar, rápido de implementar y se parece mucho a cómo NSUserDefaults trabajos. Sin embargo, también es importante tener en cuenta las desventajas. Los pares clave-valor son lo que son. Es decir, pares simples sin ningún tipo de manejo de conflictos a menos que implemente su propia lógica de manejo de conflictos. Este último no se recomienda ya que Key-Value Storage no se creó teniendo esto en cuenta. Document Storage proporciona soporte de conflictos integrado y, por lo tanto, es una opción mucho mejor si requiere un manejo de conflictos. Por último, no olvide que Key-Value Storage solo puede almacenar 1 MB de datos con un máximo de 1024 pares de clave-valor. Aunque adoptamos Key-Value Storage en esta aplicación con fines ilustrativos, no podemos garantizar que nunca haya un usuario con una lista de marcadores que supere el límite de 1 MB..

También quiero enfatizar que el propósito de nuestra aplicación es mostrarle cómo adoptar Key-Value Storage y cómo funciona detrás de escena. Esto no es de ninguna manera una aplicación que esté lista para su lanzamiento, ya que no es a prueba de balas de varias maneras.