From d52bfb73cca16b9b39de491cb147cdfe5b82b4dc Mon Sep 17 00:00:00 2001 From: nixzhu Date: Tue, 17 Mar 2015 15:31:27 +0800 Subject: [PATCH] add YepNetworking and try it --- Yep.xcodeproj/project.pbxproj | 12 ++ Yep/Services/YepNetworking.swift | 156 ++++++++++++++++++ .../Welcome/WelcomeViewController.swift | 26 +++ 3 files changed, 194 insertions(+) create mode 100644 Yep/Services/YepNetworking.swift diff --git a/Yep.xcodeproj/project.pbxproj b/Yep.xcodeproj/project.pbxproj index 6dfbadfb..330d3070 100644 --- a/Yep.xcodeproj/project.pbxproj +++ b/Yep.xcodeproj/project.pbxproj @@ -31,6 +31,7 @@ 502AE51B1AB70DDB005BD199 /* WelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 502AE51A1AB70DDB005BD199 /* WelcomeViewController.swift */; }; 502AE51E1AB712D2005BD199 /* RegisterPickNameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 502AE51D1AB712D2005BD199 /* RegisterPickNameViewController.swift */; }; 502AE5211AB71C7E005BD199 /* BorderButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 502AE5201AB71C7E005BD199 /* BorderButton.swift */; }; + 502AE5271AB72D06005BD199 /* YepNetworking.swift in Sources */ = {isa = PBXBuildFile; fileRef = 502AE5261AB72D06005BD199 /* YepNetworking.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -72,6 +73,7 @@ 502AE51A1AB70DDB005BD199 /* WelcomeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WelcomeViewController.swift; path = ViewControllers/Welcome/WelcomeViewController.swift; sourceTree = ""; }; 502AE51D1AB712D2005BD199 /* RegisterPickNameViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RegisterPickNameViewController.swift; path = ViewControllers/Register/RegisterPickNameViewController.swift; sourceTree = ""; }; 502AE5201AB71C7E005BD199 /* BorderButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BorderButton.swift; path = Views/Buttons/BorderButton.swift; sourceTree = ""; }; + 502AE5261AB72D06005BD199 /* YepNetworking.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = YepNetworking.swift; path = Services/YepNetworking.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -115,6 +117,7 @@ children = ( 5023DE441AB6B19300B3EE96 /* DummyData */, 0A8F54B01AB67D11004AD60E /* AppDelegate.swift */, + 502AE5251AB72BE9005BD199 /* Services */, 5023DE571AB6CA1400B3EE96 /* Caches */, 5023DE341AB688F900B3EE96 /* Extensions */, 5023DE391AB6979C00B3EE96 /* Views */, @@ -278,6 +281,14 @@ name = Buttons; sourceTree = ""; }; + 502AE5251AB72BE9005BD199 /* Services */ = { + isa = PBXGroup; + children = ( + 502AE5261AB72D06005BD199 /* YepNetworking.swift */, + ); + name = Services; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -394,6 +405,7 @@ 5023DE2D1AB685ED00B3EE96 /* DiscoverViewController.swift in Sources */, 5023DE301AB6861500B3EE96 /* ProfileViewController.swift in Sources */, 5023DE261AB6856300B3EE96 /* ConversationsViewController.swift in Sources */, + 502AE5271AB72D06005BD199 /* YepNetworking.swift in Sources */, 502AE51E1AB712D2005BD199 /* RegisterPickNameViewController.swift in Sources */, 5023DE2A1AB685BA00B3EE96 /* ContactsViewController.swift in Sources */, 5023DE561AB6CA1000B3EE96 /* AvatarCache.swift in Sources */, diff --git a/Yep/Services/YepNetworking.swift b/Yep/Services/YepNetworking.swift new file mode 100644 index 00000000..6f9016ff --- /dev/null +++ b/Yep/Services/YepNetworking.swift @@ -0,0 +1,156 @@ +// +// YepNetworking.swift +// Yep +// +// Created by NIX on 15/3/16. +// Copyright (c) 2015年 Catch Inc. All rights reserved. +// + +import Foundation + +public enum Method: String, Printable { + case OPTIONS = "OPTIONS" + case GET = "GET" + case HEAD = "HEAD" + case POST = "POST" + case PUT = "PUT" + case PATCH = "PATCH" + case DELETE = "DELETE" + case TRACE = "TRACE" + case CONNECT = "CONNECT" + + public var description: String { + return self.rawValue + } +} + +public struct Resource: Printable { + let path: String + let method: Method + let requestBody: NSData? + let headers: [String:String] + let parse: NSData -> A? + + public var description: String { + let decodeRequestBody: [String: AnyObject] + if let requestBody = requestBody { + decodeRequestBody = decodeJSON(requestBody)! + } else { + decodeRequestBody = [:] + } + + return "Resource(Method: \(method), path: \(path), headers: \(headers), requestBody: \(decodeRequestBody))" + } +} + +public enum Reason: Printable { + case CouldNotParseJSON + case NoData + case NoSuccessStatusCode(statusCode: Int) + case Other(NSError) + + public var description: String { + switch self { + case .CouldNotParseJSON: + return "CouldNotParseJSON" + case .NoData: + return "NoData" + case .NoSuccessStatusCode: + return "NoSuccessStatusCode" + case .Other: + return "Other" + default: + return "" + } + } +} + +func defaultFailureHandler(forResource resource:Resource, withFailureReason reason: Reason, data: NSData?) { + println("\n***************************** YepNetworking Failure *****************************") + println("Request: \(resource)") + println("Reason: \(reason)") + if let string = NSString(data: data!, encoding: NSUTF8StringEncoding) { + println("Data: \(string)") + } + println("\n") +} + +public func apiRequest(modifyRequest: NSMutableURLRequest -> (), baseURL: NSURL, resource: Resource, failure: (Resource, Reason, NSData?) -> (), completion: A -> ()) { + let session = NSURLSession.sharedSession() + let url = baseURL.URLByAppendingPathComponent(resource.path) + let request = NSMutableURLRequest(URL: url) + request.HTTPMethod = resource.method.rawValue + request.HTTPBody = resource.requestBody + + modifyRequest(request) + + for (key,value) in resource.headers { + request.setValue(value, forHTTPHeaderField: key) + } + + let task = session.dataTaskWithRequest(request) { (data, response, error) -> Void in + if let httpResponse = response as? NSHTTPURLResponse { + if httpResponse.statusCode == 200 { + if let responseData = data { + if let result = resource.parse(responseData) { + completion(result) + } else { + failure(resource, Reason.CouldNotParseJSON, data) + } + } else { + failure(resource, Reason.NoData, data) + } + } else { + failure(resource, Reason.NoSuccessStatusCode(statusCode: httpResponse.statusCode), data) + } + } else { + failure(resource, Reason.Other(error), data) + } + } + + task.resume() +} + +// Here are some convenience functions for dealing with JSON APIs + +public typealias JSONDictionary = [String: AnyObject] + +func decodeJSON(data: NSData) -> JSONDictionary? { + return NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: nil) as? [String:AnyObject] +} + +func encodeJSON(dict: JSONDictionary) -> NSData? { + return dict.count > 0 ? NSJSONSerialization.dataWithJSONObject(dict, options: NSJSONWritingOptions.allZeros, error: nil) : nil +} + +public func jsonResource(path: String, method: Method, requestParameters: JSONDictionary, parse: JSONDictionary -> A?) -> Resource { + let jsonParse: NSData -> A? = { data in + if let json = decodeJSON(data) { + return parse(json) + } + return nil + } + + let jsonBody = encodeJSON(requestParameters) + let headers = ["Content-Type": "application/json"] + + return Resource(path: path, method: method, requestBody: jsonBody, headers: headers, parse: jsonParse) +} + +public func authJsonResource(token: String, path: String, method: Method, requestParameters: JSONDictionary, parse: JSONDictionary -> A?) -> Resource { + let jsonParse: NSData -> A? = { data in + if let json = decodeJSON(data) { + return parse(json) + } + return nil + } + + let jsonBody = encodeJSON(requestParameters) + let headers = [ + "Content-Type": "application/json", + "Authorization": "Token token=\(token)" + ] + + return Resource(path: path, method: method, requestBody: jsonBody, headers: headers, parse: jsonParse) +} + diff --git a/Yep/ViewControllers/Welcome/WelcomeViewController.swift b/Yep/ViewControllers/Welcome/WelcomeViewController.swift index a62e4ced..2a88fe71 100644 --- a/Yep/ViewControllers/Welcome/WelcomeViewController.swift +++ b/Yep/ViewControllers/Welcome/WelcomeViewController.swift @@ -30,6 +30,32 @@ class WelcomeViewController: UIViewController { loginButton.setTitle(NSLocalizedString("Login", comment: ""), forState: .Normal) companyLabel.text = NSLocalizedString("Catch Inc.", comment: "") + + tryYepNetworking() + + } + + func tryYepNetworking() { + + let baseURL = NSURL(string: "http://park.catchchatchina.com/api/")! + + func verifyCode(ofMobile mobile: String, withAreaCode areaCode: String) -> Resource<[String: String]> { + + let requestParameters = [ + "mobile": mobile, + "phone_code": areaCode, + ] + + let parse: JSONDictionary -> [String: String]? = { data in + return data as? [String: String] + } + + return jsonResource("v1/auth/send_verify_code", .POST, requestParameters, parse) + } + + apiRequest({_ in}, baseURL, verifyCode(ofMobile: "18602354812", withAreaCode: "86"), defaultFailureHandler) { result in + println("result: \(result)") + } } // MARK: Actions