zoukankan      html  css  js  c++  java
  • IOS整体项目层级构建

    在创建IOS项目时,若有一个比较明确的层级架构,将对于今后代码的维护或者功能的扩展很有帮助;本文将通过一个实例来展现我对于层级的一些观点;里面有一些零碎的知识点可能无法全部介绍,到时提供源代码进行下载,也希望有其它更好的观点可以提出来;

    一:首先了解整个项目的情况

    注意:项目中结合Pod进行一些第三方插件的管理,项目中已经把几个比较常用的第三方进行引用;因为上面几个都是比较常见的第三方插件,就不在这边详细介绍,关于如何使用Pod可以通过网上其它资料进行了解;对于如何一个项目创建多个Tag的知识也可以网上搜索;当然你也可以点击这边查看;

    二:主项目的分层情况

    注意:主项目中的分层主要包含四个模块,Main(主要)、Expand(扩展)、Resource(资源)、Vender(第三方),还有本项目是有多个Tag,用于区分不同的版本,比如本地环境测试版、产品版,主要是通过Tag来区分,不同的标识对应不同的连接地址;当然也可以设置其它不同的内容;

    2.1 Main(主要)模块的内容

    此模块主要目的是为了存放项目的页面内容,比如MVC的内容,Base(基类)用于存放一些公共的内容,其它功能模块的提取,方便继承调用;在本实例中已经在BaseController整理的一个公用的ViewController

    2.2 Expand(扩展)模块的内容

    此模块主要包含Const、Macros、Tool、NetWork、Category、DataBase六个子模块;

    2.2.1 Macros(宏)主要存放宏定义的地方,这边有两个宏文件,Macros.h主要是项目的一些主要宏,比如字体、版本、色值等,而ThirdMacros.h主要用于存放一些第三放SDK的key值;

    2.2.2 Tool(工具类)主要存放一些常用的类,此处Logger用于存放日志的封装帮助类,Reachability用于存放判断网络状态的帮助类;

    2.2.3 Network(网络)这边主要用到YTKNetwork 是猿题库 iOS 研发团队基于 AFNetworking 封装的 iOS 网络库,这边是对它进行一些修改,为了满足不同Tag及不同的功能模块可能访问不同URL的要求;

    2.2.4 Category(分类)主要用到Git上面iOS-Categories分类的内容,多创建一个Other用于存放平时要扩展的分类;

    2.3 Resource(资源)模块的内容

    资源模块主要包含三方面,Global(全局)、Image(图片)、Plist(配置文件);

    2.3.1 Global用于存放项目一些全局的内容,包含启动项的内容LaunchScreen.storyboard、头部引用PrefixHeader.pch、语言包File.strings

    2.3.2 Image用于存放图片资源,可以根据功能模块进行再分不同的xcassets文件;

    2.3.3 Plist用于存放plist文件,主要是本项目中会创建多个的Tag,而每个Tag都会有自个的plist文件进行管理,所以统一存放方便管理;

    2.4 Vender(第三方)模块的内容

    虽然项目中已经用Pod来管理第三方插件,但对于一些可能要进行修改的第三方可以存放在这边,本实例中引用的几个比较常用的第三方插件,简单介绍其中的几个,GVUserDefaults是对UserDefaults的封装,简单就可以用于存取操作;JDStatusBarNotification是在状态栏提示效果的插件;ActionSheetPicker底部弹出如时间选择、选项的插件;QBImagePickerController是照片选择插件,支持多选并可以设置最多选择张数;

    三:Network(网络)介绍

    因为项目中关于Network的运用比较多,本实例又对它进行的修改,这边就单独进行讲解;首先分享两个介绍关于YTKNetwork知识的连接地址;

    YTKNetwork 使用基础教程
    https://github.com/yuantiku/YTKNetwork/blob/master/BasicGuide.md

    YTKNetwork 使用高级教程
    https://github.com/yuantiku/YTKNetwork/blob/master/ProGuide.md

    在针对每个请求时,本实例又增加一个访问类型,用于区分对应的连接前缀

    #ifndef NetWorkEnvironment_h
    #define NetWorkEnvironment_h
    
    typedef NS_ENUM(NSInteger,SERVERCENTER_TYPE)
    {
        ACCOUNT_SERVERCENTER,
        PICTURE_SERVERCENTER,
        BUSINESSLOGIC_SERVERCENTER,
        UPDATEVERSION_SERVERCENTER
    };
    
    #endif /* NetWorkEnvironment_h */
    #import "NetWorkBaseUrlConfig.h"
    
    static NSString *const developer = @"developer";
    static NSString *const product = @"product";
    
    static NSString *const ACCOUNT_SERVERCENTER_Key=@"ACCOUNT_SERVERCENTER";
    static NSString *const PICTURE_SERVERCENTER_key=@"PICTURE_SERVERCENTER";
    static NSString *const BUSINESSLOGIC_SERVERCENTER_key=@"BUSINESSLOGIC_SERVERCENTER";
    static NSString *const UPDATEVERSION_SERVERCENTER_key=@"UPDATEVERSION_SERVERCENTER";
    
    @interface NetWorkBaseUrlConfig()
    @property(nonatomic ,assign) SERVERCENTER_TYPE netType;
    @property(nonatomic ,strong) NSMutableDictionary *configDictionary;
    //开发测试环境
    @property(nonatomic ,strong) NSDictionary *develpoerDictionary;
    //产品环境
    @property(nonatomic ,strong) NSDictionary *productDictionary;
    @end
    
    @implementation NetWorkBaseUrlConfig
    
    +(instancetype)shareconfig
    {
        static id share;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            share = [[NetWorkBaseUrlConfig alloc] init];
        });
        
        return share;
    }
    
    -(id)init
    {
        if (self == [super init]) {
            //测试环境
            self.develpoerDictionary=@{ACCOUNT_SERVERCENTER_Key:@"http://private-eda65-mock.com/",PICTURE_SERVERCENTER_key:@"图片前缀",BUSINESSLOGIC_SERVERCENTER_key:@"业务逻辑前缀",UPDATEVERSION_SERVERCENTER_key:@"版本升级前缀"};
            //产品环境
            self.productDictionary=@{ACCOUNT_SERVERCENTER_Key:@"http://private-eda66-mock.com/",PICTURE_SERVERCENTER_key:@"图片前缀",BUSINESSLOGIC_SERVERCENTER_key:@"业务逻辑前缀",UPDATEVERSION_SERVERCENTER_key:@"版本升级前缀"};
            
            self.configDictionary = [NSMutableDictionary dictionary];
            [self.configDictionary setObject:self.develpoerDictionary forKey:developer];
            [self.configDictionary setObject:self.productDictionary forKey:product];
        }
        return self;
    }
    
    -(NSString*)urlWithCenterType:(SERVERCENTER_TYPE)type
    {
        NSString *urlResult=@"";
        NSString *validEnvironment = @"";
        
        //过滤不同Tag
        #ifdef LOCAL
        validEnvironment=developer;
        #else
        validEnvironment=product;
        #endif
        
        NSString *urlKey = @"";
        switch (type) {
            case ACCOUNT_SERVERCENTER:
                urlKey = ACCOUNT_SERVERCENTER_Key;
                break;
            case PICTURE_SERVERCENTER:
                urlKey = PICTURE_SERVERCENTER_key;
                break;
            case BUSINESSLOGIC_SERVERCENTER:
                urlKey = BUSINESSLOGIC_SERVERCENTER_key;
                break;
            case UPDATEVERSION_SERVERCENTER:
                urlKey = UPDATEVERSION_SERVERCENTER_key;
                break;
            default:
                break;
        }
        urlResult = self.configDictionary[validEnvironment][urlKey];
        return urlResult;
    }
    
    @end

    注意:#ifdef LOCAL 就是区分不同的Tag标识,此项目把本地测试的Tag标识定为LOCAL,然后在每个请求中设置其要访问的类型;

    ACCOUNT_SERVERCENTER(登录地址前缀),PICTURE_SERVERCENTER(图片地址前缀),BUSINESSLOGIC_SERVERCENTER(业务逻辑前缀),UPDATEVERSION_SERVERCENTER(版本升级前缀)

    develpoerDictionary(测试),productDictionary(产品)用于存放不同的连接前缀地址,若有其它版本的Tag就要再创建相应的字典;

    #import "LogInApi.h"
    
    
    @interface LogInApi()
    {
        NSString *_username;
        NSString *_password;
    }
    @end
    
    @implementation LogInApi
    
    - (id)initWithUsername:(NSString *)username password:(NSString *)password {
        self = [super init];
        if (self) {
            _username = username;
            _password = password;
        }
        return self;
    }
    
    - (NSString *)requestUrl {
        return @"user/login";
    }
    
    - (YTKRequestMethod)requestMethod {
        return YTKRequestMethodPost;
    }
    
    -(SERVERCENTER_TYPE)centerType
    {
        return ACCOUNT_SERVERCENTER;
    }
    
    - (id)requestArgument {
        return @{
                 @"user_name": _username,
                 @"user_password": _password
                 };
    }
    
    @end

    此处设置访问的前缀为ACCOUNT_SERVERCENTER类型的地址

        LogInApi *reg = [[LogInApi alloc] initWithUsername:@"username" password:@"password"];
        [reg startWithCompletionBlockWithSuccess:^(YTKBaseRequest *request) {
            NSLog(@"状态码%ld",request.responseStatusCode);
            LoginModel *model=[[LoginModel alloc]initWithString:request.responseString error:nil];
            NSLog(@"响应内容:%@",model.access_token);
            
        } failure:^(YTKBaseRequest *request) {
            NSLog(@"Error");
        }];

    调用上面那个Api的操作内容;并对还回内容进行JSONModel转换;

    其它内容导航:

    IOS比较常用的第三方及实例(不断更新中)  地址:http://www.cnblogs.com/wujy/p/4747998.html

    IOS开发基础知识碎片-导航 地址:http://www.cnblogs.com/wujy/p/4571611.html

    源代码已上传到GitHub,大家可以一起完善,地址:https://github.com/wujunyang/MobileProject

  • 相关阅读:
    枚举
    张三先唱一遍要表演的歌曲,老师觉得张三唱歌不过关,
    不断要求用户输入一个数字(假定用户输入的都是正整数
    不断要求用户输入学生姓名,输入q结束.
    要求用户输入用户名和密码,只要不是admin、888888就
    计算1到100的整数和
    c# 九九乘法表
    c#三角形
    C#循环判断密码
    什么是发动机号,发动机号码是什么?
  • 原文地址:https://www.cnblogs.com/wujy/p/5104111.html
Copyright © 2011-2022 走看看