URLService.Swift
import UIKit
class URLService: NSObject {
//请求搜索的菜谱数据
func searchRecipes(search:String,vc:UIViewController,completion:@escaping(Any,Bool) -> Void) {
//(1)判断无网络情况
if Reachability.forLocalWiFi().currentReachabilityStatus() == NotReachable && Reachability.forInternetConnection().currentReachabilityStatus() == NotReachable {
vc.showAlert(meg:"网络错误,请检查网路", 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: .reloadIgnoringLocalCacheData, timeoutInterval:15.0)
//设置请求方式为POST
req.httpMethod="POST"
//将所有的参数拼接成一个字符串
let str = "keyword=\(search)&num=10&appkey=de394933e1a3e2db"
//设置请求对象的请求体
req.httpBody= str.data(using: .utf8)
//(5)会话对象请求服务器数据
URLSession.shared.dataTask(with: req) { ( data:Data?, response:URLResponse?, error:Error?)in
//停止菊花
DispatchQueue.main.async {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
}
//如果服务器来连接失败
if error != nil {
DispatchQueue.main.async{
vc.showAlert(meg:"服务器超时", sec:2.5)
}
return
}
//JSON解析
let jsonData = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments)
if jsonData == nil{
DispatchQueue.main.async{
vc.showAlert(meg:"网络数据错误", sec:2.5)
}
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(meg: msg, sec:2.5)
}
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()
}
}
RecipeViewController.Swift
import UIKit
let scrW = UIScreen.main.bounds.size.width
let scrH = UIScreen.main.bounds.size.height
//给UIViewController类添加扩展
extension UIViewController {
funcshowAlert(meg:String,sec:TimeInterval) {
//实例化弹出控制器
letalertVC =UIAlertController(title:nil, message: meg, preferredStyle: .alert)
//从vc控制器弹出提示控制器
self.present(alertVC, animated:true, completion:nil)
//延时执行隐藏操作
self.perform(#selector(hideAlertVC(sender:)), with: alertVC, afterDelay: sec)
}
@objcfunchideAlertVC(sender:UIAlertController) {
sender.dismiss(animated:true, completion:nil)
}
}
class RecipeViewController: UIViewController,UITextFieldDelegate {
varrecipeTF:UITextField?// 菜谱输入框
varsearchBtn:UIButton?// 搜索按钮
overridefuncviewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.view.backgroundColor = UIColor.white
recipeTF=UITextField(frame:CGRect(x:0, y:0, width:200, height:50))
recipeTF?.center=CGPoint(x:scrW/2, y:200)
recipeTF?.borderStyle= .line
recipeTF?.placeholder="请输入查询的菜谱"
recipeTF?.textColor = UIColor.blue
recipeTF?.textAlignment= .center
recipeTF?.clearButtonMode = .whileEditing
recipeTF?.delegate=self
self.view.addSubview(recipeTF!)
searchBtn=UIButton(frame:CGRect(x:0, y:0, width:100, height:50))
searchBtn?.center=CGPoint(x:scrW/2, y:300)
searchBtn?.setTitle("点击查询", for: .normal)
searchBtn?.backgroundColor = UIColor.blue
searchBtn?.setTitleColor(UIColor.yellow, for: .normal)
searchBtn?.addTarget(self, action:#selector(btnDidPress(sender:)), for: .touchUpInside)
self.view.addSubview(searchBtn!)
}
@objcfuncbtnDidPress(sender:UIButton) {
if(recipeTF?.text?.isEmpty)! {
self.showAlert(meg:"信息不可为空", sec:2.5)
return
}
//实例化结果控制器
let resultVC = RecipeResultViewController()
//传递数据
resultVC.passString=recipeTF!.text!
//控制器跳转
self.navigationController?.pushViewController(resultVC, animated:true)
}
overridefuncdidReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK:-------------------UITextFieldDelegate-----------------------
//点击return按钮触发回调
functextFieldShouldReturn(_textField:UITextField) ->Bool{
//放弃第一响应
textField.resignFirstResponder()
return true
}
//MARK:-------------------Touches Methods-------------------
overridefunctouchesEnded(_touches:Set, with event:UIEvent?) {
super.touchesEnded(touches, with: event)
//
recipeTF?.resignFirstResponder()
//将View及其字视图都放弃编辑,如果是Textfield就收回键盘
self.view.endEditing(true)
}
RecipeResultViewController.Swift
import UIKit
class RecipeResultViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
varpassString:String=""
vartableData:[Recipe]?
vartable:UITableView?
overridefuncviewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.view.backgroundColor = UIColor.white
self.navigationItem.title = "\"\(passString)\"的搜索结果"
//实例化表格
table=UITableView(frame:CGRect(x:0, y:0, width:scrW, height:scrH), style:UITableViewStyle.plain)
table?.dataSource=self
table?.delegate=self
self.view.addSubview(table!)
}
overridefuncviewWillAppear(_animated:Bool) {
//请求网络数据
leturlSer =URLService()
urlSer.searchRecipes(search:self.passString, vc:self) { (data, success)in
if!success {
return
}
self.tableData= dataas? [Recipe]
DispatchQueue.main.async {
self.table?.reloadData()
}
}
}
functableView(_tableView:UITableView, numberOfRowsInSection section:Int) ->Int{
ifletcount =tableData?.count{
returncount
}
return0
}
functableView(_tableView:UITableView, cellForRowAt indexPath:IndexPath) ->UITableViewCell{
letidentifier ="cell"
varcell = tableView.dequeueReusableCell(withIdentifier: identifier)
ifcell ==nil{
cell =UITableViewCell.init(style: .subtitle, reuseIdentifier: identifier)
}
letone =self.tableData![indexPath.row]as?Recipe
cell?.textLabel?.text= one?.name
cell?.detailTextLabel?.text= one?.content
returncell!