-1

I have problems in handling the persistence of some classes in the cache. This is the code I tried and that does not work at all either recovering the archived data or deleting it:

func cacheDirectoryURL()->NSURL?{
    let fileManager=NSFileManager()
    let urls = fileManager.URLsForDirectory(.CachesDirectory, inDomains: .UserDomainMask)
    if urls.count>0{
        return urls[0]
    }
    return nil
}

func palineCacheURL()->NSURL?{
    let url=cacheDirectoryURL()?.URLByAppendingPathExtension("Paline.archive")
    return url
}

public func getMapHandlerWithDelegate(delegate:MovableAnnotationDelegate)->MapDelegate{
    let archiveURL=palineCacheURL()!
    mapHandler=NSKeyedUnarchiver.unarchiveObjectWithFile(archiveURL.absoluteString) as? MapDelegate
    if mapHandler != nil{
        mapHandler!.delegate=delegate;
    } else {
        mapHandler=MapDelegate.sharedMapDelegate()
        mapHandler!.delegate=delegate;
    }
    return mapHandler!
}

func clearMapArchives(){
    do{
        try NSFileManager.defaultManager().removeItemAtPath(palineCacheURL()!.absoluteString);
    } catch let error as NSError {
        print(error.localizedDescription+" "+(error.localizedFailureReason ?? ""));
        let alert=UIAlertView(title:NSLocalizedString("Error", comment:""), message:NSLocalizedString("Unable to clean the cache; please reinstall the app in the case of  problems", comment:""), cancelButtonTitle:NSLocalizedString("Dismiss", comment:""), otherButtonTitle:nil, onDismiss:nil, onCancel:nil)
        alert.show()
    }
}

func archive(){
//-NSLog(@"archivePath=%@ paline=%@", archivePath, self.palineArray);
    if mapHandler != nil {
        NSKeyedArchiver.archiveRootObject(mapHandler!, toFile: palineCacheURL()!.absoluteString)
        print("archivio a \(palineCacheURL()!.absoluteString)")
    }
}

I even tried retrieving the object soon after saving it and it come out nil:

        NSKeyedArchiver.archiveRootObject(mapHandler!, toFile: palineCacheURL().absoluteString)
        print("archivio a \(palineCacheURL().absoluteString)")
        let restored=NSKeyedUnarchiver.unarchiveObjectWithFile(palineCacheURL().absoluteString) as? MapDelegate
        print("restored \(restored)")
Fabrizio Bartolomucci
  • 4,948
  • 8
  • 43
  • 75
  • Define "doesn't work" – Sergio Tulentsev Nov 29 '15 at 17:09
  • Unrelated to your actual problem I strongly recommend against using `NSKeyed(Un)Archiver` when using Swift. It causes a lot of trouble when changing class structures / class names / module names or even access specifiers (private/internal/public). Esp. the archiver stores the class name as string and class names in Swift tend to be very cryptic - like `__TFCCC4test1a1b1c1dfS2_FTS0_1xS1_1vFT1xSi_Si_OVS_1e1f` (not an actual class, just an example). Backward compatibility is really annoying. – fluidsonic Nov 29 '15 at 17:13
  • Anyway, have you got a solution for that? – Fabrizio Bartolomucci Nov 29 '15 at 17:13
  • So how would you save an archived object in cache? – Fabrizio Bartolomucci Nov 29 '15 at 17:14
  • There is Core Data, sqlite, Realm and various other libraries for persisent storage on iOS. -- For archiving you should check that `init(coder:)` is actually called on your `MapDelegate` and doesn't return `nil`. Also your `MapDelegate` must conform to `NSCoding` and implement `encodeWithCoder(_:)` correctly. -- And like @SergioTulentsev said you should explain exactly where it stops working as expected. Use the debugger to run your code step by step. – fluidsonic Nov 29 '15 at 17:16
  • Of cours that is not the problem, otherwise I would have reported that piece of code. My problem in saving and restoring the data in the cache and deleting it as in the sample code. This assumes the data is well encoded. – Fabrizio Bartolomucci Nov 29 '15 at 17:18
  • As you said you posted code for saving, restoring and deleting. You should be able to figure out which of the three steps does not work as intended. Does it save but not restore? Doesn't it save at all? Does it restore but not delete? -- Also everything I posted is essential for these steps! – fluidsonic Nov 29 '15 at 17:42
  • The problem is that the recent versions have ditched the path based methods replacing them with the URL based ones. Yet there does not seem to be a URL based way to write, retrieve and delete data. So I tried to use the absoluteString, but that does not work. I even tried printing the absolute path and it is this: file:///var/mobile/Containers/Data/Application/F705E466-72F7-433E-8A17-06918B217B41/Library/Caches.Paline.archive/ strangely looking like a directory instead of a file. – Fabrizio Bartolomucci Nov 29 '15 at 17:48
  • It is not that clear how to understand where the problem is, given I need to retrieve the data in order to know if it was correctly saved. – Fabrizio Bartolomucci Nov 29 '15 at 17:49
  • If you need the path of a file URL you use `fileUrl.path!`, not `fileUrl.absouteString!`. – fluidsonic Nov 29 '15 at 18:00
  • Thank you so much: by using path instead of AbsoluteString everything works fine. I wonder that what the AbsoluteString stuff stands for. At least now I may retrieve the data soon after saving it. I need to check the general persistence. – Fabrizio Bartolomucci Nov 29 '15 at 18:05

1 Answers1

0

Thanking much fluidsonic for the hint, the code was fine with the exception of absoluteString to be replaced with path. Once replaced this part everything work seamlessly.

Fabrizio Bartolomucci
  • 4,948
  • 8
  • 43
  • 75