swift 的网络请求--Alamofire框架

[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)
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SwiftUI is a new framework introduced by Apple in 2019 for building user interfaces on all Apple platforms (iOS, iPadOS, macOS, watchOS, and tvOS). It provides a new way of declaratively building user interfaces using Swift code. Objective-C, on the other hand, is an object-oriented programming language that has been widely used for building Mac and iOS applications. It has been around for much longer than SwiftUI, and has a large and established developer community. Here are some key differences between the two: 1. Syntax: SwiftUI has a simpler and more intuitive syntax compared to Objective-C, which can be more verbose and difficult to read. 2. Declarative vs Imperative: SwiftUI is a declarative framework, which means you describe what your user interface should look like, and the framework takes care of rendering it on the screen. Objective-C, on the other hand, is an imperative language, which requires you to write code to manipulate the user interface elements directly. 3. Interoperability: SwiftUI and Objective-C can coexist in the same project, and it is possible to use SwiftUI components in Objective-C code. However, the reverse is not true, as Objective-C code cannot be used in SwiftUI. 4. Learning Curve: SwiftUI is generally considered easier to learn for new developers, whereas Objective-C has a steeper learning curve. Ultimately, the choice between SwiftUI and Objective-C depends on the specific needs and preferences of each developer and the project they are working on. Both frameworks have their strengths and weaknesses, and both can be used to build high-quality and performant applications.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值