主页面(须要导入OC的Reachability3.0第三方文件(须要导入桥接文件)
Bridging-Header.h 例:$(SRCROOT)/Swift -- 单接口/Bridging-Header.h)
let SCR_W = UIScreen.main.bounds.size.width
let SCR_H = UIScreen.main.bounds.size.height
// MARK: ------------------ 给UIViewController添加扩展 ------------
extension UIViewController {
//MARK: ---------------- 包装的提示框 ------------------
func showAlert(msg:String,sec:TimeInterval) {
// 实例化弹出控制器
let alertVC = UIAlertController(title: nil, message: msg, preferredStyle: .alert)
// 从vc控制器弹出提示控制器
self.present(alertVC, animated: true, completion: nil)
//延时执行隐藏操作
self.perform(#selector(hideAlertVC(sender:)), with: alertVC, afterDelay: sec)
}
//隐藏提示框
@objc func hideAlertVC(sender:UIAlertController) {
sender.dismiss(animated: true, completion: nil)
}
}
class RecipeViewController: UIViewController,UITextFieldDelegate {
var recipeTF:UITextField? // 菜谱输入的输入框
var searchBtn:UIButton? // 搜索按钮
override func viewDidLoad() {
super.viewDidLoad()
// 设置View的背景色
self.view.backgroundColor = UIColor.groupTableViewBackground
recipeTF = UITextField(frame: CGRect(x: 0, y: 0, width: 200, height: 50))
recipeTF?.center = CGPoint(x: SCR_W/2, y: SCR_H/2 - 150)
recipeTF?.borderStyle = .line
recipeTF?.placeholder = "请输入查询的菜谱"
recipeTF?.textColor = UIColor.red
recipeTF?.clearButtonMode = .whileEditing
recipeTF?.textAlignment = .center
recipeTF?.delegate = self
self.view.addSubview(recipeTF!)
searchBtn = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 45))
searchBtn?.center = CGPoint(x: SCR_W/2, y: SCR_H/2 - 45)
searchBtn?.setTitle("点击查询", for: .normal)
searchBtn?.backgroundColor = UIColor.blue
searchBtn?.setTitleColor(UIColor.orange, for: .normal)
searchBtn?.addTarget(self, action: #selector(searchBtnDidPress(sender:)), for: .touchUpInside)
self.view.addSubview(searchBtn!)
}
//MARK: ---------------- 触摸回调 ---------------------
@objc func searchBtnDidPress(sender:UIButton) {
if (recipeTF?.text?.isEmpty)! {
self.showAlert(msg: "信息不可为空", sec: 2.5)
return
}
// 实例化结果控制器对象
let resultVC = RecipeResultViewController()
// 传递数据
resultVC.passString = recipeTF?.text
//控制器跳转
self.navigationController?.pushViewController(resultVC, animated: true)
}
//MARK: ---------------- UITextFieldDelegate ---------------
// 点击return按钮触发回调
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// 放弃第一响应
textField.resignFirstResponder()
return true
}
//MARK: ---------------- Touches Methods ---------------
override func touchesBegan(_ touches: Set, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
recipeTF?.resignFirstResponder()
// 将view及其子视图都放弃编辑,如果是TextField就收回键盘
self.view.endEditing(true)
}
}
网络数据获取及网络状态监测封装的model
class URLService: NSObject {
//请求搜索的菜谱数据
func getSearchRecipes(search:String,vc:UIViewController,completion:@escaping (Any,Bool)->Void) {
// (1)判断无网络连接的情况
if Reachability.forLocalWiFi().currentReachabilityStatus() == NotReachable && Reachability.forInternetConnection().currentReachabilityStatus() == NotReachable {
vc.showAlert(msg: "网络错误,请检查错误", sec: 2.5)
completion("error",false)
return
}
// (2)状态栏中的菊花开始转动
UIApplication.shared.isNetworkActivityIndicatorVisible = true
// (3)网址字符串封装
let url = URL.init(string: "http://api.jisuapi.com/recipe/search")
// (4)创建请求对象
var req = URLRequest.init(url: url!, cachePolicy: .reloadRevalidatingCacheData, timeoutInterval: 15.0)
//设置请求方式为POST
req.httpMethod = "POST"
//将所有的参数拼接成一个字符串
let str = "keyword=\(search)&num=40&appkey=de394933e1a3e2db"
//设置请求对象的请求体
req.httpBody = str.data(using: .utf8)
// (5)会话对象请求服务器数据
URLSession .shared.dataTask(with: req) { (data, response, error) in
//停止菊花
DispatchQueue.main.async {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
}
//如果服务器连接失败
if error != nil {
DispatchQueue.main.async {
vc.showAlert(msg: "服务器连接超时", sec: 2.0)
}
return
}
//Json解析
let jsonData = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments)
if jsonData == nil {
DispatchQueue.main.async {
vc.showAlert(msg: "网络数据错误", sec: 2.0)
}
return
}
//如果正确,将解析的json数据返回给Controller
let jsonDic = jsonData as! NSDictionary
let status = jsonDic.value(forKey: "status") as! NSString
let msg = jsonDic.value(forKey: "msg") as! String
if status.intValue != 0 {
DispatchQueue.main.async {
vc.showAlert(msg: msg, sec: 2.0)
}
return
}
//得到json数据中result字段对应的字典
let resultDic = jsonDic.value(forKey: "result") as! NSDictionary
//获取result字典中list字典
let listArr = resultDic.value(forKey: "list") as! NSArray
//Model封装
var modelArr:[Recipe] = []
//遍历数组中的每一个字典
for item in listArr {
let itemDic = item as! NSDictionary
let one = Recipe()
one.name = itemDic.value(forKey: "name") as? String
one.id = itemDic.value(forKey: "id") as? String
one.content = itemDic.value(forKey: "content") as? String
modelArr.append(one)
}
completion(modelArr,true)
}.resume()
}
}
第二个界面请求的数据显示
class RecipeResultViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
var passString:String? = ""
var tableData:[Recipe]?
var table:UITableView?
//MARK: ------------ UITableViewDataSource -------------
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let count = tableData?.count {
return count
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let identifier = "cell"
var cell = tableView.dequeueReusableCell(withIdentifier: identifier)
if cell == nil {
cell = UITableViewCell(style: .subtitle, reuseIdentifier: identifier)
}
let one = self.tableData![indexPath.row] as? Recipe
cell?.textLabel?.text = one?.name
cell?.detailTextLabel?.text = one?.content
return cell!
}
override func viewDidLoad() {
super.viewDidLoad()
// 设置View的背景色
self.view.backgroundColor = UIColor.groupTableViewBackground
self.navigationItem.title = "\"\(passString!)的搜索结果\""
//实例化表格视图
table = UITableView(frame: CGRect(x: 0, y: 0, width: SCR_W, height: SCR_H), style: .plain)
table?.delegate = self
table?.dataSource = self
table?.rowHeight = 65
self.view.addSubview(table!)
}
override func viewWillAppear(_ animated: Bool) {
let urlser = URLService()
urlser.getSearchRecipes(search: self.passString!, vc: self) { (data, success) in
if !success {
return
}
self.tableData = data as? [Recipe]
DispatchQueue.main.async {
self.table?.reloadData()
}
}
}
}