PageRenderTime 44ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

Markdown | 340 lines | 249 code | 91 blank | 0 comment | 0 complexity | c4256e9db577ac9d3bf6f21a3e7d3044 MD5 | raw file
  1. <properties
  2. pageTitle="How to Use iOS Client Library for Azure Mobile Services"
  3. description="How to Use iOS Client Library for Mobile Services"
  4. services="mobile-services"
  5. documentationCenter="ios"
  6. authors="krisragh"
  7. manager="dwrede"
  8. editor=""/>
  9. <tags
  10. ms.service="mobile-services"
  11. ms.workload="mobile"
  12. ms.tgt_pltfrm="mobile-ios"
  13. ms.devlang="objective-c"
  14. ms.topic="article"
  17. # How to Use iOS Client Library for Azure Mobile Services
  18. [AZURE.INCLUDE [mobile-service-note-mobile-apps](../../includes/]
  19. &nbsp;
  20. [AZURE.INCLUDE [mobile-services-selector-client-library](../../includes/]
  21. This guide teaches you to perform common scenarios using the Azure Mobile Services [iOS SDK]. If you are new to Mobile Services, first complete [Mobile Services Quick Start] to configure your account, create a table, and create a mobile service.
  22. > [AZURE.NOTE] This guide uses the latest [iOS Mobile Services SDK]( If your project uses an older version of the SDK, first upgrade the framework in Xcode.
  23. [AZURE.INCLUDE [mobile-services-concepts](../../includes/]
  24. ##<a name="Setup"></a>Setup and Prerequisites
  25. This guide assumes that you have created a mobile service with a table. For more information see [Create a table], or reuse the `TodoItem` table created in [Mobile Services Quick Start]. This guide assumes that the table has the same schema as the tables in those tutorials. This guide also assumes that your Xcode references `WindowsAzureMobileServices.framework` and imports `WindowsAzureMobileServices/WindowsAzureMobileServices.h`.
  26. ##<a name="create-client"></a>How to: Create Mobile Services Client
  27. To access an Azure mobile service in your project, create an `MSClient` client object. Replace `AppUrl` and `AppKey` with the mobile service URL and the application key Dashboard values, respectively.
  28. ```
  29. MSClient *client = [MSClient clientWithApplicationURLString:@"AppUrl" applicationKey:@"AppKey"];
  30. ```
  31. ##<a name="table-reference"></a>How to: Create Table Reference
  32. To access or update data for your Azure mobile service, create a reference to the table. Replace `TodoItem` with the name of your table.
  33. ```
  34. MSTable *table = [client tableWithName:@"TodoItem"];
  35. ```
  36. ##<a name="querying"></a>How to: Query Data
  37. To create a database query, query the `MSTable` object. The following query gets all the items in `TodoItem` and logs the text of each item.
  38. ```
  39. [table readWithCompletion:^(MSQueryResult *result, NSError *error) {
  40. if(error) { // error is nil if no error occured
  41. NSLog(@"ERROR %@", error);
  42. } else {
  43. for(NSDictionary *item in result.items) { // items is NSArray of records that match query
  44. NSLog(@"Todo Item: %@", [item objectForKey:@"text"]);
  45. }
  46. }
  47. }];
  48. ```
  49. ##<a name="filtering"></a>How to: Filter Returned Data
  50. To filter results, there are many available options.
  51. To filter using a predicate, use an `NSPredicate` and `readWithPredicate`. The following filters returned data to find only incomplete Todo items.
  52. ```
  53. // Create a predicate that finds items where complete is false
  54. NSPredicate * predicate = [NSPredicate predicateWithFormat:@"complete == NO"];
  55. // Query the TodoItem table and update the items property with the results from the service
  56. [table readWithPredicate:predicate completion:^(MSQueryResult *result, NSError *error) {
  57. if(error) {
  58. NSLog(@"ERROR %@", error);
  59. } else {
  60. for(NSDictionary *item in result.items) {
  61. NSLog(@"Todo Item: %@", [item objectForKey:@"text"]);
  62. }
  63. }
  64. }];
  65. ```
  66. ##<a name="query-object"></a>How to: Use MSQuery
  67. To perform a complex query (including sorting and paging), create an `MSQuery` object, directly or by using a predicate:
  68. ```
  69. MSQuery *query = [table query];
  70. MSQuery *query = [table queryWithPredicate: [NSPredicate predicateWithFormat:@"complete == NO"]];
  71. ```
  72. `MSQuery` lets you control several query behaviors, including the following. Execute an `MSQuery` query by calling `readWithCompletion` on it, as shown in the next example.
  73. * Specify order of results
  74. * Limit which fields to return
  75. * Limit how many records to return
  76. * Specify total count in response
  77. * Specify custom query string parameters in request
  78. * Apply additional functions
  79. ## <a name="sorting"></a>How to: Sort Data with MSQuery
  80. To sort results, let's look at an example. To first ascendingly by field `text` and then descendingly by field `completion`, invoke `MSQuery` like so:
  81. ```
  82. [query orderByAscending:@"text"];
  83. [query orderByDescending:@"complete"];
  84. [query readWithCompletion:^(MSQueryResult *result, NSError *error) {
  85. if(error) {
  86. NSLog(@"ERROR %@", error);
  87. } else {
  88. for(NSDictionary *item in result.items) {
  89. NSLog(@"Todo Item: %@", [item objectForKey:@"text"]);
  90. }
  91. }
  92. }];
  93. ```
  94. ## <a name="paging"></a>How to: Return Data in Pages with MSQuery
  95. Mobile Services limits the amount of records that are returned in a single response. To control the number of records displayed to your users you must implement a paging system. Paging is performed by using the following three properties of the **MSQuery** object:
  96. ```
  97. + `BOOL includeTotalCount`
  98. + `NSInteger fetchLimit`
  99. + `NSInteger fetchOffset`
  100. ```
  101. In the following example, a simple function requests 5 records from the server and then appends them to the local collection of previously loaded records:
  102. ```
  103. // Create and initialize these properties
  104. @property (nonatomic, strong) NSMutableArray *loadedItems; // Init via [[NSMutableArray alloc] init]
  105. @property (nonatomic) BOOL moreResults;
  106. ```
  107. ```
  108. -(void)loadResults
  109. {
  110. MSQuery *query = [self.table query];
  111. query.includeTotalCount = YES;
  112. query.fetchLimit = 5;
  113. query.fetchOffset = self.loadedItems.count;
  114. [query readWithCompletion:^(MSQueryResult *result, NSError *error) {
  115. if(!error) {
  116. // Add the items to our local copy
  117. [self.loadedItems addObjectsFromArray:result.items];
  118. // Set a flag to keep track if there are any additional records we need to load
  119. self.moreResults = (self.loadedItems.count <= result.totalCount);
  120. }
  121. }];
  122. }
  123. ```
  124. ## <a name="selecting"></a><a name="parameters"></a>How to: Limit Fields and Expand Query String Parameters with MSQuery
  125. To limit fields to be returned in a query, specify the names of the fields in the **selectFields** property. This returns only the text and completed fields:
  126. ```
  127. query.selectFields = @[@"text", @"completed"];
  128. ```
  129. To include additional query string parameters in the server request (for example, because a custom server-side script uses them), populate `query.parameters` like so:
  130. ```
  131. query.parameters = @{
  132. @"myKey1" : @"value1",
  133. @"myKey2" : @"value2",
  134. };
  135. ```
  136. ##<a name="inserting"></a>How to: Insert Data
  137. To insert a new table row, create a new `NSDictionary` and invoke `table insert`. Mobile Services automatically generates new columns based on the `NSDictionary` if [Dynamic Schema] is not disabled.
  138. If `id` is not provided, the backend automatically generates a new unique ID. Provide your own `id` to use email addresses, usernames, or your own custom values as ID. Providing your own ID may ease joins and business-oriented database logic.
  139. ```
  140. NSDictionary *newItem = @{@"id": @"custom-id", @"text": @"my new item", @"complete" : @NO};
  141. [self.table insert:newItem completion:^(NSDictionary *result, NSError *error) {
  142. // The result contains the new item that was inserted,
  143. // depending on your server scripts it may have additional or modified
  144. // data compared to what was passed to the server.
  145. if(error) {
  146. NSLog(@"ERROR %@", error);
  147. } else {
  148. NSLog(@"Todo Item: %@", [result objectForKey:@"text"]);
  149. }
  150. }];
  151. ```
  152. ##<a name="modifying"></a>How to: Modify Data
  153. To update an existing row, modify an item and call `update`:
  154. ```
  155. NSMutableDictionary *newItem = [oldItem mutableCopy]; // oldItem is NSDictionary
  156. [newItem setValue:@"Updated text" forKey:@"text"];
  157. [self.table update:newItem completion:^(NSDictionary *item, NSError *error) {
  158. // Handle error or perform additional logic as needed
  159. }];
  160. ```
  161. Alternatively, supply the row ID and the updated field:
  162. ```
  163. [self.table update:@{@"id":@"37BBF396-11F0-4B39-85C8-B319C729AF6D", @"Complete":@YES} completion:^(NSDictionary *item, NSError *error) {
  164. // Handle error or perform additional logic as needed
  165. }];
  166. ```
  167. At minimum, the `id` attribute must be set when making updates.
  168. ##<a name="deleting"></a>How to: Delete Data
  169. To delete an item, invoke `delete` with the item:
  170. ```
  171. [self.table delete:item completion:^(id itemId, NSError *error) {
  172. // Handle error or perform additional logic as needed
  173. }];
  174. ```
  175. Alternatively, delete by providing a row ID:
  176. ```
  177. [self.table deleteWithId:@"37BBF396-11F0-4B39-85C8-B319C729AF6D" completion:^(id itemId, NSError *error) {
  178. // Handle error or perform additional logic as needed
  179. }];
  180. ```
  181. At minimum, the `id` attribute must be set when making deletes.
  182. ##<a name="#custom-api"></a>How to: Call a custom API
  183. A custom API enables you to define custom endpoints that expose server functionality that does not map to an insert, update, delete, or read operation. By using a custom API, you can have more control over messaging, including reading and setting HTTP message headers and defining a message body format other than JSON. For an example of how to create a custom API in your mobile service, see [How to: define a custom API endpoint](
  184. [AZURE.INCLUDE [mobile-services-ios-call-custom-api](../../includes/]
  185. ##<a name="authentication"></a>How to: Authenticate Users
  186. Azure Mobile Services supports various identity providers. For a basic tutorial, see [Authentication].
  187. Azure Mobile Services supports two authentication workflows:
  188. - **Server-managed Login**: Azure Mobile Services manages the login process on behalf of your app. It displays a provider-specific login page and authenticates with the chosen provider.
  189. - **Client-managed Login**: The _app_ requests a token from the identity provider and presents this token to Azure Mobile Services for authentication.
  190. When authentication succeeds, you get back a user object with a user ID value and the auth token. To use this user ID to authorize users, see [Service-side Authorization]. To restrict table access to only authenticated users, see [Permissions].
  191. ### Server-managed Login
  192. Here is how you can add server-managed login to the [Mobile Services Quick Start] project; you may use similar code for your other projects. For more information and to see an end-to-end example in action, see [Authentication].
  193. [AZURE.INCLUDE [mobile-services-ios-authenticate-app](../../includes/]
  194. ### Client-managed Login (Single Sign-on)
  195. You may do the login process outside the Mobile Services client, either to enable single sign-on or if your app contacts the identity provider directly. In such cases, you can log in to Mobile Services by providing a token obtained independently from a supported identity provider.
  196. The following example uses the [Live Connect SDK] to enable single sign-on for iOS apps. It assumes that you have a **LiveConnectClient** instance named `liveClient` in the controller and the user is logged in.
  197. ```
  198. [client loginWithProvider:@"microsoftaccount"
  199. token:@{@"authenticationToken" : self.liveClient.session.authenticationToken}
  200. completion:^(MSUser *user, NSError *error) {
  201. // Handle success and errors
  202. }];
  203. ```
  204. ##<a name="caching-tokens"></a>How to: Cache Authentication Tokens
  205. Let's see how you may cache tokens in the [Mobile Services Quick Start] project; you may apply similar steps to any project. [AZURE.INCLUDE [mobile-services-ios-authenticate-app-with-token](../../includes/]
  206. ##<a name="errors"></a>How to: Handle Errors
  207. When you call a mobile service, the completion block contains an `NSError *error` parameter. When an error occurs, this parameter is non-nil. In your code, you should check this parameter and handle the error as needed.
  208. The file [`<WindowsAzureMobileServices/MSError.h>`]( defines the constants `MSErrorResponseKey`, `MSErrorRequestKey`, and `MSErrorServerItemKey` to get more data related to the error. In addition, the file defines constants for each error code. For an example on how to use these constants, see [Conflict-Handler] for its usage of `MSErrorServerItemKey` and `MSErrorPreconditionFailed`.
  209. <!-- Anchors. -->
  210. [What is Mobile Services]: #what-is
  211. [Concepts]: #concepts
  212. [Setup and Prerequisites]: #Setup
  213. [How to: Create the Mobile Services client]: #create-client
  214. [How to: Create a table reference]: #table-reference
  215. [How to: Query data from a mobile service]: #querying
  216. [Filter returned data]: #filtering
  217. [Sort returned data]: #sorting
  218. [Return data in pages]: #paging
  219. [Select specific columns]: #selecting
  220. [How to: Bind data to the user interface]: #binding
  221. [How to: Insert data into a mobile service]: #inserting
  222. [How to: Modify data in a mobile service]: #modifying
  223. [How to: Authenticate users]: #authentication
  224. [Cache authentication tokens]: #caching-tokens
  225. [How to: Upload images and large files]: #blobs
  226. [How to: Handle errors]: #errors
  227. [How to: Design unit tests]: #unit-testing
  228. [How to: Customize the client]: #customizing
  229. [Customize request headers]: #custom-headers
  230. [Customize data type serialization]: #custom-serialization
  231. [Next Steps]: #next-steps
  232. [How to: Use MSQuery]: #query-object
  233. <!-- Images. -->
  234. <!-- URLs. -->
  235. [Mobile Services Quick Start]:
  236. [Get started with Mobile Services]:
  237. [Mobile Services SDK]:
  238. [Authentication]: /develop/mobile/tutorials/get-started-with-users-ios
  239. [iOS SDK]:
  240. [Handling Expired Tokens]:
  241. [Live Connect SDK]:
  242. [Permissions]:
  243. [Service-side Authorization]:
  244. [Dynamic Schema]:
  245. [Create a table]:
  246. [NSDictionary object]:
  247. [ASCII control codes C0 and C1]:
  248. [CLI to manage Mobile Services tables]: ../
  249. [Conflict-Handler]: