//要调用的方法
func refresh(){
//如果有上拉加载更多 正在执行,则取消它
if self.tableView.mj_footer.isRefreshing() {
self.tableView.mj_footer.endRefreshing()
}
//根据 tab name 获取帖子列表
TopicListModel.getTopicList(tab){
(response:V2ValueResponse<[TopicListModel]>) -> Void in
if response.success {
//var topicList:Array<TopicListModel>?
self.topicList = response.value
self.tableView.reloadData()
//判断标签是否能加载下一页, 不能就提示下
let refreshFooter = self.tableView.mj_footer as! V2RefreshFooter
if self.tab == nil || self.tab == "all" {
refreshFooter.noMoreDataStateString = nil
refreshFooter.resetNoMoreData()
}
else{
}
//重置page
self.currentPage = 0
}
self.tableView.mj_header.endRefreshing()
}
}
//////////////////
//用户代理,使用这个切换是获取 m站点 还是www站数据
let USER_AGENT = "Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d Safari/600.1.4";
let MOBILE_CLIENT_HEADERS = ["user-agent":USER_AGENT]
////////////////////
//MARK: - Request
extension TopicListModel {
/**
获取首页帖子列表
- parameter tab: tab名
*/
class func getTopicList(
_ tab: String? = nil ,
page:Int = 0 ,
completionHandler: @escaping (V2ValueResponse<[TopicListModel]>) -> Void
)->Void{
var params:[String:String] = [:]
if let tab = tab {
params["tab"]=tab
}
else {
params["tab"] = "all"
}
var url = V2EXURL
if params["tab"] == "all" && page > 0 {
params.removeAll()
params["p"] = "\(page)"
url = V2EXURL + "recent"
}
Alamofire.request(url, parameters: params, headers: MOBILE_CLIENT_HEADERS).responseJiHtml { (response) -> Void in
var resultArray:[TopicListModel] = []
if let jiHtml = response.result.value{
if let aRootNode = jiHtml.xPath("//body/div[@id=‘Wrapper‘]/div[@class=‘content‘]/div[@class=‘box‘]/div[@class=‘cell item‘]"){
for aNode in aRootNode {
let topic = TopicListModel(rootNode:aNode)
resultArray.append(topic);
}
//更新通知数量
V2User.sharedInstance.getNotificationsCount(jiHtml.rootNode!)
}
DispatchQueue.global().async {
//领取奖励
if let aRootNode = jiHtml.xPath("//body/div[@id=‘Wrapper‘]/div[@class=‘content‘]/div[@class=‘box‘]/div[@class=‘inner‘]/a[@href=‘/mission/daily‘]")?.first {
if aRootNode.content == "领取今日的登录奖励" {
print("有登录奖励可领取")
UserModel.dailyRedeem()
}
}
}
}
let t = V2ValueResponse<[TopicListModel]>(value:resultArray, success: response.result.isSuccess)
completionHandler(t);
}
}
////////////////////////////
// Request+Extension.swift
import Foundation
import Alamofire
import Ji
extension DataRequest {
enum ErrorCode: Int {
case noData = 1
case dataSerializationFailed = 2
}
internal static func newError(_ code: ErrorCode, failureReason: String) -> NSError {
let errorDomain = "me.fin.v2ex.error"
let userInfo = [NSLocalizedFailureReasonErrorKey: failureReason]
let returnError = NSError(domain: errorDomain, code: code.rawValue, userInfo: userInfo)
return returnError
}
static func JIHTMLResponseSerializer() -> DataResponseSerializer<Ji> {
return DataResponseSerializer { request, response, data, error in
guard error == nil else { return .failure(error!) }
guard let validData = data else {
return .failure(AFError.responseSerializationFailed(reason: .inputDataNil))
}
if let jiHtml = Ji(htmlData: validData){
return .success(jiHtml)
}
let failureReason = "ObjectMapper failed to serialize response."
let error = newError(.dataSerializationFailed, failureReason: failureReason)
return .failure(error)
}
}
@discardableResult
public func responseJiHtml(queue: DispatchQueue? = nil, completionHandler: @escaping (DataResponse<Ji>) -> Void) -> Self {
return response(responseSerializer: Alamofire.DataRequest.JIHTMLResponseSerializer(), completionHandler: completionHandler);
}
}
//////////////////////////////
// TopicListModel.swift
init(rootNode: JiNode) {
super.init()
self.avata = rootNode.xPath("./table/tr/td[1]/a[1]/img[@class=‘avatar‘]").first?["src"]
self.nodeName = rootNode.xPath("./table/tr/td[3]/span[1]/a[1]").first?.content
self.userName = rootNode.xPath("./table/tr/td[3]/span[1]/strong[1]/a[1]").first?.content
let node = rootNode.xPath("./table/tr/td[3]/span[2]/a[1]").first
self.topicTitle = node?.content
self.setupTitleLayout()
var topicIdUrl = node?["href"];
if var id = topicIdUrl {
if let range = id.range(of: "/t/") {
id.replaceSubrange(range, with: "");
}
if let range = id.range(of: "#") {
id = id.substring(to: range.lowerBound)
topicIdUrl = id
}
}
self.topicId = topicIdUrl
self.date = rootNode.xPath("./table/tr/td[3]/span[3]").first?.content
var lastReplyUserName:String? = nil
if let lastReplyUser = rootNode.xPath("./table/tr/td[3]/span[3]/strong[1]/a[1]").first{
lastReplyUserName = lastReplyUser.content
}
self.lastReplyUserName = lastReplyUserName
var replies:String? = nil;
if let reply = rootNode.xPath("./table/tr/td[4]/a[1]").first {
replies = reply.content
}
self.replies = replies
}
///////////////////////
//要请求解析的HTML文件地址:view-source:https://www.v2ex.com/my/nodes
//用谷歌浏览器打开