2017-07-06 1 views
0

Ich versuche, Dateien auf dem Benutzer iCloud-Laufwerk zu speichern. Nachdem ich die Datei auf ihrem iCloud-Laufwerk gespeichert habe, kann ich sie abrufen, solange ich die App nicht neu installiere. Ich speichere die Pfade zu den Dateien in NSUbiquitousKeyValueStore.App iCloud-Dokumente-Verzeichnis fehlschlägt, um Dateien nach der Neuinstallation App

-Code die Dateien zu speichern:

let data = UIImagePNGRepresentation(finalImage) 

     let filename = "sticker\((NSUbiquitousKeyValueStore.default().longLong(forKey: "stickerCount"))+1).png" 
     let filenamePath = self.getDocumentsDirectory().appendingPathComponent(filename) 
     NSUbiquitousKeyValueStore.default().set(NSUbiquitousKeyValueStore.default().longLong(forKey: "stickerCount")+1, forKey: "stickerCount") 

     var filenames : NSMutableArray! 
     if !(NSUbiquitousKeyValueStore.default().bool(forKey: "createdArray")){ 
      NSUbiquitousKeyValueStore.default().set(true, forKey: "createdArray") 
      filenames = NSMutableArray() 
     }else{ 
      filenames = (NSUbiquitousKeyValueStore.default().array(forKey: "fileNames")! as NSArray).mutableCopy() as! NSMutableArray 
     } 
     filenames.add(filename) 
     NSUbiquitousKeyValueStore.default().set(filenames, forKey: "fileNames") 
     NSUbiquitousKeyValueStore.default().synchronize() 

     try? data?.write(to: filenamePath) 

Dies ist der Code, um die Dateien zu erhalten:

func loadTheStickers() { 
    stickerNames.removeAllObjects() 
    stickers.removeAllObjects() 
    var filenames : NSMutableArray! 
    if !(NSUbiquitousKeyValueStore.default().bool(forKey: "createdArray")){ 
     NSUbiquitousKeyValueStore.default().set(true, forKey: "createdArray") 
     filenames = NSMutableArray() 
    }else{ 
     filenames = (NSUbiquitousKeyValueStore.default().array(forKey: "fileNames")! as NSArray).mutableCopy() as! NSMutableArray 
    } 
    for stickerName in filenames { 
     stickerNames.add(stickerName) 
     let url = getDocumentsDirectory().appendingPathComponent(stickerName as! String) 
     stickers.add(url) 
    } 

} 

Und ich die URLS bekommen, so die NSUbiquitousKeyValueStore richtig funktioniert, aber wenn ich die Neuinstallation App, die imageFromUrl wird das Bild nicht zurückgeben, so dass es nicht dort ist. Ich benutze einfach diese Codezeile:

cell.imageView.image = UIImage(contentsOfFile: (stickers[indexPath.row] as! URL).path) 

und wieder es funktioniert perfekt, bis ich versuche, die App zu installieren. Hier

ist die Klasse, die ich benutze den Pfad zu dem Verzeichnis iCloud zu erhalten:

class CloudDataManager { 

static let sharedInstance = CloudDataManager() // Singleton 

struct DocumentsDirectory { 
    static let localDocumentsURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: groupID) 
    static let iCloudDocumentsURL = FileManager.default.url(forUbiquityContainerIdentifier: iCloudContainerID)?.appendingPathComponent("Documents") 
} 


// Return the Document directory (Cloud OR Local) 
// To do in a background thread 

func getDocumentDiretoryURL() -> URL { 
    if isCloudEnabled() { 
     if !FileManager.default.fileExists(atPath: (DocumentsDirectory.iCloudDocumentsURL?.path)!){ 
      do { 
      try FileManager.default.createDirectory(at: DocumentsDirectory.iCloudDocumentsURL!, withIntermediateDirectories: true, attributes: nil) 
      }catch{ 
       NSLog("Error") 
      } 
     } 
     NSLog("\(DocumentsDirectory.iCloudDocumentsURL!)") 
     return DocumentsDirectory.iCloudDocumentsURL! 
    } else { 
     NSLog("\(DocumentsDirectory.localDocumentsURL!)") 
     return DocumentsDirectory.localDocumentsURL! 
    } 
} 

// Return true if iCloud is enabled 

func isCloudEnabled() -> Bool { 
    if DocumentsDirectory.iCloudDocumentsURL != nil { return true } 
    else { return false } 
} 

// Delete All files at URL 

func deleteFilesInDirectory(url: URL?) { 
    let fileManager = FileManager.default 
    let enumerator = fileManager.enumerator(atPath: url!.path) 
    while let file = enumerator?.nextObject() as? String { 

     do { 
      try fileManager.removeItem(at: url!.appendingPathComponent(file)) 
      print("Files deleted") 
     } catch let error as NSError { 
      print("Failed deleting files : \(error)") 
     } 
    } 
} 

// Copy local files to iCloud 
// iCloud will be cleared before any operation 
// No data merging 

func copyFileToCloud() { 
    if isCloudEnabled() { 
     deleteFilesInDirectory(url: DocumentsDirectory.iCloudDocumentsURL!) // Clear all files in iCloud Doc Dir 
     let fileManager = FileManager.default 
     let enumerator = fileManager.enumerator(atPath: (DocumentsDirectory.localDocumentsURL?.path)!) 
     while let file = enumerator?.nextObject() as? String { 

      do { 
       try fileManager.copyItem(at: (DocumentsDirectory.localDocumentsURL?.appendingPathComponent(file))!, to: DocumentsDirectory.iCloudDocumentsURL!.appendingPathComponent(file)) 

       print("Copied to iCloud") 
      } catch let error as NSError { 
       print("Failed to move file to Cloud : \(error)") 
      } 
     } 
    } 
} 

// Copy iCloud files to local directory 
// Local dir will be cleared 
// No data merging 

func copyFileToLocal() { 
    if isCloudEnabled() { 
     deleteFilesInDirectory(url: DocumentsDirectory.localDocumentsURL) 
     let fileManager = FileManager.default 
     let enumerator = fileManager.enumerator(atPath: DocumentsDirectory.iCloudDocumentsURL!.path) 
     while let file = enumerator?.nextObject() as? String { 

      do { 
       try fileManager.copyItem(at: DocumentsDirectory.iCloudDocumentsURL!.appendingPathComponent(file), to: (DocumentsDirectory.localDocumentsURL?.appendingPathComponent(file))!) 

       print("Moved to local dir") 
      } catch let error as NSError { 
       print("Failed to move file to local dir : \(error)") 
      } 
     } 
    } 
} 

}

und ich habe überprüft, es gibt die richtige URL für das iCloud Document-Verzeichnis. Also meine Frage ist, wo ist das Problem, wie könnte ich den Code korrigieren, so dass die Dateien nach der Neuinstallation der App oder auf anderen Geräten verfügbar sind, becaise atm das iCloud-Verzeichnis ist nicht besser als einfach im lokalen Dokumente-Verzeichnis zu speichern.

Antwort

0

Nach langen Recherchen habe ich es geschafft, das Problem zu lösen. Sie müssen iCloud manuell provozieren, um die Elemente aus der Cloud herunterzuladen. Es wird automatisch hochgeladen, aber nicht heruntergeladen.

Sie haben die folgende Zeile für alle Elemente verwenden:

FileManager.default.startDownloadingUbiquitousItem(at: url) 

So ist der Download-Code in der Appdelegates Anwendung: didfinish ... Methode sieht nun wie folgt aus:

var filenames : NSMutableArray! 
    if !(NSUbiquitousKeyValueStore.default().bool(forKey: "createdArray")){ 
     NSUbiquitousKeyValueStore.default().set(true, forKey: "createdArray") 
     filenames = NSMutableArray() 
    }else{ 
     filenames = (NSUbiquitousKeyValueStore.default().array(forKey: "fileNames")! as NSArray).mutableCopy() as! NSMutableArray 
    } 

    for stickerName in filenames { 
     let url = getDocumentsDirectory().appendingPathComponent(stickerName as! String) 
     if !FileManager.default.fileExists(atPath: url.path){ 
     do { 
      try FileManager.default.startDownloadingUbiquitousItem(at: url) 
     }catch{ 
      NSLog(error.localizedDescription) 
     } 
     } 
    } 
Verwandte Themen