Streamed Upload Example With Swift and Node.JS

Let me show you an example which allows to play with streamed upload (also known as multiplart upload) right in XCode Playground with Swift language and Node.JS server.

It consist of two snippets:

  • Node.JS Server
  • Swift Example

Node.JS Server

Pipes incoming request to the file (as per filename specified in the header of request).

Save the following snippet into server.js file and run with node command:

    node server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const http = require('http'),
      fs = require('fs');

const hostname = '127.0.0.1';
const port = 3001;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('OK\n');

  // extract filename from the header
  var filename = req.headers['x-filename']

  // streamed file
  var file = fs.createWriteStream(`${filename}`);

  // pipe request stream to file
  req.pipe(file);
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

Swift Snippet

Demonstrates streamed upload task in iOS.

  • Create New Playground project in XCode
  • Add assets (photo or video) to Resources folder
  • Copy/paste Swift snippet below
  • Update filenames used in the snippet accordingly
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
//: Playground - noun: a place where people can play

import UIKit

// Enables background tasks in plaground, i.e. allows to use task.resume()
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

// Playground bundle, i.e. assets stored in plaground
let bundle = NSBundle.mainBundle()

// Get path to one of assets (must be added  into Resources folder)
let path = bundle.pathForResource("car", ofType: "png")
// let path = bundle.pathForResource("IMG_0528", ofType: "MOV")

// Initialise request and session objects
var request = NSMutableURLRequest(URL: NSURL(string: "http://127.0.0.1:3001")!)
var session = NSURLSession.sharedSession()

// Prepare request headers
request.HTTPMethod = "POST"
request.setValue("application/octet-stream", forHTTPHeaderField: "Content-Type")

// Pass file name parameters with the headers, used by server to recognize filename
request.setValue("car1.png", forHTTPHeaderField: "X-FileName")
// request.setValue("video1.mov", forHTTPHeaderField: "X-FileName")

// Add input stream to HTTP body
request.HTTPBodyStream = NSInputStream(fileAtPath: path!)

// Create upload task with streamed request
var task = session.uploadTaskWithStreamedRequest(request)

// Finally execute upload task
task.resume()

And that’s it!

Conclusion

If you run into any problems with above, please let me know, I’ll be glad to help. Thanks for reading, hope you’ve enjoyed!

Comments