此項(xiàng)目自2017年伊始一直持續(xù)到2018年3月份馏谨,此項(xiàng)目一共兩個人開發(fā)精钮,我和我的另一個同事。這個項(xiàng)目并不是嚴(yán)格意義上的純oc項(xiàng)目踩官,它混合加入了c++ 的編碼工作,原因是底層的socket封裝是使用c++進(jìn)行的境输,而我們需要封裝遠(yuǎn)程訪問數(shù)據(jù)庫的一些增刪改查操作蔗牡,此外還需要進(jìn)行長連接的一些測試工作。
這個項(xiàng)目是一個移動版的OA協(xié)同辦公軟件嗅剖,類似微信企業(yè)版辩越,所以大部分的重點(diǎn)就在與即時通訊的開發(fā)與調(diào)試。我的同事主要負(fù)責(zé)整個聊天系統(tǒng)的開發(fā)窗悯,而我就是負(fù)責(zé)協(xié)同辦公的一些業(yè)務(wù)流程開發(fā)区匣,比如公文審批系統(tǒng)、人事考勤系統(tǒng)等蒋院。
我具體負(fù)責(zé)以下代碼工作的開發(fā),
- 遠(yuǎn)程訪問數(shù)據(jù)庫的增刪改查封裝莲绰。為什么要封裝欺旧?不是有現(xiàn)成的庫嗎?例如FMDB之類的蛤签?正是應(yīng)為底層使用了c++ 開發(fā)辞友,原有的一些庫更本就不滿足需求,應(yīng)為這個是需要和c++混合開發(fā)的項(xiàng)目震肮,其中我們需要根據(jù)我們查詢的字段是一個還是多個進(jìn)行區(qū)分称龙,因?yàn)橐粋€字段的查詢是直接返回查詢結(jié)果的,而多字段的查詢是key和value是分開的戳晌,換句話說就是返回的結(jié)果中key和value是沒有映射關(guān)系的鲫尊,所以為了項(xiàng)目以后可以直接根據(jù)key值取到value的值,在這里需要分開處理沦偎。 以下是(MNSqlDBProvider.mm)的部分代碼
nRet = dbProvider.ExecuteQuery(client, 0, sqlS, &memory);
if (nRet == 0) {
//sql語句執(zhí)行成功
if (memory.UnzipMemory() == 0) {
dbRewsult.ExtractResult(&memory);
//獲取查詢數(shù)據(jù)庫的結(jié)果
NSMutableDictionary *dict = dbRewsult.GetMfidlds();
NSMutableArray *muArray = dbRewsult.GetMuArray();
//多字段查詢處理結(jié)果
if (keyArray.count > 1) {
self.info = dict;
self.infoArray = muArray;
if ([dict count] == 0) {
return 0;//不存在信息
}
return 1;
}
//只查詢一個字段處理結(jié)果
if ([[dict objectForKey:key] isEqualToString:@"0"]) {
//不存在
self.info = dict;
self.infoArray = muArray;
return PHONE_NO_EXICT;//==0
}else{
//不為0疫向,并不代表查詢結(jié)果存在咳蔚,需進(jìn)一步解析
self.info = dict;
self.infoArray = muArray;
return PHONE_EXICT;//==1
}
}else{
//解壓失敗
NSLog(@"%s 解壓失敗",__func__);
}
return 0;
}else{
client->Close();
client->Open();
return nRet;
}
- 獲取各個服務(wù)器的IP和Prot。這里我實(shí)現(xiàn)了一個叫MNServerConfig的單例類搔驼,用于根據(jù)中心服務(wù)器的IP和Prot來獲消息服務(wù)器谈火、文件服務(wù)器、數(shù)據(jù)服務(wù)器的各自IP和Prot舌涨。這個吃了不少虧糯耍,在項(xiàng)目開始的時候各個服務(wù)的IP的端口都是寫死的了,隨著項(xiàng)目的開發(fā)和服務(wù)器的不斷升級囊嘉,需要經(jīng)常修改服務(wù)器的IP和端口號温技,這樣我們就非常麻煩的需要一個個的去修改。在項(xiàng)目進(jìn)行到中期的時候哗伯,服務(wù)器也比較穩(wěn)定了我就寫成根據(jù)中心服務(wù)器的IP來獲取其他服務(wù)器的IP荒揣,這樣就省力多了。對了焊刹,獲取到所有服務(wù)器的IP和Prot后就需要本地進(jìn)行保存系任,這樣就不用每次打開應(yīng)用都再去獲取一邊了。這里我直接保存到本地磁盤上名為company_ip.plist的文件虐块。部分代碼:
NSFileManager *fm = [NSFileManager defaultManager];
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
NSString *ipPath = [delegate.loginFilePath stringByAppendingPathComponent:FILE_IP_NAME];
if (![fm fileExistsAtPath:ipPath]) {
NSString *sql = [NSString stringWithFormat:@"SELECT ZJMC,GWIP,GWDK,DXDM FROM t_icobjectserver"];
NSString *key = @"ZJMC,GWIP,GWDK,DXDM";
ICSocketClient client = ICSocketClient();
const char *ip = [W_CENTER_SERVER_IP UTF8String]; //中心服務(wù)器的ip
client.SetServerIP(ip);
client.SetServerPort(W_CENTER_PORT);
client.Open();
NSInteger nRet = [self.mnSqlDBProvider dbExecuteQueryInSocket:&client sqlStr:sql key:key];
client.Close();
if (nRet != 0) {
[self configIPAndPort:self.mnSqlDBProvider.infoArray];
if (![self saveIPAndProt:self.mnSqlDBProvider.infoArray]) {
NSLog(@"本地存儲IP失敗,請檢查");
}
}
}else{
NSLog(@"從本地獲取ip");
NSArray *ipInfo = [NSKeyedUnarchiver unarchiveObjectWithFile:ipPath];
[self configIPAndPort:ipInfo];
}
- 登錄與注冊俩滥。用戶群體分為三大類,公司贺奠、團(tuán)隊(duì)霜旧、散戶。每一種類的業(yè)務(wù)屬性不一樣從而導(dǎo)致注冊方式不一樣儡率,挂据,比如注冊類型為公司的話就需要上傳公司的營業(yè)證照進(jìn)行審核并綁定一個管理員,管理員擁有公司的最高操作權(quán)限儿普,可以添加刪除公司的員工并賦予員工一定的管理權(quán)利崎逃,還可以把員工分配到每一個部門里。團(tuán)隊(duì)的是只需要綁定管理員帳號眉孩,添加自己團(tuán)隊(duì)的人員即刻个绍。散戶,顧名思義就是一些不在公司和團(tuán)隊(duì)里的人員浪汪,這些人只需要綁定自己的手機(jī)號就可以進(jìn)行登錄巴柿,不過登記去后只能和認(rèn)識的人聊天。自然而然的登錄就分為三類了死遭,根據(jù)登錄的類別不一樣广恢,所獲得權(quán)限不一樣。
這里有一些細(xì)節(jié)殃姓,
a袁波、 一個手機(jī)號綁定一個帳號瓦阐,一個人可以擁有不同身份的帳號,領(lǐng)導(dǎo)要求每次登錄都要記住登錄的帳號以及帳號所屬的類型篷牌,如果下次登錄的是公司類型的帳號就要自動給出這個帳號上次登錄所屬的公司名稱睡蟋,注意,這里一個帳號可以加入多個公司枷颊。
b戳杀、在登錄的成功的時候就需要開啟socket長連接,為了保持長連接需要在AppDelegate里面進(jìn)行連接夭苗,不能在登錄控制器里面連接信卡。
- 人事系統(tǒng)。人事系統(tǒng)包括集團(tuán)公司組織架構(gòu)题造、部門人事列表傍菇、人員的考勤記錄、請假流程的設(shè)計等界赔。公司的組織架構(gòu)分為三種丢习,國內(nèi)的全資子公司、國內(nèi)的合資公司淮悼,國內(nèi)的項(xiàng)目合作公司以及海外分公司咐低。種類的不同代表著公司在該系統(tǒng)中的權(quán)重不同。部門人事列表有點(diǎn)類似QQ分組列表一樣袜腥,可以進(jìn)行分組操作见擦,在組內(nèi)可以下設(shè)二級部門,對人員可以進(jìn)行增刪操作羹令。人員的考勤實(shí)現(xiàn)手機(jī)自動打卡上下班鲤屡,借助百度地圖實(shí)現(xiàn)在公司園區(qū)坐標(biāo)里在規(guī)定時間內(nèi)由服務(wù)器向手機(jī)端推送簽到消息進(jìn)行打卡操作,打卡時自動上傳當(dāng)前經(jīng)緯度以及打卡時間福侈,有服務(wù)器歸納總結(jié)一個月的考情記錄并發(fā)送給人事部执俩。如果沒有收到打卡信息或者打卡失敗,可以手動進(jìn)入系統(tǒng)進(jìn)行打卡操作癌刽。請假系統(tǒng)的開發(fā)需要考勤記錄的配合。請假有發(fā)起者和審批者兩種角色尝丐,一個人可以只是一種角色也可以擁有兩種角色显拜。
請假大致流程如下
- 公文系統(tǒng)。公文系統(tǒng)整體流程有點(diǎn)類似與請假流程爹袁,不一樣的是公文有多個步驟需要流通远荠,比如擬稿、校驗(yàn)失息、審核譬淳、定稿档址、發(fā)文等,其中步驟并不是單線一直流通的邻梆,其中可能有些步驟需要循環(huán)往復(fù)的流通才可能往下一步驟進(jìn)行守伸,并且在流轉(zhuǎn)的過程可能需要不同的人員進(jìn)行審核操作,這相比于請假復(fù)雜多了浦妄。
總結(jié)
其實(shí)項(xiàng)目早已結(jié)束尼摹,至于為什么我這么晚才來總結(jié),那可能就要問我們領(lǐng)導(dǎo)了剂娄。這也算是我真正意義上的iOS項(xiàng)目吧蠢涝,看著項(xiàng)目從0到0.8的我內(nèi)心有好多要說的,不是技術(shù)上的原因阅懦,我一直認(rèn)為阻礙項(xiàng)目的發(fā)展的永遠(yuǎn)不是技術(shù)問題而往往是人的因素和二。在這個項(xiàng)目開發(fā)的過程中,我們沒有產(chǎn)品經(jīng)理耳胎、沒有UI設(shè)計師惯吕、沒有數(shù)據(jù)庫管理人員等,所有的操作全憑自己完成...最重要的是所有的需求都是我們大領(lǐng)導(dǎo)一個人提出的场晶,沒錯混埠,一個人!你能想象到你沒有接觸到實(shí)體業(yè)務(wù)诗轻,全憑領(lǐng)導(dǎo)一張嘴說钳宪,你就完成了整個項(xiàng)目的80%,你可想而知整個開發(fā)過程是有多么的痛苦...有些功能你開發(fā)了將近一個月的時間扳炬,拿給領(lǐng)導(dǎo)看過之后吏颖,領(lǐng)導(dǎo)說他又有新想法了...所有的都要推倒從做,就比如公文系統(tǒng)恨樟,那種心情真的是不好受半醉!
代碼的編寫工作其實(shí)占用整個項(xiàng)目的生命周期是最短的,前期的需求分析以及業(yè)務(wù)邏輯的梳理是占用做多的劝术。一個好的開發(fā)規(guī)范就是前期做好項(xiàng)目分析需求缩多,這樣就可以極大避免后期的推倒從做事件。