您的位置:首页 > 理论基础 > 计算机网络

swift 的网络请求--Alamofire框架

2015-09-08 15:45 471 查看
[1]

import Alamofire

public struct DesignerNewsService {

// Designer News API Doc: http://developers.news.layervault.com //                    V2: https://github.com/metalabdesign/dn_api_v2 
private static let baseURL = "https://www.designernews.com"
private static let clientID = "750ab22aac78be1c6d4bbe584f0e3477064f646720f327c5464bc127100a1a6d"
private static let clientSecret = "53e3822c49287190768e009a8f8e55d09041c5bf26d0ef982693f215c72d87da"

private enum ResourcePath: Printable {
case Login
case Stories
case StoryUpvote(storyId: Int)
case StoryReply(storyId: Int)
case CommentUpvote(commentId: Int)
case CommentReply(commentId: Int)
var description: String {
switch self {
case .Login: return "/oauth/token"
case .Stories: return "/api/v1/stories"
case .StoryUpvote(let id): return "/api/v1/stories/\(id)/upvote"
case .StoryReply(let id): return "/api/v1/stories/\(id)/reply"
case .CommentUpvote(let id): return "/api/v1/comments/\(id)/upvote"
case .CommentReply(let id): return "/api/v1/comments/\(id)/reply"
}
}
}

public enum StorySection: Printable {
case Default
case Recent
case Search(query: String)

public var description : String {
switch (self) {

case .Default: return ""
case .Recent: return "recent"
case .Search(_): return "search"
}
}
}

public static func storiesForSection(section: StorySection, page: Int, response: ([Story]) -> ()) {
let urlString = baseURL + ResourcePath.Stories.description + "/" + section.description
var parameters : [String:AnyObject] = [
"page": toString(page),
"client_id": clientID
]

let query: String?
switch (section) {
case let .Search(keyword):
query = keyword
default:
query = nil
}

parameters["query"] = query
Alamofire.request(.GET, urlString, parameters: parameters).response { (request, res, data, error) in
let stories = JSONParser.parseStories(data as? NSData)
response(stories)
}
}

public static func loginWithEmail(email: String, password: String, response: (token: String?) -> ()) {
let urlString = baseURL + ResourcePath.Login.description
let parameters = [
"grant_type": "password",
"username": email,
"password": password,
"client_id": clientID,
"client_secret": clientSecret
]

Alamofire.request(.POST, urlString, parameters: parameters)
.responseJSON { (_, _, json, _) in
let responseDictionary = json as? NSDictionary
let token = responseDictionary?["access_token"] as? String
response(token: token)
}
}

public static func upvoteStoryWithId(storyId: Int, token: String, response: (successful: Bool) -> ()) {
let resourcePath = ResourcePath.StoryUpvote(storyId: storyId)
upvoteWithResourcePath(resourcePath, token: token, response: response)
}

public static func upvoteCommentWithId(commentId: Int, token: String, response: (successful: Bool) -> ()) {
let resourcePath = ResourcePath.CommentUpvote(commentId: commentId)
upvoteWithResourcePath(resourcePath, token: token, response: response)
}

public static func replyStoryWithId(storyId: Int, token: String, body: String, response: (comment: Comment?, error: Error?) -> ()) {
let resourcePath = ResourcePath.StoryReply(storyId: storyId)
replyWithResourcePath(resourcePath, token: token, body: body, response: response)
}

public static func replyCommentWithId(commentId: Int, token: String, body: String, response: (comment: Comment?, error: Error?) -> ()) {
let resourcePath = ResourcePath.CommentReply(commentId: commentId)
replyWithResourcePath(resourcePath, token: token, body: body, response: response)
}

// MARK: Private Methods

private static func upvoteWithResourcePath(path: ResourcePath, token: String, response: (successful: Bool) -> ()) {
let urlString = baseURL + path.description
let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
request.HTTPMethod = "POST"
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")

Alamofire.request(request).responseJSON { (_, urlResponse, _, _) in
let successful = urlResponse?.statusCode == 200
response(successful: successful)
}
}

private static func replyWithResourcePath(path: ResourcePath, token: String, body: String, response: (comment: Comment?, error: Error?) -> ()) {

let urlString = baseURL + path.description
let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
request.HTTPMethod = "POST"
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
request.HTTPBody = "comment[body]=\(body)".dataUsingEncoding(NSUTF8StringEncoding)

Alamofire.request(request).responseJSON { (_, urlResponse, json, error) in
if let message = json?["error"] as? String {
response(comment: nil, error: Error(message: message, code: urlResponse?.statusCode ?? 0))
} else if let commentDict = json?["comment"] as? NSDictionary {
let comment = JSONParser.parseComment(commentDict)
response(comment: comment, error: nil)
} else {
response(comment: nil, error: Error(message: error?.localizedDescription ?? "Something went wrong", code: error?.code ?? 0))
}
}
}
}


[2] 登陆按钮按下 调用接口

// MARK: Button
@IBAction func signupButtonPressed(sender: AnyObject) {
view.showLoading()
DesignerNewsService.loginWithEmail(emailTextField.text, password: passwordTextField.text) { token in
self.view.hideLoading()
if let token = token {
LocalStore.setAccessToken(token)
self.dialogView.animation = "zoomOut"
self.dialogView.animate()
self.dismissViewControllerAnimated(true, completion: nil)
UIApplication.sharedApplication().sendAction("reset:", to: nil, from: self, forEvent: nil)
self.delegate?.loginViewControllerDidLogin(self)
} else {
self.dialogView.animation = "shake"
self.dialogView.animate()
}
}
}


[3] 加载本地数据

//
//  LocalStore.swift
//

import UIKit

struct LocalStore {
private static let visitedStoriesKey = "visitedStoriesKey"
private static let upvotedStoriesKey = "upvotedStoriesKey"
private static let repliedStoriesKey = "repliedStoriesKey"
private static let upvotedCommentsKey = "upvotedCommentsKey"
private static let accessTokenKey = "accessTokenKey"
private static let userDefaults = NSUserDefaults.standardUserDefaults()

static func setIntroAsVisited() {
userDefaults.setObject(true, forKey: "introKey")
}

static func isIntroVisited() -> Bool {
return userDefaults.boolForKey("introKey")
}

static func setStoryAsReplied(storyId: Int) {
appendId(storyId, toKey: repliedStoriesKey)
}

static func setStoryAsVisited(storyId: Int) {
appendId(storyId, toKey: visitedStoriesKey)
}

static func setStoryAsUpvoted(storyId: Int) {
appendId(storyId, toKey: upvotedStoriesKey)
}

static func removeStoryFromUpvoted(storyId: Int) {
removeId(storyId, forKey: upvotedStoriesKey)
}

static func setCommentAsUpvoted(commentId: Int) {
appendId(commentId, toKey: upvotedCommentsKey)
}

static func removeCommentFromUpvoted(commentId: Int) {
removeId(commentId, forKey: upvotedCommentsKey)
}

static func isStoryReplied(storyId: Int) -> Bool {
return arrayForKey(repliedStoriesKey, containsId: storyId)
}

static func isStoryVisited(storyId: Int) -> Bool {
return arrayForKey(visitedStoriesKey, containsId: storyId)
}

static func isStoryUpvoted(storyId: Int) -> Bool {
return arrayForKey(upvotedStoriesKey, containsId: storyId)
}

static func isCommentUpvoted(commentId: Int) -> Bool {
return arrayForKey(upvotedCommentsKey, containsId: commentId)
}

static func setAccessToken(token: String) {
userDefaults.setObject(token, forKey: accessTokenKey)
userDefaults.synchronize()
}

private static func deleteAccessToken() {
userDefaults.removeObjectForKey(accessTokenKey)
userDefaults.synchronize()
}

static func removeUpvotes() {
userDefaults.removeObjectForKey(upvotedStoriesKey)
userDefaults.removeObjectForKey(upvotedCommentsKey)
userDefaults.synchronize()
}

static func accessToken() -> String? {
return userDefaults.stringForKey(accessTokenKey)
}

static func logout() {
self.deleteAccessToken()
}

// MARK: Helper

static private func arrayForKey(key: String, containsId id: Int) -> Bool {
let elements = userDefaults.arrayForKey(key) as? [Int] ?? []
return contains(elements, id)
}

static private func appendId(id: Int, toKey key: String) {
let elements = userDefaults.arrayForKey(key) as? [Int] ?? []
if !contains(elements, id) {
userDefaults.setObject(elements + [id], forKey: key)
userDefaults.synchronize()
}
}

static private func removeId(id: Int, forKey key: String) {
var elements = userDefaults.arrayForKey(key) as? [Int] ?? []
if let index = find(elements, id) {
elements.removeAtIndex(index)
userDefaults.setObject(elements, forKey: key)
userDefaults.synchronize()
}
}
}


[4]将数据存储在本地

//
//  StoriesLoader.swift
//

import Foundation
import DesignerNewsKit

class StoriesLoader {

typealias StoriesLoaderCompletion = (stories:[Story]) ->()

private (set) var hasMore : Bool = false
private var page : Int = 1
private var isLoading : Bool = false
private let section : DesignerNewsService.StorySection

init(_ section: DesignerNewsService.StorySection = .Default) {
self.section = section
}

func load(page: Int = 1, completion: StoriesLoaderCompletion) {
if isLoading {
return
}

isLoading = true
DesignerNewsService.storiesForSection(section, page: page) { [weak self] stories in
if let strongSelf = self {
switch (strongSelf.section) {
case .Search(_):
strongSelf.hasMore = false
default:
strongSelf.hasMore = stories.count > 0
}
strongSelf.isLoading = false
completion(stories: stories)
}
}
}

func next(completion: (stories:[Story]) ->()) {
if isLoading {
return
}

++page
load(page: page, completion: completion)
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  api 网络 swift 框架