NSSavePanel no está guardando un archivo después de aislar una aplicación

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

Sin embargo, cuando trato de guardar un nuevo archivo, parece que todo funciona bien, pero luego no hay ningún archivo guardado donde debería estar...

Este es el código que estoy usando para guardar 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];
}

preguntado el 22 de mayo de 12 a las 20:05

1 Respuestas

En primer lugar, la -[NSSavePanel filename] selector ha quedado en desuso. Utilizar -[NSSavePanel URL] en lugar de. En segundo lugar, la forma en que el -[NSString writeToFile:atomically:encoding:error] te dice que lo que estas haciendo mal es con el error:(NSError**) argumento.

También debe manejar los errores de E/S de archivos en particular, porque incluso si su código es 100 % correcto, todavía puede haber errores en el sistema del usuario (privilegios insuficientes, etc.) y presentar el error al usuario le permitirá ver que falló (y tener alguna idea de por qué). Manejar el error en el código también permitirá que su aplicación se recupere. Por ejemplo, si trató de leer el archivo debajo del código que pegó (después de escribirlo en el disco), pero el usuario intentó escribirlo en un recurso compartido de red al que no tenía acceso, su aplicación podría fallar. Si sabe que la escritura falló, puede proceder en consecuencia (tal vez solicitando una ubicación diferente para guardar).

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

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

Cuando su aplicación está en un espacio aislado, el usuario debe darle permiso para una archivo específico o con una directorio específico a través de los paneles abrir/guardar para llevarlos a su caja de arena. 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 viola la zona de pruebas. Lo que debe hacer en su lugar es configurar la extensión en el Panel 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 está mal, puede comprobar el valor de error en tiempo de ejecución. Durante la depuración, establezca un punto de interrupción dentro del if (error) declaración para comprobar error valor del objeto (hacer un po error en el depurador de Xcode). Eso debería ayudarte a descubrir qué está mal.

contestado el 23 de mayo de 12 a las 15:05

No hay problema. También olvidé mencionar que es especialmente una buena práctica manejar los errores cada vez que 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

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

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.