From 1509abf20cf5b4c65e4668138ac66254e0bdfee7 Mon Sep 17 00:00:00 2001 From: banjun Date: Sun, 29 Mar 2015 17:02:39 +0900 Subject: [PATCH] PostMessage uploads attachments --- AsakusaSatellite.podspec | 3 +- Classes/Endpoint.swift | 70 +++++++++++++++++++++++++++++++--------- Example/Podfile.lock | 11 ++++--- 3 files changed, 64 insertions(+), 20 deletions(-) diff --git a/AsakusaSatellite.podspec b/AsakusaSatellite.podspec index ed894c7..55b5931 100644 --- a/AsakusaSatellite.podspec +++ b/AsakusaSatellite.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "AsakusaSatellite" - s.version = "0.1.0" + s.version = "0.2.0" s.summary = "AsakusaSatellite API Client for Swift" s.description = <<-DESC AsakusaSatellite is a realtime chat application for developers. @@ -18,4 +18,5 @@ Pod::Spec.new do |s| s.dependency "Alamofire", "~> 1.1" s.dependency "SwiftyJSON", "~> 2.1" s.dependency "Socket.IO-Client-Swift", "~> 1.1" + s.dependency "UTIKit", "~> 1.0" end diff --git a/Classes/Endpoint.swift b/Classes/Endpoint.swift index 4f30cbc..f12bdb4 100644 --- a/Classes/Endpoint.swift +++ b/Classes/Endpoint.swift @@ -9,6 +9,10 @@ import Foundation import Alamofire import SwiftyJSON +import UTIKit + + +private let kBoundary = "AsakusaSatellite-boundary-db1235c63fb8967513000351c0482df321505fb7" public enum Endpoint { @@ -20,13 +24,37 @@ public enum Endpoint { case AddDevice(deviceToken: NSData, name: String) func URLRequest(baseURL: String, apiKey: String?) -> NSURLRequest { - let (method: Alamofire.Method, path: String, parameters: [String: AnyObject]?, requiresApiKey: Bool) = { + let (method: Alamofire.Method, path: String, parameters: [String: AnyObject]?, body: NSData?, requiresApiKey: Bool) = { switch self { - case .ServiceInfo: return (.GET, "/service/info.json", nil, false) - case .User: return (.GET, "/user.json", nil, true) - case .RoomList: return (.GET, "/room/list.json", nil, true) + case .ServiceInfo: return (.GET, "/service/info.json", nil, nil, false) + case .User: return (.GET, "/user.json", nil, nil, true) + case .RoomList: return (.GET, "/room/list.json", nil, nil, true) case let .PostMessage(message, roomID, files): - return (.POST, "/message.json", ["room_id": roomID, "message": message], true) // TODO: files + var body: NSMutableData! + if files.count > 0 { + // add multipart (currently Alamofire does not have multipart API) + body = NSMutableData() + let crlf = "\r\n" + let crlfData = crlf.dataUsingEncoding(NSUTF8StringEncoding)! + var index = 0 + for f in files { + if let data = NSData(contentsOfFile: f) { + let sequenceNumber = index > 0 ? "-\(index)" : "" + let filename = "AsakusaSat\(sequenceNumber).\(f.pathExtension)" + let mimeType: String = UTI(filenameExtension: f.pathExtension).MIMEType ?? "application/octet-stream" + + body.appendData("--\(kBoundary)\(crlf)".dataUsingEncoding(NSUTF8StringEncoding)!) + body.appendData("Content-Disposition: form-data; name=\"files[\(filename)]\"; filename=\"\(filename)\"\(crlf)".dataUsingEncoding(NSUTF8StringEncoding)!) + body.appendData("Content-Type: \(mimeType)\(crlf)".dataUsingEncoding(NSUTF8StringEncoding)!) + body.appendData(crlfData) + body.appendData(data) + body.appendData(crlfData) + } + ++index + } + body.appendData("--\(kBoundary)--\(crlf)".dataUsingEncoding(NSUTF8StringEncoding)!) + } + return (.POST, "/message.json", ["room_id": roomID, "message": message], body, true) case let .MessageList(roomID, count, sinceID, untilID, order): var params = [String: AnyObject]() params["room_id"] = roomID @@ -34,27 +62,39 @@ public enum Endpoint { params["since_id"] = sinceID params["until_id"] = untilID params["order"] = order?.rawValue - return (.GET, "/message/list.json", params, true) + return (.GET, "/message/list.json", params, nil, true) case let .AddDevice(deviceToken, name): - return (.POST, "/user/add_device", ["device": deviceToken.description, "name": name], true) + return (.POST, "/user/add_device", ["device": deviceToken.description, "name": name], nil, true) } - }() + }() var params = parameters ?? [:] if requiresApiKey { params["api_key"] = apiKey } - return Endpoint.URLRequest(baseURL, method: method, path: path, parameters: params) + return Endpoint.URLRequest(baseURL, method: method, path: path, parameters: params, body: body) } - static func URLRequest(baseURL: String, method: Alamofire.Method, path: String, parameters: [String: AnyObject]?) -> NSURLRequest { - let baseRequest = NSMutableURLRequest(URL: NSURL(string: baseURL + path)!) - baseRequest.HTTPMethod = method.rawValue - let (request, error) = Alamofire.ParameterEncoding.URL.encode(baseRequest, parameters: parameters) - if let e = error { - NSLog("error during creating request: \(e)") + static func URLRequest(baseURL: String, method: Alamofire.Method, path: String, parameters: [String: AnyObject]?, body: NSData?) -> NSURLRequest { + let urlRequestWithParams: NSURLRequest = { + let getRequest = NSMutableURLRequest(URL: NSURL(string: baseURL + path)!) + getRequest.HTTPMethod = Method.GET.rawValue + let (request, error) = Alamofire.ParameterEncoding.URL.encode(getRequest, parameters: parameters) // Alamofire encode params into body when POST + if let e = error { + NSLog("error during creating request: \(e)") + } + return request + }() + + let request = NSMutableURLRequest(URL: urlRequestWithParams.URL) + request.HTTPMethod = method.rawValue + if let b = body { + request.addValue("multipart/form-data; boundary=\(kBoundary)", forHTTPHeaderField: "Content-Type") + request.addValue("\(b.length)", forHTTPHeaderField: "Content-Length") + request.HTTPBody = b } + return request } } diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 05dc2ad..8285dc1 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,11 +1,13 @@ PODS: - Alamofire (1.1.4) - - AsakusaSatellite (0.0.1): + - AsakusaSatellite (0.2.0): - Alamofire (~> 1.1) - Socket.IO-Client-Swift (~> 1.1) - SwiftyJSON (~> 2.1) - - Socket.IO-Client-Swift (1.1.4) + - UTIKit (~> 1.0) + - Socket.IO-Client-Swift (1.4.4) - SwiftyJSON (2.1.3) + - UTIKit (1.0.0) DEPENDENCIES: - AsakusaSatellite (from `../`) @@ -16,8 +18,9 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: Alamofire: 524225da382071ee3e6d0badd0ee4b4dc36740de - AsakusaSatellite: 499c3117a42e276856fbd04608e38d40718b1c71 - Socket.IO-Client-Swift: 23d9f0db0cdcb98623486ddf0ee811b158e9cd02 + AsakusaSatellite: e71efbd093a57df4bd606be4565fd079b93ae132 + Socket.IO-Client-Swift: fa8d4061cd930cc5e853ee5d25b4126692129f8c SwiftyJSON: 48be7490a3989a58a3f511cd54167f0a2b466e76 + UTIKit: 6880d51f5d4e1242c6fb37f9e3eeae4343eb037f COCOAPODS: 0.36.0