2014-04-11 16 views
8

Al fine di risparmiare sui costi della larghezza di banda lato server associati alla mia applicazione iOS, ho confezionato una serie di risorse che altrimenti sarebbero scaricabili in fase di runtime nel mio pacchetto di applicazioni iOS. Nel contesto dell'applicazione come scritto, sarebbe ideale per me se potessi accedere ai file da una delle directory scrivibili dall'utente (es. [App Dir]/Library/Application Support/My Custom Subfolder/) senza dover copiare i file direttamente in fase di esecuzione (ad esempio all'avvio, prima esecuzione, qualunque cosa).È possibile creare collegamenti fisici ai file in un pacchetto di applicazioni iOS?

Mentre io sono stato in grado di creare con successo i collegamenti simbolici in .../My Custom Subfolder/ ai file nel fascio utilizzando l'API NSFileManagercreateSymbolicLinkAtURL:withDestinationURL:error:, alcune delle API quadro Ho quindi utilizzare per accedere al contenuto più tardi ottenere preso una cantonata e ridammi attributi e dati relativi ai collegamenti simbolici anziché al file sottostante. Probabilmente potrei mitigare tali problemi utilizzando alcune altre API di framework, ma potrebbe finire per lavorare molto a seconda dell'ambito degli usi errati.

Sul simulatore sono stato in grado di ovviare con successo a questo problema creando collegamenti rigidi al contenuto del bundle utilizzando l'API NSFileManagerlinkItemAtURL:toURL:error:. Gli hard link funzionavano alla grande per tutte le API di accesso ai file utilizzate in tutta l'app e tutto era peachy. Tuttavia, su DEVICE (testato su iPhone 5c con iOS 7.0.2 e iPad con iOS 7.1), ricevo un NSCocoaErrorDomain 513 error (Operation could not be completed. Operation not permitted.). Potrei creare un file di test in .../My Custom Subfolder/ e creare un collegamento hard a quello nella stessa cartella, ma se provo a collegarmi a qualcosa nel pacchetto di applicazioni di sola lettura, ottengo l'errore 513.

Qualcuno sa se c'è un modo per aggirare l'errore delle autorizzazioni al fine di realizzare ciò che sto cercando di fare?

+0

In questo modo: https://gist.github.com/albertodebortoli/2204433 – danh

+3

@danh, grazie per la risposta. Tuttavia, lo snippet di codice copia semplicemente i file nella directory scrivibile dall'utente, raddoppiando efficacemente la quantità di spazio che la risorsa occupa sul disco. La mia intenzione era quella di evitare di copiare il file e utilizzare invece un "hard link" al file che si comporterebbe come il file senza consumare ulteriore spazio su disco. – zemelenda

+1

Perché hai bisogno di collegamenti fisici ai file nel pacchetto di app invece di copiarli? Sembra che tu stia cercando di aggirare il divieto di modificare il pacchetto di applicazioni. Se fosse permesso, creerebbe un enorme buco di sicurezza. – Caleb

risposta

4

Semplicemente non si può eludere questo errore, ne sono sicuro. Non ho trovato alcuna documentazione ufficiale, ma diversi tutorial che spiegano come consentire l'uso di collegamenti simbolici su dispositivi jailbroken. Non c'è motivo per me perché la sicurezza su iOS sia diversa per i collegamenti fisici. Nel simulatore funziona perché funziona su un percorso sul computer locale (in ~/Libreria/Supporto applicazioni/iphone Simulator/iOSVersion/Applicazioni/...) e con sicurezza locale. Come esempio contrario, mi è venuto in mente più di una volta che ho avuto qualcosa che funzionava nel simulatore che non funzionava sul dispositivo e viceversa (per un esempio quando si prova ad aprire un db sqlite3 nel bundle principale con il flag SQLITE_WRITE) .

Risolvo questo problema di gestione risorse/controllo versioni nelle mie app utilizzando due percorsi file diversi. Le versioni originali sono come al solito nel pacchetto principale. L'altra posizione è la dir della cache o la dir documenti. Quindi utilizzo un gestore di risorse personalizzato che restituisce un percorso completo per un percorso relativo fornito. Funziona in questo modo:

  • Se esiste un percorso relativo nella directory scrivibile, restituire questo. Questa dovrebbe essere una versione aggiornata del percorso del file relativo richiesto
  • Se la verifica precedente non riesce, cercarlo nella directory fascio principale per tornare alla versione originale dal fascio principale dell'app

po 'di codice (utilizzando la cache di dir come directory aggiornabile, si consiglia di cambiare la situazione):

#define UpdateableCacheResourcePath(path) \ 
[[ResourceHandler sharedManager] updateableCacheResourcePath:path] 

- (NSString*)updateableCacheResourcePath:(NSString *)path 
{ 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory , NSUserDomainMask, YES); 
    NSString *_libraryCacheStorageDir = [[paths objectAtIndex:0] copy]; 
    NSString *updateablePath = [_libraryCacheStorageDir stringByAppendingPathComponent:path]; 
    // Cache Dir 
    if ([_fileManager fileExistsAtPath:updateablePath]) { 
     return updateablePath; 
    } 

    // mainBundle 
    NSString *mainbundleResourcePath = [_mainBundlePath stringByAppendingPathComponent:path]; 
    if ([_fileManager fileExistsAtPath:mainbundleResourcePath]) { 
     return mainbundleResourcePath; 
    } 

    NSLog(@"File not found: %@", path); 
    return nil; 
} 

nel codice si sarebbe poi utilizzare UpdateableCacheResourcePath ("some.file") invece di guardare nel fascio principale. Funziona anche con cartelle aggiornate (trascina la cartella su xcode e scegli di creare un riferimento invece di un gruppo). Quindi puoi fare riferimento ai percorsi relativi con le cartelle principali (come pubblicità/adbanner.png).

L'unico inconveniente è che se si dispone di contenuto Web è necessario aggiornare tutti i file referenziati dal proprio sito html per ovvi motivi (il browser Web può solo seguire percorsi relativi alla cartella in cui si trova il documento html).

+0

Grazie per la risposta, ma sfortunatamente non soddisfa i criteri per la taglia poiché non c'è una soluzione e nessuna spiegazione del motivo per cui non riesco a creare collegamenti fisici. I link simbolici funzionano sicuramente in questo stesso setup (vedi il 4 ° commento sulla domanda), ma non posso usarli perché ci sono degli errori nella riproduzione dei video se usati attraverso collegamenti simbolici. Sono d'accordo sul fatto che non ci sia alcuna ragione ovvia per cui gli hard link non dovrebbero funzionare, ed è per questo che ho postato la taglia. –

+1

Grazie Michael Melanson per aver iniettato alcuni incentivi per suscitare interesse in questo argomento. @benjist, grazie per il tuo suggerimento. La soluzione che ho optato per alcuni mesi fa nel periodo in cui ho posto questa domanda è molto simile a ciò che hai suggerito qui. Ho ceduto e ho pagato il prezzo del raddoppio dell'hard disk per la comodità di una soluzione praticabile. Poiché altre risorse della stessa categoria dovevano essere scaricate per tutta la durata dell'app, avevo comunque bisogno di creare il mio sistema di gestione delle risorse (leggi: cache con limiti personalizzati). Non ideale ma è stato fatto. – zemelenda