Storing gps location data in Parse - ios

I want to build an app like RunKeeper, as detailed in this tutorial. But I want to save the data in Parse cloud.
I will have a user object, and a user can have multiple runs. I am not sure how to save the gps locations for each run. Since there can be hundreds of locations for each run. Can someone please explain what would be the best/efficient way to save the locations.
Thanks.

Save lat/long pairs as double precision floating point values. That's all there is to it.

To solve your problem,
In the user class I would add an array of _runId.
After I would create a class Run with the specific property. So when the user do a run you append the id in the _runId array of the user class.
In the Run class, you could have a property like: location. It should also be an array (_location). So when the user is running you can append to the location array the location of the user for the specific run.
After that you would be able to get all the location of the user with the runId.
Hope this help!

What if you save all geo data to a JSON file, let's say that each JSON file will be a run, then save the JSON files into your Parse.com.
Good luck.

Related

Not all NSUserDefaults are restored on app relaunch

I am converting 2 custom lists into a json string and storing it the NSUserDefaults. Something like so:-
NSUserDefaults.StandardUserDefaults.SetString(JsonConvert.SerializeObject(stationList.Take(50)), "StationList1");
NSUserDefaults.StandardUserDefaults.SetString(JsonConvert.SerializeObject(stationList.Skip(50).Take(50)), "StationList2");
If I try and retrieve them immediately after saving them like below I get the saved values:-
savedStationList1 = NSUserDefaults.StandardUserDefaults.StringForKey("StationList1");
savedStationList2 = NSUserDefaults.StandardUserDefaults.StringForKey("StationList2");
But the issue is if I restart the app, and try to get the above values in another part of the code, I only get the value for:-
savedStationList2 = NSUserDefaults.StandardUserDefaults.StringForKey("StationList2");
and the value for below is always null :-
savedStationList1 = NSUserDefaults.StandardUserDefaults.StringForKey("StationList1");
I do not override these values anywhere within the app. Is there a way I can solve this?
Any help is appreciated
Although natively the iOS system does store data added through 'userdefaults' it may not do this instantly. I would suggest adding the following line:
NSUserDefaults.StandardUserDefaults.Synchronise();
After you store data to standard user defaults run the synchronise and test that you can extract the data, you should find that this will now work correctly for you.

iOS newbie: search id from a local json file then make request to server

I am learning iOS development. Currently, I started my hobby project which is a weather foracast app. I have found a open REST API, I can send request to get weather data for a city.
The REST API needs me to send request with city id instead of city name & it provides me a 20MB json file which contains city objects with fields city_id, city_name, longitude, latitude. I know I should create a City class to have those fields.
My app is supposed to allow user to input the city name, then, my app make request with the corresponding city id. My question is a about the best practice for this:
Since I need all city ids, should I download the 20MB json file & embed it to my app? Does that mean my app size would be larger than 20MB ? Any better practice to handle this?
If I have to put the 20MB json file in my project, what is the best way to parse the content to a list of City programmatically?
If user input one city name, I feel if I scan all the cities in the json file, it is inefficient, what could be the efficient way to find the city id for the city name (without scanning all the 20MB json)?
==== THE OPEN REST API ===
You do not need to include the JSON in your app. In fact, I highly recommend against doing so. This is according to the documentation:
Description:
You can call by city name or city name and country code. API responds with a list of results that match a searching word.
API call:
api.openweathermap.org/data/2.5/weather?q={city name}
api.openweathermap.org/data/2.5/weather?q={city name},{country code}
Parameters:
q city name and country code divided by comma, use ISO 3166 country codes
Examples of API calls:
api.openweathermap.org/data/2.5/weather?q=London
api.openweathermap.org/data/2.5/weather?q=London,uk
Given this information, you can send a request to the API like the example given: api.openweathermap.org/data/2.5/weather?q=London
The response should include the necessary data to make a subsequent call for the weather forecast.
No need to include 20MB of noise in your app bundle.
I'd create an array of City objects and parse the data into each City object (assuming you need all of them. If not, you'll have to find a way to parse out the ones youd on't want.) As long as you're not writing these to storage it shouldn't increase your app size, it may take a bit to download and parse depending on the methods you use, but that's all part of the fun of optimizing.
There are many JSON parsing iOS libraries, I have the most experience using RestKit to make network requests, and that includes a JSON to Objective-C Object parser built right in, it's super easy. Basically, do some research on JSON parser libraries and pick the one that best suits your needs. You shouldn't need to parse it yourself.
I'd create an NSDictionary with the city_name as your keys, and the city_id as your values. Then to retrieve the city_id simply call [dictionary objectForKey:enteredCity] (replacing with your actual variable names, of course)
I believe that they are asking you to bundle and not burden their server with requests for the 20mb file that doesn't seem to change much.
I would make a script that you run on your dev machine that turns this into a sqlite db (or some other serialized format). Don't bundle the JSON and parse at runtime --- turn it into something queryable at runtime.

Handling riak CRDT in version 2.1+ using erlang client

The answer in this post about using riak_kv_crdt shows how to extract counters. I can't locate riak_kv_crdt library api documentation. How would one extract the CRDTs such as map from a bucket object in version 2.1.4?
I checked riakc_pb but couldn't figure out from the documentation if there is any API to extract map from a bucket object. Will appreciate pointers on how to deal with riak data types using erlang code.
In the commit hooks that I am planning to write, I plan to use map datatype to create immutable log append to keep track of user info, and use post-commit hook to update another mutable map, say latest_info to point to latest log for that user. So, I need to be able to extract map from the object, and look at the contents before copying them.
Update
Following Joe's tips in comments, I tried to do map_value on a bucket object containing map but got errors below:
Let us first verify that the object has a map.
> riakc_obj:get_content_type(O1).
"application/riak_map"
Now, let us try to get the map:
> riak_kv_crdt:map_value(O1).
** exception error: no function clause matching
riak_object:get_contents({riakc_obj,
{<<"test_map">>,<<"uinfo_log">>},
<<"ahmed_info_1">>,
<<107,206,97,96,96,96,204,96,202,5,82,60,7,47,197,115,
158,125,191,80,29,34,148,200,...>>,
[{{dict,3,16,16,8,80,48,
{[],[],[],[],[],[],[],[],[],[],[],[],[],...},
{{[],[],[],[],[],[],[],[],[],[],[...],...}}},
<<69,2,0,0,0,11,114,105,97,107,95,100,116,95,109,97,
112,77,2,131,...>>}],
undefined,undefined}) (src/riak_object.erl, line 595)
in function riak_kv_crdt:merge_object/1 (src/riak_kv_crdt.erl, line 186)
in call from riak_kv_crdt:value/2 (src/riak_kv_crdt.erl, line 98)
in call from riak_kv_crdt:map_value/1 (src/riak_kv_crdt.erl, line 140)

Updating core data performance

I'm creating an app that uses core data to store information from a web server. When there's an internet connection, the app will check if there are any changes in the entries and update them. Now, I'm wondering which is the best way to go about it. Each entry in my database has a last updated timestamp. Which of these 2 will be more efficient:
Go through all entries and check the timestamp to see which entry needs to be updated.
Delete the whole entity and re-download everything again.
Sorry if this seems like an obvious question and thanks!
I'd say option 1 would be most efficient, as there is rarely a case where downloading everything (especially in a large database with large amounts of data) is more efficient than only downloading the parts that you need.
I recently did something similiar.
I solve the problem, by assigning an unique ID and a global 'updated timestamp' and thinking about 'delta' change.
I explain better, I have a global 'latest update' variable stored in user preferences, with a default value of 01/01/2010.
This is roughly my JSON service:
response: {
metadata: {latestUpdate: 2013...ecc}
entities: {....}
}
Then, this is what's going on:
pass the 'latest update' to the web service and retrieve a list of entities
update the core data store
if everything went fine with core data, the 'latestUpdate' from the service metadata became my new 'latest update variable' stored in user preferences
That's it. I am only retrieving the needed change, and of course the web service is structured to deliver a proper list. Which is: a web service backed by a database, can deal with this matter quite well, and leave the iphone to be a 'simple client' only.
But I have to say that for small amount of data, it is still quite performant (and more bug free) to download the whole list at each request.
As per our discussion in the comments above, you can model your core data object entries with version control like this
CoreDataEntityPerson:
name : String
name_version : int
image : BinaryData
image_version : int
You can now model the server xml in the following way:
<person>
<name>michael</name>
<name_version>1</name_version>
<image>string_converted_imageData</image>
<image_version>1</image_version>
</person>
Now, you can follow the following steps :
When the response arrives and you parse it, you initially create a new object from entity and fill the data directly.
Next time, when you perform an update on the server, you increase the version count of an entry by 1 and store it.
E.g. lets say the name michael is now changed to abraham, then version count of name_version on server will be 2
This updated version count will come in the response data.
Now, while storing the data in the same object, if you find the version count to be same, then the data update of that entry can be skipped, but if you find the version count to be changed, then the update of that entry needs to be done.
This way you can efficiently perform check on each entry and perform updates only on the changed entries.
Advice:
The above approach works best when you're dealing with large amount of data updation.
In case of simple text entries for an object, simple overwrite of data on all entries is efficient enough. And this also keeps the data reponse model simple.

Symfony: Save multiple same objects

I have a page that shows 3 Objects (they are the same class).
I want to save them.
Unfortunaly only the latest one gets updated. All other seems to be invalid.
So my idea was to give them unique names: testObject_1[text1], testObject_2[text1].
This works as I can see it in the source code.
But how can I pass this name to form->save() in order to get the POST-reply filtered by this name (testObject_1) and then save it?
Or is there something more easier?
Thank you
Tobias Kaminsky
I solved it:
$temp->bind($request->getParameter("testObject_$i"), $request->getFiles("testObject_$i"));
(where $i is an Index stored in the database)

Resources