文件上传
在 iOS 的 Apollo 客户端启用文件上传
Apollo iOS 支持通过 GraphQL 多部分请求规范 执行,但有一些限制:
- 使用 GraphQL 上传文件通常适用于原型设计应用。在生产环境中,使用专用的文件上传工具可能更可取。有关多种方法的优缺点,请参考此 博客文章。
- 无论是 ApolloRouter Core 还是 GraphOS Router 都不支持
multipart/form-data
上传。
使用 Apollo iOS 上传文件
Apollo iOS 只支持单个 操作 的上传,而不是批量操作。如果你的服务器支持,你也可以通过单个操作上传多个文件。
要上传文件,你需要
- 一个支持
UploadingNetworkTransport
协议的NetworkTransport
。如果你的 ApolloClient 实例正在使用RequestChainNetworkTransport
(默认设置),则该协议已经得到支持。 - 上传数据的正确
MIME
类型。默认值是application/octet-stream
。 - 所需数据的或文件 URL。
- 这是一个接受
Upload
作为参数的mutation方法。注意,这必须得到您的服务器支持。
以下为一个示例查询,用于执行接受单个上传并返回该上传id
的mutation操作
mutation UploadFile($file:Upload!) {singleUpload(file:$file) {id}}
如果您想使用这个方法上传名为a.txt
的文件,它的样子大概是这样的:
// Create the file to uploadguard let fileURL = Bundle.main.url(forResource: "a", withExtension: "txt"),let file = GraphQLFile(fieldName: "file", // Must be the name of the field the file is being uploaded tooriginalName: "a.txt",mimeType: "text/plain", // <-defaults to "application/octet-stream"fileURL: fileURL) else {// Either the file URL couldn't be created or the file couldn't be created.return}// Actually upload the fileclient.upload(operation: UploadFileMutation(file: "a"), // <-- `Upload` is a custom scalar that's a `String` under the hood.files: [file]) { result inswitch result {case .success(let graphQLResult):print("ID: \(graphQLResult.data?.singleUpload.id)")case .failure(let error):print("error: \(error)")}}
其他注意事项:
由于规范的限制,添加的文件应该位于您的GraphQL查询的根目录。因此,如果您有以下结构:
mutation AvatarUpload($userID: GraphQLID!, $file: Upload!) {id}它将正常工作,但如果您有包含以下字段的对象:
# Assumes AvatarObject(userID: GraphQLID, file: Upload) existsmutation AvatarUpload($avatarObject: AvatarObject!) {id}则无法工作。通常,您应该能够解构上传对象,以便能够发送适当的fields。
如果您正在上传文件数组,您需要为每个文件使用相同的字段名称。这些将在发送时更新。
如果您正在上传文件数组,传入查询的
String
数组必须与文件数组的数量相同。