項目問題匯總

一、結構體的使用struct

結構體能更加方便的定義好不同的屬性锈至,我們使用起來更方便,減少了我們使用中進一步去手動獲取數(shù)據(jù)译秦。

1峡捡、定義結構體:

struct TYTCommonResponse {
    NSUInteger code;
    NSString *_Nullable msg;
    id _Nullable data; //上面三個手動拆分的數(shù)據(jù)    
    id _Nullable rowData; // 接口返回原數(shù)據(jù)
};
聲明結構體:
typedef struct TYTCommonResponse TYTCommonResponse;

12击碗、使用結構體回傳數(shù)據(jù)

比如我們封裝好網絡請求,response的數(shù)據(jù)需要進一步解析们拙。

- (void)responseStructWithURLString:(NSString *)path onSuccess:(nullable void (^)(struct TYTCommonResponse))success responseObject:(id _Nullable)responseObject
{
    TYTCommonResponse resultObj;
    resultObj.code = [responseObject[@"code"] integerValue];
    resultObj.msg = responseObject[@"msg"];
    resultObj.data = responseObject[@"data"];    
    resultObj.rowData = responseObject;
    TYTLog(@"返回數(shù)據(jù)(%@):%@", path, [NSString stringWithFormat:@"\ncode: %zd\nmsg: %@\nrowData: %@", resultObj.code, resultObj.msg, resultObj.rowData]);
    
    [TYTResultCodeHandler handleMessageWithCode:resultObj.code data:responseObject];    
    if (success) {
        success(resultObj);
    }
}

二稍途、WKWebView中的Cookie

Cookie是我們日常瀏覽的網頁頁面為了識別具體的用戶身份,而在request Header加帶的一種數(shù)據(jù)砚婆。有了這個數(shù)據(jù)械拍,你要瀏覽的的網頁就知道你是哪個用戶。
舉個例子:如果瀏覽網站的時候沒有Cookie或者Cookie失效了装盯,那么就會出現(xiàn)這種情況坷虑。你隔了好多天訪問微博網頁,點擊的標簽明明之前保存的是你登錄之后的微博首頁埂奈,可以直接看到你的好友動態(tài)迄损。但是現(xiàn)在它卻給你跳轉了登錄頁面先要你登錄。就是因為你Cookie失效導致的账磺。微博沒辦法判斷你是否是有效用戶了芹敌。
另外,我們需要特別注意垮抗,在頁面跳轉的時候氏捞,網站有時候會自己在request Header中加入一些Cookie,也作為身份校驗的一部分冒版。
Cookie可以由native端設置也可以由服務端來設置液茎。
客戶端想要打印出webView中的Cookie,就有四個地方可選了:

1壤玫、native端設置Cookie的時候
2豁护、獲取request Header
3、獲取document.cookie的內容
4欲间、獲取response header中的set-cookie

WKWebView中設置Cookie的方案:


Cookie版本適配方案

適配iOS11.0~iOS11.2
蘋果在iOS11.0推出了WKHTTPCookieStore楚里,這個類對WKWebView的效果和NSHttpCookieStorage對UIWebView的效果一樣,并且也是零延遲猎贴。在請求發(fā)起的時候班缎,我們只需要將Cookie設置到WKHTTPCookieStore就可以了。

// 1. 設置Cookie
WKWebsiteDataStore *store = [WKWebsiteDataStore defaultDataStore];
[store.httpCookieStore setCookie:cookie completionHandler:^{
NSLog(@“cookie添加成功”);
}];

// 2. 加載請求
[self.wkwebView loadRequest: request];

適配iOS11.3
WKHTTPCookieStore第一次設置Cookie之后她渴,發(fā)起請求达址,Cookie不能同步到request Header中。此時趁耗,webView重新請求頁面沉唠,WKHTTPCookieStore的作用恢復正常,之后請求其他的webView也不會出現(xiàn)Cookie丟失的問題苛败。 總結就是在iOS11.3中满葛,WKHTTPCookieStore設置Cookie之后径簿,第一次發(fā)起請求Cookie會丟失,第二次及以后的請求的Cookie沒有問題嘀韧。

解決方式是篇亭,我們在執(zhí)行l(wèi)oadRequest之前主動設置一次Cookie。我這里是在didFinishLaunchOption:中設置的锄贷。設置完之后译蒂,就沒有問題了,注意谊却,他是單利奧柔昼。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{
   WKWebsiteDataStore *store = [WKWebsiteDataStore defaultDataStore];
    [store.httpCookieStore setCookie:cookie completionHandler:^{
        NSLog(@“cookie添加成功”);
    }];
}

WKWebView如何加Cookie系列

三、Bundle 和 xcassets 的主要區(qū)別

簡述:

1因惭、工程中所有使用 Asset Catalog 管理的圖片(在 .xcassets 文件夾下)岳锁,最終輸出的時候,都會被壓縮到 Assets.car 內蹦魔。
2激率、反之,不在 Assets.car 內的勿决,我們將它統(tǒng)一歸類為 Bundle 管理的乒躺。

Bundle 和 xcassets 的主要區(qū)別有:

1、xcassets 里面的圖片低缩,只能通過 imageNamed 加載嘉冒。Bundle 還可以通過 imageWithContentsOfFile 等方式。
2咆繁、xcassets 里的 2x 和 3x讳推,會根據(jù)具體設備分發(fā),不會同時包含玩般。而 Bundle 會都包含银觅。(App Slicing)
3、xcassets 內坏为,可以對圖片進行 Slicing究驴,即裁剪和拉伸。Bundle 不支持匀伏。所以洒忧,Bundle會使包的體積變大。
4够颠、Bundle 內支持多語言熙侍,xcassets 不支持。
xcassets使用 imageNamed 創(chuàng)建的 UIImage,會立即被加入到 NSCache 中(解碼后的 Image Buffer)核行,直到收到內存警告的時候牢硅,才會釋放不在使用的 UIImage。
而 Bundle的imageWithContentsOfFile方式芝雪,它每次都會重新申請內存,相同圖片不會緩存综苔。
所以惩系,xcassets 內的圖片,加載后會產生緩存如筛,Bundle則不會堡牡,所以在開發(fā)中,常用的杨刨,較小的圖晤柄,應該放在 xcassets 內管理。而大圖應該放在 Bundle 內管理妖胀。

三芥颈、宏定義調用方法

以block的方式調用,每次換行都要添加\赚抡,否則報錯爬坑。

#pragma mark - 適配ios11 和iPhone X
#define isiPhoneX \
({BOOL isPhoneX = NO;\
if (@available(iOS 11.0, *)) {\
isPhoneX = [[UIApplication sharedApplication] delegate].window.safeAreaInsets.bottom > 0.0;\
}\
(isPhoneX);})

// 判斷是否是iPhone 5
#define  isiPhone5 Screen_Width == 320
// iPhoneX的狀態(tài)欄的高度
//#define  TYT_StatusBarHeight      (isiPhoneX ? 44.f : 20.f)
#define  TYT_StatusBarHeight \
^(){\
 if (@available(iOS 13.0, *)) {\
     UIStatusBarManager *statusBarManager = [[[UIApplication sharedApplication] windows] objectAtIndex:0].windowScene.statusBarManager;\
     return statusBarManager.statusBarFrame.size.height;\
 }else{\
     return [[UIApplication sharedApplication] statusBarFrame].size.height;\
 }\
}()

// iPhoneX的導航欄的高度
#define  TYT_NavBarHeight \
^(){\
 if (@available(iOS 13.0, *)) {\
     UIStatusBarManager *statusBarManager = [[[UIApplication sharedApplication] windows] objectAtIndex:0].windowScene.statusBarManager;\
     return statusBarManager.statusBarFrame.size.height+44;\
 }else{\
     return [[UIApplication sharedApplication] statusBarFrame].size.height+44;\
 }\
}()

四、Block作為返回值使用

__nullable:可以為空
這里遇到一個崩潰涂臣,設置為nil盾计,打斷點發(fā)現(xiàn)completion是null,就是但是completion沒有判空赁遗,導致崩潰署辉,加了判空就可以了。

[self startAreaSelViewAnimation:nil];
#pragma mark -- 開始動畫
- (void)startAreaSelViewAnimation:(void (^ __nullable)(BOOL finished))completion{
    [UIView animateWithDuration:0.25 animations:^{
        self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.7];
        _backGroundView.frame = CGRectMake(0, _backGroundView.frame.origin.y, Screen_Width, _newBgHeight);//locationView.y+locationView.height
    } completion:^(BOOL finished) {
        if (completion != nil) {
            completion(finished);
        }
    }];
}

五岩四、Xcode 14.3升級后運行報錯

模擬器:

ld: file not found: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphonesimulator.a
clang: error: linker command failed with exit code 1 (use -v to see invocation)

真機:

ld: file not found: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphoneos.a
clang: error: linker command failed with exit code 1 (use -v to see invocation)

由于Xcode 14.3版本移除了ARC相關的庫哭尝,從而導致一些默認部署目標是iOS 8版本的第三方庫出現(xiàn)報錯。只要最低部署目標不低于iOS 9版本炫乓,運行項目時就不會去鏈接ARC相關的庫刚夺,也就不會出現(xiàn)找不到庫的報錯。

解決方法

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0' 
    end
  end
end

11.0是你支持的最低版本末捣,并不是固定的侠姑。
解決方案鏈接

六、自定義AlertView的文字顏色

Title使用富文本箩做。
alterView使用KVC設置顏色莽红。

- (void)createWaitActivateAlertView{
    NSString *message = @"您的企業(yè)賬戶未完成激活,不能發(fā)”專票“貨源,請盡快激活安吁。激活之前醉蚁,您只能發(fā)布不開票或普票貨源。";
    NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:message];
    [attrStr addAttribute:NSForegroundColorAttributeName
                    value:kUIColorFromRGB(0x666666)
                    range:NSMakeRange(0, 28)];
    [attrStr addAttribute:NSForegroundColorAttributeName
                    value:kUIColorFromRGB(0xFE9D09)
                    range:NSMakeRange(attrStr.length-19, 19)];
    [attrStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:12] range:NSMakeRange(0, attrStr.length)];
    
    UIAlertController *alterView = [UIAlertController alertControllerWithTitle:@"您的企業(yè)賬戶待激活" message:nil preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *cancle = [UIAlertAction actionWithTitle:@"暫不激活" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
    }];
    [alterView setValue:attrStr forKey:@"attributedMessage"];
    [cancle setValue:kUIColorFromRGB(0x999999) forKey:@"titleTextColor"];
    UIAlertAction *sure = [UIAlertAction actionWithTitle:@"去激活" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
        
    }];
    [sure setValue:kUIColorFromRGB(0x3194EF) forKey:@"titleTextColor"];
    [alterView addAction:cancle];
    [alterView addAction:sure];
    [self presentViewController:alterView animated:YES completion:nil];
}

七鬼店、限定鍵盤輸入的內容

TextField只能輸入字母和數(shù)字+字數(shù)限制网棍。
傳送門

1、設置鍵盤樣式

self.textField.keyboardType = UIKeyboardTypeASCIICapable;

2妇智、設置宏條件

#define NUM @"0123456789"
#define ALPHA @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
#define ALPHANUM @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"

3滥玷、textFieldDelegate代理方法

// 只能輸入字母和數(shù)字
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:ALPHANUM] invertedSet];
    NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
    return [string isEqualToString:filtered];
}
// 小寫字母轉大寫字母
- (void)textFieldDidEndEditing:(UITextField *)textField {
    textField.text = [textField.text uppercaseString];
}

八、組件化block傳參

需求一個組件調用另一個組件巍棱,需要獲取返回的參數(shù)惑畴,有兩種方式,一個是delegate航徙,另一個就是block如贷。

1、delegate

通過設置代理到踏,使用responseSelect的方式直接調用方法杠袱,方法返回數(shù)據(jù)之后,使用代理回傳參數(shù)夭禽。調用中CTM的時候不需要在調用VC中聲明代理霞掺。

1.1 中間件方法
- (UIViewController *)Main_Car_complaintShowBigImagesViewControllerWithDelegate:(id)delegate dataArray:(NSArray *)dataArray index:(NSInteger)index isHidden:(BOOL)isHidden {
    NSMutableDictionary *params = @{}.mutableCopy;
    if (delegate) {
        params[@"delegate"] = delegate;
    }    
    params[@"index"] = @(index);
    return [self performTarget:MainApp_Car_TargetName action:@"complaintShowBigImagesViewController" params:params shouldCacheTarget:NO];
}
1.2 組件中被調用的事件
- (UIViewController *)Action_complaintShowBigImagesViewController:(NSDictionary *)params {
    id data = params[@"data_array"];
    if (![data isKindOfClass:[NSArray class]]) {
        return nil;
    }
    NSArray *images = (NSArray *)data;
    
    TYTComplaintShowBigImagesViewController *viewImage = [[TYTComplaintShowBigImagesViewController alloc] init];
    viewImage.delegate = params[@"delegate"];
    viewImage.dataArray = [NSMutableArray arrayWithArray:images];
    viewImage.isHidden = [params[@"is_hidden"] boolValue];
    viewImage.currentIndex = [params[@"index"] intValue];
    return viewImage;
}

2、block

2.1 中間件方法:
- (void)Shipment_shipViewControllerExcellentCar:(void(^)(NSDictionary *response,BOOL isExcellentCar))callBack{
    NSMutableDictionary *params = [NSMutableDictionary new];
    if(callBack){
        params = @{
            @"block": callBack
        }.mutableCopy;
    }
    [CT() performTarget:Shipment_TargetName action:@"shipmmentManagerExcellentCar" params:params shouldCacheTarget:NO];
}
2.2 組件內被CTM調用的方法:
- (void)Action_shipmmentManagerExcellentCar:(NSDictionary *)params
{
    TYTShipmmentManager *manager = [[TYTShipmmentManager alloc] init];
    void (^callBack)(NSDictionary *response, BOOL isExcellentCar) = params[@"block"];
    if (callBack) {
        manager.callBack  = callBack;
    }
    [manager queryExcellentCarResult:^(NSDictionary *response, BOOL isExcellentCar) {}];
}
2.3 TYTShipmmentManager網絡請求賦值

注意讹躯,這里的self.callBack(GlobalBlock)一定要有值菩彬,否則會崩潰,所以如果CTM沒有調用傳參復制的話潮梯,我們就需要手動復制骗灶。

- (void)queryExcellentCarResult:(TYTGShipmmentManagerBlock)callBack{

    if (self.callBack == nil) {
        self.callBack = callBack;
    }
    callBack = self.callBack;
    [[TYTCommonRequestManager sharedManager] fetchResponseMethod:GET forPlatURLString:@"deposit/queryEquity.action" parameters:@{} success:^(struct TYTCommonResponse response) {
        if(response.code == 200){
            NSDictionary *dataDic = (NSDictionary *)response.data;
            if( [dataDic[@"isJoin"] intValue] == 1 && [dataDic[@"blackStatus"] intValue] == 0 && [dataDic[@"authStatus"] intValue] == 1){
                self.callBack(dataDic, YES);
            }else{
                self.callBack(dataDic, NO);
            }
        }else{
            self.callBack(@{},NO);
        }
    } failure:^(NSError * _Nonnull error) {
        self.callBack(@{},NO);
    }];
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市秉馏,隨后出現(xiàn)的幾起案子耙旦,更是在濱河造成了極大的恐慌,老刑警劉巖萝究,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件免都,死亡現(xiàn)場離奇詭異,居然都是意外死亡帆竹,警方通過查閱死者的電腦和手機绕娘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來栽连,“玉大人险领,你說我怎么就攤上這事侨舆。” “怎么了绢陌?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵挨下,是天一觀的道長。 經常有香客問我脐湾,道長臭笆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任秤掌,我火速辦了婚禮耗啦,結果婚禮上,老公的妹妹穿的比我還像新娘机杜。我一直安慰自己,他們只是感情好衅谷,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布椒拗。 她就那樣靜靜地躺著,像睡著了一般获黔。 火紅的嫁衣襯著肌膚如雪蚀苛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天玷氏,我揣著相機與錄音堵未,去河邊找鬼。 笑死盏触,一個胖子當著我的面吹牛渗蟹,可吹牛的內容都是我干的。 我是一名探鬼主播赞辩,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼雌芽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了辨嗽?” 一聲冷哼從身側響起世落,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎糟需,沒想到半個月后屉佳,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡洲押,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年武花,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诅诱。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡髓堪,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情干旁,我是刑警寧澤驶沼,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站争群,受9級特大地震影響回怜,放射性物質發(fā)生泄漏。R本人自食惡果不足惜换薄,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一玉雾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧轻要,春花似錦复旬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至凡恍,卻和暖如春志秃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嚼酝。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工浮还, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人闽巩。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓钧舌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親又官。 傳聞我的和親對象是個殘疾皇子延刘,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內容

  • 1.封裝 --> 重用a.函數(shù)b.類c.庫 注意:類與類之間的關系必須越獨立越好。 面向接口(方法)編程(把方法規(guī)...
    jayck閱讀 145評論 0 0
  • 最近寫了一個node+mongo+vue的全棧項目六敬,寫一個博客網站碘赖,該代碼node/vue都很注重模塊化處理, ...
    積小流閱讀 247評論 0 0
  • zhongxia2016-07-22 18:21:19 1. React使用心得 ES6中, 給標簽 添加事件, ...
    izhongxia閱讀 273評論 0 0
  • OC轉Swift外构,橋接頭文件 沒有橋接頭文件普泡,新建OC文件也沒有頭文件的解決方法: 自己新建一個.h頭文件,但是一...
    jayck閱讀 187評論 0 0
  • 1說一下非極大值抑制(NMS) 用處:本質是搜索局部極大值审编,抑制非極大值元素撼班。原理:NMS為非極大值抑制,用來抑制...
    walkMAN_aholic閱讀 3,732評論 0 2