当前位置: 首页 > 工具软件 > siesta > 使用案例 >

siesta swift_让我向您介绍我最喜欢的图书馆Siesta的Swift联网。

唐元凯
2023-12-01

siesta swift

by Nikolay Derkach

通过尼古拉·德卡赫(Nikolay Derkach)

让我向您介绍我最喜欢的图书馆Siesta的Swift联网。 (Let me introduce you to Swift networking with Siesta — my new favorite library.)

Today I’d like to tell you about my new favorite iOS networking library called Siesta. “What’s so great about it, and why can’t I just use Alamofire?” you might ask. Actually, you can use Alamofire with Siesta! Because it’s a networking abstraction layer above HTTP clients.

今天,我想向您介绍我最喜欢的iOS网络库Siesta 。 “这有什么好处,为什么我不能只使用Alamofire?” 你可能会问。 实际上,您可以将Alamofire与Siesta一起使用! 因为它是HTTP客户端之上的网络抽象层。

But unlike libraries like Moya, this one doesn’t hide HTTP from you. This gives you a great middle ground, and that’s exactly how I like to consume my REST APIs.

但是与Moya之类的库不同,该库不会向您隐藏HTTP。 这为您提供了一个很好的中间立场,而这正是我喜欢使用我的REST API的方式。

By adopting a resource-centric approach, rather than a request-centric one, Siesta provides an app-wide observable model of a RESTful resource’s state.

通过采用以资源为中心的方法,而不是以请求为中心的方法,Siesta提供了RESTful资源状态的整个应用程序可观察模型

What does this mean? It means avoiding unnecessary network requests and redundant response deserialization. It decouples view controllers from network request lifecycles. It provides transparent response parsing out of the box. And much more.

这是什么意思? 这意味着避免不必要的网络请求和冗余响应反序列化。 它使视图控制器与网络请求生命周期脱钩。 它提供了开箱即用的透明响应解析。 以及更多。

In this tutorial, I’d like to show you how to get started with this awesomeness and make your networking great again, swiftly ?

在本教程中,我想向您展示如何开始使用这种出色功能,并Swift使您的网络恢复正常?

建立 (Setup)

Install it from Cocoapods:

从Cocoapods安装:

pod 'Siesta', '~> 1.0'

For the purposes of this tutorial, I built a simple CRUD app with a REST API and JWT-based authentication which I deployed to Heroku.

出于本教程的目的,我使用REST API和基于JWT的身份验证构建了一个简单的CRUD应用程序 ,并将其部署到Heroku

To get started, create a separate class for your API. Let’s call it AwesomeAPI.swift

首先,为您的API创建一个单独的类。 我们称它为AwesomeAPI.swift

Let’s define a basic API configuration here:

让我们在这里定义基本的API配置:

Here we define a global singleton for our API. We configure the service with the URL for our API and standardTransformers which are default parsers for text and image responses. We also enable logging in debug mode, which is very useful for debugging requests against your API. Finally, we define our first resource accessor, a public method of our API class returning a resource which we are now going to use in our view controller.

在这里,我们为API定义了一个全局单例。 我们使用API​​和standardTransformers的URL配置服务,这是用于文本和图像响应的默认解析器。 我们还启用了调试模式下的日志记录功能,这对于根据您的API调试请求非常有用。 最后,我们定义我们的第一个资源访问器,这是我们的API类的公共方法,返回的资源现在将在视图控制器中使用。

To fetch the data from our newly defined resource we need to create a resource observer in our view controller:

为了从新定义的资源中获取数据,我们需要在视图控制器中创建一个资源观察器:

Here we add a resource observer to our ping resource, and define a delegate method which is called when the resource’s state is changed. A state could change when an observer is added or when it has some new data, for example.

在这里,我们将资源观察器添加到ping资源中,并定义一个委托方法,当资源状态更改时将调用该方法。 例如,当添加观察者或拥有一些新数据时,状态可能会改变。

Because Siesta allows you to decouple request configuration from request initialization, you can request a resource without worrying about nitty-gritty details of how it would be requested.

由于Siesta允许您将请求配置与请求初始化脱钩,因此您可以请求资源而不必担心如何请求资源的细节。

For example, you don’t need to worry loadIfNeeded too often, since Siesta allows you to avoid redundant requests. The default expiration time for a resource is 30 seconds and is configurable.

例如,您不必担心loadIfNeeded ,因为Siesta允许您避免冗余请求。 资源的默认到期时间是30秒,并且是可配置的。

Now, if you run your app, you should hopefully see something like this:

现在,如果您运行您的应用程序,则希望看到以下内容:

Siesta:network        │ GET https://jwt-api-siesta.herokuapp.com/ping
Siesta:network        │ Response:  200 ← GET https://jwt-api-siesta.herokuapp.com/ping
pong

变形金刚 (Transformers)

Let’s do something more fun. Let’s define some transformers which would automatically decode out raw JSON response into a data model.

让我们做些更有趣的事情。 让我们定义一些转换器 ,这些转换器将自动将原始JSON响应解码为数据模型。

In our API we have an endpoint /status which returns

在我们的API中,我们有一个端点/status ,它返回

{  "text": "ok"}

To decode JSON on the backend, we are going to use JSONDecoder, a recent addition to Swift 4.

为了在后端解码JSON,我们将使用JSONDecoder ,这是Swift 4的最新功能。

First, we are going to add a transformer like this:

首先,我们将添加一个这样的转换器:

[String: String] means that we expect a string-to-string mapping dictionary in our JSON response.

[String: String]表示我们希望在JSON响应中使用字符串到字符串的映射字典。

Then, we need to update our view controller with resource observer.

然后,我们需要使用资源观察器更新视图控制器。

As you noticed here, to decode the JSON we are using typedContent() when unwrapping the optional. In this case, we need to explicitely provide a data type ([String: String]) otherwise the data type cannot be inferred. Likewise, we can rewrite the previous resource observer for /ping endpoint like this:

正如您在此处注意到的那样,在typedContent()可选参数时,我们使用typedContent()来解码JSON。 在这种情况下,我们需要明确提供数据类型( [String: String] ),否则无法推断该数据类型。 同样,我们可以这样重写/ping端点的先前资源观察器:

认证方式 (Authentication)

In our API we have a couple of authenticated endpoints: /incomes and /expenses. To access them, we’d need to obtain a JWT token first. Let’s define a method to authenticate requests. This time, instead of creating a function that returns a Resource, we are going to make one returning a Request. This would be a way to handle everything besides GET requests on your API.

在我们的API中,我们有几个经过身份验证的端点: /incomes/expenses 。 要访问它们,我们需要首先获取JWT令牌。 让我们定义一个验证请求的方法。 这次,我们将创建一个返回Request.的函数,而不是创建一个返回Resource的函数Request. 这将是一种处理API上除GET请求之外的所有内容的方法。

First, we are going to add a class property, which would store the JWT authentication token:

首先,我们将添加一个类属性,该属性将存储JWT身份验证令牌:

Every time this property is set, we want to invalidate our service configuration so that the next time a resouce is fetched, request headers would be refreshed. This is necessary because you’ll likely send your authentication token either in a cookie or in Authorization header.

每次设置此属性时,我们都要使服务配置无效,以便下次提取资源时,将刷新请求标头。 这是必要的,因为您可能会在Cookie或Authorization标头中发送身份验证令牌。

Also consider storing your authentication token in the Keychain, rather than in NSUserDefaults or other insecure storage. We are using JWTDecode library here to decode a JWT token and obtain its expiration date.

还可以考虑将身份验证令牌存储在钥匙串中,而不是存储在NSUserDefaults或其他不安全的存储中。 我们在这里使用JWTDecode库来解码JWT令牌并获取其到期日期。

After that, we also want to automatically refresh the token once it expires. In a more sophisticated implementation of JWT we’d get a refresh token alongside, which we’d later use to refresh our authentication token. In our case, we have a simple JWT implementation, and we are just going to send the login response again.

之后,我们还希望令牌过期后自动刷新。 在JWT的更复杂的实现中,我们将获得一个刷新令牌 ,稍后我们将使用它来刷新我们的身份验证令牌。 在我们的例子中,我们有一个简单的JWT实现,我们将再次发送登录响应。

Here is how you can implement the login request in your AwesomeAPI class to obtain an authentication token:

这是在AwesomeAPI类中实现登录请求以获取身份验证令牌的方法:

Here we send a POST to /login with user credentials in a JSON payload. We also define two closures: onSuccess and OnFailure and we store an authentication token on a successful authentication.

在这里,我们使用JSON负载中的用户凭据将POST发送到/login 。 我们还定义了两个闭包: onSuccessOnFailure并且在成功进行身份验证时存储身份验证令牌。

Finally, we want to automatically update our authentication token before it expires. We can use a single-shot timer for that:

最后,我们希望在认证令牌过期之前自动对其进行更新。 我们可以为此使用单次计时器:

Yes, the actual login credentials for our test API are test and test. You can easily integrate the AwesomeAPI.login() call in your login flow by obtaining credentials from a view controller responsible for the login. To successfully decode the response from the login request, you need to define a transformer for it as well:

是的,我们测试API的实际登录凭据为test and test。 通过从负责登录的视图控制器获取凭据,可以轻松地将AwesomeAPI.login()调用集成到登录流中。 为了成功解码来自登录请求的响应,您还需要为其定义一个转换器:

The API requires us to pass the JWT token in the Authorization header. In order to do that, we can add the following to our service configuration (init() ):

该API要求我们在Authorization标头中传递JWT令牌。 为此,我们可以将以下内容添加到我们的服务配置( init() )中:

Now that we have our request authenticated, let’s try to make some requests to authenticated resources, like /expenses. This endpoint returns a list of the following dictionaries:

现在,我们的请求已经过身份验证,让我们尝试对已身份验证的资源(例如/expenses.发出一些请求/expenses. 该端点返回以下字典的列表:

{    "amount": -50.0,    "created_at": "2017-12-07T16:00:52.988245",    "description": "pizza",    "type": "TransactionType.EXPENSE"}

Our goal is to create a model to store the response of this format. Let’s create a class called Expense. As we are using JSONDecoder here, we just need to inherit our class from Codable:

我们的目标是创建一个模型来存储这种格式的响应。 让我们创建一个称为Expense的类 当我们在这里使用JSONDecoder时 ,我们只需要从Codable继承我们的类

The CodingKeys enum allows us to map field names in our JSON response to the struct’s property names. Note that we are also decoding dates here (createdAt). Since our date has a custom format, we need to configure that via JSONDecoder’s dateDecodingStrategy:

CodingKeys枚举允许我们将JSON响应中的字段名称映射到该结构的属性名称。 请注意,我们也在此处解码日期( createdAt )。 由于我们的日期具有自定义格式,因此我们需要通过JSONDecoderdateDecodingStrategy进行配置:

Finally, let’s create a transformer for this class:

最后,让我们为此类创建一个转换器:

We are using [Expense] here as we are expecting an array of Expense objects.

我们在这里使用[Expense] ,因为我们期望有一个Expense对象数组。

After defining an expenses() resource accessor the same way as we did previously, we can fetch our authenticated resource like this:

在按照与前面相同的方式定义了expenses()资源访问器之后,我们可以像这样获取经过身份验证的资源:

最后一件事… (One last thing…)

One last thing I want to show you is what to do when your authentication token expires. What we could do with Siesta, for example, is automatically authenticate and retry a failed request.

我想向您展示的最后一件事是身份验证令牌过期时该怎么办。 例如,我们可以使用Siesta进行自动身份验证,然后重试失败的请求。

First, we need to add the following to our configuration:

首先,我们需要在配置中添加以下内容:

Then we chain our request and repeat it with a new token!

然后,我们将请求链接起来,并用新令牌重复它!

If you want to check out the final project, it’s available on Github.

如果您想查看最终项目,可以在Github上找到它。

Happy hacking!

骇客入侵!

翻译自: https://www.freecodecamp.org/news/swift-networking-with-siesta-5b5e7089bd8f/

siesta swift

 类似资料: