iOS Development: Create file failed(return domain:NSCocoaErrorDomain,code:512)

I need to save file to library directory to support retry capability, but some users found it not working.

After some research, I got the following information:

  1. It affects about 100+ users per day, about one in ten thousand of DAU.
  2. 96% of them are iOS 13, others are iOS 9, iOS 10, iOS 12(App lowest support version is iOS9).
  3. Once it occurs, later file creations always failed.
  4. App cant save file to sandbox, including library document temp caches directory, using API [NSString writeToFile:atomically:encoding:error:],the error it returns is "{"localizedRecoveryOptions":"","localizedDescription":"The operation couldn’t be completed.","domain":"NSCocoaErrorDomain","code":512,"localizedFailureReason":"","userInfo":{"NSUserStringVariant":"Folder"},"localizedRecoverySuggestion":""}", The localizedDescription is in Chinese(because the phone locale is Chinese), but I cant type Chinese in the post.
  5. Users some have remaining iCloud storage space and some not. They all have remaining disk stroage space.
  6. The sandbox is not empty, it contains some other files that App creates, but the files cretaed date earlier than the user last reinstall date, may synchronized by iCloud, but the user charging via power, not PC.
  7. The files in sandbox that already exist(eg: sqlite datebase file) can be edited.
  8. Scanning sandbox directory attribute using api -[NSFileManager attributesOfItemAtPath:error:], directory write permission returns "NSFilePosixPermissions":493(755 in Octal).
  9. After reinstall the App, It can create files again, some users after some time(may one day or longer) it occurs agains, the old files come back, newly created files disappear. and other users no more problems.



So why this happned and how can I fix this problem?

Replies

If someone still interested in the solution.
We had an exact same problem as TS. During investigation it turned out our /tmp folder was filled up with empty folders, in the form of "(A Document Being Saved by $APPNAME)", caused by 3rd party framework (couchbase-lite to be exact), since it was using NSItemReplacementDirectory to create temporary directory, but never removing it. Once the number of those directories gets to 1000, the OS won't let you create any other directory with NSItemReplacementDirectory or any other file with NSDataWritingAtomic. So the solution for us was cleaning those directories.
I'm almost certainly sure all of those problems lie in the field of OS limits, so I'd check total number of files on disk (by downloading container for example) or number of open files in your app.
I'd love that Cocoa would give some form of defined error for this, but for now we have to deal with what we have.

Once the number of those directories gets to 1000, the OS won't let
you create any other directory with NSItemReplacementDirectory or
any other file with NSDataWritingAtomic.

That’s a super helpful tidbit. I had a look at the code backing NSItemReplacementDirectory and, yeah, it definitely has a 1000 item limit and, on hitting that limit, it will fail with NSFileWriteUnknownError (that is, 512).

Based on that tip I had a look for other instances of NSFileWriteUnknownError. One useful tidbit here is that many places that fail with this error will add an underlying error to the user info dictionary via the NSUnderlyingErrorKey, so it would be a good idea to add that to whatever logging you create on hitting this error.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
I can confirm 1000-limit-error is not the same error as @logicat encountered.
I write a for loop to create 1000+ directories, I get 512. But it has detailed description.

Too many temporary directories for $APPNAME in $DIR

The original error is 512 without other useful info but UserInfo={NSUserStringVariant=Folder}.

Start from 13.x, I guess, Apple change some code on write atomically results in this error.
Has anyone experienced this problem with Xcode 12.x?

We feel the occurence of this issue had increased since we upgraded Xcode from 11.3.1 to 11.5.
Upgrading to 11.6 didn't have effect.
After rolling back to 11.3.1, it seems to have gradually decreased.

We wonder if upgrading Xcode to 12.x affects this problem or not.
I can confirm we had this issue in our App and the only fix is to erase items from tmp and Caches directories.

It took about 3 years for us to get here and only after a DTS ticket did we understand this to be the source of the problem. I am not sure if it is specifically due to storing items in those directories with UUID's in the filename as has been suggested before. Regardless, cleaning up will fix the issue.

I would love to see Apple improve how these directories are pruned since the OS should be helping here.

I have found a way to solve it and if someone else has the same problem:

1000-limit-error is not the same error as @logicat encountered, the problem seems to be that when iOS atomic write to a file, system first create a temporary file and then write data to it, and if the temporary file is accidentally interrupted while writing.

For example, [MLModel compileModelAtURL] will temporarily create XXXX /Temp/(A Document Being Saved By yourApp)/***.mlmodelc when it is accidentally interrupted, (A Document Being Saved By ***) - temporary files will not be deleted, causing all atomic writes to fail, even if you restart your app.

Try the following solve it(Language: Objective-C):

1.Use nonatomic write, e.g.

[NSData writeToFile:path options:0 error:&error]; // No temporary file, nonatomic

[NSData writeToFile:path atomically:NO];

[NSString writeToFile:path atomically:NO encoding:enc error:&error];

[NSDictionary writeToURL:url atomically:NO];

2.To solve the problem completely, you need to remove the temporary file from the problem folder, which is a hidden file like ***/(A Document Being Saved By yourApp)/xxxx

So I restore the atomic write ability after I clear the temporary file or temporary folder(Note: Do not delete some files generated by the system).

Hope the above tips help you.

@logicat I have the same problem as you. Have you found the reason?Error Domain=NSCocoaErrorDomain Code=512 "wei neng cun chu gai wen jian。" UserInfo={NSUserStringVariant=Folder}。 And @eskimo it‘s a system problem? I don't have any ideas about this.