Swift4.x普通笔记02使用Alamofire和SwiftyJSON进行网络请求与解析

首先说一下,我是从读者的角度来写着篇文章。整篇文章通俗易懂。

 

在我们上次的项目里开始,首先明白一点,Swift是面向协议的编程,它里面Class是很少的。用的比较多的是protocol,然后在里面进行拓展extension,使用struct

 

以上都是废话。下面开始干货

首先我们在Podfile 里面输入以下代码添加库,不指定版本就是最新版本

  pod 'Alamofire'
  pod 'SwiftyJSON'
  pod 'HandyJSON'

然后在Podfile的所在目录下运行命令行工具 pod update ,这可能多花些时间,然后 pod install  (必做)

接口我这里已经准备好了,看我文章的同学,可以自备接口,只要是JSON格式就好,基本操作都一样。

这里的BASE_URL你可以写在工具类里面

let BASE_URL = "https://xxxxxxxxxxx.com"

接下来写我们的协议,我把它命名为NetworkTool.swift,这是第一步

protocol NetworkToolProtocol{

    //我的数据
    static func loadMyData()
    
    //我的关注数据
    static func loadMyConcern()

}

然后是我们的重头戏extension,这是第二步

extension NetworkToolProtocol{
    //我的数据,这里面主要写我们的网络请求逻辑,每一行都有注释,看起来更轻松。
    static func loadMyData(){

        //这是具体的url
        let url = BASE_URL + "/user/info/"
        //这是我们的参数,意思一下
        let params = ["user_id":user_id]

        //这里有的xcode可能不会有提示,第一个参数是url,第二个是请求参数
        Alamofire.request(url,parameters:params).responseJSON{
            //这里是返回的数据也是swift语法,guard守护,简单说一下只有后面的语句是错误的才会执行大括号里面的内容,后面会经常遇到。
            (response) in guard response.result.isSuccess else {
                return
            }
            
            //这里取到我们数据返回的字符串,这里是赋值加判断的if语句
            if let value = response.result.value{
                //这里我们用SwiftyJSON进行处理数据
                let json = JSON(value)



                //这里判断数据是否成功,这是返回的一部分JSON数据
                {
                    ....
                    "message" : "success"
                    ....
                }
                //以下是判断
                guard json["message"] == "success" else{
                    return
                }


                //这里是赋值加判断的if语句,判断data里面是否是一个字典,并赋值给data
                if let data = json["data"].dictionary{


                    //判断sections里面是否是一个数组,并赋值给sections
                    if let sections = data["sections"]?.array{

                        //这里的[[]]()  最外层的[]()代表对象,里面的[]代表MyCellModel类型的数组,这里这段话代表申明一个MyCellModel类型的数组
                        var sectionArray = [[MyCellModel]]()

                        //这里是遍历sections数组
                        for item in sections{

                            //申明一个MyCellModel类型的对象
                            var rows = [MyCellModel]()

                            //取出数组对象存放进入rows
                            for row in item.arrayObject!{

                                //字典序列化为对象
                                let myCellModel = MyCellModel.deserialize(from: row as? NSDictionary)
                                
                                rows.append(myCellModel!)
                            }
                            
                            sectionArray.append(rows)
                            
                        }



                    }

                }







            }
            
            
            
            
            
            
            
        }
    }
    
    //我的关注数据
    static func loadMyConcern(){

    }


}

接下来写我们的struct

struct NetworkTool :NetworkToolProtocol {

}

在我们要获取数据的地方只要这样调用就好了

NetworkTool.loadMyData()
NetworkTool.loadMyConcern()

 

 

还没结束,我们网络请求的数据需要返回,这里我们就要用到闭包回调,

在我们的原有代码上更改

protocol NetworkToolProtocol {
 
    
    //这里面是多出的回调,返回一个MyCellModel对象的数组
    static func loadMyData(completionHandler: (_ sections:[[MyCellModel]]) -> ())
    
    ........
}

主体代码的修改,下面文章通过 //?????这里修改过??????,来表示修改内容

 

extension NetworkToolProtocol{
    //我的数据,这里面主要写我们的网络请求逻辑,每一行都有注释,看起来更轻松。
    //?????这里修改过??????,加入@escaping,swift4.x默认都是非逃逸的,这里加入逃逸的,也是作为安全警告,需要加上
    static func loadMyData(completionHandler: @escaping (_ sections:[[MyCellModel]]) -> ()){

        //这是具体的url
        let url = BASE_URL + "/user/info/"
        //这是我们的参数,意思一下
        let params = ["user_id":user_id]

        //这里有的xcode可能不会有提示,第一个参数是url,第二个是请求参数
        Alamofire.request(url,parameters:params).responseJSON{
            //这里是返回的数据也是swift语法,guard守护,简单说一下只有后面的语句是错误的才会执行大括号里面的内容,后面会经常遇到。
            (response) in guard response.result.isSuccess else {
                return
            }
            
            //这里取到我们数据返回的字符串,这里是赋值加判断的if语句
            if let value = response.result.value{
                //这里我们用SwiftyJSON进行处理数据
                let json = JSON(value)



                //这里判断数据是否成功,这是返回的一部分JSON数据
                {
                    ....
                    "message" : "success"
                    ....
                }
                //以下是判断
                guard json["message"] == "success" else{
                    return
                }


                //这里是赋值加判断的if语句,判断data里面是否是一个字典,并赋值给data
                if let data = json["data"].dictionary{


                    //判断sections里面是否是一个数组,并赋值给sections
                    if let sections = data["sections"]?.array{

                        //这里的[[]]()  最外层的[]()代表对象,里面的[]代表MyCellModel类型的数组,这里这段话代表申明一个MyCellModel类型的数组
                        var sectionArray = [[MyCellModel]]()

                        //这里是遍历sections数组
                        for item in sections{

                            //申明一个MyCellModel类型的对象
                            var rows = [MyCellModel]()

                            //取出数组对象存放进入rows
                            for row in item.arrayObject!{

                                //字典序列化为对象
                                let myCellModel = MyCellModel.deserialize(from: row as? NSDictionary)
                                
                                rows.append(myCellModel!)
                            }
                            
                            
                            sectionArray.append(rows)
                           
                            
                        }
                         //?????这里修改过??????
                        completionHandler(sectionArray)

                    }

                }







            }
            
            
            
            
            
            
            
        }
    }
    
    //我的关注数据
    static func loadMyConcern(){

    }


}

 

这里我遇到了一个问题,....  does not conform to protocol  ....

这里我把拓展里面的方法,放到struct里面。

struct NetworkTool :NetworkToolProtocol {

    
    static func loadMyCellData(completionHandler: @escaping ([[MyCellModel]]) -> ()) {
        let url = BASE_URL + "/user/tab/tabs/?"
        
        let params = ["device_id":device_id]
        
        Alamofire.request(url,parameters:params).responseJSON{
            (response) in guard response.result.isSuccess else{
                return
            }
            
            if let value = response.result.value{
                
                let json = JSON(value)
                print(json)
                guard json["message"] == "success" else{
                    return
                }
                
                
                if let data = json["data"].dictionary{
                    print(data)
                    if let sections = data["sections"]?.array{
                        var sectionArray = [[MyCellModel]]()
                        for item in sections{
                            var rows = [MyCellModel]()
                            for row in item.arrayObject!{
                                let myCellModel = MyCellModel.deserialize(from: row as? NSDictionary)
                                rows.append(myCellModel!)
                            }
                            
                            sectionArray.append(rows)
                            
                        }
                        
                        completionHandler(sectionArray)
                    }
                }
                
            }
    }
    

}
}

也就是说extension里面的方法可以干掉了,并且在protocol NetworkToolProtocol {}   里面多加了 @escaping

这里面我多加了一个@escaping 
static func loadMyCellData(completionHandler: @escaping (_ sections:[[MyCellModel]]) -> ())

 

接下来是回调方法,

    var sections = [[MyCellModel]]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        .......

        //这里的self代表控制器
        NetworkTool.loadMyCellData { (sections) in
            //这里自定义一个个体
            let string = "{\"text\":\"我的关注\",\"grey_text\":\"\"}"
            //序列化字符串
            let myConcern = MyCellModel.deserialize(from: string)
            //定义一个数组
            var myConcerns = [MyCellModel]()
            //把对象添加到数组里面
            myConcerns.append(myConcern!)
            //添加到数组对象里面
            self.sections.append(myConcerns)

            //这里用的是+=
            self.sections+=sections

            //这里比做的刷新数据(要不然数据显示不出来)
            self.tableView.reloadData()
        }
        
    }

 

在显示的时候,MineViewController

    这是分组的数据,这里的sections其实是个二维数组

    override func numberOfSections(in tableView: UITableView) -> Int {
        return sections.count
    }
    

    这里tableView里面有几行View
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return sections[section].count
    }
    
    这里是显示每一行table数据
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        定义一个TableView
        let cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
        拿出数据二维数组
        let section = sections[indexPath.section]
        一维数组,每个对象
        let myCellModel = section[indexPath.row]
        
        取出里面的数据
        cell.textLabel?.text = myCellModel.text
        return cell
    }

 

接下来run,就会出现结果,如果遇到爆红直接Fix,界面上显示出来了。

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值