{"_id":"588f722cbcace50f0052ba16","category":{"_id":"588f722bbcace50f0052b9e5","version":"588f722bbcace50f0052b9e1","__v":0,"project":"565f5fa26bafd40d0030a064","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2016-02-18T20:31:28.395Z","from_sync":false,"order":3,"slug":"sdks","title":"Client SDKs"},"user":"565f5f29de5dc50d00acfe9f","version":{"_id":"588f722bbcace50f0052b9e1","project":"565f5fa26bafd40d0030a064","__v":1,"createdAt":"2017-01-30T17:04:43.410Z","releaseDate":"2017-01-30T17:04:43.410Z","categories":["588f722bbcace50f0052b9e2","588f722bbcace50f0052b9e3","588f722bbcace50f0052b9e4","588f722bbcace50f0052b9e5","588f722bbcace50f0052b9e6","588f722bbcace50f0052b9e7"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"5.3.0","version":"5.3.0"},"project":"565f5fa26bafd40d0030a064","__v":0,"parentDoc":null,"updates":["57e54bb5f3d7fc0e009c50e8","57ea8be92e84700e007432c0"],"next":{"pages":[],"description":""},"createdAt":"2016-02-18T20:34:48.108Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":0,"body":"The nanoscale.io Swift SDK is a lightweight SDK written in Swift. It can be used to connect an iOS client to a nanoscale.io gateway. You can view the source <a href=\"https://github.com/nanoscaleio/justapis-swift-sdk\" target=\"_blank\">here on GitHub</a>.\n\n##Dependencies\n\nThere are no external dependencies when using this framework in your own project. \n\nHowever, this SDK is a Swift dynamic framework, and is written in Swift 2.1 and needs a minimum deployment target of iOS 8.0. \n\nSome features used in the SDK (i.e. tuples, structs) are not currently available in Objective-C code. If you want to use this framework in an Objective-C app, you'll need to marshall these features through Swift code of your own. \n\n## Introduction\n\nThe core features of the SDK are exposed through three simple protocols: `Gateway`, `Request`, and `Response`. \n\nThese basic protocols are defined in `CoreTypes.swift`\n\nA `Gateway` represents your connection to a single nanoscale.io server. You can send `Request`s to this gateway, and you'll receive a `Response` through a simple callback closure.\n\nThe SDK includes two implementations of `Gateway`:\n\n### CompositedGateway\nThe composited gateway is built from a few configurable and replaceable components.\n\n* A `NetworkAdapter` that accepts a `Request` and sends it out over the network before returning a `Response` or an error. The default NetworkAdapter is `FoundationNetworkAdapter`, which uses NSURLSession. \n\n  If you prefer to use a different communications technique (AFNetworking, Alamofire, background sessions, caching, etc) you can write a simple NetworkAdapter and plug it into CompositedGateway's constructor.\n\n* An optional `RequestPreparer`. A RequestPreparer can modify requests at the gateway level. You might use one to insert a token on certain requests, apply default headers, remap URL's, or serialize body data into a standard format like JSON or form-data.\n\n  Two sample `RequestPreparer`s are included in the SDK. `DefaultFieldsRequestPreparer` can apply missing query parameters or header fields to all requests. `RequestPreparerClosureAdapter` allows you to provide a simple closure that does whatever you'd like.\n\n* An optional `ResponseProcessor`. A `ResponseProcessor` can modify a response at the gateway level, before the original response callback is invoked. This provides an opportunity to do logging, handle errors, or parse common response formats like JSON or XML.\n\n  Two sample `ResponseProcessor`s are included in the SDK. `JsonResponseProcessor` deserializes the body of all responses using NSJSONSerialization. `ResponsePreparerClosureAdapter` allows you to provide a simple closure that does whatever you'd like.\n\n* An `CacheProvider` that can cache responses and return them on later requests without making another network request. The default CacheProvider is an `InMemoryCacheProvider` that stores responses in-memory using Foundation's NSCache.\n\n  If you'd like more persistent or sophisticated caching, you can implement your own CacheProvider and pass it to the CompositeGateway on initialization. \n  \n* An optional `SSLCertificate` to be used for certificate pinning. If you provide the public key or certificate associated with your server, its identity will be validated before any requests are sent.\n\n* An optional `DefaultRequestPropertySet` that allows you to customize the default options for GET, POST, PUT, and DELETE requests submitted to the Gateway. These defaults are used when using the Gateway's convenience methods to submit a request. If you don't provide your own defaults, the Gateway will use `GatewayDefaultRequestProperties` as found in `Request.swift` \n\n### JsonGateway\n\n`JsonGateway` is Gateway implementation provided for convenience. It's just a `CompositedGateway` that includes a `JsonResponseProcessor` by default.\n\n##Setup\n\n### Framework Integration\n\n#### Cocoapods\n\nThe preferred way to include the SDK in your project is by using [Cocoapods](https://cocoapods.org).\n\nYou can find this project on Cocoapods <a href=\"https://cocoapods.org/pods/JustApisSwiftSDK\" target=\"_blank\">here.</a> \n\nFor the most recent stable version of this SDK, you can add the following directive to the target definition in your Podfile:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"pod 'JustApisSwiftSDK'\",\n      \"language\": \"ruby\",\n      \"name\": \"Podfile latest stable release\"\n    }\n  ]\n}\n[/block]\nFor the bleeding edge version of this SDK, you can add the following directive to the target definition in your Podfile:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"pod 'JustApisSwiftSDK', :git => 'https://github.com/AnyPresence/justapis-swift-sdk.git'\",\n      \"language\": \"ruby\",\n      \"name\": \"Podfile bleeding edge\"\n    }\n  ]\n}\n[/block]\nSince this SDK is a dynamic framework that uses Swift 2.1, you'll also need to make sure that your Podfile targets iOS 8.0 or higher and is set to use dynamic frameworks:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"platform :ios 8.0\\nuse_frameworks!\",\n      \"language\": \"ruby\",\n      \"name\": \"Podfile example\"\n    }\n  ]\n}\n[/block]\nThe repository includes a basic Demo project that uses Cocoapods. You're encoraged to look at it and its Podfile for a better understanding.\n\n### Module Import\n\nOnce the framework is included in your project, simply import the module into your own code using:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"import JustApisSwiftSDK\",\n      \"language\": \"swift\",\n      \"name\": \"Import module\"\n    }\n  ]\n}\n[/block]\n## Usage\n\n### Making requests\n\nTo make requests to your nanoscale.io server, you'll just need to create a `Gateway` and submit a `Request`. \n\nA simple example is shown here: \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"var gateway = CompositedGateway(baseUrl: NSURL(string:\\\"http://my-justapi-server.local:5000/\\\"))\\n\\ngateway.get(\\\"/foo\\\", params:[\\\"id\\\":123], callback:\\n{ (result:RequestResult) in\\n  \\n  if let error = result.error\\n  {\\n     print(\\\"Received an error: \\\\(error)\\\")\\n     return\\n  }\\n  guard let response = result.response else\\n  {\\n     print(\\\"Received no response!\\\")\\n     return\\n  }\\n  \\n  print(\\\"Received a response with HTTP status code: \\\\(response.statusCode)\\\")\\n})\",\n      \"language\": \"swift\",\n      \"name\": \"Simple GET example\"\n    }\n  ]\n}\n[/block]\nIn this example, you can see us use the `get` conveneince method on our gateway. \n\nThis method prepares and submits a GET request using as few parameters as we likely need. There are a number of these convenience methods available for each of the common HTTP methods (GET, POST, PUT, DELETE). The full list of these convenience methods are available in `Gateway.swift`\n\nYou may also prepare your own requests from scratch using any object that conforms to the `RequestProperties` protocol. `MutableRequestProperties` is provided for your convenience. Instead of calling one of the convenience methods, simply pass your request properties and the callback to the `submitRequest` method.\n\n### Request Queue\n\nEach instance of Gateway throttles requests so that no more than `maxActiveRequests` run at any time (default=2). If you submit requests faster than they can be processed, the pending requests can be accessed through the `pendingRequests` property.\n\nYou may pause and resume the request queue at any time. When paused, the Gateway will not start any new requests that have been queued. You may want to pause the queue when you go offline and resume it when connectivity is restored.\n\nRequests are immutable and **cannot** be modified once they've been submitted to the Gateway. However, you can cancel requests that are still pending by calling `cancelRequest(...)`\n \n### Automatic Content-Type Parsing\n\nThe CompositedGateway supports automatic parsing based on Content-Type. By calling `setParser(...)`. You may register a `ResponseProcessor` to run whenever a certain Content-Type is encountered on the gateway. The `JsonCompositedGateway` uses this tecnique to automatically parse JSON responses when the Content-Type is `application/json`\n\nYou may assign as many Content-Type parsers as you'd like.\n\nYou may disable automatic Content-Type parsing for any request by setting the `applyContentTypeParsing` Request property to false.\n\nYou may force a response to be interpreted with a certain Content-Type by setting the `contentTypeProperty` Request property to a non-nil value. This Content-Type will be used in place of any returned in the response headers. \n\n### Response Caching\n\nThe CompositedGateway supports caching of responses. You may control cache behavior using Request properties.\n\nYou make sure a fresh network request is performed by setting `allowCachedResponse` to false.\n\nYou may disable the caching of a response by setting `cacheResponseWithExpiration` to 0. Setting it to a higher value suggests the number of seconds for which a cached response will be preserved.\n\nYou may provide a custom cache identifier for a request by setting the `customCacheIdentifier` property. By default, only the method, path, and query parameters are used to distinguish requests from one another. If your headers or body are relevant to cached responses, you'll want to set a customCacheIdentifer that appropriately captures this information.  An example might be if you send search parameters using the BODY of a GET or POST request and want to cache the responses.\n\n### Receiving JSON Responses\n\nIf your nanoscale.io endpoints provide their responses in JSON, you can use the `JsonGateway` or set a `JsonResponseProcessor` as a `CompositedGateway` content-type parser.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"var gateway = JsonGateway(baseUrl: NSURL(string:\\\"http://my-justapi-server.local:5000/\\\"))\\n\\ngateway.get(\\\"/foo\\\", params:[\\\"id\\\":123], callback:\\n{ (result:RequestResult) in\\n  \\n  if let error = result.error\\n  {\\n     print(\\\"Received an error: \\\\(error)\\\")\\n     return\\n  }\\n  guard let response = result.response else\\n  {\\n     print(\\\"Received no response!\\\")\\n     return\\n  }\\n  guard let jsonData = response.parsedBody else\\n  {\\n  \\t  print:(\\\"No parsed body data found!\\\")\\n  \\t  return\\n  }\\n  print(\\\"Received a response with JSON content: \\\\(jsonBody)\\\")\\n})\\n\",\n      \"language\": \"swift\",\n      \"name\": \"JSON parsing example\"\n    }\n  ]\n}\n[/block]\n### Request Preparers\n\nRequestPreparers allow you to modify Requests after they've been submitted to your Gateway instance, but before they're added to the Request Queue.\n\nCommon uses would be to add additional headers to the request, build and add an authentication token based on query parameters, or encode body data using a specific format.\n\n### Response Processors\n\nResponseProcessors are extremely flexible and can modify, observe, or reject a response before it makes its way to the callback. \n\nAll response processors expose an asynchronous `processResponse(...)` method that receives the current (immutable) response and eventually calls a ResponseProcessorCallback with a response and/or error. `processResponse` is always invoked on the main thread.\n\nThe `ResponseProcessorClosureAdapter` is a convenience wrapper to use when you have a fast and simple action you want to perform on responses (i.e. signalling an error if an expected header or response field is invalid). It wraps a simple, synchronous closure.\n\nThe `CompoundResponseProcessor` lets you easily chain a series of response processors together so that they run sequentially. If any response processor signals an error, the remainder will be skipped.","excerpt":"","slug":"swift","type":"basic","title":"Swift"}
The nanoscale.io Swift SDK is a lightweight SDK written in Swift. It can be used to connect an iOS client to a nanoscale.io gateway. You can view the source <a href="https://github.com/nanoscaleio/justapis-swift-sdk" target="_blank">here on GitHub</a>. ##Dependencies There are no external dependencies when using this framework in your own project. However, this SDK is a Swift dynamic framework, and is written in Swift 2.1 and needs a minimum deployment target of iOS 8.0. Some features used in the SDK (i.e. tuples, structs) are not currently available in Objective-C code. If you want to use this framework in an Objective-C app, you'll need to marshall these features through Swift code of your own. ## Introduction The core features of the SDK are exposed through three simple protocols: `Gateway`, `Request`, and `Response`. These basic protocols are defined in `CoreTypes.swift` A `Gateway` represents your connection to a single nanoscale.io server. You can send `Request`s to this gateway, and you'll receive a `Response` through a simple callback closure. The SDK includes two implementations of `Gateway`: ### CompositedGateway The composited gateway is built from a few configurable and replaceable components. * A `NetworkAdapter` that accepts a `Request` and sends it out over the network before returning a `Response` or an error. The default NetworkAdapter is `FoundationNetworkAdapter`, which uses NSURLSession. If you prefer to use a different communications technique (AFNetworking, Alamofire, background sessions, caching, etc) you can write a simple NetworkAdapter and plug it into CompositedGateway's constructor. * An optional `RequestPreparer`. A RequestPreparer can modify requests at the gateway level. You might use one to insert a token on certain requests, apply default headers, remap URL's, or serialize body data into a standard format like JSON or form-data. Two sample `RequestPreparer`s are included in the SDK. `DefaultFieldsRequestPreparer` can apply missing query parameters or header fields to all requests. `RequestPreparerClosureAdapter` allows you to provide a simple closure that does whatever you'd like. * An optional `ResponseProcessor`. A `ResponseProcessor` can modify a response at the gateway level, before the original response callback is invoked. This provides an opportunity to do logging, handle errors, or parse common response formats like JSON or XML. Two sample `ResponseProcessor`s are included in the SDK. `JsonResponseProcessor` deserializes the body of all responses using NSJSONSerialization. `ResponsePreparerClosureAdapter` allows you to provide a simple closure that does whatever you'd like. * An `CacheProvider` that can cache responses and return them on later requests without making another network request. The default CacheProvider is an `InMemoryCacheProvider` that stores responses in-memory using Foundation's NSCache. If you'd like more persistent or sophisticated caching, you can implement your own CacheProvider and pass it to the CompositeGateway on initialization. * An optional `SSLCertificate` to be used for certificate pinning. If you provide the public key or certificate associated with your server, its identity will be validated before any requests are sent. * An optional `DefaultRequestPropertySet` that allows you to customize the default options for GET, POST, PUT, and DELETE requests submitted to the Gateway. These defaults are used when using the Gateway's convenience methods to submit a request. If you don't provide your own defaults, the Gateway will use `GatewayDefaultRequestProperties` as found in `Request.swift` ### JsonGateway `JsonGateway` is Gateway implementation provided for convenience. It's just a `CompositedGateway` that includes a `JsonResponseProcessor` by default. ##Setup ### Framework Integration #### Cocoapods The preferred way to include the SDK in your project is by using [Cocoapods](https://cocoapods.org). You can find this project on Cocoapods <a href="https://cocoapods.org/pods/JustApisSwiftSDK" target="_blank">here.</a> For the most recent stable version of this SDK, you can add the following directive to the target definition in your Podfile: [block:code] { "codes": [ { "code": "pod 'JustApisSwiftSDK'", "language": "ruby", "name": "Podfile latest stable release" } ] } [/block] For the bleeding edge version of this SDK, you can add the following directive to the target definition in your Podfile: [block:code] { "codes": [ { "code": "pod 'JustApisSwiftSDK', :git => 'https://github.com/AnyPresence/justapis-swift-sdk.git'", "language": "ruby", "name": "Podfile bleeding edge" } ] } [/block] Since this SDK is a dynamic framework that uses Swift 2.1, you'll also need to make sure that your Podfile targets iOS 8.0 or higher and is set to use dynamic frameworks: [block:code] { "codes": [ { "code": "platform :ios 8.0\nuse_frameworks!", "language": "ruby", "name": "Podfile example" } ] } [/block] The repository includes a basic Demo project that uses Cocoapods. You're encoraged to look at it and its Podfile for a better understanding. ### Module Import Once the framework is included in your project, simply import the module into your own code using: [block:code] { "codes": [ { "code": "import JustApisSwiftSDK", "language": "swift", "name": "Import module" } ] } [/block] ## Usage ### Making requests To make requests to your nanoscale.io server, you'll just need to create a `Gateway` and submit a `Request`. A simple example is shown here: [block:code] { "codes": [ { "code": "var gateway = CompositedGateway(baseUrl: NSURL(string:\"http://my-justapi-server.local:5000/\"))\n\ngateway.get(\"/foo\", params:[\"id\":123], callback:\n{ (result:RequestResult) in\n \n if let error = result.error\n {\n print(\"Received an error: \\(error)\")\n return\n }\n guard let response = result.response else\n {\n print(\"Received no response!\")\n return\n }\n \n print(\"Received a response with HTTP status code: \\(response.statusCode)\")\n})", "language": "swift", "name": "Simple GET example" } ] } [/block] In this example, you can see us use the `get` conveneince method on our gateway. This method prepares and submits a GET request using as few parameters as we likely need. There are a number of these convenience methods available for each of the common HTTP methods (GET, POST, PUT, DELETE). The full list of these convenience methods are available in `Gateway.swift` You may also prepare your own requests from scratch using any object that conforms to the `RequestProperties` protocol. `MutableRequestProperties` is provided for your convenience. Instead of calling one of the convenience methods, simply pass your request properties and the callback to the `submitRequest` method. ### Request Queue Each instance of Gateway throttles requests so that no more than `maxActiveRequests` run at any time (default=2). If you submit requests faster than they can be processed, the pending requests can be accessed through the `pendingRequests` property. You may pause and resume the request queue at any time. When paused, the Gateway will not start any new requests that have been queued. You may want to pause the queue when you go offline and resume it when connectivity is restored. Requests are immutable and **cannot** be modified once they've been submitted to the Gateway. However, you can cancel requests that are still pending by calling `cancelRequest(...)` ### Automatic Content-Type Parsing The CompositedGateway supports automatic parsing based on Content-Type. By calling `setParser(...)`. You may register a `ResponseProcessor` to run whenever a certain Content-Type is encountered on the gateway. The `JsonCompositedGateway` uses this tecnique to automatically parse JSON responses when the Content-Type is `application/json` You may assign as many Content-Type parsers as you'd like. You may disable automatic Content-Type parsing for any request by setting the `applyContentTypeParsing` Request property to false. You may force a response to be interpreted with a certain Content-Type by setting the `contentTypeProperty` Request property to a non-nil value. This Content-Type will be used in place of any returned in the response headers. ### Response Caching The CompositedGateway supports caching of responses. You may control cache behavior using Request properties. You make sure a fresh network request is performed by setting `allowCachedResponse` to false. You may disable the caching of a response by setting `cacheResponseWithExpiration` to 0. Setting it to a higher value suggests the number of seconds for which a cached response will be preserved. You may provide a custom cache identifier for a request by setting the `customCacheIdentifier` property. By default, only the method, path, and query parameters are used to distinguish requests from one another. If your headers or body are relevant to cached responses, you'll want to set a customCacheIdentifer that appropriately captures this information. An example might be if you send search parameters using the BODY of a GET or POST request and want to cache the responses. ### Receiving JSON Responses If your nanoscale.io endpoints provide their responses in JSON, you can use the `JsonGateway` or set a `JsonResponseProcessor` as a `CompositedGateway` content-type parser. [block:code] { "codes": [ { "code": "var gateway = JsonGateway(baseUrl: NSURL(string:\"http://my-justapi-server.local:5000/\"))\n\ngateway.get(\"/foo\", params:[\"id\":123], callback:\n{ (result:RequestResult) in\n \n if let error = result.error\n {\n print(\"Received an error: \\(error)\")\n return\n }\n guard let response = result.response else\n {\n print(\"Received no response!\")\n return\n }\n guard let jsonData = response.parsedBody else\n {\n \t print:(\"No parsed body data found!\")\n \t return\n }\n print(\"Received a response with JSON content: \\(jsonBody)\")\n})\n", "language": "swift", "name": "JSON parsing example" } ] } [/block] ### Request Preparers RequestPreparers allow you to modify Requests after they've been submitted to your Gateway instance, but before they're added to the Request Queue. Common uses would be to add additional headers to the request, build and add an authentication token based on query parameters, or encode body data using a specific format. ### Response Processors ResponseProcessors are extremely flexible and can modify, observe, or reject a response before it makes its way to the callback. All response processors expose an asynchronous `processResponse(...)` method that receives the current (immutable) response and eventually calls a ResponseProcessorCallback with a response and/or error. `processResponse` is always invoked on the main thread. The `ResponseProcessorClosureAdapter` is a convenience wrapper to use when you have a fast and simple action you want to perform on responses (i.e. signalling an error if an expected header or response field is invalid). It wraps a simple, synchronous closure. The `CompoundResponseProcessor` lets you easily chain a series of response processors together so that they run sequentially. If any response processor signals an error, the remainder will be skipped.