2012-05-22 10 views
8

Ho riscontrato un problema durante il salvataggio di un file di stringa con NSSavePanel dopo l'installazione in sandbox dell'app per Mac App Store. Ho impostato com.apple.security.files.user-selected.read-write su YES e il NSOpenPanel funziona come dovrebbe.NSSavePanel non salva un file dopo il sandboxing di un'app

Quando si tenta di salvare un nuovo file, però, sembra che tutto sta funzionando bene, ma poi non c'è alcun file salvato dove dovrebbe essere ....

Questo è il codice che sto usando per salvare il file:

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]; 
} 

risposta

10

Prima di tutto, il selettore -[NSSavePanel filename] è stato sconsigliato. Utilizzare invece -[NSSavePanel URL]. In secondo luogo, il modo in cui il -[NSString writeToFile:atomically:encoding:error] ti dice cosa stai facendo male è con l'argomento error:(NSError**).

Dovresti anche gestire gli errori per l'I/O di file in particolare, perché anche se il tuo codice è corretto al 100%, potrebbero ancora esserci errori nel sistema dell'utente (privilegi insufficienti, ecc.) E presentare l'errore all'utente permetterà loro di vederlo fallito (e hanno qualche idea del perché). La gestione dell'errore nel codice consentirà inoltre il ripristino della tua app. Ad esempio, se hai provato a leggere il file sotto il codice incollato (dopo averlo scritto sul disco), ma l'utente ha provato a scriverlo su una condivisione di rete a cui non avevano accesso, l'app potrebbe bloccarsi. Se sai che la scrittura non è andata a buon fine, puoi procedere di conseguenza (magari chiedendo una diversa posizione di salvataggio).

In questo caso, però, credo che la riga seguente è il tuo problema:

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

Quando la vostra applicazione è sandbox, l'utente deve dare il permesso sia per una specifica file di o un specifica directory attraverso i pannelli di apertura/salvataggio per portarli nella sandbox. Quello che stai facendo è prendere il file che l'utente ti ha dato il permesso di scrivere e dire "è grandioso, ma voglio salvare un file diverso", che viola la sandbox. Quello che dovresti fare invece è impostare l'estensione nel pannello di salvataggio. La soluzione fissa completo sarebbe:

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]; 
} 

Se in futuro qualcosa è sbagliato, è possibile controllare il valore della error in fase di esecuzione. Durante il debug, impostare un breakpoint all'interno dell'istruzione if (error) per verificare il valore dell'oggetto error (fare un po error nel debugger di Xcode). Questo dovrebbe aiutarti a capire cosa c'è che non va.

+0

Grazie mille amico! Ha funzionato come un fascino!!! Grazie per il vostro aiuto! Massy – Blue

+0

Nessun problema. Ho anche dimenticato di menzionare, è particolarmente utile gestire gli errori ogni volta che si ha a che fare con I/O di file, perché anche quando il codice è corretto al 100%, potrebbero esserci problemi sul sistema dell'utente (privilegi insufficienti, ecc.). L'ho aggiunto alla risposta. – Dov

+0

È inoltre possibile impostare il nome file di salvataggio richiesto in modo che non salvi come documento "Senza titolo": [salva setNameFieldStringValue: @ "MySuggestedFilename"] –