In October 2014, Apple announced
that all submissions to the App Store must include
To ease this transition we have built a sample app that demonstrates how to authorize a user via OAuth using only built-in Foundation libraries.
Once an access_token
has been obtained via OAuth, you can make GET
requests like so:
let urlSession = NSURLSession.sharedSession()
let urlString = "https://api.soundcloud.com/me"
let urlComponents = NSURLComponents(string: urlString)!
urlComponents.queryItems = [ NSURLQueryItem(name: "oauth_token", value: "insert an OAuth token here")]
let url = urlComponents.URL!
let dataTask = urlSession.dataTaskWithRequest(NSURLRequest(URL: url)) { (data, response, error) -> Void in
if let jsonOutput = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as? [String:AnyObject] {
// do stuff with JSON
}
}
dataTask.resume()
POST
requests that contain multipart data (e.g. uploading a track) look like this:
import UIKit
class ViewController: UIViewController {
func uploadTrack(title: String, trackPath: String) {
let urlSession = NSURLSession.sharedSession()
let urlRequest = getURLRequest(title, audioPath: trackPath)
let task = urlSession.dataTaskWithRequest(urlRequest) { (data, response, error) -> Void in
if let httpResponse = response as? NSHTTPURLResponse {
println("returned \(httpResponse.statusCode)")
}
if data != nil, let response = NSString(data: data, encoding: NSUTF8StringEncoding) {
println(response)
}
if let err = error {
println(err)
}
}
task.resume()
}
func getURLRequest(title: String, audioPath: String) -> NSURLRequest {
let boundary = NSUUID().UUIDString
let request = NSMutableURLRequest(URL: NSURL(string: "https://api.soundcloud.com/tracks")!)
request.HTTPMethod = "POST"
request.HTTPBody = getPostData("insert an OAuth token here", boundary: boundary, title: title, audioPath: audioPath)
let contentType = "multipart/form-data; boundary=" + boundary
request.setValue(contentType, forHTTPHeaderField: "Content-Type")
return request
}
func getPostData(token: String, boundary: String, title: String, audioPath: String) -> NSData {
let boundaryStart = "--\(boundary)\r\n"
let boundaryEnd = "\r\n--\(boundary)--\r\n"
let bodyData : NSMutableData = NSMutableData()
// add the token
var tokenSection = boundaryStart
tokenSection += "Content-Disposition: form-data; name=\"oauth_token\"\r\n\r\n"
tokenSection += "\(token)\r\n"
bodyData.appendData(tokenSection.dataUsingEncoding(NSUTF8StringEncoding)!)
// add the track title
var titleSection = boundaryStart
titleSection += "Content-Disposition: form-data; name=\"track[title]\"\r\n\r\n"
titleSection += "\(title)\r\n"
bodyData.appendData(titleSection.dataUsingEncoding(NSUTF8StringEncoding)!)
// add the audio file
let trackData = NSData(contentsOfFile: audioPath)!
var trackSection = boundaryStart
trackSection += "Content-Disposition: form-data; name=\"track[asset_data]\"; "
trackSection += "filename=\"\(audioPath.lastPathComponent)\"\r\n"
trackSection += "Content-Type: application/octet-stream\r\n"
trackSection += "\r\n"
bodyData.appendData(trackSection.dataUsingEncoding(NSUTF8StringEncoding)!)
bodyData.appendData(trackData)
bodyData.appendData(boundaryEnd.dataUsingEncoding(NSUTF8StringEncoding)!)
return bodyData
}
}
Note: This example assumes access tokens will never expire, however, we encourage you not to make this assumption in your production code. Instead, build your app assuming that tokens will periodically expire and can be refreshed using a refresh token. For details on how to use a refresh token, see Section 1.5 of the OAuth 2.0 specification.