In my last blog post, I discussed how to create a backend that supports image transfers using Base64 encoding, as well as the front-end code for the iOS client. In this article, I’ll be documenting an alternative (and arguably, better) approach to handling RESTful image transfer.
在我的上一篇博文中 ,我讨论了如何创建一个使用Base64编码支持图像传输的后端,以及iOS客户端的前端代码。 在本文中,我将记录处理RESTful图像传输的另一种方法(可能是更好的方法)。
Base64 encoding images was traditionally used in websites as an alternative to static file loading, helping to save an additional HTTP call to retrieve an image. In REST-land, sending base64 through API requests is useful if you want to adopt a purely JSON-driven API. That being said, encoding images in base64 format increases the size by ~33%, making it an inefficient method to transmit images between client and server.
传统上,在网站中使用Base64编码图像来替代静态文件加载,从而有助于节省额外的HTTP调用来检索图像。 在REST领域中,如果要采用纯JSON驱动的API,则通过API请求发送base64很有用。 也就是说,以base64格式编码图像会使大小增加约33%,这使其成为在客户端和服务器之间传输图像的低效方法。
So, what’s the better alternative?
那么,还有什么更好的选择?
1多部分表格数据 (1 Multipart Form Data)
Multipart form data as part of a POST request is exactly what it sounds like — it is the standard method by which clients transmit form-based data to the server. It’s suitable for our purpose as this method of data transmission supports file uploads.
听起来像是POST请求一部分的多部分表单数据-这是客户端将基于表单的数据传输到服务器的标准方法。 它适合我们的目的,因为这种数据传输方法支持文件上传。
Sending images through a multipart form is sufficient if we’re uploading one image at a time (or at most, a few images). For videos and batched image uploads, it would be more feasible to use some sort of streaming upload.
如果我们一次上传一幅图像(或最多几幅图像),则通过多部分形式发送图像就足够了。 对于视频和批量图像上传,使用某种流媒体上传会更加可行。
2基本的Python REST服务器 (2 Basic Python REST Server)
As in my last blog post, a basic backend server can be created in Python with flask together with flask-restful. With flask-restful, endpoints are defined as Python classes. Again, we create a post
function to indicate that this endpoint supports HTTP POST operations.
就像我在上一篇博客文章中一样,可以使用Python与flask和flask-restful一起创建基本的后端服务器。 在烧瓶稳定的情况下,端点被定义为Python类。 同样,我们创建一个post
函数来指示该端点支持HTTP POST操作。
In our RequestParser
, we used to define the following expected argument: parser.add_argument("image", type=str, location='json')
. Now, we're sending data over a form upload, so we change the expected argument to: parser.add_argument("image", type=werkzeug.datastructures.FileStorage, location='files')
在我们的RequestParser
,我们用来定义以下预期参数: parser.add_argument("image", type=str, location='json')
。 现在,我们通过表单上载发送数据,因此我们将预期参数更改为: parser.add_argument("image", type=werkzeug.datastructures.FileStorage, location='files')
This is not too different at all from the base64 case. By implementing image transfer this way, we save a lot of bandwidth in the long run. We also reduce the time spent in transit — translating to shorter wait times for the end user.
这与base64情况完全没有太大不同。 通过这种方式实现图像传输,从长远来看,我们可以节省大量带宽。 我们还减少了运输时间,从而缩短了最终用户的等待时间。
3使用Swift发送图像(iOS) (3 Sending Images with Swift (iOS))
As in the last blog post, recall that when you take an image using the Swift AVFoundation library, you get an output of type AVCapturePhoto
. We can easily retrieve a data representation of the photo using .fileDataRepresentation()
.
就像在上一篇博客文章中一样,回想一下,当您使用Swift AVFoundation库拍摄图像时,将获得AVCapturePhoto
类型的输出。 我们可以使用.fileDataRepresentation()
轻松检索照片的数据表示。
Again, we leverage the Alamofire framework, which easily facilitates multipart form POST requests. We can then create a service with a makeRequest
function:
同样,我们利用Alamofire框架,该框架可轻松实现多部分形式的POST请求。 然后,我们可以使用makeRequest
函数创建服务:
If you have other arguments you would like to send, you can either attach them to the request as headers, add it to the URL as a parameter, or just add an additional entry to formData
.
如果您要发送其他参数,则可以将它们作为标头附加到请求,可以将其作为参数添加到URL,也可以仅向formData
添加其他条目。