nghialv blog

practice makes perfect

Net - a HttpRequest Wrapper

| Comments

Net is a HttpRequest wrapper written in Swift.

source code : https://github.com/nghialv/Net

Features

  • GET, POST, PUT, DELETE method
  • Powerful request params: nested params, number, string, dic, array, image, data
  • Json, Image, Xml Response
  • Download file: resume, suspend, cancel
  • Upload file, data, params(multi-part)
  • Progress closure
  • Background donwload, upload
  • Authentication
  • Batch of operations
  • BaseURL
  • Customizable header

Demo app

screenshot

Usage

Use one of the following methods to create a Net instance

1
2
3
4
5
// without baseURL
let net = Net()

// with baseURL
let net = Net(baseUrlString: "http://www.puqiz.com/")

HttpRequest

GET Request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let url = "get_path"
let params = ["integerNumber": 1, "doubleNumber": 2.0, "string": "hello"]

net.GET(url, params: params, successHandler: { responseData in
      let result = responseData.json(error: nil)
      NSLog("result \(result)")
  }, failureHandler: { error in
      NSLog("Error")
  })

// you can also make a request with absolute url
let url = "http://www.puqiz.com/get_path"
net.GET(absoluteUrl: url, params: params, successHandler: { responseData in
      let result = responseData.json(error: nil)
      NSLog("result \(result)")
  }, failureHandler: { error in
      NSLog("Error")
  })

You can also use nested params

1
2
3
4
5
6
7
// nested params
let params = ["string": "test",
            "integerNumber": 1,
            "floatNumber": 1.5,
            "array": [10, 20, 30],
            "dictionary": ["x": 100.0, "y": 200.0],
            "image": NetData(pngImage: img, filename: "myIcon")]

By using responseData in sucessHandler closure you can quickly

  • get json dictionary
  • get image
  • parse xml

for GET, POST, PUT, DELETE request.

1
2
3
4
5
6
7
8
// get json dictionary from response data
let jsonDic = responseData.json(error: error)

// get image from response data
let image = responseData.image()

// parse xml with delegate
let result = responseData.parseXml(delegate: self)
POST Request

Net will automatically check your params to send request as a URL-Encoded request or a Multi-Part request. So you can easily post with number, string, image or binary data.

  • URL-Encoded Request
1
2
3
4
5
6
7
8
9
let url = "post_path"
let params = ["string": "test", "integerNumber": 1, "floatNumber": 1.5]

net.POST(url, params: params, successHandler: { responseData in
      let result = responseData.json(error: nil)
      NSLog("result: \(result)")
  }, failureHandler: { error in
      NSLog("Error")
  })
  • Multi-Part Request
1
2
3
4
5
6
7
8
9
10
11
12
let url = "post_path"
let img = UIImage(named: "puqiz_icon")

let params = ["string": "test", "integerNumber": 1,
            "icon": NetData(pngImage: img, filename: "myIcon")]

net.POST(url, params: params, successHandler: { responseData in
      let result = responseData.json(error: nil)
      NSLog("result: \(result)")
  }, failureHandler: { error in
      NSLog("Error")
  })
PUT Request
1
2
3
4
5
6
7
8
9
let url = "put_path"
let params = ["string": "test", "integerNumber": 1, "floatNumber": 1.5]

net.PUT(url, params: params, successHandler: { responseData in
      let result = responseData.json(error: nil)
      NSLog("result: \(result)")
  }, failureHandler: { error in
      NSLog("Error")
  })
DELETE Request
1
2
3
4
5
6
7
8
let url = "delete_path"
let params = ["id": 10]

net.DELETE(url, params: params, successHandler: { responseData in
      NSLog("result: \(result)")
  }, failureHandler: { error in
      NSLog("Error")
  })

Task

Before using download/upload function you have to call setupSession method to setup the session.

1
2
// setup session without backgroundIdentifier
net.setupSession()

To perform background downloads or uploads, you have to call setupSession method with a background identifier string. Then your download/upload tasks can be run even when the app is suspended, exits or crashes.

1
2
3
4
5
6
7
8
9
10
11
12
// setup session with backgroundIdentifier
net.setupSession(backgroundIdentifier: "com.nghialv.download")

// you can set eventsForBackgroundHandler closure
// this closure will be invoked when a task is completed in the background
net.eventsForBackgroundHandler = { urlSession in
      urlSession.getDownloadingTasksCount{ downloadingTaskCount in
      if downloadingTaskCount == 0 {
          NSLog("All files have been downloaded!")
      }
  }
}
Download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let downloadTask = net.download(absoluteUrl: url, progress: { progress in
      NSLog("progress \(progress)")
  }, completionHandler: { fileUrl, error in
      if error != nil {
          NSLog("Download failed")
      }
      else {
          NSLog("Downloaded to  : \(fileUrl)")
      }
  })

// you can control your task
downloadTask.resume()
downloadTask.suspend()
downloadTask.cancel()
Upload
  • Upload with file path
1
2
3
4
5
6
7
8
9
10
let task = net.upload(absoluteUrl: url, fromFile: file, progressHandler: { progress in
      NSLog("progress \(progress)")
  }, completionHandler: { error in
      if error != nil {
          NSLog("Upload failed : \(error)")
      }
      else {
          NSLog("Upload completed")
      }
  })
  • Upload with data
1
2
3
4
5
6
7
let yourData = NSData(...)

net.upload(absoluteUrl: url, data: yourData, progressHandler: { progress in
      NSLog("progress: \(progress)")
  }, completionHandler: { error in
      NSLog("Upload completed")
  })
  • Upload with params
1
2
3
4
5
6
7
8
9
let image = UIImage(named: "image_file")
let imageData = UIImagePNGRepresentation(image)
let params = ["number": 1, "string": "net", "data": imageData]

net.upload(absoluteUrl: imgUrl, params: params, progressHandler: { progress in
      NSLog("progress: \(progress)")
  }, completionHandler: { error in
      NSLog("Upload completed")
  })

By default, the upload task will be performed as POST method and

  • Content-Type = application/octet-stream (upload with file or data)
  • Content-Type = multipart/form-data (upload with params)

But you can configure the upload task before resuming.

1
2
3
4
5
// set method
yourUploadTask.setHttpMethod(.PUT)

// set header field
yourUploadTask.setValue(value: "your_value", forHttpHeaderField: "header_field")

In progress

  • Batch of operations
  • Basic authentiacation

Integration

Just drag Net folder to the project tree

| Comments

Description

プログラミングクイズアプリです. Swift, Ruby, Java, C++などの言語に関する質問を解いてみませんか.

プログラミングが好きな人は大歓迎. (^^)

FEATURES

  • クイズを 解く (コードのクイズもある)
  • ランキング
  • 歴史の閲覧
  • 質問のストック
  • 質問作成
  • 共有

GCD - a Wrapper of Grand Central Dispatch

| Comments

GCD is a wrapper of Grand Central Dispatch written in Swift.

source code : https://github.com/nghialv/GCD

Examples

- gcd
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
// submit your code for asynchronous execution on a global queue with high priority
gcd.async(.High) {
    // your code
}

// or with main thread
gcd.async(.Main) {
    // your code
}

gcd.async(.Default) {
    // your code
    gcd.async(.Main) {
        // code run on main thread
    }
}

// with your custom queue
let myQueue = GCDQueue(serial: "myQueue")
gcd.async(.Custom(myQueue)) {
    // your code
}

// run with delay
gcd.async(.Background, delay: 5.0) {
    // your code
}

// sync code
gcd.sync(.Main) {
    // your code
}

// apply
gcd.apply(.Default, 10) { index in
    // your code
}

// once
var onceToken: GCDOnce = 0
gcd.once(&onceToken) {
    // your code
}
- manage group of block with GCDGroup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// create group
let group = GCDGroup()

// you can add async code to group
group.async(.Defaul) {
    // your code
}

// you can set notify for this group
group.notify(.Main) {
    // your code
}

// or wait synchronously for block in group to complete and timeout is 10 seconds
group.wait(10)
- create your custom queue with CGDQueue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// create a serial queue
let serialQueue = GCDQueue(serial: "mySerialQueue")

// create a concurrent queue
let concurrentQueue = GCDQueue(concurrent: "myConcurrentQueue")

// you can submit async barrier to queue
myQueue.asyncBarrier {
    // your code
}

// or sync code
myQueue.syncBarrier {
    // your code
}

Integration

Just drag GCD.swift file to the project tree