Skip to content

Commit 591ee0e

Browse files
authored
Merge pull request #80 from tombaileywzd/swift-development
Add support for Upload-Metadata
2 parents 19a1539 + c4c5182 commit 591ee0e

File tree

5 files changed

+41
-23
lines changed

5 files changed

+41
-23
lines changed

Example/TUSKit/ViewController.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class ViewController: UIViewController, TUSDelegate, UIImagePickerControllerDele
5959
//When you have a file, create an upload, and give it a Id.
6060
var fileData = try! Data(contentsOf: file)
6161
let upload: TUSUpload = TUSUpload(withId: String(number), andData: fileData, andFileType: "jpeg")
62+
upload.metadata = ["hello": "world"]
6263
//Create or resume upload
6364
TUSClient.shared.createOrResume(forUpload: upload, withCustomHeaders: ["Header": "Value"])
6465
}

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ var uploadObject = TUSUpload(withId: "Another Id to reference a file", andData:
6969
//An existing upload
7070
var uploadObject = TUSUpload(withId: "Just an ID of a past upload") //Will fail out if data on the device matching the ID isn't found.
7171

72+
//An upload with metadata
73+
var uploadObject = TUSUpload(withId: "Some Id to reference a file", andFile: "FilePathHere")
74+
uploadObject.metadata = ["hello": "world"]
75+
7276
```
7377

7478
## TUSClient

TUSKit/Classes/TUSClient.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,25 +79,25 @@ public class TUSClient: NSObject, URLSessionTaskDelegate {
7979
/// - upload: the upload object
8080
/// - retries: number of retires to take if a call fails
8181
public func createOrResume(forUpload upload: TUSUpload, withRetries retries: Int) {
82-
let fileName = String(format: "%@%@", upload.id!, upload.fileType!)
82+
let fileName = String(format: "%@%@", upload.id, upload.fileType!)
8383
let tusName = String(format: "TUS-%@", fileName)
8484

8585

8686
if (fileManager.fileExists(withName: fileName) == false) {
87-
logger.log(forLevel: .Info, withMessage:String(format: "File not found in local storage.", upload.id!))
87+
logger.log(forLevel: .Info, withMessage:String(format: "File not found in local storage.", upload.id))
8888
upload.status = .new
8989
currentUploads?.append(upload)
9090
if (upload.filePath != nil) {
9191
if fileManager.moveFile(atLocation: upload.filePath!, withFileName: fileName) == false{
9292
//fail out
93-
logger.log(forLevel: .Error, withMessage:String(format: "Failed to move file.", upload.id!))
93+
logger.log(forLevel: .Error, withMessage:String(format: "Failed to move file.", upload.id))
9494

9595
return
9696
}
9797
} else if(upload.data != nil) {
9898
if fileManager.writeData(withData: upload.data!, andFileName: fileName) == false {
9999
//fail out
100-
logger.log(forLevel: .Error, withMessage:String(format: "Failed to create file in local storage from data.", upload.id!))
100+
logger.log(forLevel: .Error, withMessage:String(format: "Failed to create file in local storage from data.", upload.id))
101101

102102
return
103103
}
@@ -110,11 +110,11 @@ public class TUSClient: NSObject, URLSessionTaskDelegate {
110110

111111
switch upload.status {
112112
case .paused, .created:
113-
logger.log(forLevel: .Info, withMessage:String(format: "File %@ has been previously been created", upload.id!))
113+
logger.log(forLevel: .Info, withMessage:String(format: "File %@ has been previously been created", upload.id))
114114
executor.upload(forUpload: upload)
115115
break
116116
case .new:
117-
logger.log(forLevel: .Info, withMessage:String(format: "Creating file %@ on server", upload.id!))
117+
logger.log(forLevel: .Info, withMessage:String(format: "Creating file %@ on server", upload.id))
118118
upload.contentLength = "0"
119119
upload.uploadOffset = "0"
120120
upload.uploadLength = String(fileManager.sizeForLocalFilePath(filePath: String(format: "%@%@", fileManager.fileStorePath(), fileName)))
@@ -197,10 +197,10 @@ public class TUSClient: NSObject, URLSessionTaskDelegate {
197197
/// - Parameter upload: the upload object
198198
public func cleanUp(forUpload upload: TUSUpload) {
199199
//Delete stuff here
200-
let fileName = String(format: "%@%@", upload.id!, upload.fileType!)
200+
let fileName = String(format: "%@%@", upload.id, upload.fileType!)
201201
currentUploads?.remove(at: 0)
202202
fileManager.deleteFile(withName: fileName)
203-
logger.log(forLevel: .Info, withMessage: "file \(upload.id!) cleaned up")
203+
logger.log(forLevel: .Info, withMessage: "file \(upload.id) cleaned up")
204204
}
205205

206206
public func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {

TUSKit/Classes/TUSExecutor.swift

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ class TUSExecutor: NSObject, URLSessionDelegate {
2525
// request.addValue(contentLength, forHTTPHeaderField: "Content-Length")
2626
// request.addValue(uploadLength, forHTTPHeaderField: "Upload-Length")
2727
request.addValue(TUSConstants.TUSProtocolVersion, forHTTPHeaderField: "TUS-Resumable")
28-
request.addValue(String(format: "%@ %@", "filename", fileName.toBase64()), forHTTPHeaderField: "Upload-Metadata")
29-
28+
3029
for header in headers.merging(customHeaders, uniquingKeysWith: { (current, _) in current }) {
3130
request.addValue(header.value, forHTTPHeaderField: header.key)
3231
}
@@ -35,13 +34,13 @@ class TUSExecutor: NSObject, URLSessionDelegate {
3534
}
3635

3736
internal func create(forUpload upload: TUSUpload) {
38-
var request: URLRequest = urlRequest(withEndpoint: "", andMethod: "POST", andContentLength: upload.contentLength!, andUploadLength: upload.uploadLength!, andFilename: upload.id!, andHeaders: ["Upload-Extension": "creation"])
37+
var request: URLRequest = urlRequest(withEndpoint: "", andMethod: "POST", andContentLength: upload.contentLength!, andUploadLength: upload.uploadLength!, andFilename: upload.id, andHeaders: ["Upload-Extension": "creation", "Upload-Metadata": upload.encodedMetadata])
3938
request.addValue(upload.contentLength!, forHTTPHeaderField: "Content-Length")
4039
request.addValue(upload.uploadLength!, forHTTPHeaderField: "Upload-Length")
4140
let task = TUSClient.shared.tusSession.session.dataTask(with: request) { (data, response, error) in
4241
if let httpResponse = response as? HTTPURLResponse {
4342
if httpResponse.statusCode == 201 {
44-
TUSClient.shared.logger.log(forLevel: .Info, withMessage:String(format: "File %@ created", upload.id!))
43+
TUSClient.shared.logger.log(forLevel: .Info, withMessage:String(format: "File %@ created", upload.id))
4544
// Set the new status and other props for the upload
4645
upload.status = .created
4746
// upload.contentLength = httpResponse.allHeaderFields["Content-Length"] as? String
@@ -62,9 +61,9 @@ class TUSExecutor: NSObject, URLSessionDelegate {
6261
*/
6362
//First we create chunks
6463
//MARK: FIX THIS
65-
TUSClient.shared.logger.log(forLevel: .Info, withMessage: String(format: "Preparing upload data for file %@", upload.id!))
66-
let uploadData = try! Data(contentsOf: URL(fileURLWithPath: String(format: "%@%@%@", TUSClient.shared.fileManager.fileStorePath(), upload.id!, upload.fileType!)))
67-
let fileName = String(format: "%@%@", upload.id!, upload.fileType!)
64+
TUSClient.shared.logger.log(forLevel: .Info, withMessage: String(format: "Preparing upload data for file %@", upload.id))
65+
let uploadData = try! Data(contentsOf: URL(fileURLWithPath: String(format: "%@%@%@", TUSClient.shared.fileManager.fileStorePath(), upload.id, upload.fileType!)))
66+
let fileName = String(format: "%@%@", upload.id, upload.fileType!)
6867
let tusName = String(format: "TUS-%@", fileName)
6968
//let uploadData = try! UserDefaults.standard.data(forKey: tusName)
7069
//upload.data = uploadData
@@ -77,8 +76,8 @@ class TUSExecutor: NSObject, URLSessionDelegate {
7776
}
7877

7978
private func upload(forChunks chunks: [Data], withUpload upload: TUSUpload, atPosition position: Int) {
80-
TUSClient.shared.logger.log(forLevel: .Info, withMessage:String(format: "Upload starting for file %@ - Chunk %u / %u", upload.id!, position + 1, chunks.count))
81-
let request: URLRequest = urlRequest(withFullURL: upload.uploadLocationURL!, andMethod: "PATCH", andContentLength: upload.contentLength!, andUploadLength: upload.uploadLength!, andFilename: upload.id!, andHeaders: ["Content-Type":"application/offset+octet-stream", "Upload-Offset": upload.uploadOffset!, "Content-Length": String(chunks[position].count)])
79+
TUSClient.shared.logger.log(forLevel: .Info, withMessage:String(format: "Upload starting for file %@ - Chunk %u / %u", upload.id, position + 1, chunks.count))
80+
let request: URLRequest = urlRequest(withFullURL: upload.uploadLocationURL!, andMethod: "PATCH", andContentLength: upload.contentLength!, andUploadLength: upload.uploadLength!, andFilename: upload.id, andHeaders: ["Content-Type":"application/offset+octet-stream", "Upload-Offset": upload.uploadOffset!, "Content-Length": String(chunks[position].count), "Upload-Metadata": upload.encodedMetadata])
8281
let task = TUSClient.shared.tusSession.session.uploadTask(with: request, from: chunks[position], completionHandler: { (data, response, error) in
8382
if let httpResponse = response as? HTTPURLResponse {
8483
switch httpResponse.statusCode {
@@ -93,7 +92,7 @@ class TUSExecutor: NSObject, URLSessionDelegate {
9392
if (httpResponse.statusCode == 204) {
9493
TUSClient.shared.logger.log(forLevel: .Info, withMessage:String(format: "Chunk %u / %u complete", position + 1, chunks.count))
9594
if (position + 1 == chunks.count) {
96-
TUSClient.shared.logger.log(forLevel: .Info, withMessage:String(format: "File %@ uploaded at %@", upload.id!, upload.uploadLocationURL!.absoluteString))
95+
TUSClient.shared.logger.log(forLevel: .Info, withMessage:String(format: "File %@ uploaded at %@", upload.id, upload.uploadLocationURL!.absoluteString))
9796
TUSClient.shared.updateUpload(upload)
9897
TUSClient.shared.delegate?.TUSSuccess(forUpload: upload)
9998
TUSClient.shared.cleanUp(forUpload: upload)

TUSKit/Classes/TUSUpload.swift

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,27 @@ public class TUSUpload: NSObject, NSCoding {
1919
coder.encode(uploadLength, forKey: "uploadLength")
2020
coder.encode(uploadOffset, forKey: "uploadOffset")
2121
coder.encode(status?.rawValue, forKey: "status")
22+
coder.encode(metadata, forKey: "metadata")
2223

2324
}
2425

2526
public required init?(coder: NSCoder) {
2627
//
27-
id = coder.decodeObject(forKey:"id") as? String
2828
fileType = coder.decodeObject(forKey:"fileType") as? String
2929
filePath = coder.decodeObject(forKey:"filePath") as? URL
30-
data = coder.decodeObject(forKey:"datas") as? Data
3130
uploadLocationURL = coder.decodeObject(forKey:"uploadLocationURL") as? URL
3231
contentLength = coder.decodeObject(forKey:"contentLength") as? String
3332
uploadLength = coder.decodeObject(forKey:"uploadLength") as? String
3433
uploadOffset = coder.decodeObject(forKey:"uploadOffset") as? String
34+
id = coder.decodeObject(forKey: "id") as! String
35+
data = coder.decodeObject(forKey: "data") as? Data
3536
status = TUSUploadStatus(rawValue: coder.decodeObject(forKey: "status") as! String)
37+
metadata = coder.decodeObject(forKey: "metadata") as! [String : String]
3638
}
3739

3840

3941
// MARK: Properties
40-
var id: String?
42+
public let id: String
4143
var fileType: String? // TODO: Make sure only ".fileExtension" gets set. Current setup sets fileType as something like "1A1F31FE6-BB39-4A78-AECD-3C9BDE6D129E.jpeg"
4244
var filePath: URL?
4345
var data: Data?
@@ -46,29 +48,41 @@ public class TUSUpload: NSObject, NSCoding {
4648
var uploadLength: String?
4749
var uploadOffset: String?
4850
var status: TUSUploadStatus?
51+
public var metadata: [String : String] = [:]
52+
var encodedMetadata: String {
53+
metadata["filename"] = id
54+
return metadata.map { (key, value) in
55+
"\(key) \(value.toBase64())"
56+
}.joined(separator: ",")
57+
}
4958

5059
public init(withId id: String, andFilePathString filePathString: String, andFileType fileType: String) {
51-
super.init()
5260
self.id = id
5361
filePath = URL(string: filePathString)
5462
self.fileType = fileType
5563

64+
super.init()
5665
}
5766

5867
public init(withId id: String, andFilePathURL filePathURL: URL, andFileType fileType: String) {
59-
super.init()
6068
self.id = id
6169
filePath = filePathURL
6270
self.fileType = fileType
71+
72+
super.init()
6373
}
6474

6575
public init(withId id: String, andData data: Data, andFileType fileType: String) {
6676
self.id = id
6777
self.data = data
6878
self.fileType = fileType
79+
80+
super.init()
6981
}
7082

7183
public init(withId id: String) {
7284
self.id = id
85+
86+
super.init()
7387
}
7488
}

0 commit comments

Comments
 (0)