2012-05-22 9 views
8

Tengo un problema al guardar un archivo de cadena con NSSavePanel después de guardar la aplicación de la Mac App Store. Configuré com.apple.security.files.user-selected.read-write en YES y el NSOpenPanel está funcionando como debería.NSSavePanel no está guardando un archivo después de la aplicación de sandboxing

Cuando trato de guardar un nuevo archivo, sin embargo, parece que todo está funcionando bien, pero entonces no hay archivo guardado donde debe estar ....

Este es el código que estoy utilizando para ahorrar el archivo:

NSSavePanel *save = [NSSavePanel savePanel]; 

long int result = [save runModal]; 

if (result == NSOKButton) 
{ 
    NSString *selectedFile = [save filename]; 
    NSString *fileName = [[NSString alloc] initWithFormat:@"%@.dat", selectedFile]; 
    NSString *arrayCompleto = [[NSString alloc]initWithFormat:@"bla bla bla"]; 
    [arrayCompleto writeToFile:fileName 
        atomically:NO 
         encoding:NSUTF8StringEncoding 
         error:nil]; 
} 

Respuesta

10

En primer lugar, el selector -[NSSavePanel filename] ya no se utiliza. Use -[NSSavePanel URL] en su lugar. En segundo lugar, la forma en que el -[NSString writeToFile:atomically:encoding:error] le dice lo que está haciendo mal es con el argumento error:(NSError**).

También debe manejar los errores de archivos E/S en particular, porque incluso si su código es 100% correcto, puede haber errores en el sistema del usuario (privilegios insuficientes, etc.) y presentar el error al usuario les permitirá ver que falló (y tener alguna idea de por qué). El manejo del error en el código también permitirá que tu aplicación se recupere. Por ejemplo, si trataste de leer en el archivo debajo del código que pegaste (después de escribirlo en el disco), pero el usuario intentó escribirlo en un recurso compartido de red al que no tuvo acceso, es posible que la aplicación se bloquee. Si sabe que la escritura falló, puede proceder en consecuencia (tal vez solicitando una ubicación de guardado diferente).

En este caso, sin embargo, creo que la siguiente línea es su problema:

NSString *fileName = [[NSString alloc] initWithFormat:@"%@.dat", selectedFile]; 

Cuando se recinto de seguridad de su aplicación, el usuario tiene que dar permiso para que sea un archivo específico o una específica directorio a través de los paneles de abrir/guardar para ponerlos en su sandbox. Lo que está haciendo es tomar el archivo que el usuario le dio permiso para escribir y decir "eso es genial, pero quiero guardar un archivo diferente", lo que infringe la zona de pruebas. Lo que debe hacer en su lugar es configurar la extensión en el Panel de Guardar. La solución fija completa sería:

NSSavePanel *save = [NSSavePanel savePanel]; 
[save setAllowedFileTypes:[NSArray arrayWithObject:@"dat"]]; 
[save setAllowsOtherFileTypes:NO]; 

NSInteger result = [save runModal]; 

if (result == NSOKButton) 
{ 
    NSString *selectedFile = [[save URL] path]; 
    NSString *arrayCompleto = @"bla bla bla"; 

    NSError *error = nil; 
    [arrayCompleto writeToFile:selectedFile 
        atomically:NO 
         encoding:NSUTF8StringEncoding 
          error:&error]; 
} 

if (error) { 
    // This is one way to handle the error, as an example 
    [NSApp presentError:error]; 
} 

Si en el futuro algo más es incorrecto, se puede comprobar el valor de error en tiempo de ejecución. Durante la depuración, establezca un punto de interrupción dentro de la declaración if (error) para verificar el valor del objeto error (haga un po error en el depurador de Xcode). Eso debería ayudarte a descubrir qué está mal.

+0

¡Muchas gracias, hermano! ¡¡¡Funcionó a las mil maravillas!!! ¡Gracias por su ayuda! Massy – Blue

+0

No hay problema. También olvidé mencionar que es especialmente útil manejar los errores cuando se trata de E/S de archivos, porque incluso cuando su código es 100% correcto, puede haber problemas en el sistema de un usuario (privilegios insuficientes, etc.). Agregué eso a la respuesta. – Dov

+0

También puede configurar el nombre de archivo guardado para que no se guarde como documento 'Sin título': [save setNameFieldStringValue: @ "MySuggestedFilename"] –

Cuestiones relacionadas