iOS開發手冊

聲明:git

  • 本文檔面向以Objective-C做爲開發語言的iOS團隊。
  • 本文檔以蘋果開發文檔爲基礎,結合網絡內容和開發實踐進行整理,針對iOS開發進行規範和約定。
  • 最後更新時間:2019年3月13日
  • 爲保證時效性,持續更新地址爲:iOS開發手冊

1.項目基礎

1.1 項目新建信息

  • Product Name:工程名。
  • Team:開發者帳號信息,沒有選擇None,我的開發者帳號(含Personal Team),公司/企業帳號(如:XXX Co.,LTD),也能夠暫時選擇None,後續再配置調試。
  • Organization Name:我的開發者帳號(自定義名字),公司/企業帳號(如:XXX Co.,LTD),此處內容明顯體如今代碼文件頭部註釋中。
  • Organization Identifier:我的開發者帳號(自定義標識),公司/企業帳號(域名反寫如:com.xxx)。
  • Bundle Identifier:自動生成格式爲 [Organization Identifier] + [Product Name],也可後續配置時進行修改。
  • Language:根據須要選擇Objective-C 或者 Swift。
  • Use Core Data:根據項目狀況勾選,若是明確須要請直接勾選,也可後續添加。
  • Include Unit Tests:單元測試,根據須要勾選,也可後續添加。
  • Include UI Tests:UI測試,根據須要勾選,也可後續添加。
  • Source Control:默認git進行版本管理,根據須要勾選,也可後續添加。

1.2 項目初始配置

  • Display Name:應用名稱。
  • Deployment Info:系統版本、設備、屏幕方向、狀態欄等,
  • Build Active Architecture Only:通常Debug模式YES,Release模式NO。若是Release模式爲YES,那麼上傳AppStore以後會顯示大量而具體的兼容設備,Release模式爲NO則僅顯示模糊的兼容信息。
  • Architecture:默認$(ARCHS_STANDARD)不做修改。
  • Valid Architecture:默認arm64/armv7/armv7s不做修改。模擬器32位處理器是i386架構,模擬器64位處理器是x86_64架構,真機32位處理器是armv7或armv7s架構,真機64位處理器是arm64架構。

1.3 項目文件結構

  • 全部的文件應放在工程中的項目目錄下。
  • 項目文件和物理文件需保持一致。
  • Xcode建立的任何組(group)都必須有文件夾映射。
  • 項目文件不只能夠按照業務類型分組,也能夠根據功能分組。

2.代碼格式規範

2.1 代碼註釋格式

  • 文件註釋:採用Xcode自動生成的註釋格式。segmentfault

    //
    //  AppDelegate.h
    //  項目名稱
    //
    //  Created by 開發者姓名 on 2018/6/8.
    //  Copyright © 2018年 公司名稱. All rights reserved.
    //
  • import註釋:若是有一個以上的import語句,對這些語句進行分組,每一個分組的註釋是可選的xcode

    // Framework
    #import <UIKit/UIKit.h>
    
    // Model
    #import "WTUser.h"
    
    // View
    #import "WTView.h"
  • 方法註釋:Xcode8以後快捷鍵自動生成(option + command + /)。網絡

    /**
    <#Description#>
    
    @param application <#application description#>
    @param launchOptions <#launchOptions description#>
    @return <#return value description#>
    */
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
  • 代碼塊註釋:單行的用 「// + 空格」 開頭, 多行用「/* */」。架構

    2.2 代碼結構與排版

  • 聲明文件:方法順序和實現文件的順序保持一致,根據須要用」#pragma mark -「將方法分組。
  • 實現文件:必須用」#pragma mark -「將方法分組。分組先後優先級:Lifecycle方法 > Public方法 > UI方法 > Data方法 > Event方法 > Private方法(邏輯處理等) > Delegate方法 > 部分Override方法 > Setter方法 > Getter方法。app

#pragma mark - Lifecycle

- (instancetype)init {}
- (void)viewDidLoad {}
- (void)viewWillAppear:(BOOL)animated {}
- (void)viewDidAppear:(BOOL)animated {}
- (void)viewWillDisappear:(BOOL)animated {}
- (void)viewDidDisappear:(BOOL)animated {}
- (void)didReceiveMemoryWarning {}
- (void)dealloc {}

#pragma mark - Public

- (void)refreshData {}

#pragma mark - UI

- (void)initSubViews {}

#pragma mark - Data

- (void)initData {}
- (void)constructData {}

#pragma mark - Event

- (void)clickButton:(UIButton *)button {}

#pragma mark - Private

- (CGFloat)calculateHeight {}

#pragma mark - UIScrollViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {}

#pragma mark - Override

- (BOOL)needNavigationBar {}

#pragma mark - Setter

- (void)setWindow:(UIWindow *)window {}

#pragma mark - Getter

- (UIWindow *)window {}
  • 變量:優先使用屬性聲明而非變量聲明,注意屬性修飾符、變量類型、變量之間的間隔。ide

    @property (strong, nonatomic) UIWindow *window;
  • 點語法:應始終使用點語法來訪問和修改屬性。
  • 間距要求以下:svn

    • 一個縮進使用四個空格。
    • 在」-「或者」+「號以後應該有一個空格,方法的大括號和其它大括號始終和聲明在同一行開始,在新的一行結束,另外方法之間應該空一行。
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        if (door.isClosed) {
            // Do something
        } else {
            // Do something
        }
        return YES;
    }
  • 長度要求以下:函數

    • 每行代碼的長度不該該超過100個字符。
    • 單個函數或方法的實現代碼控制在50行之內。
    • 單個文件裏的代碼行數控制在500~600行以內。

3.代碼命名規範

3.1 代碼命名基礎

  • 最好是既清晰又簡短,但不要爲簡短喪失清晰性,並使用駝峯命名法。
  • 名稱一般不縮寫,即便名稱很長也要拼寫徹底(禁止拼音),然而可以使用少數很是常見的縮寫,部分舉例以下:工具

    經常使用縮寫詞 含義 經常使用縮寫詞 含義
    app application max maximum
    alt alternate min minimum
    calc calculate msg message
    alloc allocte rect rectangle
    dealloc deallocte msg message
    init initialize temp temporary
    int integer func function
  • 因爲Cocoa(Objective-C)沒有C++同樣的命名空間機制,需添加前綴(公司名首字母)防止命名衝突,前綴使用2個字符(如下統稱項目前綴)。
  • 常見的單詞略寫:ASCII,PDF,HTTP,XML,URL,JPG,GIF,PNG,RGB

3.2 類和協議命名

  • 類名應明確該類的功能,而且要有項目前綴防止命名衝突。
  • 協議組合一組相關的方法,不關聯具體的一個類,使得某些類似類有統一的接口,這種協議的命名應採用動名詞形式(ing),例如:NSLocking。
  • 協議組合一些不相關的方法(主要是避免建立多個獨立的協議),僅僅關聯某一個具體的類(該類是協議的具體體現者),這種協議用該類名命名,例如:NSObject。
  • 委託形式的協議命名爲類名加上Delegate,例如:UIScrollViewDelegate。

3.3 變量和屬性命名

  • 變量名應前置下劃線「_」,屬性名沒有下劃線。
  • 屬性本質上是存取方法setter/getter,可進行重寫(注意內存管理)。

    @property (strong, nonatomic) UIWindow *window;
    - (void)setWindow:(UIWindow *)window;
    - (UIWindow *)window;
  • 能夠適當的對setter/getter進行別名設置。

    @property(nonatomic,getter=isUserInteractionEnabled) BOOL userInteractionEnabled;

3.4 方法和函數命名

  • 方法名和函數名通常不須要前綴,但函數(C語言形式)做爲全局做用域的時候最好加上項目前綴。
  •  表示行爲的方法名稱以動詞開頭,但不要使用do/does等無實際意義的助動詞。
  • 參數前面的單詞要可以描述該參數,而且參數名最好能用描述該參數的單詞命名。

    - (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
  • 方法中多個參數可使用適當的介詞進行鏈接。

    // 後續多個參數使用with
     - (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2; 
      //  添加適當介詞可以使方法的含義更明確
      - (BOOL)lockWhenCondition:(NSInteger)condition beforeDate:(NSDate *)limit;
       // 第一個參數用了with,後面的參數不使用with
        - (instancetype)initWithImage:(nullable UIImage *)image highlightedImage:(nullable UIImage *)highlightedImage;
  • 只有在方法返回多個值的時候使用get單詞進行明確。

    - (void)getLineDash:(nullable CGFloat *)pattern count:(nullable NSInteger *)count phase:(nullable CGFloat *)phase;
  • 方法返回某個對象實例。

    + (instancetype)buttonWithType:(UIButtonType)buttonType;// 類方法建立對象
    + (UIApplication *)sharedApplication;// 單例命名
  • 委託或代理方法命名第一個參數最好能相關某個對象。

    - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
  • 私有方法不要如下劃線「_「開頭,由於系統私有方法保留此方式。
  • 自定義方法和系統方法重名,建議在方法開頭加前綴」xx_methodName「。

    3.5 常量和宏的命名

  • const常量外部聲明:在Objective-C文件中優先採用FOUNDATION_EXTERN和UIKIT_EXTERN,而非C語言中的extern。
  • const常量採用駝峯命名原則。
  • const常量根據做用域適當加上前綴(含項目前綴):可供外部使用需加上相應的類名或者模塊前綴,僅文件內部使用須要加上小寫字母「k」.
  • 宏定義每一個字母採用大寫,單詞之間用下劃線「_」間隔。
  • 宏定義也可根據做用範圍加上適當前綴,避免命名衝突。

    3.6 枚舉的命名

  • 使用枚舉來定義一組相關的整數常量,加強代碼的可讀性。
  • 枚舉可根據做用域添加前綴(含項目前綴),格式:[相關類名或功能模塊名] + [描述] + [狀態]。
  • 建議優先採用Objective-C的聲明NS_ENUM和NS_OPTIONS,少採用C語言形式的enum等枚舉聲明.
  • 枚舉定義時需指定None狀態,而且其rawValue通常爲起始值0。

    // NS_ENUM
    typedef NS_ENUM(NSInteger, UIStatusBarAnimation) {
        UIStatusBarAnimationNone    = 0,
        UIStatusBarAnimationFade    = 1,
        UIStatusBarAnimationSlide   = 2,
    }
    typedef NS_OPTIONS(NSUInteger, UIRemoteNotificationType) {
        UIRemoteNotificationTypeNone    = 0,
        UIRemoteNotificationTypeBadge   = 1 << 0,
        UIRemoteNotificationTypeSound   = 1 << 1,
        UIRemoteNotificationTypeAlert   = 1 << 2,
        UIRemoteNotificationTypeNewsstandContentAvailability = 1 << 3,
    }

3.7 通知命名

  • 外部聲明:在Objective-C文件中優先採用FOUNDATION_EXTERN和UIKIT_EXTERN,而非C語言中的extern。
  • 通知的命名通常都是跨文件使用的,需添加項目前綴。

    // [相關聯類名或者功能模塊名] + [will/Did](可選) + [描述] + Notification
    UIApplicationDidEnterBackgroundNotification       
    UIApplicationWillEnterForegroundNotification

3.8 類型別名命名

  • 根據做用域添加前綴(含項目前綴),格式:[類名或功能模塊名] + [描述]。

4.文件資源命名規範

  • 資源文件命名也需加上項目前綴。
  • 資源文件名全小寫,單詞之間用下劃線「_」間隔。
  • 資源文件命名格式:[項目前綴] + [業務] + [文件名]
  • 圖片文件命名格式:[項目前綴] + [業務] + [類型] + [狀態]。

    // 常見類型:logol,icon,img
    // 常見狀態:normal,selected,highlight
    UIImage *image = [UIImage imageNamed:@"wt_mine_setting_normal"];

5.代碼警告處理

  • 注意警告問題的隱蔽性,所以最好修復警告。
  • 警告類型的查看步驟:選中警告 -> 右鍵Reveal in Log(不編譯Reveal in Log是灰色的,所以先編譯) ->查看方括號的內容
  • 若是須要忽略警告,建議優先代碼push或者pop處理。

    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Warc-retain-cycles"
    // 形成警告的代碼
    #pragma clang diagnostic pop
  • 若是警告數量過大,檢查警告類型以及必要性,可xcode配置忽略此類型警告。步驟:選中工程 -> TARGETS -> Build Settings -> Other Warning Flags。

    忽略單個和全局配置稍有差異,以下舉例:
    push/pop    Other Warning Flags
    -Wformat —-> -Wno-format 
    -Wunused-variable —-> -Wno-unused-variable 
    -Wundeclared-selector —-> -Wno-undeclared-selector 
    -Wint-conversion —-> -Wno-int-conversion
  • 也能夠在pch等大範圍做用域的頭文件中添加代碼來忽略後續警告:#pragma clang diagnostic ignored 「警告名稱」 。

6.外部庫文件引入

  • 庫文件引入最好把警告處理掉。
  • 庫文件引入優先採用CocoaPods引入,而且指定版本號。
  • 源文件方式需引入文件到工程目錄下。
    圖例
  • 源文件方式需注意有無版本說明信息(可能在README文件中,也可能在某個.h頭文件中,又或者有Version文件)沒有時需在庫文件目錄下新增版本說明文件,

7.代碼版本管理

  • 版本管理工具:svn 或 git。
  • svn文件管理配置:目錄~/.subversion打開config文件全局配置global-ignore,全部的倉庫都會受到影響,而svn:ignore隻影響倉庫目錄。
  • git文件管理配置:.gitignore_global爲全局配置,而倉庫目錄下的.gitignore文件僅註明本倉庫被git忽略的文件,常見語法以下:

    • 井號(#)用來添加註釋用的,好比 "#註釋"。
    • build/ : 星號()是通配符,build/*則是要說明要忽略 build 文件夾下的全部內容。
    • *.pbxuser : 表示要忽略後綴名爲.pbxuser的文件。
    • !default.pbxuser : 感嘆號(!)是取反的意思,*.pbxuser 表示忽略全部後綴名爲.pbxuser的文件,若是加上!default.pbxuser則表示,除了default.pbxuse忽略其它後綴名爲pbxuse的文件。
  • 提交信息規範:

    • BUG類型爲「Fix + [BUG編號] + [BUG描述]」。
    • 任務類型爲「Done + [任務編號] + [任務描述]」。
    • 任務中間態爲「Doing + [任務編號] + [任務描述]」。
    • 引入類庫爲「import + [類庫名]」。

8.構建和分發

  • 手動構建:Xcode界面化構建、xcodebuild終端命令構建。
  • 自動化構建:Jenkins+Fastlane、xcodebuild腳本執行 。
  • 內測分發渠道:fir.im蒲公英等。
  • 線上分發渠道:AppStore。
相關文章
相關標籤/搜索