# 2. Reading / Writing Data

## PDA Data I/O

A PDA is a data store. That means you can read and write any data you want, be it a passport, your health records or any data you can think of.

`HAT for iOS` has built-in support for reading or writing data to your `PDA.`

This section describes the mechanism of **writing** data. Make sure to read all the way to [data-debits](/build/dataswyft-one-apis/data-api/data-debits.md) for details about **reading** data and our system of consented data exchange.

### Make network requests

`Hat for iOS` offers a general method to create network requests:

```swift
HATNetworkManager.asynchronousRequest(
  url,
  method: .post,
  encoding: Alamofire.JSONEncoding.default,
  contentType: "text/string",
  parameters: ["key": value],
  headers: ["key": value],
  completion: completionCallback)
```

* `url` is the URL to send the request to
* `method` is the HTTP method of the request, you can find the different methods [here](https://restfulapi.net/http-methods/)
* `encoding` is the encoding method of the request, default types of `Alamofire`
* `contentType` is the content-type of the request, you can find more [here](https://www.w3.org/Protocols/rfc1341/4_Content-Type.html)
* `parameters` is the parameters of the request, this field can be an empty dictionary, `[:]`. Also, if the request method is `POST`, then this will be the body of the request and the actual data structure that will be saved on the `PDA`.
* `headers` is the additional headers of the request, this field can be an empty dictionary, `[:]`
* `completion` is a callback function to execute when the request has finished. The *result type* of the callback can either be

  `isSuccess(isSuccess: Bool, statusCode: Int?, result: JSON, token: String?)` if the request was successful or `error(error: Error, statusCode: Int?, result: JSON?)`if the request has failed.

The result type is an `enum`. Depending on whether the request was a success or a failure it will have the right type. When the request is successful the result type will include:

* A boolean value `isSuccess`, indicating if the request was successful. It may be that the request triggers the successful result type but the isSuccess is false; for example the response was 404.
* The `statusCode` of the request. Usually the `200..299` range is a success and `400..599` is failure. You can learn more about the different status codes [here](https://httpstatuses.com).
* The `result` is `JSON` type of `SwiftyJSON`, can be found [here](https://github.com/SwiftyJSON/SwiftyJSON).
* The `token` is a refreshed token returned from the `PDA`. It's ***optional*** and sometimes can be nil or empty.

When the request has failed the result type will include:

* The `error` that has occurred with the request, e.g. no internet connection or time out.
* The `statusCode` of the request. Usually the `200..299` range is a success and `400..599` is failure. You can learn more about the different status codes [here](https://httpstatuses.com).
* The `result` is `JSON` type of `SwiftyJSON`, and can be found [here](https://github.com/SwiftyJSON/SwiftyJSON). Usually it will hold more info about the failure.

## Write data

Let's say we want to save the `randomStructure` below in our `PDA`:

```javascript
{
  "value 1": "random",
  "Int value": 0
}
```

The `URL` in which the data will be saved is `https://\(hatAddress)/api/v2.6/data/\(path)`

If the `hatAddress` is `postman.hubat.net` and the `path` is `randomdata` then the `URL` will be: `https://postman.hubat.net/api/v2.6/data/dataswift-sandbox/randomdata`.

The `path` is formed by your app name, `dataswift-sandbox`, and the rest of the path, `randomdata`. It can also be `folder/something/data/random`. How deep the path will be, depends on the data structure that your app uses to navigate to different files.

In order to write data to the `PDA` we also need the user's token in the headers of the request. The header you need to add is `x-auth-token` along with the token retrieved from the `Keychain`. **NEVER** save the token in an unencrypted database.

Using the function from `Hat-for-iOS` that will be:

```swift
HATNetworkManager.asynchronousRequest(
  "https://postman.hubat.net/api/v2.6/data/dataswift-sandbox/randomdata",
  method: .post,
  encoding: Alamofire.JSONEncoding.default,
  contentType: "application/json",
  parameters: randomStructure,
  headers: ["x-auth-token": token],
  completion: completionCallback)
```

Based on the type of the `completionCallback` you might have gotten the data back or you might get an error. Your app should know how to react in both scenarios:

```swift
switch response {

case .error(let error, let statusCode, let result):

    // do something....
case .isSuccess(let isSuccess, let statusCode, let result, let token):

    // do something....
}
```

A successful response will have `statusCode` 201 and look like this:

```javascript
{
    "endpoint": "randomdata",
    "recordId": "cf2c4ad5-bbb2-4a0e-8aaa-d3be8b76e115",
    "data": {
      "value 1": "random",
      "Int value": 0
    }
}
```

* `endpoint` is the `path` where the file resides: `https://\(hatAddress)/api/v2.6/data/\(path)`
* `recordId` is the record identifier in the `PDA`. It's useful for when you want to delete the file, for example.
* `data` is the data structure that you have saved in the `PDA`

A request that has failed will look like this:

```javascript
{
  "error": "Not Authenticated",
  "message": "Not Authenticated"
}
```

* `error` is the error that has occurred
* `message` is a more descriptive message about the `error` that has occurred

## Read data

If we want to read data, we will use the same request again but the `method` will be `GET` instead of `POST`:

```swift
HATNetworkManager.asynchronousRequest(
  url,
  method: .get,
  encoding: Alamofire.JSONEncoding.default,
  contentType: "text/string",
  parameters: ["key": value],
  headers: ["key": value],
  completion: completionCallback)
```

Making the same assumptions again, the `hatAddress` is `postman.hubat.net`, the `path` is `randomdata`, and the `x-auth-token` in the headers includes the token. Then the call will look like below:

```swift
HATNetworkManager.asynchronousRequest(
  "https://postman.hubat.net/api/v2.6/data/dataswift-sandbox/randomdata",
  method: .get,
  encoding: Alamofire.JSONEncoding.default,
  contentType: "application/json",
  parameters: [:],
  headers: ["x-auth-token": token],
  completion: completionCallback)
```

Notice that since we want to read data and not write, we don't include any parameters.

Based on the type of the `completionCallback` you might have gotten the data back or you might have gotten an error. Your app should know how to react in both scenarios:

```swift
switch response {

case .error(let error, let statusCode, let result):

    // do something....
case .isSuccess(let isSuccess, let statusCode, let result, let token):

    // do something....
}
```

A successful response will have `statusCode` 200 and look like this:

```javascript
{
    "endpoint": "randomdata",
    "recordId": "cf2c4ad5-bbb2-4a0e-8aaa-d3be8b76e115",
    "data": {
      "value 1": "random",
      "Int value": 0
    }
}
```

* `endpoint` is the `path` where the file resides, `https://\(hatAddress)/api/v2.6/data/\(path)`
* `recordId` is the record identifier in the`PDA`. It's useful for when you want to delete the file, for example.
* `data` is the data structure that you have saved in the`PDA`

A request that has failed will look like this:

```javascript
{
  "error": "Not Authenticated",
  "message": "Not Authenticated"
}
```

* `error` is the error that has occurred
* `message` is a more descriptive message about the `error` that has occurred

## Update data

Let's say that we want to change our original example:

```javascript
{
  "value 1": "random",
  "Int value": 0
}
```

To something like this:

```javascript
{
  "value 1": "random",
  "newValue": true,
  "Int value": 1
}
```

In order to update the data, the HTTP `method` has to change to `PUT`:

```swift
HATNetworkManager.asynchronousRequest(
  url,
  method: .put,
  encoding: Alamofire.JSONEncoding.default,
  contentType: "text/string",
  parameters: ["key": value],
  headers: ["key": value],
  completion: completionCallback)
```

If we make the same assumptions again, the `hatAddress` is `postman.hubat.net` and request and the `x-auth-token` in the headers includes the token. Then the call will look like below:

```swift
HATNetworkManager.asynchronousRequest(
  "https://postman.hubat.net/api/v2.6/data",
  method: .put,
  encoding: Alamofire.JSONEncoding.default,
  contentType: "application/json",
  parameters: parameters,
  headers: ["x-auth-token": token],
  completion: completionCallback)
```

Where `parameters` is an array of `Key-value pair` of type `[String: Any]` represent the new structure that we want to update. Mind the brackets, it has to be an array even if it's just one element.

Based on the type of the `completionCallback` you might have gotten the data back or you might get an error. Your app should know how to react in both scenarios:

```swift
switch response {

case .error(let error, let statusCode, let result):

    // do something....
case .isSuccess(let isSuccess, let statusCode, let result, let token):

    // do something....
}
```

A successful response will have `statusCode` 201 and look like this:

```javascript
{
    "endpoint": "randomdata",
    "recordId": "cf2c4ad5-bbb2-4a0e-8aaa-d3be8b76e115",
    "data": {
      "value 1": "random",
      "newValue": true,
      "Int value": 1
    }
}
```

* `endpoint` is the `path` where the file resides, `https://\(hatAddress)/api/v2.6/data/\(path)`
* `recordId` is the record identifier in the `PDA`. It's useful for when you want to delete the file for example.
* `data` is the data structure that you have saved in the `PDA`.

A request that has failed will look like this:

```javascript
{
  "error": "Not Authenticated",
  "message": "Not Authenticated"
}
```

* `error` is the error that has occurred
* `message` is a more descriptive message about the `error` that has occurred

## Delete data

If we now want to delete the file we have just created we need to create a `DELETE` request:

```swift
HATNetworkManager.asynchronousRequest(
  url,
  method: .delete,
  encoding: Alamofire.JSONEncoding.default,
  contentType: "text/string",
  parameters: ["key": value],
  headers: ["key": value],
  completion: completionCallback)
```

If we make the same assumptions again, the `hatAddress` is `postman.hubat.net` and request and the `x-auth-token` in the headers includes the token. Then the call will look like below:

```swift
HATNetworkManager.asynchronousRequest(
  "https://postman.hubat.net/api/v2.6/data",
  method: .delete,
  encoding: Alamofire.JSONEncoding.default,
  contentType: "application/json",
  parameters: parameters,
  headers: ["x-auth-token": token],
  completion: completionCallback)
```

Where `parameters` in this case is the `recordId` of the entry we want to delete. We can also delete multiple entries with one request using more parameters. If the `recordId` is 5 then the `parameters` will be:

```javascript
{
  "records": 5
}
```

A successful response will have `statusCode` 200 and look like this:

```javascript
{
    "message": "All records deleted"
}
```

A request that has failed will look like this:

```javascript
{
  "error": "Not Authenticated",
  "message": "Not Authenticated"
}
```

* `error` is the error that has occurred
* `message` is a more descriptive message about the `error` that has occurred


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.dataswyft.com/build/advanced-topics/pda-authentication/password-management/tutorials/ios-swift/2.-reading-writing-data.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
