iOS 8: cambios en la ruta del paquete
objective-c (4)
Tengo una aplicación para iOS que almacena la ruta absoluta de los archivos en una base de datos y en documentos html generados. Recientemente actualicé mi iPhone a iOS 8 y ahora, cuando ejecuto la aplicación, parece que la aplicación se instala en un directorio diferente cada vez que se vuelve a compilar. Por ejemplo, en la primera compilación / ejecución [[NSBundle mainBundle] bundlePath] devuelve algo diferente en la próxima compilación / ejecución. Que esta pasando? ¿Es esta una nueva característica de Apple?
Actualización: se creó un informe de error
Ejemplo de código:
Si ejecuto la siguiente línea en varias compilaciones / ejecuciones, obtendré un resultado diferente cada vez.
#define kOLD_PATH @"oldPath"
NSString* newPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
NSString* oldPath = [[NSUserDefaults standardUserDefaults] objectForKey:kOLD_PATH];
NSLog(@"New Path: %@", newPath);
NSLog(@"Old Path: %@", oldPath);
NSLog(@"Result: %@", [oldPath isEqualToString:newPath] ? @"Same" : @"Changed");
[[NSUserDefaults standardUserDefaults] setObject:newPath forKey:kOLD_PATH];
[[NSUserDefaults standardUserDefaults] synchronize];
El resultado se ve así en varias ejecuciones
New Path: /var/mobile/Containers/Data/Application/4FFCE2CB-580D-409A-90CB-EF2B8A1FB653/Library
Old Path: /var/mobile/Containers/Data/Application/B038B2DA-F85D-4E18-A5F1-8635834EC454/Library
Result: Changed
Divulgación completa: en mi aplicación, el usuario importa una página web (ePub) que tiene recursos. Los recursos se almacenan con la página web. La página web también accede a recursos que forman parte del paquete de aplicaciones. Para lograr esto cuando cargo la página web, la URL base se establece en el directorio en el que se encuentra la página web y se accede a los recursos del paquete a través de rutas de archivos absolutas. Ahora que las rutas de archivo cambian en cada actualización, esto se rompe. Intenté crear enlaces simbólicos a los recursos del paquete, pero eso también falla en actualizaciones posteriores.
Creo que la ruta diferente para cada compilación y ejecución es la forma prevista de cosas que suceden en el simulador de iOS. No es un problema.
/ var / mobile / Containers / Data / Application / 4FFCE2CB-580D-409A-90CB-EF2B8A1FB653 / Library / var / mobile / Containers / Data / Application / B038B2DA-F85D-4E18-A5F1-8635834EC454 / Library
Encontré incluso si usas la forma recomendada
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject];
}
Los resultados son iguales. Ruta diferente para cada compilación y ejecución.
En iOS 8, el diseño del sistema de archivos de los contenedores de aplicaciones ha cambiado. Las aplicaciones y su contenido ya no se almacenan en un directorio raíz.
De las notas de la versión de iOS 8:
El diseño del sistema de archivos de los contenedores de aplicaciones ha cambiado en el disco. En lugar de confiar en la estructura de directorios codificada, use la función
NSSearchPathForDirectoriesInDomains
o laURLForDirectory:inDomain:appropriateForURL:create:error:
método de la claseNSFileManager
. Consulte Acceso a archivos y directorios en la Guía de programación del sistema de archivos .
Esto no es un error. Asegúrese de utilizar las API recomendadas (de la cita anterior) y no tendrá ningún problema.
Entonces, si está intentando acceder a un recurso agrupado que agregó al proyecto, usaría:
[[NSBundle mainBundle] pathForResource:@"resourceName" ofType:@"extension"];
Pero si desea usar algo que puso en el directorio de documentos, usaría:
[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"resourceName.extension"];
No sé si resolvió su problema, pero este enlace es la respuesta posible.
Ubicar archivos usando marcadores
Algunas líneas antes de esta sección en la página es este texto:
"Importante: aunque son seguros de usar mientras su aplicación se está ejecutando, las URL de referencia de archivo no son seguras para almacenar y reutilizar entre lanzamientos de su aplicación porque la ID de un archivo puede cambiar si se reinicia el sistema. Si desea almacenar la ubicación de un archivo de forma persistente entre lanzamientos de su aplicación, cree un marcador como se describe en Localización de archivos usando marcadores ".
Adiós.
Consulte la nota técnica 2406 de Apple
El cambio radical es
A partir de iOS 8, los directorios Documentos y Biblioteca ya no son hermanos del paquete de su aplicación.
No almacene la ruta / URL completa a sus documentos. Almacene el nombre del archivo y siempre genere la ruta / URL completa con el enfoque recomendado.
Obtenga la URL de DocumentsDirectory
// Returns the URL to the application''s Documents directory.
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
Luego obtiene la ruta de la url y agrega el nombre del archivo para generar la ruta completa.