I'm currently making a word game for iOS that, when loading, reads in a text file of around 30000 words and loads them into a prefix tree for quick searching during gameplay. This works well, but the loading and tree construction process adds a noticeable few seconds to the app's startup time. At the moment I'm testing on an iPhone 4, but I imagine it would be a good deal slower on a 3GS earlier models.
Is there a way to create this tree at compile time rather than when the app opens? Or, less ideally, would it be possible to prebake the data with another program and add that file to the project instead of doing it at runtime? How would I go about doing that?
I run into the same issue with a game we developed, and for us, it performed better to use a SQLite DB with the words instead of the in-memory tree. The DB used less space than the plist that represented the tree, it did not require us to preload it in memory, and the performance (when querying for a valid word) was about the same.
pgb's answer is good. If you do not want to use SQLite, you can store your data in a plist and have [NSDictionary dictionaryWithContentsOfFile:] create a tree for you.
If you do choose to have the data compiled into your program, it will have to be built of primitive types, such as numbers and characters. Then, use structures and arrays to define the structure, and use a constant variable to store the data. Here is a simple example which is just an array of character strings:
const char *words[] = {"Word1","Word2","Word3"};
const unsigned numWords = (sizeof(words) / sizeof(char*));
Related
Let's say i have a xml file with a tag named which contains the number of fields i want to show in my tableView and in another xml file i have the information to be displayed in that tableView.
The question is : Should i create 2 different file in my project (xmlparse1.h and .m + xmlparse2.h and .m) or should i just put all my code in 1 (xmlparse.h + .m) and differenciate which file i am parsing at the moment with a bool or something like that in the code?
I am developing an iphone app on Xcode 4.3 mac os x 10.7.4 if this might change
EDIT: 1st file :
<MenuPrin>
<humidite>82,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</humidite>
<tempmoy>
189,124,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700
</tempmoy>
</MenuPrin>
2nd File :
<Instal>
<nbrField>2</nbrField>
</Instal>
So it looks like this. So, since nbrField is 2 I would take the 2 first value from tempMoy and humidite and show them in a tableView.
END OF EDIT
If how you're parsing is similar in both instances, to add two sets of files that do effectively the same thing would be extremely inefficient and considered bad practice. It makes a lot more sense to create a parser that can handle the two different files than to write two parsers that can only handle a specific file each.
To more specifically answer your question, I would determine which file you are parsing and behave accordingly, whether you do this with a bool or something else is up to you.
EDIT: Here is the idea that just popped into my head, so if for whatever reason this wont work for you(Like I said its been a while), or someone has a better idea, I'm all ears. You could still have a set of files(.h and .m) that contain the definition of your parser. Your parser could contain within it a two variables of type Object1 and Object2 which are built in such a way that they resemble the data structure that you need to store what you parse once for your first type of file, and a different definition for your second type of file. This way when parsing once you determine which file it is you are reading, it just changes which of these two objects you write into. There are also plenty of variations for how you could set this up, and I can also think of a few cases for what you might be trying to do where this might not work, but there is the idea regardless.
If you think that the two sets of files approach is better for the application you are trying to write and makes more sense to you, given what has been discussed in the comments, it isn't necessarily a bad idea.
In case if u want to create two table view in one view u need to create a single .h & .m file...If u want to create individual table view u need to create two .h & .m...
Try TBXML parser...that is the easiest way and less memory usage for xmlparsing...
What does this file hold and how important is it to keep it "correct"?
I've seen people write scripts to just merge any change dealing with it and I've heard others merging it manually every time.
What is the correct way to handle it and why?
The project.pbxproj contains all of the metadata about your project that Xcode uses to build it; the settings, the file references, configuration, targeted platforms, etc...
I.e. it is a critically important.
There really isn't a great answer for this. Typically, teams will avoid conflict by limiting edits to the project to one team member at a time.
The Xcode team has put a lot of effort into making the file merge-friendly. In managing several large projects via svn, I've generally found that the merges are automatic and painless.
Until they aren't. And when they aren't, revert, merge changes by hand (i.e. make the changes in the project that conflicted), and move on.
Try my script xUnique.
What it does:
convert project.pbxproj to JSON format
Iterate all objects in JSON and give every UUID an absolute path, and create a new UUID using MD5 hex digest of the path
All elements in this json object is actually connected as a tree
We give a path attribute to every node of the tree using its unique attribute; this path is the absolute path to the root node,
Apply MD5 hex digest to the path for the node
Replace all old UUIDs with the MD5 hex digest and also remove unused UUIDs that are not in the current node tree and UUIDs in wrong format
Sort the project file inlcuding children, files, PBXFileReference and PBXBuildFile list and remove all duplicated entries in these lists
see sort_pbxproj method in xUnique.py if you want to know the implementation;
It's ported from my modified sort-Xcode-project-file, with some differences in ordering PBXFileReference and PBXBuildFile
With different options, you can use xUnique with more flexibility
Still working my way through this program. Next task on my to-do list is selecting random words from a pre-generated list. I've got the randomisation code sorted, but I now need to know the best way to store and retrieve words from my big list (and it is a fairly big list - over 220 words).
Since I'm designing for iPhone, memory is a paramount concern. Because of this I was hoping to avoid loading the whole file into memory. I'd much rather have the file laid out so that I can jump straight to an indexed position in the file and grab only the data I need. It would be nice if I could make use of the text file I already have with all the words in it, but I don't mind converting if there is benefit to some other method.
Anyone got any suggestions about the best way to do this?
-Ash
Well, 220 words isn't exactly a big list :-) Let's say each word is long, say 20 characters. Then you're talking about a measly 4.4kB. So I wouldn't worry about the size here. As Kevin pointed out, [NSArray arrayWithContentsOfFile:...] is likely the easiest way (also have a look at [NSDictionary dictionaryWithContentsOfFile:...]).
But if your list is getting really big (say 10000 words) then I'd suggest you read up on SQLite which is also supported on the iPhone.
Don't worry about the storage space (the storage required is far less than you think). Use a PLIST (File > New File > Resource (Mac OS X) > Property List), and arrayWithContentsOfFile to make loading the words simple (define an array as the root item in the PLIST; Apple's documentation has further details). Then, simply:
srandom(time(NULL));
NSUInteger index = rand() % [array length];
NSString *word = [array objectAtIndex:index];
I'm writing an iPhone app that is mainly centered around grid patterns, so I have a Pattern class which contains an NSMutableArray of NSMutableArrays. This class implements NSCoding, and it seems the following code works just fine in my iPhone app:
GridPattern * pattern = [GridPattern patternWithWidth:8 height:8];
[pattern setValueAtColumn:0 row:7 value:1];
[NSKeyedArchiver archiveRootObject:pattern toFile:#"test.pat"];
pattern = [NSKeyedUnarchiver unarchiveObjectWithFile:#"test.pat"];
If I debug the code above, I find after stepping over line 4, that I have a GridPattern object with the appropriate value set for column 0, row 7.
I have also written a Cocoa OSX application intended for creating patterns for the iPhone app, which also uses the same GridPattern class. It can also load and save the patterns successfully.
What I wanted to do was:
create and save the patterns in the OS X app
add the pattern files into Resources group in XCode for the iPhone app; (I added it as test.pat)
unarchive the patterns in my iPhone app, using code such as:
pattern = [NSKeyedUnarchiver unarchiveObjectWithFile:#"test.pat"];
However, when I try to unarchive the objects from this file, all that is returned is nil. I thought I might have had the file path wrong and also tried #"Resources/test.pat" to no avail.
Am I simply referring to the file incorrectly? Or are archived objects simply not cross-platform? Is this whole approach just plain wrong? If so, how would you do it?
I don't know about the compatibility of archiving across platforms, but to refer to a bundle resource, you should always use NSBundle to find it. Don't depend on the current path.
As your model is just an array of arrays, you could use XML property lists which do work across architectures.
In my application, I am using a plist. Please, can anyone explain what are the uses of plist with an example or a sample code?
In the context of iPhone development, Property Lists are a key-value store that your application can use to save and retrieve persistent data.
All iPhone applications have at least one of these by default, the Information Property List:
The information property list is a
file named Info.plist that is included
with every iPhone application project
created by Xcode. It is a property
list whose key-value pairs specify
essential runtime-configuration
information for the application. The
elements of the information property
list are organized in a hierarchy in
which each node is an entity such as
an array, dictionary, string, or other
scalar type.
Plist are XML files in a specific format. Prior to XML, they had a custom format now called 'old plist'. (You almost never see that anymore save in legacy code.)
Foundations collection classes automatically generate XML files in the plist format when you use their serialization methods to write them to disk. They also automatically read them back. You can also write your own serializers for your own custom objects. This allows you to persistently store complex objects in a robust, human readable format.
One use for plist for programmers is that it is easier to use the plist editor to input and manage a lot of data than it is to try and code it. For example, if you have an class that requires setting a large number of ivars, you can create a plist, read it into an NSArray or NSDictionary and then initialize the instance by passing it the dictionary.
I use this technique when I have to use a large number of paths to draw complex objects. You define the path in the plist file instead of the code and edit the path in the plist editor.
It's also a handy way to create a large amount of detailed test data.
PList means PropertyList
It is XML file format
It is mainly user for store and reterve the data
It can store the key-value pair
It's been a long time since I've looked at them, but plist is a short-form of "properties list" and can be used to store application configuration settings that need to persist between instances of an application's execution. Could be similar to a .properties file (I see those a lot on Java projects).
A plist is essentially just a data file, it stores information in a documented format.
From Wikipedia:
In the Mac OS X Cocoa, NeXTSTEP, and
GNUstep programming frameworks,
property list files are files that
store serialized objects. Property
list files use the filename extension
.plist, and thus are often referred to
as plist files. Property list files
are often used to store a user's
settings. They are also used to store
information about bundles and
applications, a task served by the
resource fork in the old Mac OS.
.plist
Info.plist is key/value persistence storage(property list) which is used by system and user. It contains user-friendly text in XML format. Info.plist is mandatory file for any Bundle. For example it contains Bundle id[About] which is usually is used by system but as a programmer/user you are not limited on changing/reading[More]. The same as you can add K/V for your own purposes and read it in runtime. You could noticed that some frameworks forces you to add K/V into your's application to identify you or some other cases.
.entitlements is a property list with enabled capabilities(e.g. ApplePay)
[Info.plist location]
[Vocabulary]