I am developing one application. In my application I want to develop log in page using a plist.
My requirement is when user enters username and password they go to next view.
How do I create a log in page?
I am new to the programming. Please send me any tutorial or sample code.
Thanks in advance
I don't know why you are try to use plist for that. You can (and should) use NSUserDefaults (this is also plist but easy to manage).
Try to save data:
[[NSUserDefaults standardUserDefaults] setObject:#"myName" forKey:#"userName"];
and later get:
[[NSUserDefaults standardUserDefaults] stringForKey:#"userName"];
Of course i probably don't have to tell you that storing password in plain text is a very bad idea in general.
We are developing an iPhone application for which i need to read iPhone Settings value (precisely the status of 'Settings->General->Date & Time->Set Automatically'). Is there any way easy/difficult way to find out that value? Any tips and tricks will be highly appreciated.
You can use the following code (I just found this out by examining the contents of the /var/mobile/Library/Preferences/ directory on my iPad):
NSDictionary *pref = [[NSUserDefaults standardUserDefaults] persistentDomainForName:#"com.apple.timed"];
BOOL autotime = [[pref objectForKey:#"TMAutomaticTimeEnabled"] boolValue];
NSLog(#"Automatic time is %#", autotime ? #"enabled" : #"disabled");
These keys are undocumented and you should probably not use them in an AppStore app. You can, however, safely use them in in-house apps or softwares for jailbroken devices.
Nope, sorry, this is not possible.
I have an app submitted to the app store that was rejected due to:
2.30 Apps that do not comply with the Mac OS X File System documentation will be rejected
They claim my app is modifying the ~/Library/Preferences/com.apple.spaces.plist file which is unsupported.
My app is in fact modifying that file, but only with NSUserDefaults via: (I'm omitting some code for brevity...)
NSMutableDictionary *spacesDefaults =
[[NSUserDefaults standardUserDefaults] persistentDomainForName:#"com.apple.spaces"];
NSMutableDictionary *dict = [spacesDefaults objectForKey:#"app-bindings"];
NSString *bundleId = [[[NSBundle mainBundle] bundleIdentifier] lowercaseString];
[dict setObject:#"AllSpaces" forKey:bundleId];
[spacesDefaults setObject:dict forKey:#"app-bindings"];
[[NSUserDefaults standardUserDefaults] setPersistentDomain:spacesDefaults
forName:#"com.apple.spaces"];
It seems to me that this falls under the first bullet of "File-System Usage Requirements for the Mac App Store" http://developer.apple.com/library/mac/#releasenotes/General/SubmittingToMacAppStore/_index.html#//apple_ref/doc/uid/TP40010572
* You may use Apple frameworks such as User Defaults, Calendar Store, and Address Book that implicitly write to files in specific locations, including locations is not allowed to access directly.
Does anyone know why this would get rejected? I just don't see it...
Thanks!
This is a really important issue that I bemoaned on the Apple Dev Forums...
And I suppose that filing a Feedback Request might have an effect, someday... But apparently this LAME restriction.. which limits an App's ability to do ANYTHING outside the sandbox.. EVEN IF it's something your user can do... This is a serious step backwards in the ability of third-party apps on the mac to perform SIMPLE, implicit commands by the user.
This seems like a fundamental paradigm shift on Apple's part. Here's the jist of the above forum listing..
NSUserDefaults can be used only for our own app,
and sandboxing will not allow to modify other apps defaults
Additionally, you cannot modify in any way ANY other app's .plist, via XML, or otherwise.
And, no, doing defaults write via a task or terminal on another domain, besides YOUR OWN APP is outlawed as well. Ugh, it's very annoying.
Don't worry, I'm not trying to hack someone else's app, if that's what you're thinking =).
I want to have 2 versions of my app, a free version and a deluxe version. My plan was to use an in-app purchase to enable the deluxe version by setting a boolean value in the plist file.
My question is: is this secure or is it easily circumvented? And if it is not secure, can someone suggest a simple alternative? I don't want to download additional content, I would rather keep all of the functionality within the app and enable it somehow.
Edit: I don't mean the application plist file, but something like the user defaults file.
You should store this in the keychain, this is what I'll do. The keychain is far more secure than a .plist or the user defaults (which are .plists, too, as far as I know). Have a look at SFHFKeychainUtils, you should be able to use this or just implement a better method exactly for the need to save a simple bool.
It is easy to edit the com.something.plist without jailbreaking. With a free tool* you can browse your device, you can also edit and save these files. If you store your inapp purchase something like this:
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"com.example.pack1"];
[[NSUserDefaults standardUserDefaults] synchronize];
then this will be written to the plist:
<key>com.example.pack1</key>
<true/>
If you name your packages like this: pack1, pack2 etc., and somebody edits your plist (copy/pasting the first key), he/she could use the locked feature easily.
A not too hard to implement method would be to save like this:
[[NSUserDefaults standardUserDefaults] setValue:[self sha1ValueForKey:#"com.example.pack1"]
forKey:#"com.example.pack1"];
[[NSUserDefaults standardUserDefaults] synchronize];
where -sha1ValueForKey: is
-(NSString *)sha1ValueForKey:(NSString *)key {
return [self sha1:[NSString stringWithFormat:#"<SALT>%#", key]];
}
You have to change <SALT> to something.
You can find -sha1: here: http://www.makebetterthings.com/iphone/how-to-get-md5-and-sha1-in-objective-c-ios-sdk/
After this you can verify if the key matches the hashed value.
If somebody wants to hack your plist he/she has to know your hashing mechanism and salt.
This is not the safest way to protect your application but it is easy to implement.
*iExplorer
EDIT:
The suggested method only protects - somewhat - your IAP if the user doesn't have access to the hashed value. If someone gets it from somewhere, it is easy to copy that data to the plist. If the SALT is device dependent copying is useless.
I would recommend reading up on verifying in-app purchases. It sounds to me like you are trying to roll your own in-app purchase verification system which may be wrought with issues you might not have thought of yet. You have to be careful with your user's purchases that they will behave the same in your application as they will in any other, lest ye lose their trust (and future sales!)
Instead of worrying about the Info.plist file, why not just set a preference? Somewhere in your code, this would give you your boolean value:
[[NSUserDefaults standardUserDefaults] boolForKey:#"someKey"];
If the value doesn't exist, the result will be nil. This code sets the value:
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"someKey"];
Plus, these values will be backed up in iTunes, so if the user moves their backup to a new iPhone or simply restores from backup, the values will be restored.
I don't have an answer, but it seems that editing your plist file dynamically is not possible, if I trust this subject :
You can not edit you're info.plist
file dynamically. When you submit your
app to The App Store, your app bundle,
which includes info.plist, can't
change because the signature created
when you compile you app is based on
the bundle.
Any pirate has a jail-broken iPhone
Any jail-broken device offers full file system access via tools like PhoneDisk, etc
Any file system access allows people to change the values in your applications .plist file
Game over.
Now, its not trivial to wrapper that up for the script kiddies but then again its not that hard either.
Storing state in defaults is no more nor less safe from privacy than having two versions of your app. Pirates will either pirate the deluxe version, or they'll pirate the unified version with the flag set.
Is there any way to save data without connecting to server on the iPhone? If so, please describe how.
Look at the NSUserDefaults class. It can save primitives and NSArray objects of primitives.
Example, your app might write out before app terminates in your app delegate:
[[NSUserDefaults standardUserDefaults] setString:#"Value" forKey:#"Key"];
And then read it in after launch:
NSString *dataYouNeed = [[NSUserDefaults standardUserDefaults] stringForKey:#"Key"];
Just remember to handle the nil case gracefully (i.e. that the app will keep working immediately after a fresh install or a reset to the user defaults).
Edit: the question has already been more-or-less rewritten. Obviously if you need to store data that will act as your application's model (in the MVC sense), Core Data or sqlite is where you would do best to start looking.
If it's a small number of things, use NSUserDefaults. If it's a lot of stuff, use Core Data.