Editing .plist file through objective-c - ios

I am currently making a tweak for personal use but I don't really know a hell lot about programming. I know it isn't a smart idea to make tweaks if you don't know how to program properly but I'm only making one small tweak so I don't wan't/have time to spend months studying objective-c.
Now the problem: I have a plist located here:"/var/mobile/Applications/F5E2CB37-FC1B-46BC-8264-C7E2F17CD0EC/Library/Preferences/nl.telegraaf.ipad.plist"
That .plist contains a lot of options and I only need to change one. But the value that I wanna change is located in a dictionary so you have something like this.
.plist ----> cells ---> dictionary named OpenUDID ----> value i wan't to change.
The dictionary in the plist has 4 items and i only wan't to change is the first one.
So I created a tweak and added this to it:
%hook SBLockScreenViewController //only for testing
NSMutableDictionary *settings = [NSMutableDictionary dictionaryWithContentsOfFile:
[NSString stringWithFormat:#"/var/mobile/Applications/F5E2CB37-FC1B- 46BC-8264-C7E2F17CD0EC/Library/Preferences/nl.telegraaf.ipad.plist"]]; //accessing the .plist
-(void)displayDidDisappear
{
[settings setValue:#"test" forKey:#"PaywallAuthMethodStringKey"]; //trying to change a value from the .plist doesn't work
//NOTE this isn't a value in the dictionary in the .plist
%orig;
}
%end
The problems I have is that I don't know how to edit a value in a .plist in code(I searched about it on google but none of the solutions worked)
Also I don't know how to get into the dictionary and than be able to change values in there.(I couldn't find any information on this on the internetz)

Related

NSUserDefaults in iOS is randomly disappearing and reappearing

Just wondering if anybody experience this issue?
I am developing an application in iOS using Objective-C at the moment.
Sometimes my data in NSUserDefaults will be missing after I compile the app.
But if I ignore it and recompile the app again the data suddenly reappears.
I already synchronized in several places (not in every key, but only in several places).
If anyone happened to face this issue before I hope you can share how to handle this issue.
P.S. I need a storage to save 1 particular object so I can retrieve it when the app reopens.
Edited to add the code
NSString *enPIN = [[NSString alloc]initWithString:[NSString stringWithFormat:#"%#", [enterField.text md5]]];
[[NSUserDefaults standardUserDefaults] setObject:enPIN forKey:#"pin"];
[[NSUserDefaults standardUserDefaults]synchronize];
NSLog(#"check pin %#", [[NSUserDefaults standardUserDefaults] objectForKey:#"pin"]);
The object is a string, i hash it using md5 and then store it in nsuserdefault, if it only randomly dissapearing maybe its not weird, but its also reapearing again after it dissapear if i recompile the apps
Check if your defaults are using only string value or bool or such.
If you are using any Object with Class (key and parameters) like NSObject to store in defaults I prefer you do the encoding and decoding accordingly before storing and retrieving the values.
Also If you storing any NSDictionary check if any of the object value inside that dictionary is not anything other than Bool, String , if there also any NSObject class or reference is stored then you may face same issue.
Refer this stackoverflow link as to how encode objects before storing to NSUserDefaults.
Lastly [defaults synchronise] call mandatory on viewwilldisappear or immediately after storing new value whichever way is your implementation.
Hope this helps.
I had a similar issue the other day with NSUserDefaults
Not quite sure what was causing it, but it was due to a bug in Xcode. I was able to fix the issue without changing my code at all. I simply cleaned the project (CMD-Shift-K) and restarted my computer, and then it worked just fine. It's worth a try
Are you getting any kind of error messages in the console?

What is the need to store the Content of plist file into an NSArray?

I am learning Objective-C language. I have covered the following questions:
What is plist?
How to create a plist file?
What are the representation of plist file?
But I did not find the answer of these questions:
Why do we store a plist in NSArray?
What is the need to store a plist into NSArray?
Can you please help me to clear my doubts?
Sometime you want to do something at runtime or create something base on something else.
Let's imagine you have a game with a different levels and you want the levels to be vary you can hard code the levels in code but much nicer would be store it in the file. iOS lets you very easily load plist to array or dictionary and that's the reason why iOS developers choose to use it.
// Example of plist file
Level1:
NumberOfEnemies: 6
ScoreTarget: 100
....
Level2:
NumberOfEnemies: 12
ScoreTarget: 120
....
When you load the game you can read the plist and you can load the level base on the content.
It's much easier to add another level or add more customisation to the plist (file) that go back to the code any do it there.
It's just one of the examples but you could use plist to do much more.
Plist are mostly configuration files or place to store some values that you know that will never change. One particular example of the plist file is info.plist where you define attributes for the application.
Plist are nothing else but the same old XML file with attributes and elements. That said, you actually access plist through dictionary, not array.
For your question why do we store it in dictionary, you use dictionary to access these values since there is no other way to extract the information from it.
One more thing, plists have their own restrictions regarding the type you can store: Array, Dictionary, String, Date, Data, Number and Boolean.
PList : is a "Property List" file, uses the XML format to store objects such as arrays, dictionaries, String, Data, Number and Boolean.
How to create :
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *plistPath = [documentsDirectory stringByAppendingPathComponent:#"myPlistFile.plist"];
if (![fileManager fileExistsAtPath: path])
{
NSString *bundle = [[NSBundle mainBundle] pathForResource:#”myPlistFile” ofType:#”plist”];
[fileManager copyItemAtPath:bundle toPath:path error:&error];
}
[myDict writeToFile:plistPath atomically: YES];
Representation : Based on what is stored in plist file .
Key and Value. (NSDictionaries)
Key and multiple value . (NSArray) etc..
What is PLIST?
Plist stands for Property List. Plist is used to store data in hierarchical manner.A Property List can contain containers and primitives.
Containers – Array, Dictionary
Primitives – Boolean, String, Number(Integer,Float), Date, Data
A Container can contain other containers and primitive data-types.
i.e. Dictionary can contain other Dictionaries,Arrays and Primitives. Array can contain other Dictionaries,Arrays,Primitives.
How to Create PLIST File?
STEP 1: Right Click the Project
STEP 2: Choose New File
STEP 3: Select Resource from left side of the Template.
STEP 4: Then Click Property List
STEP 5: Click NEXT button of the Bottom.
STEP 6: Give property List Name.
STEP 7: Finally Click OK
For more Reference please go through the below link
https://stackoverflow.com/questions/9044735/steps-to-create-and-edit-a-plist-file-in-xcode
What are the Representation of PLIST file?
A property list can be stored in one of three different ways:
1. in an XML representation,
2. in a binary format, or
3. in an “old-style” ASCII format inherited from OpenStep.
You can serialize property lists in the XML and binary formats. The serialization API with the old-style format is read-only
XML property lists are more portable than the binary alternative and can be manually edited, but binary property lists are much more compact; as a result, they require less memory and can be read and written much faster than XML property lists. In general, if your property list is relatively small, the benefits of XML property lists outweigh the I/O speed and compactness that comes with binary property lists. If you have a large data set, binary property lists, keyed archives, or custom data formats are a better solution.
I refer the link for Why do we store a plist in NSArray? and What is the need to store a plist into NSArray?
1.http://hayageek.com/plist-tutorial/
2.https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/PropertyLists/AboutPropertyLists/AboutPropertyLists.html
3.http://nscookbook.com/2013/02/ios-programming-recipe-13-using-property-lists-plists/
4.Getting plist data in a order

How to export data to an Xcode-project file

Is it possible to export data to a Xcode-project file?
For example, I want to generate a new "hello.csv" file, using swift, that says "hello world"
into my Xcode Project locally but not in in-app document.
To put it simply, no. If you want to use databases in code, use .plist (Preference List) files. Unfortunately, I don't know how to do this in Swift, but I do know how to in Objective-C.
To start off, make a PLIST file in Xcode, and add your data to it. Remember the key name values.
In your .m file, add this code to create an NSMutableDictionary that you can modify in code later:
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"yourFile" ofType:#"plist"]];
Then, to pull data out of the dictionary you made (dict), do something like this. Switch data types as necessary.
NSString *helloWorld = (NSString*)[dict valueForKey:#"yourKeyName"];
(Note: the cast of NSString* is necessary because, otherwise, it will yell at you for having the incompatible type of id. In Swift, it's object. If you plan on modifying the string, then use NSMutableString.)
Then, to save it to the file, save the key/value pair in the dictionary:
[dict setValue:helloWorld forKey:#"yourKeyName"];
And finally, save the dictionary and overwrite the PLIST file.
[dict writeToFile:[[NSBundle mainBundle] pathForResource:#"yourFile" ofType:#"plist"] atomically:YES];
Note: the writeToFile method's atomically parameter is asking whether or not it has to write the file right away or after it does whatever it needs to (as in, it's not a high priority). I recommend setting this to YES or true.

Objective C: Print/Log an array as usable code?

I'm programmatically building an array of dictionaries with hundreds of values I'm pulling from various sources. I then plan to go in and manually change a few of them as needed. I don't want to use this pulling method in the production code, I want to just store it as a vanilla array with dictionaries. However when using NSLog it returns the array obviously, but not as code I can copy and paste. I'd hate to have to go through several hundred values and and manually convert everything to be proper objective c code.
So in short, is there any way to return my array as actual code?
One approach would be to write the final array to a plist file. Then make the plist file part of your project. No need to generate code for the array. Simply load the plist into an array at runtime.
To save the array as a plist:
[myFinalArray writeToFile:somePath atomically:YES];

Plist writeToFile overwrites the entire plist

I have been successfully using a Plist to read and write data in my iPhone app. The Plist consists of dictionaries in arrays. When I want to append a dictionary I use the writeToFile method. This works well but it overWrites the entire Plist. Is there way to add to a dictionary without having to read the whole Plist and then right the whole Plist back again ??
Pete, if I understand your question correctly, you should do the following:
Load your plist file in an NSMutableArray. Then, when you want to add another dictionary, instead of saving it directly (it will of course overwrite...), you just add this dictionary to your existing NSMutableArray and then you save it.
NSMutableArray *arrayLoaded = <load here your plist>
NSDictionary *dictionaryToAdd = <create your dictionary>
[arrayLoaded addObject:dictionaryToAdd];
[arrayLoaded writeToFile:filePath];

Resources