Using restkit object manager - ios

I want to use RestKit to consume a web service.
My collections end point returns something like this.
{
"meta": {
"limit": 20,
"next": "...",
"offset": 0,
"previous": null,
"total_count": 23
},
"objects": [
"..."
],
"requested_time": 1396875600.810225
}
The key "objects" can return an array of one of many types of elements. But always the same for a given collection.
How can I map this response with the ObjectManager?

The complete your object manager configuration you create a number of response descriptors. These descriptors match against path patterns of the response URL and include the mapping to be used to process the response content.
In this way you will have a different response descriptor for each path pattern which returns different content and the linked mapping will instruct RestKit on what type of object to create and how top populate it.

Related

How to parse JSON to an entity that has a relationship to itself using Sync?

I am using Sync trying to parse some JSON to Core Data.
My "Creature" entity has a parent-children relationship that looks like this:
and the JSON has a format similar to this:
[
{
"id": 1,
"name": "Mad king",
"parent": null,
"children": [
5
]
},
{
"id": 2,
"name": "Drogon",
"parent": 5,
"children": []
},
{
"id": 3,
"name": "Rhaegal",
"parent": 5,
"children": []
},
{
"id": 4,
"name": "Viserion",
"parent": 5,
"children": []
},
{
"id": 5,
"name": "Daenerys",
"parent": 1,
"children": [
2,
3,
4
]
}
]
The Mad king has one child Daenerys who has 3 children (Drogon, Rhaegal and Viserion).
Now, I know that Sync does support this sort of setup (where the JSON contains only the ids of parents/children instead of whole objects) and I suspect I have to parse the file twice - one for just getting all the objects and the second to create the relationships among them. For the second to work, I need to rename children to children_ids and parent to parent_id (as described in their README).
However I can't understand how exactly would I do that. Is it possible to ignore the parent/children during the first pass and then take them into account (using the modified keys) during the second?
Or could someone maybe propose a better solution that would (ideally) require just one pass?
According to the documentation:
For example, in the one-to-many example, you have a user, that has
many notes. If you already have synced all the notes then your JSON
would only need the notes_ids, this can be an array of strings or
integers. As a side-note only do this if you are 100% sure that all
the required items (notes) have been synced, otherwise this
relationships will get ignored and an error will be logged.
So you can, in theory, just blindly perform a full sync to actually get all the models(letting it fail on the relationships), and then sync again immediately after to get the relationships.
If you want to avoid the errors, you might want to write some helper functions to create 2 sets of JSON for these models, 1 to define the objects, and then a second to define the relationships. Either way, you'd need to do 2 passes.

Restricting results of $expand parameter in SensorThings API

I am attempting to truncate the results of an $expand parameter from SensorThingsAPI e.g.
http://example.org/v1.0/Things?$expand=Datastreams
However, $top only restricts the trunk of the query (e.g. Things). Is there a way to truncate the results of the 'leaves' of an $expand?
In this case, the server-side pagination should be controlling the 'leaves' of an $expand.
For example, if the service limit 100 entities for each response and the expanded entities (or the collection) have more than 100, the service will return the top 100 entities following a service-defined order. A #iot.nextLink will also be returned, so that the client know how to fetch the next 100 entities (i.e., next page). Using the above query as an example, an example nextLink to retrieve the Datastreams will be
Datastreams#iot.nextLink:"http://URL_to_retrieve_the_next_page/"
You can use this OGC SensorThings sandbox to see an example return of $expand: http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Datastreams?$expand=Observations
The following JSON shows an example response of the following query with $expand: http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Datastreams?$expand=Observations:
{
"#iot.count": 1,
"value": [{
"#iot.id": 8,
"#iot.selfLink": "http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Datastreams(8)",
"description": "Daily Water level",
"observationType": "http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Observation",
"unitOfMeasurement": {
"symbol": "m",
"name": "meter",
"definition": "https://en.wikipedia.org/wiki/Metre"
},
"Observations#iot.nextLink": "http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Datastreams(8)/Observations?$top=3&$skip=3",
"Observations#iot.count": 1826,
"Observations": [{
"#iot.id": 1835,
"#iot.selfLink": "http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Observations(1835)",
"phenomenonTime": "2015-12-30T16:00:00.000Z",
"result": "1375.44",
"resultTime": null,
"Datastream#iot.navigationLink": "http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Observations(1835)/Datastream",
"FeatureOfInterest#iot.navigationLink": "http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Observations(1835)/FeatureOfInterest"
}],
"ObservedProperty#iot.navigationLink": "http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Datastreams(8)/ObservedProperty",
"Sensor#iot.navigationLink": "http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Datastreams(8)/Sensor",
"Thing#iot.navigationLink": "http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Datastreams(8)/Thing"
},{},{}]
}

oData - how to use filter for specific odata.type

My oData query is as follow.
http://localhost:21005/api/v1/Devices?$expand=Jobs
My oData JSON response (in Postman's Pretty format) is as follow.
{
"#odata.context": "http://localhost:21005/api/v1/$metadata#Devices",
_"value": [
{
"Id": "abc03c74-8697-49ec-85e6-6444112d0336",
"TimeOffset": 0,
"TimeOffsetMode": "Unmanaged",
"Jobs": [
{
"#odata.type": "#VT.Api.Models.GetDataJob",
"Id": "ba07d50a-f17d-4c65-b3cf-f3e03d1ba1cf"
},
{
"#odata.type": "#VT.Api.Models.GetDataProfilerJob",
"Id": "5aa9c046-e4f2-44de-b932-16c06b86b084"
},
{
"#odata.type": "#VT.Api.Models.GetDeviceConfigurationJob",
"Id": "d7dc0ac5-1f89-4356-aaa8-9ac40353e1af"
}
}
{
"Id": "d42ac1f0-1261-4100-8391-013a226ff25f",
"TimeOffset": 0,
"TimeOffsetMode": "Unmanaged",
"Jobs": [ ]
}
}
Now, I want to query for only specific "#oData.type"
For example, I just want all the "Jobs" whose data type is "#VT.Api.Models.GetDataJob" ("#odata.type": "#VT.Api.Models.GetDataJob"). What kind of filter or query should I use?
The query should be:
http://localhost:21005/api/v1/Devices?$expand=Jobs($filter=isof('VT.Api.Models.GetDataJob'))
but as Brad said, IsOf has not been implemented in webapi odata v4.
According to the current spec, the correct way would be to apply a type filter to the expand expression, e.g.:
http://host/service/Orders?$expand=Customer/Model.VipCustomer
or, using your example,
http://localhost:21005/api/v1/Devices?$expand=Jobs/VT.Api.Models.GetDataJob
Please note that this will return all devices, expand their Jobs association, and only add GetDataJob instances to the resulting association sets. If you only want to query devices that have GetDataJob instances, you will need to see if you can use lambdas with type filters.
See also this SO question and OData Version 4.0 Part 2: URL Conventions
According to the OData spec you should be able to use the "IsOf" function to accomplish this. However, I don't believe this has been implemented yet in WebApi OData v4 (assuming that's what you're using):
https://github.com/OData/WebApi/issues/185

In Mandrill's API, is there any way to know the size limits of JSON attributes in their Responses?

I'm looking at the Mandrill API documentation e.g. https://mandrillapp.com/api/docs/messages.JSON.html#method=info. In the JSON response there may be seomthing like the following
{
"ts": 1365190001,
"url": "http://www.example.com",
"ip": "55.55.55.55",
"location": "Georgia, US",
"ua": "Linux/Ubuntu/Chrome/Chrome 28.0.1500.53"
}
Is there are way to know how large the String's may be for these attributes? i.e. how many characters might be returned for "ua" or "url" etc... I'm asking as I need to capture and store some of this data in Oracle, but I don't want to LOB everything!

Restkit: How to get and map data from multiple source

I'm currently working on iOS Application with RestKit 0.20 to access data from Tastypie API.
And I am trying to get feeds data from URL like this
/api/v2/feed/?format=json
Then I will get array of feeds as below.
{
"meta": {
"limit": 20,
"next": null,
"offset": 0,
"previous": null,
"total_count": 2
},
"objects": [
{
"id": 1,
"info": "This is my first post",
"pub_date": "2013-02-03T15:59:33.311000",
"user": "/api/v2/user/1/",
"resource_uri": "/api/v2/feed/1/"
},
{
"id": 2,
"info": "second post, yeah",
"pub_date": "2013-02-03T16:00:09.350000",
"user": "/api/v2/user/1/",
"resource_uri": "/api/v2/feed/2/"
}
]
}
if I want to fetch more data about user which Tastypie send it as url like a foreign key "user": "/api/v2/user/1/", do I have to nested call objectRequestOperation.
I'm confusing because I'm using block to callback when data is successful loaded. So is there any better way than requesting user data again for each feed after requesting feed complete.
Thank you very much :)
You have to define in the Feed resource :
user = fields.ToOneField(UserResource, full=True)
More info in the tastypie doc http://django-tastypie.readthedocs.org/en/latest/resources.html
Why Resource URIs?
Resource URIs play a heavy role in how Tastypie delivers data. This can seem very different from other solutions which simply inline related data. Though Tastypie can inline data like that (using full=True on the field with the relation), the default is to provide URIs.
URIs are useful because it results in smaller payloads, letting you fetch only the data that is important to you. You can imagine an instance where an object has thousands of related items that you may not be interested in.
URIs are also very cache-able, because the data at each endpoint is less likely to frequently change.
And URIs encourage proper use of each endpoint to display the data that endpoint covers.
Ideology aside, you should use whatever suits you. If you prefer fewer requests & fewer endpoints, use of full=True is available, but be aware of the consequences of each approach.

Resources