Archivo de la categoría: IT

IT, Information Technologies, Tecnologías de la Información

[2016 Aug] ImageCaching for CellForRow

La carga de una imagen suele ser lenta, y en general considero recomendable realizarlo de manera asíncrona. Así el proceso de cargar la imagen desde disco, interpretarla, redimensionarla se pueden realizar sin interferir en el hilo de atención a las acciones del usuario.


let id = thought.valueForKey("id") as! String
if let cachedImage = ImageCache.sharedCache.imageForKey("image-\(id)") {
cell.picture.image = cachedImage
} else {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
let scaledImage = Helper.scaleUIImageToSize(image!, size: size)
ImageCache.sharedCache.setImage(scaledImage, forKey: "image-\(id)")
dispatch_async(dispatch_get_main_queue(), {
cell.picture.image = scaledImage
})
})
}

view raw

code1.swift

hosted with ❤ by GitHub

El mecanismo utilizado es una clase que tiene un diccionario (arreglo asociativo) en memoria e identifica a las imágenes con un key.

El nombre del key debe trabajarse de acuerdo a sí tendremos distintas dimensiones de imágenes en el mismo caché, o si deseamos poder controlar caching para otros elementos. Seguramente podemos utilizar también un library (ej. Haneke).

Aunque esta implementación es simple, sencilla y suficiente para muchos casos.

La fuente de este método es un artículo de Ray Wenderlich acerca de la utilización de Instruments. Y, pues, al verificar el consumo de tiempo de procesador, resalta el trabajo por hacer un Resize de las fotos. Esta tarea desaparece cuando se cuenta con las fotos ya redimensionadas en el caché.

https://www.raywenderlich.com/97886/instruments-tutorial-with-swift-getting-started

[2016 Aug] LocalNotifications, data in LocalNotifications

Un LocalNotification lleva datos esenciales como el mensaje para la alerta y la fecha de fire.

Una vez creado no podemos identificarlo si es que no le hemos dado un ID

Esto es posible si le agregamos información custom


notification.userInfo = [ "notificationId": myNotificationId ]

view raw

code1.swift

hosted with ❤ by GitHub


notification.userInfo = [ "notificationId": myNotificationId ]

view raw

code1.swift

hosted with ❤ by GitHub

Luego podemos identificarlo así


let userInfoCurrent = notification.userInfo! as! [String:AnyObject]
let uid = userInfoCurrent["notificationId"]! as! String
if uid == targetNotificationId {
// aplicamos alguna acción aquí
}

view raw

code2.swift

hosted with ❤ by GitHub

[2016 Aug] Core Data, migrations to App Group Container

Cuando necesitamos que dos Apps utilicen los mismos datos vamos a tener que darles la capacidad de compartir un mismo repositorio de datos.

Core Data puede manejar varias opciones, pero en general, podemos considerar que se trata de un archivo sqlLite

No solo es el caso en el que tengamos dos apps, que muy probablemente sean de la misma empresa, sino que un App Extension también puede ser considerada como un segundo App, en la perspectiva del acceso a datos.

Para esto vamos a necesitar crear un App Group y asignarlo, desde los properties del target del Extension y del App principal.

Luego nuestra configuración de core data, en AppDelegate y en el código del Extension deben utilizar otro enfoque, así


lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// ..
let containerURL = fileManager.containerURLForSecurityApplicationGroupIdentifier("group.com.myapp.MyApp")
let groupURL = containerURL!.URLByAppendingPathComponent(databaseName)
// ..
}

Luego es similar a cuando se trabaja con CoreDara por default


let store = try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: groupURL, options: options)

Algunas validaciones serán necesarias si ya estábamos trabajando inicialmente sin considerar el escenario de App Group Container, entonces habrá que validar la existencia del archivo sqlite.

Y si ya teníamos datos, debemos efectuar una migración


try coordinator.migratePersistentStore(store, toURL: groupURL, options: options, withType:NSSQLiteStoreType)

Esta migración no considera el orden de los registros. Y en general, el orden no se lo dejamos a la base de datos, sino a alguna columna con timestamp. Debemos incorporar esa especie de ORDER BY en nuestro query. Se trata de un sortDescriptor.