主頁(yè)面(須要導(dǎo)入OC的Reachability3.0第三方文件(須要導(dǎo)入橋接文件)
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添加擴(kuò)展 ------------
extension?UIViewController?{
?//MARK: ---------------- 包裝的提示框 ------------------
?func?showAlert(msg:String,sec:TimeInterval) {
?// 實(shí)例化彈出控制器
?let?alertVC =?UIAlertController(title:?nil, message: msg, preferredStyle: .alert)
?// 從vc控制器彈出提示控制器
?self.present(alertVC, animated:?true, completion:?nil)
?//延時(shí)執(zhí)行隱藏操作
?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()
?// 設(shè)置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?=?"請(qǐng)輸入查詢的菜譜"
?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("點(diǎn)擊查詢", 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: ---------------- 觸摸回調(diào) ---------------------
?@objc?func?searchBtnDidPress(sender:UIButton) {
?if?(recipeTF?.text?.isEmpty)! {
?self.showAlert(msg:?"信息不可為空", sec:?2.5)
?return
? ? ? ? }
?// 實(shí)例化結(jié)果控制器對(duì)象
?let?resultVC =?RecipeResultViewController()
?// 傳遞數(shù)據(jù)
resultVC.passString?=?recipeTF?.text
?//控制器跳轉(zhuǎn)
?self.navigationController?.pushViewController(resultVC, animated:?true)
? ? }
?//MARK: ---------------- UITextFieldDelegate ---------------
?// 點(diǎn)擊return按鈕觸發(fā)回調(diào)
?func?textFieldShouldReturn(_?textField:?UITextField) ->?Bool?{
?// 放棄第一響應(yīng)
? ? ? ? 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)
? ? }
}
網(wǎng)絡(luò)數(shù)據(jù)獲取及網(wǎng)絡(luò)狀態(tài)監(jiān)測(cè)封裝的model
class?URLService:?NSObject?{
?//請(qǐng)求搜索的菜譜數(shù)據(jù)
?func?getSearchRecipes(search:String,vc:UIViewController,completion:@escaping?(Any,Bool)->Void) {
?// (1)判斷無(wú)網(wǎng)絡(luò)連接的情況
?if?Reachability.forLocalWiFi().currentReachabilityStatus() ==?NotReachable?&&?Reachability.forInternetConnection().currentReachabilityStatus() ==?NotReachable?{
vc.showAlert(msg:?"網(wǎng)絡(luò)錯(cuò)誤,請(qǐng)檢查錯(cuò)誤", sec:?2.5)
completion("error",false)
?return
? ? ? ? }
?//? (2)狀態(tài)欄中的菊花開始轉(zhuǎn)動(dòng)
?UIApplication.shared.isNetworkActivityIndicatorVisible?=?true
?// (3)網(wǎng)址字符串封裝
?let?url =?URL.init(string:?"http://api.jisuapi.com/recipe/search")
?// (4)創(chuàng)建請(qǐng)求對(duì)象
?var?req =?URLRequest.init(url: url!, cachePolicy: .reloadRevalidatingCacheData, timeoutInterval:?15.0)
?//設(shè)置請(qǐng)求方式為POST
req.httpMethod?=?"POST"
?//將所有的參數(shù)拼接成一個(gè)字符串
?let?str =?"keyword=\(search)&num=40&appkey=de394933e1a3e2db"
?//設(shè)置請(qǐng)求對(duì)象的請(qǐng)求體
req.httpBody?= str.data(using: .utf8)
?// (5)會(huì)話對(duì)象請(qǐng)求服務(wù)器數(shù)據(jù)
?URLSession?.shared.dataTask(with: req) { (data, response, error)?in
?//停止菊花
?DispatchQueue.main.async?{
?UIApplication.shared.isNetworkActivityIndicatorVisible?=?false
? ? ? ? ? ? }
?//如果服務(wù)器連接失敗
?if?error !=?nil?{
?DispatchQueue.main.async?{
vc.showAlert(msg:?"服務(wù)器連接超時(shí)", sec:?2.0)
? ? ? ? ? ? ? ? }
?return
? ? ? ? ? ? }
?//Json解析
?let?jsonData =?try??JSONSerialization.jsonObject(with: data!, options: .allowFragments)
?if?jsonData ==?nil?{
?DispatchQueue.main.async?{
vc.showAlert(msg:?"網(wǎng)絡(luò)數(shù)據(jù)錯(cuò)誤", sec:?2.0)
? ? ? ? ? ? ? ? }
?return
? ? ? ? ? ? }
?//如果正確晦溪,將解析的json數(shù)據(jù)返回給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
? ? ? ? ? ? }
?//得到j(luò)son數(shù)據(jù)中result字段對(duì)應(yīng)的字典
?let?resultDic = jsonDic.value(forKey:?"result")?as!?NSDictionary
?//獲取result字典中l(wèi)ist字典
?let?listArr = resultDic.value(forKey:?"list")?as!?NSArray
?//Model封裝
?var?modelArr:[Recipe] = []
?//遍歷數(shù)組中的每一個(gè)字典
?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()
? ? }
}
第二個(gè)界面請(qǐng)求的數(shù)據(jù)顯示
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()
?// 設(shè)置View的背景色
?self.view.backgroundColor?=?UIColor.groupTableViewBackground
?self.navigationItem.title?=?"\"\(passString!)的搜索結(jié)果\""
?//實(shí)例化表格視圖
?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()
? ? ? ? ? ? }
? ? ? ? }
? ? }
}