-
Notifications
You must be signed in to change notification settings - Fork 749
Expand file tree
/
Copy pathGraphQLFile.swift
More file actions
93 lines (84 loc) · 3.53 KB
/
GraphQLFile.swift
File metadata and controls
93 lines (84 loc) · 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import Foundation
/// A file which can be uploaded to a GraphQL server
public struct GraphQLFile {
public let fieldName: String
public let originalName: String
public let mimeType: String
public let data: Data?
public let fileURL: URL?
public let contentLength: UInt64
public enum GraphQLFileError: Error, LocalizedError {
case couldNotCreateInputStream
case couldNotGetFileSize(fileURL: URL)
public var errorDescription: String? {
switch self {
case .couldNotCreateInputStream:
return "An input stream could not be created from either the passed-in file URL or data. Please check that you've passed at least one of these, and that for files you have proper permission to stream data."
case .couldNotGetFileSize(let fileURL):
return "Apollo could not get the file size for the file at \(fileURL). This likely indicates either a) The file is not at that URL or b) a permissions issue."
}
}
}
/// A convenience constant for declaring your mimetype is octet-stream.
public static let octetStreamMimeType = "application/octet-stream"
/// Convenience initializer for raw data
///
/// - Parameters:
/// - fieldName: The name of the field this file is being sent for
/// - originalName: The original name of the file
/// - mimeType: The mime type of the file to send to the server. Defaults to `GraphQLFile.octetStreamMimeType`.
/// - data: The raw data to send for the file.
public init(fieldName: String,
originalName: String,
mimeType: String = GraphQLFile.octetStreamMimeType,
data: Data) {
self.fieldName = fieldName
self.originalName = originalName
self.mimeType = mimeType
self.data = data
self.fileURL = nil
self.contentLength = UInt64(data.count)
}
/// Throwing convenience initializer for files in the filesystem
///
/// - Parameters:
/// - fieldName: The name of the field this file is being sent for
/// - originalName: The original name of the file
/// - mimeType: The mime type of the file to send to the server. Defaults to `GraphQLFile.octetStreamMimeType`.
/// - fileURL: The URL of the file to upload.
/// - Throws: If the file's size could not be determined
public init(fieldName: String,
originalName: String,
mimeType: String = GraphQLFile.octetStreamMimeType,
fileURL: URL) throws {
self.contentLength = try GraphQLFile.getFileSize(fileURL: fileURL)
self.fieldName = fieldName
self.originalName = originalName
self.mimeType = mimeType
self.data = nil
self.fileURL = fileURL
}
/// Uses either the data or the file URL to create an
/// `InputStream` that can be used to stream data into
/// a multipart-form.
///
/// - Returns: The created `InputStream`.
/// - Throws: If an input stream could not be created from either data or a file URL.
public func generateInputStream() throws -> InputStream {
if let data = data {
return InputStream(data: data)
} else if let fileURL = fileURL,
let inputStream = InputStream(url: fileURL) {
return inputStream
} else {
throw GraphQLFileError.couldNotCreateInputStream
}
}
private static func getFileSize(fileURL: URL) throws -> UInt64 {
guard let fileSizeAttribute = try? FileManager.default.attributesOfItem(atPath: fileURL.path)[.size],
let fileSize = fileSizeAttribute as? NSNumber else {
throw GraphQLFileError.couldNotGetFileSize(fileURL: fileURL)
}
return fileSize.uint64Value
}
}