I need info on using NSUserDefaults in Xcode - xcode

I came across this information in the posting of a question I found on here:
"Apple has added an extra rule for apps being submitted to the app store.
We can no longer store arbitrary data files in the Documents folder. Only content generated by the user like a text file they manually typed and saved or a photo they took with the camera can be saved in the Documents folder.
We are now expected to store our app generated files in the Library/Cache folder instead of the Documents folder. In addition, we should mark the files we don't want to be sync to iCloud with the skip backup attribute.
Failure to comply with this will result in an app being rejected by Apple.
Reason: The Documents folder is now used for syncing to iCloud. iCloud does a sync every few minutes and if we were to have megabytes of our app generated files stored in the Documents folder, it would get mixed up with the user's own iCloud synced files."
This makes me wonder if the way I have used NSUserDefaults in my app is "legal" in the eyes of apple.
I'm making a simple app that takes user input in about five different places. I'm saving these simple strings in NSUserDefault variables.
My question to anyone that fully understands the statements made within the quotes above is:
Am I saving data in a way that is no longer allowed by apple?
I'm new to the development game, and the information within quotes doesn't make it clear to me (in the context of my app's situation) whether I'm in the wrong or not.
Thanks for the help!

NSUserDefault is the official, supported way of storing user preferences. If that's what you're storing, then it's the correct way to do it.

Related

Can an app-scoped security scoped bookmark be copied from one Mac to another?

I have a sandboxed application that uses a document format which can contain embedded filenames. E.g. some of these referenced files are for image files which the user selects in order to associate the image file with data stored in the document. Whilst such images will sometimes be located in the users pictures folder, sometimes they are elsewhere. The document format itself cannot be changed for portability reasons (it is shared with an existing Windows version of the app).
In order for the app to be able to access the files whose names are embedded within the document, when the user selects a filename (using nsopenpanel) to be stored in the document like this, the app also creates an app-scoped security scoped bookmark for each such stored filename. It then stores these bookmarks by serialising them to another file. When the app runs again it loads its previously serialised bookmarks and uses them when accessing the 'embedded' filename and that works fine.
But when I copy such a document (and its associated serialised bookmarks file) from one Mac to another, it doesnt work, even though all the files the bookmarks refer to are known to exist on both Macs. What happens is that whilst the app opens the document file ok (after the user selected it with an nsopenpanel), and successfully reads in the serialised bookmarks from its associated serialised bookmarks file (which again the user has selected using nsopenpanel), and even though the exact same filenames that the bookmarks refer to are known to exist on the other Mac (and can be accessed by the user through finder etc), the sandboxed app still cannot access them. Resolving the bookmarks seems to fail.
The question is: are app-scoped bookmarks restricted to only working on the Mac on which they were created? If I cannot move an app-scoped bookmark from one system to another, how else can I achieve the effect I want without forcing the user to have to manually re-select every such 'embedded' filename with an nsopenpanel?
Tried to find the answer to this question in the Apple docs without success.
I take it it goes without saying that security-scoped bookmarks can only be used by the app that creates them.
No, because if this were possible, developers could save security-scoped bookmarks to sensitive files/directories on their own computers and then deploy their apps and have access to those same sensitive files/directories on other peoples' computers.

Save Data Within Signed App

I am distributing my OS X application on individual USBs and, for this reason, everything must be self contained.
The app itself lets users input information and then saves this information to an existing text file (specifically an ObjectDB database). Herein is my problem.
I'd like to keep this text file inside the app itself (i.e. inside the Content folder) so it's out of the way and can't be deleted by the average user. But once the app is signed, it seems the text file can't be altered with any new information without getting flagged by Gatekeeper. Is this really the case? There's no way to store data files within apps now?
I'd appreciate any suggestions. Thanks.
Yes, you are correct. If you modify the application package, the signed package is no longer valid. That's kind of the purpose of signing a package.
Your options are to store the text file in a temporary folder on the user's computer, or to instruct your users to disable gatekeeper (don't do this).

NSMetadataQuery does not find documents after moving them to iCloud

In my Mac app I have an NSMetadataQuery to watch the app's iCloud directory. When the user decides to enable iCloud from within the app I do the following in this order:
Call [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil] to establish access to the iCloud container
Start a NSMetadataQuery to find all files (pattern: "*") in the iCloud container
Now I iterate over all files in the local container and move them to iCloud by using [fileManager setUbiquitous:YES itemAtURL:fileURL destinationURL:targetURL error:&error]
I have two types of documents that I move to iCloud:
The actual documents stored as file packages
For each document I have a .preview file as simple binary file
My problem is that the meta data query only returns my binary preview files, but not my actual documents until I relaunch my app (or open a Finder window of the app's iCloud folder from the Terminal - in this case my app gets another query result with all files).
So is this some weird caching issue? Is this because the documents are file packages and not simple binary files?
I don't see why that should be a problem. If I restart my app the query does return all files correctly.
Could this be a problem with the way my custom document type is exported in Info.plist?
Could this be a problem with the way my custom document type is
exported in Info.plist?
I suppose so: the issue you are describing is most likely because your document format is a file package (I assume written with NSFileWrapper). Remember that the package bit is set when writing the file, so if you have other apps writing to iCloud, that could make the issue much more confusing as it's not about interpreting a file bundle but writing it in a correct manner.
NSMetadataQuery unfortunately ignores folders, so your files will never be reported back unless you have correctly registered your filetype as bundle in the application that writes the file to the iCloud container.
There are a lot of similar and potentially confusing settings in the info.plist, so many things that can go wrong. I experienced an issue when I registered my document filetype correctly on OS X, but failed to do so on iOS: https://stackoverflow.com/a/14993694/388412
The first thing you should do is to go to https://developer.icloud.com/#documents and see if you're looking at files (correct) or folders (problem).
Work on your info.plist document types until you see the documents as files, then it should work.

NSSavePanel for saving a file after sandboxing

I have a mac AVRecording app, which records a video and save it to a location selected via NSSavePanel. It was working fine till I sandboxed the app.
For sandboxing I have added the following entitlements
com.apple.security.files.user-selected.read-write
com.apple.security.assets.movies.read-write
com.apple.security.files.downloads.read-write
This enables saving to Downloads and movies folder only.
How is it possible to save my file to any desired location, Desktop, Documents etc ?
It's not clear from your question whether you are referring to saving a particular file (in which case you can use the NSSavePanel and manually copy the file using NSFileManager to write the file into the user-specified new file), or whether you are referring to having the user choose a location for all future downloads.
If you want to prompt the user for a location to use for future downloads, you'll need to use the secure bookmark entitlement and secure bookmarks to retain access to the folder.
There's another stackoverflow answer about sandboxing which covers the process of saving and using the secure bookmark.

Mac App Store Sandboxing - Writing a new file?

I've been playing around with an app I want to submit to the Mac App Store, and part of the functionality is simply grabbing a file the user chose by dragging or opening, and saving a modified of it to the same directory as the original file (but with a different file name).
I don't want to use a 'Save' dialog box, as that destroys the utility of the application I'm building, but it looks like that might be the only way the app would be allowed—under sandboxing requirements—to write a file to an arbitrary location (arbitrary, in this case, being in the same folder as the existing file) on the disk as a new file.
Is there any way I can approach this without disabling sandboxing? Also, if I submit the app without entitlements/sandboxing turned on today, will it be approved by Apple (supposing it passes all the other requirements), or are they already turning down non-sandboxed apps?
For your first question, no, I don't believe there is any way to write to a file the user didn't specify, unless it's either in your app's container, or (as of 10.7.3) in a directory you have a security-scoped URL for. See the documentation here. If the user specifies a file, I doubt you get permissions to the enclosing folder, but it's worth a shot.
Answering your second question, as of today, Friday April 27th, 2012, the App Store does not require sandboxing. The latest deadline given was June 1, 2012.

Resources