zoukankan      html  css  js  c++  java
  • 如何搭建iOS项目基本框架

    今天我们来谈谈如何搭建框架,框架需要做一些什么。

    第一步:找到我们的目标
    我们的目标是让其他开发人员拿到手后即可写页面,不再需要考虑其他的问题。


    第二步:我们需要做哪些东西
    各位跟着我一步一步来进行。

    假定我们即将要写的项目是一个tabbar+navgation的项目结构。

    1. 新建工程

    1.1 删除不必要类目

    选择Single ViewApplication,命名为HomeHome
    删除选中的三项。


    删除选中的三项

    1.2 修改info.plist

    1.删除info.plist main.storyboard字段


    main.storyboard

    2.添加字段
    info.plist 中添加以下
    Bundle display name --- 对应应用名
    开启http访问,不添加该字段导致不能访问http,只能访问https。


    开启http

    3.添加应用白名单
    iOS9之后分享等必须添加白名单后才可以打开相关应用。字段值为LSApplicationQueriesSchemes

    1. 添加URL Types
      用于分享到QQ,微信等平台或者打开支付宝等,已经设置当前APP的Url shesmes

    1.3 修改项目配置

    1. 关闭bitCode
      build setting中搜索bitCode 改为NO

    2.配置项目

    2.1 建立目录


    项目目录

    2.2 拖入各大依赖库

    我在这里主要依赖了以下库:

    AFNetWorking 网络请求
    SDWebImage 图片加载
    MWPhotoBrowser 图片浏览器
    MJRefresh 刷新加载控件
    RDVTabBarController 一个很好用的tabbar控件
    MBProgressHUD 菊花转圈
    NJKWebViewProgress webview的加载进度条
    Masonry 用于适配

    2.3 依赖常用第三方服务

    通常集成了:

    友盟分享
    极光推送
    腾讯bugly
    Mob验证码服务

    均根据官方文档安装

    3. 编写代码

    3.1 建立pch

    xcode6之后建立pch 参考该网址

    3.1 建立Api.h文件

    该声明文件用于查询接口等

    3.2 建立Config.h文件

    该声明文件用于编写某些全局配置参数
    如以下:

    #define kPushPhotoBrowserNotifitationName @"PushPhotoBrowser"
    #define kPresentVideoPlayerNotifitationName @"playCallBackVideo"
    
    #define APPICONIMAGE [UIImage imageNamed:[[[[NSBundle mainBundle] infoDictionary] valueForKeyPath:@"CFBundleIcons.CFBundlePrimaryIcon.CFBundleIconFiles"] lastObject]]
    #define APPNAME [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]
    #define Main_Color [UIColor colorWithRed:(3)/255.0 green:(160)/255.0 blue:(235)/255.0 alpha:1.0]
    #define Main2_Color [UIColor colorWithRed:(135)/255.0 green:(202)/255.0 blue:(231)/255.0 alpha:1.0]
    #define VTColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0]
    #define Text_Color [UIColor colorWithRed:(51)/255.0 green:(71)/255.0 blue:(113)/255.0 alpha:1.0]
    #define BackGround_Color [UIColor colorWithRed:(235)/255.0 green:(235)/255.0 blue:(241)/255.0 alpha:1.0]
    
    #define Default_Person_Image [UIImage imageNamed:@"default_parents"]
    #define Default_General_Image [UIImage imageNamed:@"default_general"]
    
    #define kScreenW [UIScreen mainScreen].bounds.size.width
    #define kScreenH [UIScreen mainScreen].bounds.size.height
    //以及各种第三方服务商的appId或者App key

    3.3 开始编写项目结构

    我们分别建立了3个AppDelegate的类别

    HHAppDelegate+AppService //app的服务管理
    HHAppDelegate+AppLifeCircle//app的生命周期管理
    HHAppDelegate+RootController//app的跟视图控制器实例

    先看看HHAppDelegate+RootController

    声明文件

    /**
     *  首次启动轮播图
     */
    - (void)createLoadingScrollView;
    /**
     *  tabbar实例
     */
    - (void)setTabbarController;
    
    /**
     *  window实例
     */
    - (void)setAppWindows;
    
    /**
     *  设置根视图
     */
    - (void)setRootViewController;

    实现:

    - (void)setRoot
    {
        UINavigationController * navc = [[UINavigationController alloc] initWithRootViewController:self.viewController];
        navc.navigationBar.barTintColor = Main_Color;
    
        navc.navigationBar.shadowImage = [[UIImage alloc] init];
        [navc.navigationBar setTranslucent:NO];
    
        [[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];
    
        [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
    
        [navc.navigationBar setTitleTextAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:19],NSForegroundColorAttributeName:[UIColor whiteColor]}];
        navc.navigationBar.tintColor = [UIColor whiteColor];
        self.window.rootViewController = navc;
    }
    
    - (void)setTabbarController
    {
        HomePageViewController *school = [[HomePageViewController alloc]init];
       AboutChildViewController *child  = [[AboutChildViewController alloc]init];
        CommuntiyViewController *edu = [[CommuntiyViewController alloc]init];
        SZCourseListViewController *courseList = [[SZCourseListViewController alloc]init];
        AboutMeViewController *about = [[AboutMeViewController alloc]init];
        RDVTabBarController *tabBarController = [[RDVTabBarController alloc] init];
        [tabBarController setViewControllers:@[school,edu,child,courseList,about]];
        self.viewController = tabBarController;
        tabBarController.delegate = self;
        [self customizeTabBarForController:tabBarController];
    }
    
    - (void)setAppWindows
    {
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        self.window.backgroundColor = [UIColor whiteColor];
        [[UIApplication sharedApplication]setStatusBarHidden:NO];
        [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent];
    
        [[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor]}];
    }
    
    
    - (void)createLoadingScrollView
    {
      //引导页实例
    }

    注意:这里将Navgation作为根视图控制器,tabbar作为Navgation的rootViewController。
    如此全局只有一个跟导航控制器。页面Controller与Tabbar处于平级状态。这与接下来我们弹出各种页面均由关联
    自此一个大致的结构就出来了,一个Tabbar+Navgation的格式

    3.4 编写AppService

    这类信息大都跟需求有关,我们在这里处理项目相关信息。如可能会由以下信息

    - (void)registerBugly;
    
    /**
     *  基本配置
     */
    - (void)configurationLaunchUserOption;
    
    /**
     *  友盟注册
     */
    - (void)registerUmeng;
    /**
     *  Mob注册
     */
    
    - (void)registerMob;
    
    /**
     *  检查更新
     */
    - (void)checkAppUpDataWithshowOption:(BOOL)showOption;
    
    /**
     *  上传用户设备信息
     */
    - (void)upLoadMessageAboutUser;
    
    /**
     *  检查黑名单用户
     */
    -(void)checkBlack;

    3.5 App结构整理

    以上我们处理了跟视图,服务,app声明周期等方法实现
    现在我们开始调用这些方法。

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        [self setAppWindows];
        [self setTabbarController];
        [self setRootViewController];
    
        [self configurationLaunchUserOption];
    
        [self registerBugly];
    
        [self registerMob];
    
        [self registerUmeng];
    
        [VTJpushTools setupWithOptions:launchOptions];
    
        [self upLoadMessageAboutUser];
    
        [self checkAppUpDataWithshowOption:NO];
    
        [SZNotificationCenter addObserver:self selector:@selector(phontoBroserPush:) name:kPushPhotoBrowserNotifitationName object:nil];
        [SZNotificationCenter addObserver:self selector:@selector(playCallBackVideo:) name:kPresentVideoPlayerNotifitationName object:nil];
        [self.window makeKeyAndVisible];
    
        return YES;
    }

    好了,我们着重说一下这里两个通知。
    分别是收到图片查看的通知、视频播放的通知
    这里以查看图片举列。我们认为查看图片是push到一个新页面中去。

    因此我们需要找到导航控制器
    根据之前所说,当前结构中只有一个导航控制器就是Root

    + (UINavigationController *)rootNavigationController
    {
        HHAppDelegate *app = (HHAppDelegate *)[UIApplication sharedApplication].delegate;
        return (UINavigationController *)app.window.rootViewController;
    }

    找到控制器后就变得简单的多了。
    我们开始实现:

    这里我们对传来的数据格式由一定要求,类似于这样的一个格式。

    @{@"imageInfo":@[HHImageInfo*info,HHImageInfo *info2],@"index":@3};

    原因:图片一般有高清图片和非高清图片两种格式。以及图片有可能带有文字描述。因此引入ImageInfo。

    - (void)phontoBroserPush:(NSNotification *)note
    {
        self.imageArr = [NSMutableArray arrayWithCapacity:0];
        [self.imageArr removeAllObjects];
    
        NSDictionary *dic = note.object;
        NSArray *arr = dic[@"imageInfo"];
        NSInteger index = [dic[@"index"] integerValue];
        self.imageIndex = index;
        for(HHImageInfo *info in arr)
        {
            //[self.imageArr addObject:info.url];
            MWPhoto *photo = [MWPhoto photoWithURL:[NSURL URLWithString:info.url]];
            photo.caption = info.desc;
            [self.imageArr addObject:photo];
        }
    
        MWPhotoBrowser *browser = [[MWPhotoBrowser alloc]initWithDelegate:self];
        browser.zoomPhotosToFill = YES;
    
        browser.displayNavArrows = YES;
        browser.displayActionButton = NO;
        browser.alwaysShowControls = NO;
        browser.autoPlayOnAppear = YES;
        [browser setCurrentPhotoIndex:index];
        [[HHAppDelegate rootNavigationController]pushViewController:browser animated:YES];
    }

    到这里,其他开发人员在进行模块开发的时候需要图片浏览器的时候直接发送通知即可集成。

    HHImageInfo中

    @property (nonatomic,strong)NSString *desc;
    
    @property (nonatomic,strong)NSString *url;
    
    //@property (nonatomic,assign)NSInteger imageIndex;
    
    + (NSString *)getHUDImageUrl:(NSString *)smallImageUrl;

    实现:

    + (NSString *)getHUDImageUrl:(NSString *)smallImageUrl
    {
        NSMutableString *str = [NSMutableString stringWithString:smallImageUrl];
        NSRange substr = [str rangeOfString:@"_thu"];
        while (substr.location != NSNotFound)
        {
            [str replaceCharactersInRange:substr withString:@""];
            substr = [str rangeOfString:@"_thu"];
        }
        [str insertString:@"" atIndex:0];
        return str;
    }

    4. 其他配置

    4.1 rootViewController -- 所有页面均继承该控制器

    我通常在RootViewController实现以下方法以供调用

    /**
     *  显示没有数据页面
     */
    -(void)showNoDataImage;
    
    /**
     *  移除无数据页面
     */
    -(void)removeNoDataImage;
    
    /**
     *  需要登录
     */
    - (void)showShouldLoginPoint;
    
    /**
     *  加载视图
     */
    - (void)showLoadingAnimation;
    
    /**
     *  停止加载
     */
    - (void)stopLoadingAnimation;
    
    /**
     *  分享页面
     *
     *  @param url   url
     *  @param title 标题
     */
    - (void)shareUrl:(NSString *)url andTitle:(NSString *)title;
    
    - (void)goLogin;
    
    /**
     *  状态栏
     */
    - (void)initStatusBar;
    
    - (void)showStatusBarWithTitle:(NSString *)title;
    
    - (void)changeStatusBarTitle:(NSString *)title;
    - (void)hiddenStatusBar;

    具体实现方法请看demo

    Demo下载
    有点乱七八糟,但是你明白我的意思对不?


    2016.04.29

    • 关于中文文件夹:咱们提倡使用英文。但是不反对中文.

    楼主认为所有便于开发的操作都是可以允许的。

    我接手过那么几个项目,内部蹩脚(或高端)的英文让我猝不及防。我多想他用的是拼音我就不会理解的那么困难了。

    • 关于pod:demo只是提供了一种思路与步骤,仅做参考。继承第三方库方式就看个人了。
    • 关于stroyboad:不利于团队开发。

  • 相关阅读:
    浅谈 Nginx 的内部核心架构设计
    项目中常用的19条MySQL优化
    Redis分布式锁的正确实现方式
    C# 读取XML文件示例
    C# LINQ to XML示例
    最新的极光推送服务器端代码(java服务器后台向手机端自定义推送消息)
    极光推送>>java SDK服务端集成后台项目(使用详解)
    关于如何在Listener中注入service和ServletContextListener源码分析
    mysql 去除重复 Select中DISTINCT关键字的用法 在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的所有值。其原因是 distinct只能返回它的目标字段,而无法返回其它字段,这个问题让我困扰了很久,用distinct不能解决的话,
    Spring 整合 Quartz 实现动态定时任务
  • 原文地址:https://www.cnblogs.com/sunfuyou/p/7676752.html
Copyright © 2011-2022 走看看