[Swift]简单的选择城市demo

本文通过一个Swift项目演示了如何使用AFNetworking发起GET和POST请求,利用MJExtension进行JSON数据转换,同时介绍了SDWebImage和MJRefresh在Swift中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Github:https://github.com/Gamin-fzym/SelectCityDemo
创建一个demo,用Swift写个简单的get和post请求,再将接口返回的数据用MJExtension转为model。最后,体验一下SDWebImage和MJRefresh在Swift上使用与OC上有没什么不同。
先在网上找了个API:https://dev.heweather.com/docs/search/top
使用pod导入第三方

    pod 'AFNetworking'
    pod 'SDWebImage'
    pod 'MJRefresh'
    pod 'MJExtension'

再创建桥接文件(DMSelectCityDemo-Bridging-Header)并导入第三方

#ifndef DMSelectCityDemo_Bridging_Header_h
#define DMSelectCityDemo_Bridging_Header_h

#import "MJRefresh.h"
#import "SDWebImage.h"
#import "AFNetworking.h"
#import "MJExtension.h"

#endif 

下面做个代码备份

目录

AppDelegate

ShareAFHTTPSessionManager

CityListAPI

 HomeViewController

CityListViewController

CityListCell

CityListModel

示意图​


AppDelegate

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        window = UIWindow(frame: UIScreen.main.bounds);
        window?.backgroundColor = UIColor.white;
        let home = HomeViewController();
        let nav = UINavigationController(rootViewController: home);
        window?.rootViewController = nav;
        window?.makeKeyAndVisible();
        return true
    }

}

ShareAFHTTPSessionManager

因为Swift中AFHTTPSessionManager无法调用类方法manager(+ (instancetype)manager;),所以这样要自己为AFHTTPSessionManager写个单例来管理。

import UIKit

class ShareAFHTTPSessionManager: AFHTTPSessionManager {
    
    static let shareInstance : ShareAFHTTPSessionManager = {
        let baseUrl = NSURL(string: "xxxxxx")!;
        let manager = ShareAFHTTPSessionManager.init(baseURL: baseUrl as URL, sessionConfiguration: URLSessionConfiguration.default);
        manager.responseSerializer.acceptableContentTypes = NSSet(objects: "pplication/json","text/plain") as? Set<String>;
        manager.requestSerializer.timeoutInterval = 60;
        return manager;
    }()
    
    /**
     get请求
     
     - parameter urlString:  请求的url
     - parameter parameters: 请求的参数
     - parameter success:    请求成功回调
     - parameter failure:    请求失败回调
     */
    class func get(urlString:String,parameters:AnyObject?,success:((_ responseObject:AnyObject?) -> Void)?,failure:((_ error:NSError) -> Void)?) -> Void {
        ShareAFHTTPSessionManager.shareInstance.get(urlString, parameters: parameters, progress: { (progress) in
            
        }, success: { (task, responseObject) in
            // 如果responseObject不为空时
            if responseObject != nil {
                success!(responseObject as AnyObject?);
            }
        }, failure: { (task, error) in
            failure!(error as NSError);
        })
    }
    
    /**
     post请求
     
     - parameter urlString:  请求的url
     - parameter parameters: 请求的参数
     - parameter success:    请求成功回调
     - parameter failure:    请求失败回调
     */
    class func post(urlString:String,parameters:AnyObject?,success:((_ responseObject:AnyObject?) -> Void)?,failure:((_ error:NSError) -> Void)?) -> Void {
        ShareAFHTTPSessionManager.shareInstance.post(urlString, parameters: parameters, progress: { (progress) in
            
        }, success: { (task, responseObject) in
            // 如果responseObject不为空时
            if responseObject != nil {
                success!(responseObject as AnyObject?);
            }
        }, failure:  { (task, error) in
            failure!(error as NSError);
        })
    }
    
}

CityListAPI

import UIKit

class CityListAPI: NSObject {
    // 和风天气控制台应用的key https://console.heweather.com/app/index
    static let CITY_KEY = "447d7b4d0f074982910f76250d55e4e0";
    // 域名
    static let CITY_DOMAIN = "https://search.heweather.net";
    
    /*
     参数:
     group  world:全球 cn:中国 overseas:海外(不包括中国)
     number 返回热门城市的数量,默认返回20个,可选1-50个
     lang   多语言,默认为简体中文(lang=en),海外城市默认为英文。详见 https://dev.heweather.com/docs/refer/i18n
     */
    class func requestCityList(group: String, page: NSString, number: String, lang: String, success:((_ responseObject:AnyObject?) -> Void)?, failure:((_ error:NSError) -> Void)?) -> Void {
        
        let url = CITY_DOMAIN + "/top?" + "group=" + group + "&key=" + CITY_KEY + "&number=" + number + "&lang=" + lang;
        ShareAFHTTPSessionManager.shareInstance.get(url, parameters: Any?.self, progress: { (progress) in
            
        }, success: { (task, responseObject) in
            success!(responseObject as AnyObject?);
        }) { (task, error) in
            failure!(error as NSError);
        }
    }
    
    // post请求
    class func postRequestCityList(group: String, page: NSString, number: String, lang: String, success:((_ responseObject:AnyObject?) -> Void)?, failure:((_ error:NSError) -> Void)?) -> Void {
        
        let url = CITY_DOMAIN + "/top";
        var parm = [String: Any]();
        parm["group"] = group;
        parm["key"] = CITY_KEY;
        parm["number"] = number;
        parm["lang"] = lang;

        ShareAFHTTPSessionManager.shareInstance.post(url, parameters: parm, progress: { (progress) in
            
        }, success: { (task, responseObject) in
            success!(responseObject as AnyObject?);
        }) { (task, error) in
            failure!(error as NSError);
        }
    }
}

 HomeViewController

import UIKit

class HomeViewController: UIViewController {

    @IBOutlet weak var selectCityBut: UIButton!
    @IBOutlet weak var picIV: UIImageView!
    @IBOutlet weak var picBut: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        title = "首页";
        loadPictureAction(path: "https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=657915244,3179044488&fm=26&gp=0.jpg");
    }

    @IBAction func tapCityListAction(_ sender: Any) {
        let cityList = CityListViewController();
        cityList.selectBlock = { [weak self] (selectModel: CityListModel) -> () in
            if (!selectModel.isEqual(nil)) {
                self?.selectCityBut.setTitle("选择了" + (selectModel.location ?? ""), for: .normal);
            }
        }
        navigationController?.pushViewController(cityList, animated: true);
    }
    
    func loadPictureAction(path: String) -> () {
        picIV.sd_setImage(with: URL(string: path), placeholderImage: UIImage(named: "lty1.jpg"), options: .retryFailed) { (image , error, _, _) in

        }
        
        picBut.sd_setImage(with: URL(string: path), for: .normal, placeholderImage: UIImage(named: "lty1.jpg"), options: .retryFailed) { (image, error, _, _) in
            
        }
    }
    
}

CityListViewController

import UIKit

typealias SelectModelBlock = (_ selectModel: CityListModel) -> ();

class CityListViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!
    private var dataMArr: [CityListModel] = [];
    private var page: Int = 0;
    var selectBlock: SelectModelBlock?;
    
    override func viewDidLoad() {
        super.viewDidLoad()
        title = "选择城市";
        setupTableViewUI();
    }

    func setupTableViewUI() {
        // 设置透明,默认为NO控制器中y=0实际效果上=64,设置为YES时控制器中y=0实际效果上y=0
        navigationController?.navigationBar.isTranslucent = false;
        
        if #available(iOS 11.0, *) {
            tableView.contentInsetAdjustmentBehavior = .never
            tableView.insetsContentViewsToSafeArea = false;
        } else {
            self.automaticallyAdjustsScrollViewInsets = false
        }
        
        tableView.separatorStyle = UITableViewCell.SeparatorStyle.none;
        tableView.estimatedRowHeight = 100;
        tableView.rowHeight = UITableView.automaticDimension;
        // 纯代码的cell
        //tableView.register(LinkmanListCell.self, forCellReuseIdentifier: "LinkmanListCell");
        // xib的cell
        tableView.register(UINib(nibName: "CityListCell", bundle: nil), forCellReuseIdentifier: "CityListCell");
        tableView.mj_header = MJRefreshNormalHeader(refreshingBlock: {
            self.refresh();
        });
        tableView.mj_footer = MJRefreshBackNormalFooter(refreshingBlock: {
            self.refreshMore();
        });
        refresh();
    }
    
    // 下拉刷新
    func refresh() {
        page = 0;
        dataMArr.removeAll();
        requestDataAction();
    }
    
    // 上拉加载
    func refreshMore() {
        page += 1;
        requestDataAction();
    }
    
    // 数据请求
    func requestDataAction() {
        CityListAPI.requestCityList(group: "cn", page: "\(page)" as NSString, number: "50", lang: "cn", success: { (responseObject) in
            let weather = responseObject?["HeWeather6"] as! Array<Any>;
            let basic = ((weather[0] as! Dictionary<String, Any>)["basic"]) as! Array<Any>;
            if (basic.count > 0) {
                let listArr = CityListModel.mj_objectArray(withKeyValuesArray: basic);
                self.dataMArr = listArr as! [CityListModel];
            }
            self.tableView.mj_header?.endRefreshing();
            self.tableView.mj_footer?.endRefreshing();
            self.tableView.reloadData();
        }) { (error) in
            
        }
        /*
        CityListAPI.postRequestCityList(group: "cn", page: "\(page)" as NSString, number: "50", lang: "cn", success: { (responseObject) in
            let weather = responseObject?["HeWeather6"] as! Array<Any>;
            let basic = ((weather[0] as! Dictionary<String, Any>)["basic"]) as! Array<Any>;
            if (basic.count > 0) {
                let listArr = CityListModel.mj_objectArray(withKeyValuesArray: basic);
                self.dataMArr = listArr as! [CityListModel];
            }
            self.tableView.mj_header?.endRefreshing();
            self.tableView.mj_footer?.endRefreshing();
            self.tableView.reloadData();
        }) { (error) in
            
        }
        */
    }

    // MARK: UITableViewDelegate
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1;
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataMArr.count;
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CityListCell", for: indexPath) as! CityListCell;
        if (dataMArr.count > indexPath.row) {
            cell.cellModel = dataMArr[indexPath.row];
        } else {
            cell.cellModel = nil;
        }
        return cell;
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let cell = tableView.cellForRow(at: indexPath) as? CityListCell;
        guard let model = cell?.cellModel else {
            return;
        }
        if ((selectBlock) != nil) {
            selectBlock!(model);
        }
        navigationController?.popViewController(animated: true);
    }
}

CityListCell

import UIKit

class CityListCell: UITableViewCell {

    @IBOutlet weak var cityLab: UILabel!
    @IBOutlet weak var cidLab: UILabel!
    @IBOutlet weak var cntyLab: UILabel!
    
    var cellModel: CityListModel? {
        didSet {
            cityLab.text = cellModel?.location;
            cidLab.text = cellModel?.cid;
            cntyLab.text = cellModel?.cnty;
        }
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
    
}

CityListModel

import UIKit

class CityListModel: NSObject {

    @objc var location: String?;      // 地区/城市名称     卓资
    @objc var cid: String?;           // 地区/城市ID     CN101080402
    @objc var lat: String?;           // 地区/城市纬度     40.89576
    @objc var lon: String?;           // 地区/城市经度     112.577702
    @objc var parent_city: String?;   // 该地区/城市的上级城市     乌兰察布
    @objc var admin_area: String?;    // 该地区/城市所属行政区域     内蒙古
    @objc var cnty: String?;          // 该地区/城市所属国家名称     中国
    @objc var tz: String?;            // 该地区/城市所在时区     +8.0
    @objc var type: String?;          // 该地区/城市的属性,目前有city城市和scenic中国景点     city

}

示意图



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值