caiyue1993/IceCream

CreamAsset fails save() when given a Specific ID or propName.

Open

#172 opened on Nov 4, 2019

 (3 comments) (0 reactions) (1 assignee)Swift (260 forks)user submission
enhancementgood first issuehelp wanted

Repository metrics

Stars
 (2,005 stars)
PR merge metrics
 (No merged PRs in 30d)

Description

Thank you for the wonderful library.

For example, initializing CreamAsset causes save() inside init() to fail.

CreamAsset.create(object: SomeObject, propName: "https://example.com/", data: someData)

CreamAsset generates uniqueFileName as the concatenation of Object's ID and propName:.

https://github.com/caiyue1993/IceCream/blob/1d6cc98831a743864176e0cc9dbddf8d0ad2e0cc/IceCream/Classes/CreamAsset.swift#L30

Next, CreamAsset.filePath use URL.appendingPathComponent() to generate a filePath from the uniqueFileName generated in the previous section, as shown below.

https://github.com/caiyue1993/IceCream/blob/1d6cc98831a743864176e0cc9dbddf8d0ad2e0cc/IceCream/Classes/CreamAsset.swift#L47

The URL contains the directory separator '/'. Therefore, the generated CreamAsset points to a file in a directory that does not exist in the generated filePath. Therefore, save() called in init() will fail.

https://github.com/caiyue1993/IceCream/blob/1d6cc98831a743864176e0cc9dbddf8d0ad2e0cc/IceCream/Classes/CreamAsset.swift#L31

I can't suggest a solution "correct" because I don't know the set of characters that can't be used as filenames, but as far as I'm concerned, I can work around this problem by making init() generate uniqueFileName like this:.

self.uniqueFileName = "\(objectID)_\(propName)".addingPercentEncoding(withAllowedCharacters: CharacterSet(charactersIn: "/").inverted) ?? "\(objectID)_\(propName)"

Of course, if I don't use "/" for the Object ID or propName, I shouldn't have any problems. However, in my project, URL is used for ID of Object, so I think it is difficult to avoid this problem. If possible, I would appreciate it if IceCream could take care of it. Thank you in advance.

Expected behavior

let asset = CreamAsset.create(object: SomeObject, propName: "https://example.com/", data: someData)

asset.storedData() is not return nil

Contributor guide