How to check for existing item in NSSet or NSCountedSet? - iphone

I'm currently populating model objects into an NSSet (perhaps I should be using NSCountedSet). The models should be unique. What I do is pull them in from a web service, and then instantiate them on the client-side and add them to a set.
My problem is the following: There are times when I'll only pull one model and add it to the set, for instance say I have an inventory of Ferrari's. So I'll ask my server to pull me in one specific Ferrari because an individual clicks on that Ferrari's detail view from an inventory. The individual Ferrari detail view will list all of the different paints available for this model. So once the user drills into this Ferrari view, I will ask the server for all of the paints available for a particular Ferrari model.
Next, the user backs out and then goes to a view controller which asks for all of the paint colors I have available for every vehicle. I already have the Ferrari paints available in a stash. Now I'm asking for ALL of the paints from the server. What's the best way to aggregate the existing paints with all of the paints without duplicating resources?

What you need is a way to uniquely identify each object from the server. In a database an object (part or whole) can be represented as a row and the rowid is typically a monotonically increasing integer (although your data source could use something else). In any case, store this unique id in each object you create, and before creating a new object check for the existence of an object with that id. If the object already exists, return the existing object, and if it doesn't, create a new object and then store it in the cache. Using integers as ids works out nicely, because you can use NSMapTable as a cache with the rowids as the keys, and the values are the object pointers.

Maintain an NSArray* in your app which stores NSString* objects based on some hash function of your features:
hashValue = hash(color + horsepower + leatherSeating + whatever...)
For example, you might take the SHA1 hash of a collated string (example code).
Take the features you obtain from the web service and generate a hashed value from them using the same function.
Search your app's hash table for the web-service-value using -containsObject:.
If it returns YES, do X, else do Y.

Related

How can I bind switches (input checkbox) to a mutually exclusive (input radio) in leaflet.js?

There are three groups of markers (grocery stores, clothing stores, pharmacies). Each of them is from a different company. I need to make a display on the map by stores and their companies. When switching to stores, so that only the selected companies are displayed. That is, when selecting a store, other stores should not be displayed. Input radio -> (grocery stores, clothing stores, pharmacies), input checkbox -> (company1, company2,...). How can I make it so that when selecting, for example, "clothing stores", only the clothing store companies with an optional selection by company are shown?
Here's an example: https://codesandbox.io/s/billowing-cache-805g6?file=/index.html
This example uses buttons but you could easily switch them to radio buttons if you would rather use those.
The code is quite simple. One page load, it creates the map. I defined a static array of objects that are companies and each company contains objects by store types (yours might be different).
The doLoadCompany function takes a the id of the company and if it matches, it will loop through the grocery store object for that company and load the markers onto the map. Before it loads the new grocery stores though, it will clear the previously loaded company, if one existed.
This is one simple example. It can get much more complicated depending on your object or it could be simpler again, depending on your object. The basics is to determine a way to identify the company you are wanting to load data for and then load that data. If you're doing this from an API, I would return only the data that you need for the specific company then loop through the data set and plot the markers based on their coordinates.

How to reference the same object that comes from diferents streams?

I have an application with an api works like a web (when you ask for 'favorites' it sends a json with some elements that fit in the category, when you ask for all the elements it sends another list, which contains the favorites as well, but when the json is transformed it will be a reference of a different object).
I am trying to find the best way, not to make a call each time, storing the view in a tab and working with 'streams' instead of 'builders', but how to update the object if in a category view we assign a value to it, and when we go back to the full list tab (without reloading), show the change in the object that represents the same one that we have in favorites?
Actually I am storing the first reference of the object in a block, in an array of objects, if we first call 'favorites' the next time the same object arrives from another source, it references the first occurrence of the same object, it works, but the object list can be very large and I'm afraid maybe not the best implementation.
In a prefect world I would like not to have to store the objects and just work with the tabs loaded in streams, but I don't know how to propagate the change if the same item is on different tabs.
Any idea for a good implementation?

SCNNode names, suggestions for a unique value?

My app reads a text file line-by-line, copies the data into an array of Card objects, and then creates SceneKit nodes for each one. Some of the Cards modify or make iterative copies of the data on earlier lines, so there is no 1:1 correspondence between line numbers and the number of SCNNodes.
I'm trying to come up with a way that I can uniquely name the nodes when they are created so that I can use childNodeWithName(_:recursively:) to find them if. Using the Cards index in the array is not useful because that might change - the user might add or remove objects or reorder them, for instance.
Is there some sort of unique ID or hash on the Card (or any) objects themselves that I can access that I might use for this task?
the answer to your question depends on what a Card represents and is completely independent of SceneKit. I guess it's up to you to find a hash function that works well for what's contained in a Card, or you can simply store a NSUUID in the Card's initializer.

How to store tree base data into Data base?

I am developing an application of iphone which is navigation based, and i am showing data on first View Items then on second View Sub Items and so on. So my question is that what will good approach to save this on Data base (sqlite).
Keep this simple.
Each object/View has it's own ID and at least one parent ID.
This will ensure your data can represent trees of any depth and any complexity.
i am not an expert in this field but you can do it like this ... now that you said all you data can be represented something like tree...
Find all the objects that will be leaf of your tree make those objects as a table in DB, (please keep in mind that you make table only for objects that have different structure not because they have different values)
Repeat above step for one level above until you reach top
Eventually you will find that you just got your DB.
To be more precise you need to study DBMS

What is the most practical Solution to Data Management using SQLite on the iPhone?

I'm developing an iPhone application and am new to Objective-C as well as SQLite. That being said, I have been struggling w/ designing a practical data management solution that is worthy of existing. Any help would be greatly appreciated.
Here's the deal:
The majority of the data my application interacts with is stored in five tables in the local SQLite database. Each table has a corresponding Class which handles initialization, hydration, dehydration, deletion, etc. for each object/row in the corresponding table. Whenever the application loads, it populates five NSMutableArrays (one for each type of object). In addition to a Primary Key, each object instance always has an ID attribute available, regardless of hydration state. In most cases it is a UUID which I can then easily reference.
Before a few days ago, I would simply access the objects via these arrays by tracking down their UUID. I would then proceed to hydrate/dehydrate them as I needed. However, some of the objects I have also maintain their own arrays which reference other object's UUIDs. In the event that I must track down one of these "child" objects via it's UUID, it becomes a bit more difficult.
In order to avoid having to enumerate through one of the previously mentioned arrays to find a "parent" object's UUID, and then proceed to find the "child's" UUID, I added a DataController w/ a singleton instance to simplify the process.
I had hoped that the DataController could provide a single access point to the local database and make things easier, but I'm not so certain that is the case. Basically, what I did is create multiple NSMutableDicationaries. Whenever the DataController is initialized, it enumerates through each of the previously mentioned NSMutableArrays maintained in the Application Delegate and creates a key/value pair in the corresponding dictionary, using the given object as the value and it's UUID as the key.
The DataController then exposes procedures that allow a client to call in w/ a desired object's UUID to retrieve a reference to the actual object. Whenever their is a request for an object, the DataController automatically hydrates the object in question and then returns it. I did this because I wanted to take control of hydration out of the client's hands to prevent dehydrating an object being referenced multiple times.
I realize that in most cases I could just make a mutable copy of the object and then if necessary replace the original object down the road, but I wanted to avoid that scenario if at all possible. I therefore added an additional dictionary to monitor what objects are hydrated at any given time using the object's UUID as the key and a fluctuating count representing the number of hydrations w/out an offset dehydration. My goal w/ this approach was to have the DataController automatically dehydrate any object once it's "hydration retainment count" hit zero, but this could easily lead to significant memory leaks as it currently relies on the caller to later call a procedure that decreases the hydration retainment count of the object. There are obviously many cases when this is just not obvious or maybe not even easily accomplished, and if only one calling object fails to do so properly I encounter the exact opposite scenario I was trying to prevent in the first place. Ironic, huh?
Anyway, I'm thinking that if I proceed w/ this approach that it will just end badly. I'm tempted to go back to the original plan but doing so makes me want to cringe and I'm sure there is a more elegant solution floating around out there. As I said before, any advice would be greatly appreciated. Thanks in advance.
I'd also be aware (as I'm sure you are) that CoreData is just around the corner, and make sure you make the right choice for the future.
Have you considered implementing this via the NSCoder interface? Not sure that it wouldn't be more trouble than it's worth, but if what you want is to extract all the data out into an in-memory object graph, and save it back later, that might be appropriate. If you're actually using SQL queries to limit the amount of in-memory data, then obviously, this wouldn't be the way to do it.
I decided to go w/ Core Data after all.