本章節主要講述利用MVC架構與AF網絡,搭建獲取到該需要的信息。以這種方式實現,主要是項目結構直觀明瞭,不會像從前那樣混亂。真正從事IT,是需要把項目歸納起來,讓別人看的舒適,也讓自己在今後的維護上有更好的優勢,那麼,具體實現也是非常之簡單的,跟着我一步一步地走…
它們的目錄名以MVC方式創建(model,view,controller);
- model:放置服務器的數據信息,如:jaon的請求,返回函數成功與失敗。
- view:該界面展示的UI,如利用Masonry方式。
- controller:控制器文件,主要寫功能,函數的調用與實現。如:model寫的請求體,在控制器加入相應代理,進行調用成功與失敗的結果,從而顯示該項目需求的功能。
也可以多一個cell文件,主要是把view層和cell聯合,view實現最外層的佈局,而cell則在view上進行佈局,實現剩餘的界面UI,進行展示描述。
具體程序如下所示:
一:Model層(device,devicebean兩個文件是該對應json數據的每個字符數,以及請求體的成功與失敗的返回)
<device.h>這個是獲取服務器json成功後的每一個對應的實際字符。
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Device : NSObject
@property(nonatomic, strong) NSString *userid;
@property(nonatomic, strong) NSString *companyid;
@property(nonatomic, strong) NSString *devicename;
@property(nonatomic, strong) NSString *address;
@property(nonatomic, strong) NSString *lat;
@property(nonatomic, strong) NSString *lon;
@property(nonatomic, strong) NSString *isonline;
@end
NS_ASSUME_NONNULL_END
<device.m>
#import "Device.h"
@implementation Device
@end
<devicebean.h>這個是服務器設置的data裏面的數據
#import <Foundation/Foundation.h>
#import "Device.h"
#import "BaseBean.h"
NS_ASSUME_NONNULL_BEGIN
@interface DeviceBean : BaseBean
@property(nonatomic,copy) NSString *code;
@property(nonatomic,copy) NSString *message;
@property(nonatomic,copy) NSArray *data;
+(NSDictionary*)mj_objectClassInArray;
@end
NS_ASSUME_NONNULL_END
<DeviceBean.m>
#import "DeviceBean.h"
@implementation DeviceBean
+(NSDictionary*)mj_objectClassInArray{
return @{@"data":[Device class],};
}
@end
<WifiModel.h> 這個文件主要寫json的返回函數,成功失敗的代理,以及設備的數據獲取;
#import <Foundation/Foundation.h>
#import "BaseModel.h"
#import "AFNetRequest.h"
#import "DeviceBean.h"
@protocol WifiModelDelegate <NSObject>
- (void)WifiSuccess:(NSString * _Nullable) result;
- (void)WifiFail:(NSString * _Nullable) result;
@end
NS_ASSUME_NONNULL_BEGIN
@interface WifiModel : BaseModel
@property(weak,nonatomic) id<WifiModelDelegate> delegate;
-(void)getAllDevice:(NSString *)userid;
//設備名稱
@property(copy,nonatomic) NSString *deviceName;
//設備RSSI的值
@property(copy,nonatomic) NSString *deviceRssi;
//設備的MAC地址
@property(copy,nonatomic) NSString *deviceAddre;
@property(assign,nonatomic) BOOL isselect;
@end
NS_ASSUME_NONNULL_END
<WifiModel.m>重點是這個,請求的函數體。所有的請求都歸根於此。要詳細的好好看看哦。
#import "WifiModel.h"
@implementation WifiModel
-(void)getAllDevice:(NSString *)userid{
NSString *strUrl = [NSString stringWithFormat:@"%@device/getAllDevice",BASE_URL];
NSDictionary *params = @{@"userid":userid
};
[[AFNetRequest sharedInstance] setHeaderWithValue:@"xx10925" HeaderField:@"token"];
[[AFNetRequest sharedInstance] POST:strUrl Parameters:params Success:^(id _Nullable responseObject){
DeviceBean *bean = [DeviceBean mj_objectWithKeyValues:responseObject];
if([bean.code isEqual:@"200"]){
if([self.delegate respondsToSelector:@selector(WifiSuccess:)]){
[self.delegate WifiSuccess:bean.data];
}
}else{
if([self.delegate respondsToSelector:@selector(WifiFail:)]){
[self.delegate WifiFail:bean.message];
}
}
} Failure:^(NSError * _Nonnull error){
if([self.delegate respondsToSelector:@selector(WifiFail:)]){
[self.delegate WifiFail:error.localizedDescription];
}
} Cookie:^(NSURLSessionDataTask * _Nullable task){
if (@available(iOS 11.0, *)) {
NSLog(@"%@",task.accessibilityAttributedLabel);
} else {
// Fallback on earlier versions
}
}];
}
@end
二:View層(這個是總佈局)
<WifiView.h>
#import <UIKit/UIKit.h>
@interface WifiView : UIView
//設置代理
@property(nonatomic,strong) UITableView *mDeviceTb;
@end
<WifiView.m>
#import "WifiView.h"
#ifdef __OBJC__
//define this constant if you want to use Masonry without the 'mas_' prefix
#define MAS_SHORTHAND
//define this constant if you want to enable auto-boxing for default syntax
#define MAS_SHORTHAND_GLOBALS
#import "Masonry.h"
#endif
@implementation WifiView
-(instancetype) init{
self = [super init];
if(self){
[self initView];
}
return self;
}
-(void)initView{
self.mDeviceTb = [[UITableView alloc] init];
[self addSubview:self.mDeviceTb];
//佈局
[self.mDeviceTb makeConstraints:^(MASConstraintMaker *make){
make.left.equalTo(self).offset(0);
make.right.equalTo(self).offset(0);
make.top.equalTo(self).offset(0);
make.bottom.equalTo(self).offset(-49);
}];
}
@end
三:Cell(這個是在view外層上再進行寫該需求的樣式)
<WifiCell.h>
#import <UIKit/UIKit.h>
#import "CommonUtil.h"
@interface WifiCell : UITableViewCell
@property(nonatomic,strong) UIView *mMainVw;
@property (strong, nonatomic) UILabel *mDeviceNameLb;
@property (strong, nonatomic) UILabel *mDeviceRssiLb;
@property (strong, nonatomic) UILabel *mDeviceAddreLb;
@property(nonatomic,strong) UIImageView *mStatusIv;
@end
<WifiCell.m>
#import "WifiCell.h"
#ifdef __OBJC__
//define this constant if you want to use Masonry without the 'mas_' prefix
#define MAS_SHORTHAND
//define this constant if you want to enable auto-boxing for default syntax
#define MAS_SHORTHAND_GLOBALS
#import "Masonry.h"
#endif
@implementation WifiCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if(self){
CommonUtil *cmUtil = [[CommonUtil alloc] init];
self.mMainVw = [[UIView alloc] init];
self.mMainVw.backgroundColor = [cmUtil stringToColor:@"#EAEAEA"];
self.mMainVw.layer.cornerRadius = 5.f;
self.mMainVw.clipsToBounds=YES;
self.mMainVw.layer.shadowColor=[UIColor blackColor].CGColor;
self.mMainVw.layer.shadowOffset=CGSizeMake(5, 5);
self.mMainVw.layer.shadowOpacity=0.5;
self.mMainVw.layer.shadowRadius=5;
[self addSubview:self.mMainVw];
[self.mMainVw makeConstraints:^(MASConstraintMaker *make){
make.top.equalTo(self).offset(10);
make.left.equalTo(self).offset(10);
make.right.equalTo(self).offset(-10);
make.height.equalTo(self).offset(-10);
}];
self.mStatusIv = [[UIImageView alloc] init];
[self.mMainVw addSubview:self.mStatusIv];
[self.mStatusIv makeConstraints:^(MASConstraintMaker *make){
make.top.equalTo(self.mMainVw).offset(30);
make.left.equalTo(self.mMainVw).offset(15);
make.width.equalTo(@25);
make.height.equalTo(@25);
}];
self.mDeviceNameLb = [[UILabel alloc] init];
self.mDeviceNameLb.textColor = [UIColor blackColor];
self.mDeviceNameLb.font = [UIFont fontWithName:@"Helvetica-Bold" size:18];
self.mDeviceNameLb.textAlignment = NSTextAlignmentCenter;
[self.mMainVw addSubview:self.mDeviceNameLb];
[self.mDeviceNameLb makeConstraints:^(MASConstraintMaker *make){
make.top.equalTo(self.mMainVw).offset(10);
make.left.equalTo(self.mMainVw).offset(55);
make.right.equalTo(self.mMainVw).offset(-10);
make.height.equalTo(@30);
}];
self.mDeviceAddreLb = [[UILabel alloc] init];
self.mDeviceAddreLb.textColor = [UIColor grayColor];
self.mDeviceAddreLb.font = [UIFont fontWithName:@"Helvetica" size:14];
self.mDeviceAddreLb.textAlignment = NSTextAlignmentCenter;
[self.mMainVw addSubview:self.mDeviceAddreLb];
[self.mDeviceAddreLb makeConstraints:^(MASConstraintMaker *make){
make.top.equalTo(self.mDeviceNameLb).offset(40);
make.left.equalTo(self.mMainVw).offset(58);
make.right.equalTo(self.mMainVw).offset(-10);
make.height.equalTo(@30);
}];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
@end
四:Controller(主控制器文件,上面也描述了,就是寫他的功能文件,調用外部的數據,與其他的一些邏輯)
<WifiController.h>
#import <UIKit/UIKit.h>
#import "BaseTableViewController.h"
#import "WifiView.h"
#import "WifiModel.h"
#import "WifiCell.h"
NS_ASSUME_NONNULL_BEGIN
@interface WifiController : BaseTableViewController
@property(nonatomic,strong) WifiView *WfView;
@property(nonatomic,strong) WifiModel *WfModel;
@property(nonatomic,strong) WifiCell *WfCell;
@property(strong, nonatomic) NSMutableArray *dcList;
@end
NS_ASSUME_NONNULL_END
<WifiController.m>
#import "WifiController.h"
#define CELLIDENTIFITER "DEVICETABLEVIEWCELLS"
@interface WifiController ()<WifiModelDelegate,UITableViewDataSource, UITableViewDelegate>{
}
@property(nonatomic,strong) NSString *userid;
@end
@implementation WifiController
- (void)viewDidLoad {
[super viewDidLoad];
[self initData];
}
//添加頭部
- (void)customContentView{
UIColor *commonBlue = [self.commonUtil stringToColor:@"#333333"];
[self.navigationController.navigationBar setBarTintColor:commonBlue];
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
self.navigationItem.title = @"WI-FI";
//創建下啦刷新
NSString *dropscan = NSLocalizedString(@"dropscan", nil);
UIRefreshControl *rc = [[UIRefreshControl alloc] init];
rc.attributedTitle = [[NSAttributedString alloc] initWithString:dropscan];
[rc addTarget:self action:@selector(redreshTableView) forControlEvents:UIControlEventValueChanged];
self.refreshControl = rc;
}
-(void)initData{
[self getWfModel];
[self getDeviceView];
self.WfView.frame = self.view.bounds;
[self.view addSubview:self.WfView];
self.tableView.delegate = self;
self.tableView.dataSource = self;
UIView *view = [[UIView alloc] init];
self.tableView.tableFooterView =view;
self.tableView.separatorStyle = NO;//隱藏分割線
//_userid = [[CommonUserDefaults shared] getValue:USERID];
//得到wifi數據
//[self.wfModel getWifiData];
}
/*
程序加載的時候調用
*/
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
if(_userid){
[self.WfModel getAllDevice:@"1"];
}else{
[self.WfModel getAllDevice:@"1"];
}
if (self.refreshControl.refreshing) {
//TODO: 已經在刷新數據了
NSLog(@"12233");
} else {
NSLog(@"y is %f",self.tableView.contentOffset.y);
if (self.tableView.contentOffset.y == -64.0) {
[UIView animateWithDuration:0.25
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^(void){
self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height);
} completion:^(BOOL finished){
[self.refreshControl beginRefreshing];
[self.refreshControl sendActionsForControlEvents:UIControlEventValueChanged];
}];
}
}
}
//讀取刷新TableView
-(void)redreshTableView{
if(self.refreshControl.refreshing){
self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:@"Refresh"];
if(_userid){
[self.WfModel getAllDevice:@"1"];
}else{
[self.WfModel getAllDevice:@"1"];
}
[self.refreshControl endRefreshing];
self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:@"Down Refresh"];
//掃描
//[self.tableView reloadData];
//[self stopscan];
}
}
-(WifiView *)getDeviceView{
if(self.WfView==nil){
self.WfView = [[WifiView alloc] init];
self.WfView.mDeviceTb.delegate = (id)self;
self.WfView.mDeviceTb.dataSource = (id)self;
}
return self.WfView;
}
-(WifiModel*)getWfModel{
if(self.WfModel==nil){
self.WfModel = [[WifiModel alloc] init];
self.WfModel.delegate = (id)self;
}
return self.WfModel;
}
-(NSMutableArray*)dcList{
if(!_dcList){
_dcList = [NSMutableArray array];
}
return _dcList;
}
#pragma mark
-(void)WifiSuccess:(NSArray *_Nullable) result{
// [self.WfView.mDeviceTb.mj_header endRefreshing];
if(result.count>0){
self.dcList = [NSMutableArray arrayWithArray:result];
[self.WfView.mDeviceTb reloadData];
NSLog(@"d%@wo wo shi result",result);
// [self.WfView.mDeviceTb reloadData];
}
}
-(void)WifiFail:(NSString *_Nullable) result{
NSLog(@"d%@uowula",result);
}
#pragma mark tableView
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.dcList.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
WifiCell *cell = [tableView dequeueReusableCellWithIdentifier:@CELLIDENTIFITER];
if (cell == nil) {
cell = [[WifiCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@CELLIDENTIFITER];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.mMainVw.hidden = NO;
if(self.dcList.count>0){
if([indexPath row]<self.dcList.count){
Device *device = [self.dcList objectAtIndex:indexPath.row];
cell.mDeviceNameLb.text = device.devicename;
cell.mDeviceAddreLb.text = device.address;
if([device.isonline isEqualToString:@"1"]){
[cell.mStatusIv setImage:[UIImage imageNamed:@"yes"]];
}else{
[cell.mStatusIv setImage:[UIImage imageNamed:@"tip"]];
}
}
}
// cell.mDeviceNameLb.text = @"datcva";
// cell.mDeviceAddreLb.text = @"82:31:32:19:ab:39";
return cell;
}
//定義列的高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 60;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
//用完之後需要關閉掉
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
/*if ([self.deviceTimer isValid]) {
[self.deviceTimer invalidate];
}
self.deviceTimer = nil;*/
}
@end
OK,本章節就講述到此爲止。利用Masonry+MVC+AFNetworking實現動態獲取列表,這樣更具清晰,代碼閱讀維護也方便,功能親測是可以的,只要各位看官跟着我一步一步來,相信是沒有問題的,代碼都在以上,如需看demo,此處是鏈接:https://download.csdn.net/download/qq_37523448/11262582
若有不懂之處或不對之處,歡迎留言以及評論,一起努力解決項目需求,謝謝您的閱讀,再見!~by