CocoaPods trunk is moving to be read-only. Read more on the blog, there are 12 months to go.
| TestsTested | ✓ |
| LangLanguage | Obj-CObjective C |
| License | MIT |
| ReleasedLast Release | Dec 2014 |
Maintained by Todd Grooms, Aaron London.
| Depends on: | |
| AFNetworking | ~> 2.3.1 |
| CoreDataMate | ~> 0.1 |
| LPMJSONUtils | ~> 1.0.0 |
| Mantle | ~> 1.5 |
LPMSirenKit is a lightweight library for interacting with Hypermedia APIs that adhere to the Siren specification.
LPMSirenKit sits on top of AFNetworking and submits requests on behalf of the application. The library will parse the results and cache the entity, link, action, and field objects. The properties for the entity objects are not cached at this level (the library only caches those things that are necessary for navigation).
$ git clone [email protected]:lonelyplanet/lpm-sirenkit-ios.git
$ cd lpm-sirenkit-ios/Example
$ pod install
LPMSirenKit.xcworkspace
$ open LPMSirenKit.xcworkspace
Now you can run the project from Xcode. Once the application launches, you will be presented with a screen that will request a URL for a server you wish to run the application against and the location of the manifest. In our definition, the manifest is simply the location of the initial SirenEntity. For most servers, you can leave this field blank as the initial SirenEntity is located at the root URL you specify.
You will create an LPMSirenSessionManager with a base URL, a path to where the manifest for the API can be found, and an instance of NSURLSessionConfiguration (the defaultSessionConfiguration works really well). The manifest is simply the root of the API or, rather, where the API indicates what root level links and/or actions are available. Initialize your LPMSirenSessionManager:
LPMSirenSessionManager *sirenSessionManager = [[LPMSirenSessionManager alloc] initWithBaseURL:[NSURL URLWithString:@"http://siren.api"]
manifestPath:manifestPath
sessionConfiguration:NSURLSessionConfiguration.defaultSessionConfiguration];You will then need to request the manifest:
[sirenSessionManager GETManifestWithParameters:nil completion:^(LPMSirenEntityModel *manifestEntity, NSError *error) {
// Check manifestEntity and error to determine if request was successful
}];When you request the manifest, you are fetching the initial SirenEntity which is where you start traversing the API. This entity will most likely contain top-level SirenLinks and SirenActions for the API.
After successfully requesting the API's manifest, you are ready to rock. If you take one of the LPMSirenLinkModels that is connected to the manifest LPMSirenEntityModel (since the manifest is just a LPMSirenEntityModel, you can check the manifestEntityModel.sirenLinks relationship for any LPMSirenLinkModels you wish to use), you can request links by using the LPMSirenLinkModel:
[sirenSessionManager GETLink:sirenLinkModel withParameters:nil completion:^(LPMSirenEntityModel *sirenEntityModel, NSError *error) {
// Check sirenEntityModel and error to determine if request was successful
} error:&error];Or by using the link's relationship(s) and the GUID of the entity that owns the link:
[sirenSessionManager GETLinkForRelationship:@"self" ofEntityWithGUID:@"guid" withParameters:nil completion:^(LPMSirenEntityModel *sirenEntityModel, NSError *error) {
// Check sirenEntityModel and error to determine if request was successful
} error:&error];If the LPMSirenLinkModel is not found for the request method that performs the lookup on LPMSirenKit's local cache, GETLinkForRelationship:ofEntityWithGUID:withParameters:completion:error: will return nil instead of a valid NSURLSessionDataTask and an error code of SirenKitError_ErrorCode_LinkNotFound is given in the NSError parameter.
You can submit actions by using the LPMSirenActionModel with a dictionary of parameters:
[sirenSessionManager HTTPActionWithSirenAction:sirenActionModel withParameters:parameters completion:^(LPMSirenEntityModel *sirenEntityModel, NSError *error) {
// Check sirenEntityModel and error to determine if request was successful
} error:&error];Or by using the action's name and the GUID of the entity that owns the action:
[sirenSessionManager HTTPActionWithName:@"action" onEntityWithGUID:@"guid" withParameters:parameters completion:^(LPMSirenEntityModel *sirenEntityModel, NSError *error) {
// Check sirenEntityModel and error to determine if request was successful
} error:&error];If the LPMSirenActionModel is not found for the request method that performs the lookup on LPMSirenKit's local cache, HTTPActionWithName:onEntityWithGUID:withParameters:completion:error: will return nil instead of a valid NSURLSessionDataTask and an error code of SirenKitError_ErrorCode_ActionNotFound is given in the NSError parameter.
LPMSirenKit will attempt to map the parameters given for an action request to the fields associated with that action. Any keys in the parameters dictionary that do not have corresponding LPMSirenFieldModels for the specified LPMSirenActionModel will be ignored in the request (matched by the name property). If you try to set the value of a hidden field, this will be ignored in the request. LPMSirenKit also attempts to match types. For example, if a field indicates that it is a number or url input type, LPMSirenKit validates that the value given for these keys matches the same type (i.e. NSNumber or NSURL). If the type does not match, an error code of SirenKitError_ErrorCode_FieldTypeMismatch is given in the NSError parameter.
Are you interacting with an authenticated Siren API? Cool! We (at Lonely Planet) are as well. LPMSirenSessionManager supports the use of a HTTP Authorization header. Simply set the authorizationHeaderValue property and all subsequent requests will include the header:
sirenSessionManager.authorizationHeaderValue = @"Bearer some-hex-string";Each entity requires a globally unique identifier. However, different APIs use different identifiers and, within the same API, different types/kinds of entities can use different identifiers. LPMSirenSessionStore has a method that allows the client to specify where these GUIDs can be found for each kind of entity.
[LPMSirenSessionStore setGUIDMappingDictionary:@{
@"order": @"properties.orderNumber",
@"items, collection": @"href",
@"info, customer": @"properties.customerId"
}];In the above scenario, the key should match the entity's class. The value will be the path for the identifier after the response is parsed into LPMSirenEntityModels, LPMSirenLinkModels, or LPMSirenActionModels.
If I would like to make a place/collection entity's GUID that entity's 'self' link, the mapping may look like this:
@"places, collection": @"sirenLinks[0].href" // First link is usually 'self'Or
@"places, collection": @"sirenLinks[@rel~self].href" // A link whose rel property contains the 'self' identifier; This means rel could be "self" or "this, self" and it would be foundOr even
@"places, collection": @"sirenLinks[@rel=self].href" // A link whose rel property is equal to the 'self' identifier; This means rel has to be "self" to be foundLPMSirenKit currently uses Core Data to cache the Siren related metadata when parsing responses from the server. This is used to help quickly recall what entities, links, and actions a server supports quickly before subsequent requests. LPMSirenKit uses an embedded data store that you as a developer will not have to worry about or maintain. For more information about this data store, check out the LPMSirenKit.xcdatamodeld, ManagedSirenEntity, ManagedSirenLink, ManagedSirenField, and/or ManagedSirenAction.
LPMSirenKit depends on several other libraries: AFNetworking, CoreDataMate, LPMJSONUtils, and Mantle. These are included as dependencies in the .podspec and will be installed upon running pod install after adding LPMSirenKit to your Podfile.
LPMSirenKit is available through CocoaPods. To install
it, simply add the following line to your Podfile:
pod 'LPMSirenKit'
Todd Grooms, [email protected]
LPMSirenKit is available under the MIT license. See the LICENSE file for more info.