項目文件層次結(jié)構(gòu)

開發(fā)是個持續(xù)性的過程,無論項目大小,都需要一套嚴(yán)格的開發(fā)規(guī)范。遵守規(guī)范的好處,自然不用多說,我只想就項目開發(fā)中的代碼文件結(jié)構(gòu)談?wù)勛约旱睦斫狻?/p>

先來看看下面這張圖吧,這是公司目前的一個項目,框架是我搭建的,在項目啟動前期,我將文件分為如下六大類:(注明:YZ是項目的縮寫前綴)

YZUser代碼文件結(jié)構(gòu)

1、AppDelegate

放置AppDelegate文件,有時候項目會需要自定義自己的AppDelegate來處理更多的消息通知類的東西。

2、Main

主要放的是項目的每個模塊對應(yīng)的代碼。因為本項目是用戶端和企業(yè)端互相切換身份而共存的,所以Main下面我分為:Company和User,并在相應(yīng)目錄下新增各自的業(yè)務(wù)功能頁面

3、Common

是項目中通用的模塊,Model & View & VC的集合。

4、Expand

放置的是宏定義、封裝好的網(wǎng)絡(luò)和工具、分類、常量定義等。其中就Const和Macros文件夾下子目錄做介紹:
1)Const:該文件夾下放置了YZConst類, 定義了App相關(guān)的常量和通知、userDefault名稱
2)Macros:包含YZHeader.h、YZNetUrlConfig.h、YZDefine.h、YZConfig.h四個頭文件。前兩個分別是添加常用頭文件需要#import的類和定義所有的網(wǎng)絡(luò)請求地址,YZDefine.h和YZConfig.h兩個頭文件定義的東西,詳見如下:

//
//  YZDefine.h
//  YZUser
//
//  Created by shuni on 2017/5/27.
//  Copyright ? 2017年 shuni. All rights reserved.
//  定義常用方法和常量

#ifndef YZDefine_h
#define YZDefine_h

#define WEAKSELF __weak typeof(self) weakSelf = self;

//測試模式 true,正式上線模式 false
#define DEBUG_MODE true

#if DEBUG_MODE
#define DebugLog( s, ... ) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define DebugLog( s, ... )
#endif

/*
 *  Singleton
 */
//單例對象定義
#define DEFINE_SINGLETON_FOR_HEADER(className) \
\
+ (className *)shared##className;
//單例對象實現(xiàn)
#define DEFINE_SINGLETON_FOR_CLASS(className) \
\
+ (className *)shared##className { \
static className *shared##className = nil; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
shared##className = [[self alloc] init]; \
}); \
return shared##className; \
}

/*
 *  Standard UserDefaults
 */
#define kStandardUserDefaults                   [NSUserDefaults standardUserDefaults]
#define kStandardUserDefaultsObject(_KEY)       [kStandardUserDefaults objectForKey:_KEY]
#define kSaveStandardUserDefaults(_O,_K)        [kStandardUserDefaults setObject:_O forKey:_K]
#define kRemoveStandardUserDefaults(_K)         [kStandardUserDefaults removeObjectForKey:_K]
#define kStandardUserDefaultsSync               [kStandardUserDefaults synchronize]

/*
 *  UIColor
 */
#define UIColorFromRGB(rgbValue)                [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
#define UIColorFromRGBA(rgbValue, _A)           [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:_A]
#define kColorWithRGB(_R,_G,_B)                 ((UIColor *)[UIColor colorWithRed:_R/255.0 green:_G/255.0 blue:_B/255.0 alpha:1.0])
#define kColorWithRGBA(_R,_G,_B,_A)             ((UIColor *)[UIColor colorWithRed:_R/255.0 green:_G/255.0 blue:_B/255.0 alpha:_A])

/*
 *  Screen size
 */
#define kScreenWidth                            [UIScreen mainScreen].bounds.size.width
#define kScreenHeight                           [UIScreen mainScreen].bounds.size.height

/*
 *  App info
 */
#define kAppDisplayName                         [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]
#define kAppVersion                             [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]
#define kAppIdentifier                          [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIdentifier"]
#define kAppBuildVersion                        [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]

#endif /* YZDefine_h */
//
//  YZConfig.h
//  YZUser
//
//  Created by shuni on 2017/5/27.
//  Copyright ? 2017年 shuni. All rights reserved.
//  定義全局變量、Block和枚舉類型

#ifndef YZConfig_h
#define YZConfig_h

/*
 * 全局變量定義
 */
//默認字體
static NSInteger NavBarRightTitleFont = 14;

//默認高度
static NSInteger NavPortraitHeight = 64;
static NSInteger NavPortraitStatusHeight = 20;
static NSInteger NavPortraitNoStatusHeight = 44;
static NSInteger NavLandscapeHeight = 32;
static NSInteger TabBarHeight = 49;

//獲取驗證碼倒計時間隔
static int kGetCodeTime = 60;      

//錄制默認最大最時長
static float kYZMinRecordTime = 6;      
static float kYZMaxRecordTime = 10;     

//上傳的視頻限制
static float kYZUploadMaxTime = 60;     //上傳的視頻最長視頻
static float kYZUploadMinWidth = 720;   //上傳的分辨率最低提醒
static float kYZUploadMaxBuff = 200;    //上傳視頻大小限制

//整個水印的高/寬比
static float kYZWatermarkComplateHWScale  = 2277.0/1280.0;  


/*
 * Block定義
 */
typedef void(^YZNetCompletionHandler)(NSURLResponse *response, id responseObject);
typedef void(^YZNetErrorCompletionHandler)(NSURLResponse *response, id responseObject, NSError * error);
typedef void(^YZNetUploadCompetionHandler)(NSURLResponse *response, id responseObject);
typedef void(^YZNetErrorUploadCompetionHandler)(NSURLResponse *response, id responseObject, NSError * error);
typedef void(^YZNetDownloadCompetionHandler)(NSURLResponse *response, NSURL *filePath);
typedef void(^YZNetErrorDownloadCompetionHandler)(NSURLResponse *response, NSURL *filePath, NSError * error);
typedef void(^YZCommonToolVedioCompletionHandler)(NSURL *assetURL, NSError *error, BOOL isVideoAssetvertical);

typedef void(^YZMyHeaderItemSelectedBlock)();
typedef void(^YZPositionCellSelectedBlock)();
typedef void(^YZSendResumeBlock)(UIButton *sendResumeBtn);
typedef void(^YZGotoChatBlock)(UIButton *chatBtn);
typedef void(^YZSignUpBlock)(UIButton *signupBtn);
typedef void(^YZShowLocationInMapBlock)();
typedef void(^YZShowCompanyInfoBlock)();
typedef void(^YZEmptyViewGotoPositionBlock)();

typedef void(^YZVideoChangedBlock)();
typedef void(^YZFinishedCropImagesBlock)(NSArray *images);
typedef void(^YZUnInterviewBtnSelectedBlock)();
typedef void(^YZEndedBtnSelectedBlock)();
typedef void(^YZPositionTypeViewHideBlock)(NSArray *selectedPostionArray);
typedef void(^YZResumeListClickBlock)();
typedef void(^YZPositionDetailPublisherViewCallBlock)();
typedef void(^YZPositionDetailPublisherViewArrowBlock)();
typedef void(^YZNetToolInitConfigFinishBlock)();
typedef void(^YZStartMakeResumeVCPlayVideoBlock)();
typedef void(^YZStartMakeResumeVCStopVideoBlock)();

typedef void(^YZTalentGenderViewSelItemBlock)(NSString *itemName);
typedef void(^YZTalentCityViewSelItemBlock)(NSDictionary *provinceDic, NSDictionary *areaDic);
typedef void(^YZClickChatBtnPopViewBtnClickBlock)();
typedef void(^YZChoosePostVCSelectedItemBlock)(NSString *positionId);

//刷新企業(yè)基礎(chǔ)信息回調(diào)
typedef void(^YZReloadCompanyInfoComplete)();

//職位詳情的初始化完成回調(diào)
typedef void(^YZResumeDetailVCInitComplete)();
typedef void(^YZCreatePostInitComplete)();


/*
 * 枚舉類型定義
 */
typedef NS_ENUM(NSInteger, YZBarItemPostion) {
    YZBarItemPostionLeft = 0,
    YZBarItemPostionRight
};

//網(wǎng)絡(luò)狀態(tài)
typedef NS_ENUM(NSInteger, YZNetReachabilityStatus) {
    kYZNetReachabilityStatusUnknown = -1,
    kYZNetReachabilityStatusNotReachable,
    kYZNetReachabilityStatusReachableViaWWAN,
    kYZNetReachabilityStatusReachableViaWiFi
};

//網(wǎng)絡(luò)狀態(tài)回調(diào)Block
typedef void(^YZNetReachabilityStatusComplete)(YZNetReachabilityStatus netStatus);

typedef NS_ENUM(NSUInteger, YZUserInfoType) {
    kYZUserInfoUID = 1,
    kYZUserInfoUserName,
    kYZUserInfoAvatarImg,
    kYZUserInfoResumeID,
    kYZUserInfoAccessToken,
    kYZUserInfoUserPhone,
    kYZUserInfoUserType,
    kYZUserInfoUserRequestURL,
    kYZUserInfoRongCloudToken
};

typedef NS_ENUM(NSUInteger, YZCompanyInfoType) {
    kYZCompanyInfoID = 1,    //公司ID
    kYZCompanyInfoName,      //公司名稱
    kYZCompanyInfoInfo,      //公司介紹
    kYZCompanyInfoEmail,     //公司郵箱
    kYZCompanyInfoType,      //公司type
    kYZCompanyInfoAreaId,    //公司區(qū)域ID
    kYZCompanyInfoProvName,  //公司的省
    kYZCompanyInfoCityName,  //公司市
    kYZCompanyInfoAddress,   //公司詳細地址
    kYZCompanyInfoState,     //公司審核狀態(tài)(狀態(tài)0:審核中,1:正常,2:封號,3未通過)
    kYZCompanyInfoJobCount,  //公司發(fā)布崗位數(shù)
    kYZCompanyInfoUserAvater,//公司頭像
    kYZCompanyInfoUserName,  //公司注冊時填寫的用戶名
    kYZCompanyInfoLinkCount  //公司已與用戶聊天個數(shù)
};

typedef NS_ENUM(NSUInteger, YZCompanyReviewState) {
    YZCompanyInReview = 0,  //審核中
    YZCompanyInNormal,      //正常
    YZCompanyInBlock,       //封號
    YZCompanyInFail         //未通過
};

typedef NS_ENUM(NSUInteger, YZConfigType) {
    YZConfigPostArray = 1,      //職位
    YZConfigSalary,             //薪資
    YZConfigDegree,             //學(xué)歷
    YZConfigSpecialtyTags,      //個人標(biāo)簽和職位誘惑
    //公共的配置configBase
    YZConfigShareToFriend,      //app分享給好友
    YZConfigShareToZone,        //app分享到朋友圈/QQ空間
    YZConfigLoginShare,         //第三方登陸和分享是否全部顯示,0不開啟,1全部顯示
    YZConfigCurrentVersion,     //服務(wù)器版本地址
    YZConfigUpgradeVersionUrl,  //升級的網(wǎng)址
    YZConfigShouldForceUpgrade, //強制升級
    YZConfigUpgradeDesc,        //升級描述
    YZConfigRouter,             //跳轉(zhuǎn)url
    YZConfigBackgroundMusic,    //視頻背景音樂
    YZConfigCompanyLinkLimit,   //企業(yè)與用戶聊的限制
    YZConfigUserLookLimit       //用戶查看職位的限制
};

typedef NS_ENUM(NSUInteger, YZMimeType) {
    kYZMimeTypeImgPng = 1,  //png格式
    kYZMimeTypeImgJpg,      //jpg格式
    kYZMimeTypeVideoMov,    //mov格式
    kYZMimeTypeVideoMp4     //mp4格式
};

typedef NS_ENUM(NSUInteger, YZPrivateAuth) {
    YZAuthorized = 1,  //用戶允許
    YZDenied,          //用戶拒絕
    YZNotDetermined    //用戶尚未選擇
};

typedef NS_ENUM(NSUInteger, YZLanguage) {
    YZLanguageEn = 1,  //英文
    YZLanguageTC,      //繁體中文
    YZLanguageCN       //簡體
};

typedef NS_ENUM(NSUInteger, YZVideoDealType) {
    YZVideoAddWater = 1 ,  //增加水印
    YZVideoCrop,           //裁剪視頻
    YZVideoMontage         //視頻拼接
};

//錄像的狀態(tài)
typedef NS_ENUM(NSUInteger, YZRecordState) {
    kYZRecordNone = 1,
    kYZRecordStart,    //開始錄制
    kYZRecordPause,    //暫停錄制
    kYZRecordDone      //完成錄制
};

//時間戳快速轉(zhuǎn)換為時間字符串
typedef NS_ENUM(NSUInteger, YZQuickFormatType) {
    kYZQuickFormateTypeNone = 0,    //自己定義轉(zhuǎn)換
    kYZQuickFormateTypeYMD,         //年月日   2010-09-02
    kYZQuickFormateTypeMD,          //月日     09-02
    kYZQuickFormateTypeYMDTime,     //年月日時間 2010-09-02 05:23:17
    kYZQuickFormateTypeTime,        //時間    05:23:17
    kYZQuickFormateTypeMDTime       //月日時間 09-02 05:23
};

//popup的消失動畫
typedef NS_ENUM(NSUInteger, YZPopupviewAnimation) {
    kYZPopAnimationNone = 1,    //無動畫直接消失
    kYZPopAnimationPopup,       //上劃彈出
    kYZPopAnimationScale,       //縮放直至消失
};

//職位類型
typedef NS_ENUM(NSUInteger, kYZPositionType) {
    kYZPositionPartTime,    //兼職
    kYZPositionFullTime,    //全職
    kYZPositionAnnouncement //通告
};

//職位發(fā)布人類型
typedef NS_ENUM(NSUInteger, kYZPositionPublisherType) {
    kYZPersonalPublisher,   //個人
    kYZEnterprisePublisher  //企業(yè)
};

//錄制的方案
typedef NS_ENUM(NSUInteger, YZRecordType) {
    kYZRecordVedio = 1,    //錄制
    kYZChangeVedio         //重錄
};

//圖片裁剪類型
typedef NS_ENUM(NSUInteger, PhotoClipType) {
    PhotoClipTypeCircle = 0,
    PhotoClipTypeSquare
};

//已投遞的職位狀態(tài)
typedef NS_ENUM(NSUInteger, YZPostedPositionStatusType) {
    kYZUninterviewPosition,  //待面試
    kYZEndedPosition         //已結(jié)束
};

//審核狀態(tài)
typedef NS_ENUM(NSUInteger, YZResumeState) {
    kResumeStatePass = 1,   //審核通過
    kResumeStateinReview,   //審核中
    kResumeStateFail        //審核未通過
};

//反饋類型
typedef NS_ENUM(NSUInteger, YZFeedBackType) {
    kYZFeedBackSuggest = 1,
    kYZFeedBackBUG,
    kYZFeedBackOther
};

//用戶身份
typedef NS_ENUM(NSUInteger, YZUserType) {
    kYZUsrTypeNone = 0,     //沒有選擇用戶身份
    kYZUserType,            //用戶版
    kYZCompanyType          //企業(yè)版
};

typedef NS_ENUM(NSUInteger, YZBannerType) {
    kCommonWebType = 1, //普通跳轉(zhuǎn)網(wǎng)頁
    kPostDetailType,    //職位詳情
    kResumeDetailType,  //簡歷詳情
    kCreateResumeType   //制作或完善簡歷
};

//選擇查看的職位類型
typedef NS_ENUM(NSUInteger, YZPostState) {
    kYZReviewPost = 0,      //審核中
    kYZProcessingPost = 1,  //發(fā)布中
    kYZOverPost = 3,        //已結(jié)束
    kYZFailedPost = 4       //審核未通過
};

//選擇出行導(dǎo)航工具類型
typedef NS_ENUM(NSUInteger, YZTraveToolTypeForNavigation) {
    kYZDriveForNavigation = 0,   //駕車
    kYZBusForNavigation,         //公交
    kYZWalkForNavigation         //步行
};

typedef void(^YZMapNavigationBlock)(YZTraveToolTypeForNavigation type);

#endif /* YZConfig_h */

5、Vender

這部分是用于管理項目中使用到的常被修改和自定義的第三方庫。

6、Resource

從名字很容易理解到,就是放項目中用到的資源文件,除開image放置在Assets.xcassets中,預(yù)配置的本地音頻、plist、json均放在這個目錄之下。

當(dāng)然這是我的個人習(xí)慣,每個人都有自己的一套命名和規(guī)范,只要足夠的清晰都是可以接受的。干凈分明的文件結(jié)構(gòu)層次,某種程度上也有助于開發(fā)過程中業(yè)務(wù)功能的分析,便于將封裝的工具類剝離業(yè)務(wù)而獨立開來,降低各個模塊之間的粘性,從而提高復(fù)用性。而且這個過程在搭建項目時就要考慮的,也在一定程度上能反映開發(fā)人員是否具有一定的前瞻性和架構(gòu)思維。目前,這也是我很需要努力的一個方向~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,829評論 25 708
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,837評論 18 139
  • 最近不知道怎么了,做夢夢到的全是吃的。我知道兩天時間從51.6kg升到53.5kg是什么概念。可是。我就是控制不了...
    諾米Naomi閱讀 195評論 1 4
  • html部分 合理的title、description、keywords:搜索對這三項的權(quán)重逐個減小,title值...
    xiao_333閱讀 185評論 0 1
  • 喬喬跟我一個學(xué)院的,我們考的是文學(xué)類專業(yè),報考的學(xué)校也在一個大學(xué)城。我跟喬喬大一就認識了,當(dāng)時我們同在本院的學(xué)生會...
    七分白閱讀 385評論 0 0