Proper model for multiple Alamofire requests for multiple websites

我只是一个虾纸丫 提交于 2019-12-03 14:15:10

问题


I am using Alamofire to scrap web pages for some data, let’s say News. News is a generic object with something like title, content, picture, date, author etc. However for each web site, I use different method. For some I use json for others I use hpple to extract the data. How can I create a some kind of service for each website. Should I create different Services for each web site or is there a better way to use some kind of generic function templates for each web site. Like

Login()
Fetch()
Populate()
return News(…..)

Then after I create the news and populate the tableview, how can I refresh the News object? Since News is generic, it can’t know who created it with which method.


回答1:


There are many ways to design this type of abstraction. I tend to lean towards simplicity as much as possible in my architectural designs if possible. A great pattern here is to use a Service object with class methods to handle calling your different services, parsing the result and calling a success or failure closure.

You can also use a completion handler that doesn't split the success and failure into two things, but then you need to handle the failure or success in your caller objects which I don't really like. Here's an example of the Service design in action.

FirstNewsService

import Alamofire

struct News {
    let title: String
    let content: String
    let date: NSDate
    let author: String
}

class FirstNewsService {

    typealias NewsSuccessHandler = ([News]) -> Void
    typealias NewsFailureHandler = (NSHTTPURLResponse?, AnyObject?, NSError?) -> Void

    // MARK: - Fetching News Methods

    class func getNews(#success: NewsSuccessHandler, failure: NewsFailureHandler) {
        login(
            success: { apiKey in
                FirstNewsService.fetch(
                    apiKey: apiKey,
                    success: { news in
                        success(news)
                    },
                    failure: { response, json, error in
                        failure(response, json, error)
                    }
                )
            },
            failure: { response, json, error in
                failure(response, json, error)
            }
        )
    }

    // MARK: - Private - Helper Methods

    private class func login(#success: (String) -> Void, failure: (NSHTTPURLResponse?, AnyObject?, NSError?) -> Void) {
        let request = Alamofire.request(.GET, "login/url")
        request.responseJSON { _, response, json, error in
            if let error = error {
                failure(response, json, error)
            } else {
                // NOTE: You'll need to parse here...I would suggest using SwiftyJSON
                let apiKey = "12345678"
                success(apiKey)
            }
        }
    }

    private class func fetch(
        #apiKey: String,
        success: ([News]) -> Void,
        failure: (NSHTTPURLResponse?, AnyObject?, NSError?) -> Void)
    {
        let request = Alamofire.request(.GET, "fetch/url")
        request.responseJSON { _, _, json, error in
            if let error = error {
                failure(response, json, error)
            } else {
                // NOTE: You'll need to parse here...I would suggest using SwiftyJSON
                let news = [News]()
                success(news)
            }
        }
    }
}

Inside a View Controller

override func viewDidLoad() {
    super.viewDidLoad()

    FirstNewsService.getNews(
        success: { news in
            // Do something awesome with that news
            self.tableView.reloadData()
        },
        failure: { response, json, error in
            // Be flexible here...do you want to retry, pull to refresh, does it matter what the response status code was?
            println("Response: \(response)")
            println("Error: \(error)")
        }
    )
}

Feel free to mod the design however you like to tailor it to your use cases. None of this pattern is set in stone. It just gives you a common way to construct different services. @mattt also has some really cool patterns (Router and CRUD) in the Alamofire README which I would highly recommend reading through. They are definitely more complicated though and still require a Service type of object to maximize code reuse.

Hopefully that helps shed some light.



来源:https://stackoverflow.com/questions/28984518/proper-model-for-multiple-alamofire-requests-for-multiple-websites

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!