转眼就到了18年的最后一个月份了,想必大家 一定都在期待 新年的到来吧,那小编就先在这里提前祝大家新年快乐了
新年快乐
好了,上期我们有了解了ARC的运行方式以及Java语言的增删效果…
这期我们来简单了解一下S4语言的网络数据请求,
关于网络数据请求我们常见的有Get和POST请求.
GET
//MARK:-------------------获取网络数据-----------------
func getNetData() -> Void {
//菊花转动
self.hud?.show(true)
UIApplication.shared.isNetworkActivityIndicatorVisible = true
//(1)网址字符串拼接
let appKey = "1b9f570e367ce24e51135d69eac7d04e"
var urlStr = "http://web.juhe.cn:8080/finance/gold/shgold?key=\(appKey)"
//(2)将网址字符串做成网址对象
let url = URL.init(string: urlStr)
//(3)封装为请求对象,同时设置缓存策略和超时时长
let req = URLRequest.init(url: url!, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5.0)
//(4)连接服务器请求网络数据
let task:URLSessionDataTask = URLSession.shared.dataTask(with: req) { (data:Data?, response:URLResponse?, neterror:Error?) in
//在主线程队列中异步执行,停止转动指示器
DispatchQueue.main.async {
self.hud?.hide(true)
UIApplication.shared.isNetworkActivityIndicatorVisible = false
//停止下拉刷新
self.mjHeader?.endRefreshing()
}
//如果发生了服务器错误或请求超时
if neterror != nil {
DispatchQueue.main.async {
self.showMBAlert(msg: "服务器错误")
}
return
}
//json数据转化
let jsonData = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments)
//使用guarde-else语句
guard let rightData = jsonData else{
DispatchQueue.main.async {
self.showMBAlert(msg: "网络数据错误")
}
return
}
let dataDic = rightData as! [String:Any]
let resultcode = dataDic["resultcode"] as! String
let reason = dataDic["reason"] as! String
if resultcode != "200" {
DispatchQueue.main.async {
self.showMBAlert(msg: reason)
}
return
}
//获取result数组
let result = dataDic["result"] as! NSArray
// let result = dataDic["result"] as! [[String:[String:String]]]
//获取最外层的字典
let allDic = result[0] as! NSDictionary
//开辟
self.tableData = []
//遍历字典中的键值对
for oneDic in allDic.allValues{
let oneGold = Gold.init()
oneGold.setValuesForKeys(oneDic as! [String:String])
self.tableData?.append(oneGold)
}
DispatchQueue.main.async {
self.table?.reloadData()
}
// //在全局并发队列中异步执行,相当于开辟新的子线程
// DispatchQueue.global().async {
//
// }
}
//(5)启动任务
task.resume()
}
//MARK:---------------------viewdidload----------------
}```
==POST==
//(1)指示器转动
UIApplication.shared.isNetworkActivityIndicatorVisible = true
//(2)网络请求
//<1>网址字符串拼接
let urlStr = “http://py.cmshop.net/tPyshNewnoticController.do?godongtai2&style2=(titlIndex)”
//<2>转换为url地址
let url = URL.init(string: urlStr)
//<3>请求对象,并设置缓存策略超时时长
let req = URLRequest.init(url: url!, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 8.0)
//<4>连接服务器任务
let task = URLSession.shared.dataTask(with: req){
(data,response,error) in
//停止指示器
DispatchQueue.main.async {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
self.mjHeader?.endRefreshing()
}
//如果服务器连接失败或超时
if error != nil{
DispatchQueue.main.async {
self.view.showMBAlert(msg: "服务器错误")
}
return
}
//如果连接服务器成功,将二进制数据转换为数组字典
let jsonData = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments)
//如果jsonData为nil表示转换失败,后台提供的json数据是错误的
if jsonData == nil{
DispatchQueue.main.async {
self.view.showMBAlert(msg: "网络数据错误")
}
return
}
//转换成功,将数据强转为字典类型
let jsonDic = jsonData! as! NSDictionary
//获取resultcode值
let resultcode = jsonDic["resultcode"] as! String
//如果resultcode不为0,表示有错误发生,给出客户提示
if resultcode != "0" {
let errmsg = jsonDic["errmsg"] as! String
DispatchQueue.main.async {
self.view.showMBAlert(msg: errmsg)
}
return
}
//如果数据都正确,做json解析
let dataArr = jsonDic["data"] as! [[String:Any]]
self.tableData = News.createNewsArray(arr:dataArr)
//回到主线程刷新表格
DispatchQueue.main.async {
self.table?.reloadData()
}
}
//<5>开启任务
task.resume()
}
那么就简单的了解一下详细的代码吧
![文件列表](https://img-blog.csdnimg.cn/20190307200339168.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Mzc3NTk5OA==,size_16,color_FFFFFF,t_70)
================== (1)EXten.Alert======================
import UIKit
extension UIView {
//显示MB提示框
func showMBAlert(msg:String) -> Void {
//实例化MB
let alert = MBProgressHUD.init(view: self)
//设置提示为文本样式
alert?.mode = MBProgressHUDModeText
//设置隐藏时自动从父视图移除
alert?.removeFromSuperViewOnHide = true
//设置显示的提示文本
alert?.labelText = msg
//添加为子视图
self.addSubview(alert!)
//显示提示框
alert?.show(true)
//设置几秒自动隐藏
alert?.hide(true, afterDelay: 3.0)
}
}
================== (2)Student类======================
==h==
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Student : NSObject
@property(nonatomic,strong)NSString * type;
@property(nonatomic,strong)NSString * id;
@property(nonatomic,strong)NSString * img;
@property(nonatomic,strong)NSString * title;
@property(nonatomic,strong)NSString * read_num;
@property(nonatomic,strong)NSString * content;
@property(nonatomic,strong)NSString * author;
@property(nonatomic,strong)NSString * create_time;
//把得到的json数据中的data数组转换为Student数组
+(NSArray<Student >)createNewsArrWithDataArr:(NSArray *)dataArr;
@end
NS_ASSUME_NONNULL_END
==m==
#import “Student.h”
@implementation Student
+(NSArray<Student >)createNewsArrWithDataArr:(NSArray *)dataArr{
//定义可变数组,用于储存3Student对象
NSMutableArray * newsArr = [[NSMutableArray alloc]init];
//遍历dataArr中的每个字典
for (NSDictionary * dic in dataArr){
//将每个dic转化为Student对象
Student * one = [[Student alloc]init];
//对one的属性赋值
[one setValuesForKeysWithDictionary:dic];
//把每次循环生成的one对象加入到数组中
[newsArr addObject:one];
}
//在循环外,将newsArr返回
return [newsArr copy];
}
@end
==桥接 文件==
#import “Student.h”
#import “UIImageView+WebCache.h”
#import “MJRefresh.h”
#import “MBProgressHUD.h”
================== (3)baset类======================
import UIKit
class BaseViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
self.navigationController?.navigationBar.isTranslucent = false
}
}
================== (3)One类======================
import UIKit
//屏幕的宽
var scrW = UIScreen.main.bounds.size.width
//屏幕的高
var scrH = UIScreen.main.bounds.size.height
class OneViewController: BaseViewController,UITableViewDelegate,UITableViewDataSource {
//MARK:--------------------属性的声明------------------
var tbv:UITableView?
var tbvData:[Student]?
var segment:UISegmentedControl?
var titles = ["推荐新闻","实时对话","行情分析","专栏"]
var onetitle = ["1","2","3","4"]
//下拉刷新控件
var mjHeader:MJRefreshHeaderView?
//MARK:--------------------UI创建------------------
func initUI() {
//创建segment分段控制器
self.segment = UISegmentedControl.init(items: titles)
//设置位置
self.segment?.frame = CGRect.init(x: 0, y: 0, width: scrW, height: 40)
//设置默认选中的下标
self.segment?.selectedSegmentIndex = 0
//自动获取第一个标题的新闻数据
self.getURLData(titleIndex: onetitle[0])
//设置触发方法
self.segment?.addTarget(self, action: #selector(segmentDidChange(seg:)), for: .valueChanged)
self.segment?.tintColor = UIColor.black
//添加到view子视图
self.view.addSubview(self.segment!)
//实例化表格
self.tbv = UITableView.init(frame: CGRect.init(x: 0, y: 40, width: scrW, height: scrH - 40), style: .plain)
//设置代理和数据源
self.tbv?.delegate = self
self.tbv?.dataSource = self
//添加到子视图
self.view.addSubview(self.tbv!)
//实例化下拉刷新的控件
self.mjHeader = MJRefreshHeaderView.init(scrollView: self.tbv!)
//设置刷新的回调的闭包
self.mjHeader?.beginRefreshingBlock = {refreshView in
}
self.tbv?.rowHeight = 150
}
//MARK:--------------------UI控件的触发方法------------------
@objc func segmentDidChange(seg:UISegmentedControl) -> Void {
//根据选中的分段下标获取对应的标题,获取网络数据
self.getURLData(titleIndex: titles[seg.selectedSegmentIndex])
}
//MARK:-------------------viewDidLoad-------------------
override func viewDidLoad() {
super.viewDidLoad()
self.initUI()
}
//MARK:------------------代理和数据源的实现的方法-------------------
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let count = self.tbvData?.count{
return count
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//定义一个标识符
let identifier = "Mycell"
var cell = tableView.dequeueReusableCell(withIdentifier: identifier) as? StudentTableViewCell
if cell == nil{
cell = StudentTableViewCell.init(style: .subtitle, reuseIdentifier: identifier)
}
if let oneNew = self.tbvData?[indexPath.row]{
//图片
cell?.imgview?.sd_setImage(with: URL.init(string: oneNew.img), completed: nil)
//标题
cell?.titleLabel?.text = oneNew.title
//作者
cell?.author?.text = "作者\(oneNew.author)"
//阅读量
cell?.readNum?.text = "阅读量:\(oneNew.read_num)"
}
return cell!
}
//MARK:--------------------获取网络请求数据------------------
func getURLData(titleIndex:String) -> Void {
//转动指示器
UIApplication.shared.isNetworkActivityIndicatorVisible = true
//网络请求,网址字符串拼接
let url = URL.init(string: "http://buluokes.huimor.com/api")
//创建请求对象,同时设置缓存策略及超时时长
var req = URLRequest.init(url: url!, cachePolicy: .reloadRevalidatingCacheData, timeoutInterval: 5.0)
//设置POST请求
req.httpMethod = "POST"
//把请求参数拼接成字符串
let paramStr = "method=app.news.getarticlelist&class_id\(titleIndex)&page=1&user_token="
//将参数字符串转换为二进制Data数据
let paramData = paramStr.data(using: .utf8)
//将参数二进制数据放入请求体中
req.httpBody = paramData
//正式请求网络数据,使用URLsession
let task = URLSession.shared.dataTask(with: req) { (data, response, error) in
//回到UI主线程停止转动指示器
DispatchQueue.main.async {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
self.mjHeader?.endRefreshing()
}
//如果服务器错误,给客户提示
if error != nil{
DispatchQueue.main.async {
self.view.showMBAlert(msg: "服务器错误")
}
return
}
//如果连接成功,将二进制数据转换为数组或字典
let jsonData = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments)
//如果转换失败
if jsonData == nil{
DispatchQueue.main.async {
self.view.showMBAlert(msg: "json数据解析错误")
}
return
}
//t如果转换成功,将数据转换为字典类型
let jsonDic = jsonData as! NSDictionary
//获取code值
let oneCode = jsonDic["code"] as! Int
//如果code的值不为200 ,表示有错误发生,给出用户提示
if oneCode != 200{
DispatchQueue.main.async {
self.view.showMBAlert(msg: "code值不是200")
}
return
}
//如果数据都正确,做JSON解析
let resultDic = jsonDic["data"] as! NSDictionary
let dataArr = resultDic["list"] as! NSArray
print(dataArr)
//将dataArr转换为News数组,赋值给表格数据数组
self.tbvData = Student.createNewsArr(withDataArr: dataArr as! [Any])
//刷新表格
DispatchQueue.main.async {
self.tbv?.reloadData()
}
}
task.resume()
}
}
================== (4)StudentTableViewCell======================
import UIKit
class StudentTableViewCell: UITableViewCell {
//图片视图
var imgview:UIImageView?
//标题标签
var titleLabel:UILabel?
//作者标签
var author:UILabel?
//阅读量
var readNum:UILabel?
func initUI() {
//图片
self.imgview = UIImageView.init(frame: CGRect.init(x: 5, y: 5, width: 140, height: 140))
self.contentView.addSubview(self.imgview!)
//标题
self.titleLabel = UILabel.init(frame: CGRect.init(x: 145, y: 5, width: scrW - 155, height: 50))
self.titleLabel?.font = UIFont.systemFont(ofSize: 20.0)
self.contentView.addSubview(self.titleLabel!)
//作者标签
self.author = UILabel.init(frame: CGRect.init(x: 145, y: 80, width: 150, height: 40))
self.author?.font = UIFont.systemFont(ofSize: 17.0)
self.author?.textColor = UIColor.gray
self.contentView.addSubview(self.author!)
//阅读量
self.readNum = UILabel.init(frame: CGRect.init(x: 300, y: 80, width: 150, height: 40))
self.readNum?.font = UIFont.systemFont(ofSize: 17.0)
self.readNum?.textColor = UIColor.gray
self.contentView.addSubview(self.readNum!)
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.initUI()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
================== (5)StudentTableViewCell======================
let oneVC = OneViewController()
let oneNav = UINavigationController.init(rootViewController: oneVC)
oneNav.tabBarItem = UITabBarItem.init(title: “新闻”, image: UIImage.init(named: “”), tag: 1)
oneVC.navigationItem.title = “我的新闻”
let twoVC = TwoViewController()
let twoNav = UINavigationController.init(rootViewController: twoVC)
twoNav.tabBarItem = UITabBarItem.init(title: "娱乐", image: UIImage.init(named: ""), tag: 2)
twoVC.navigationItem.title = "我的娱乐"
let tbc = UITabBarController()
tbc.viewControllers = [oneNav,twoNav]
self.window?.rootViewController = tbc
END
11111111111111
1111111111111
111111111111
11111111111
1111111111
111111111
11111111
1111111
111111
11111
1111
111
11
1
标签控制器
懒惰初始化
使用lazy关键字可以让变量在使用的时候再初始化。
Global的变量是自动懒惰初始化的,不需要lazy关键字。
Static的变量也是自动懒惰初始化的,不需要lazy关键字。
Property变量用关键字lazy进行懒惰初始化。
如果没有lazy关键字,是不能通过编译的,因为MyView还没有初始化,不能调用实例方法。
一个比较常用的技术手段是结合使用define and call的函数来初始化lazy的成员变量:
//初始化
let one = oneViewController()
let two = VCTwo()
let three = threeViewController()
let four = fourViewController()
let five = fiveViewController()
let oneNav = UINavigationController(rootViewController: one)
let twoNav = UINavigationController(rootViewController: two)
let threeNav = UINavigationController(rootViewController: three)
let fourNav = UINavigationController(rootViewController: four)
let fiveNav = UINavigationController(rootViewController: five)
//添加图片
oneNav.tabBarItem.image = UIImage(named: "tabbar_me")
twoNav.tabBarItem.image = UIImage(named: "tabbar_me")
threeNav.tabBarItem.image = UIImage(named: "tabbar_me")
fourNav.tabBarItem.image = UIImage(named: "tabbar_me")
fiveNav.tabBarItem.image = UIImage(named: "tabbar_me")
//添加标题
oneNav.tabBarItem.title = "1"
oneNav.tabBarItem.title = "2"
oneNav.tabBarItem.title = "3"
oneNav.tabBarItem.title = "4"
oneNav.tabBarItem.title = "5"
//添加
let tabbar = UITabBarController()
tabbar.viewControllers = [oneNav,twoNav,threeNav,fourNav,fiveNav]
tabbar.selectedViewController = twoNav
//设置跟视图
self.window?.rootViewController = tabbar
self.window?.backgroundColor = UIColor.white
MD
import UIKit
class OneMD: NSObject {
var headImg:String
var title:String
var detailTitle:String
var img:String
var time:String
var num:String
var type:String
init(headImg:String,title:String,detailTitle:String,img:String,time:String,num:String,type:String) {
self.headImg = headImg
self.title = title
self.time = time
self.detailTitle = detailTitle
self.img = img
self.num = num
self.type = type
}
}
无论是类成员还是全局变量,都可以定义成计算变量,就是在使用的时候计算一个值出来,而不是保存这个值。也就是getter和setter。
ALL
import UIKit
class VWC: UIViewController,UITableViewDelegate,UITableViewDataSource {
let mArr:NSMutableArray = []
var cellHight:CGFloat = 0
var tv:UITableView?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
NotificationCenter.default.addObserver(self, selector: #selector(test), name: NSNotification.Name(rawValue:"cellHight"), object: nil)
view.backgroundColor = UIColor.white
let path = Bundle.main.path(forResource: "daren", ofType: "json")
let url = URL(fileURLWithPath: path!)
do {
let data = try Data(contentsOf: url)
let jsonData:Any = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers)
// print(jsonData)
let jsonArr:NSArray = jsonData as! NSArray
print(jsonArr)
for item in jsonArr {
let k:NSDictionary = item as! NSDictionary
if k.object(forKey: "type") as! String == "0"{
let md:OneMD = OneMD(headImg: k.object(forKey: "head") as! String, title: k.object(forKey: "title") as! String, detailTitle: k.object(forKey: "detailTitle") as! String, img: k.object(forKey: "img") as! String, time: k.object(forKey: "time") as! String, num: k.object(forKey: "num") as! String, type: k.object(forKey: "type") as! String)
mArr.add(md)
}else if k.object(forKey: "type") as! String == "1" {
let md:TwoMD = TwoMD(headImg: k.object(forKey: "head") as! String, title: k.object(forKey: "title") as! String, detailTitle: k.object(forKey: "detailTitle") as! String, img: k.object(forKey: "img") as! NSMutableArray, time: k.object(forKey: "time") as! String, num: k.object(forKey: "num") as! String, type: k.object(forKey: "type") as! String)
mArr.add(md)
}else{
let md:ThreeMD = ThreeMD(headImg: k.object(forKey: "head") as! String, title: k.object(forKey: "title") as! String, detailTitle: k.object(forKey: "detailTitle") as! String, img: k.object(forKey: "img") as! String, time: k.object(forKey: "time") as! String, num: k.object(forKey: "num") as! String, type: k.object(forKey: "type") as! String)
mArr.add(md)
}
}
} catch let error as Error? {
print(error as Any)
}
tv = UITableView(frame:CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height-120), style: .plain)
view.addSubview(tv!)
tv!.delegate = self
tv!.dataSource = self
tv!.register(UINib(nibName: "OneCell", bundle: Bundle.main), forCellReuseIdentifier: "cell1")
tv?.register(UINib(nibName: "TwoCell", bundle: Bundle.main), forCellReuseIdentifier: "cell2")
tv!.register(UINib(nibName: "ThreeCell", bundle: Bundle.main), forCellReuseIdentifier: "cell3")
tv!.tableFooterView = UIView()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return mArr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = mArr[indexPath.row]
if item is OneMD{
let md:OneMD = mArr[indexPath.row] as! OneMD
let cell:OneCell = tableView.dequeueReusableCell(withIdentifier: "cell1") as! OneCell
cell.setCellWithData(model: md)
return cell
} else if item is TwoMD{
let md:TwoMD = mArr[indexPath.row] as! TwoMD
let cell:TwoCell = tableView.dequeueReusableCell(withIdentifier: "cell2") as! TwoCell
cell.setCellWithData(model: md)
print(cellHight)
return cell
}else{
let md:ThreeMD = mArr[indexPath.row] as! ThreeMD
let cell:ThreeCell = tableView.dequeueReusableCell(withIdentifier: "cell3") as! ThreeCell
cell.setCellWithData(model: md)
return cell
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let item = mArr[indexPath.row]
if item is TwoMD{
return cellHight+10
} else{
return 200
}
}
@objc func test(nofi : Notification){
cellHight = nofi.userInfo!["post"] as! CGFloat
tv?.reloadData()
/// 移除通知
NotificationCenter.default.removeObserver(self)
}
}