1.cocoa pods 常用的framework
platform?:ios,'7.0'
target'store'do
pod'AFNetworking','~>?3.1.0'
pod'JSONKit','~>?1.5pre'
pod'MBProgressHUD','~>?0.9.2'
pod'SDWebImage','~>?3.7.6'
pod'SVPullToRefresh','~>?0.4.1'
pod'JTObjectMapping','~>?1.1.2'
pod'MagicalRecord','~>?2.3.2'
pod'GetuiSDK','~>?1.4.2'
pod'XTSafeCollection','~>?1.0.4'
pod'libWeChatSDK','~>?1.6.2'
pod'XMLDictionary','~>?1.4'
pod'Masonry','~>?1.0.0'
pod'OpenUDID','~>?1.0.0'
pod'SAMKeychain','~>?1.5.0'
pod'iVersion','~>?1.11.4'
pod'iCloudDocumentSync','~>?7.4.1'
end
2.NSInteger打印以及字符串的轉換
使用%zd打印NSInteger, %tu打印NSUInteger。
NSInteger?integer?=?1;
NSLog(@"first?number:?%zd",?integer);
NSUInteger?uinteger?=?1;
NSLog(@"second?number:?%tu",?uinteger);
3.UIScrollView 在iOS7中使用了Autolayout 導致不能滾動
-?(void)viewDidLayoutSubviews
{
[_mainScrollView?setContentSize:CGSizeMake(SCREEN_WIDTH,?SCREEN_HEIGHT?+?10)];//增加10個像素讓scrollview可上下滑動}
添加scrollView的content高度.
4.APP包瘦身
1)刪除項目中沒有使用的圖片。查找XCode工程中沒被使用的圖片資源
2)刪除項目中沒有用到的class 和 xib 及storyboard。分析工程中沒有用到class
安裝 fui 工具
sudo gem install fui -n /usr/local/bin
fui usage:?https://github.com/dblock/fui
到工程目錄下,執行 fui find 命令,可以找出所有的沒有用到的class文件。
3)分析ipa包,找出大于500K的文件或內容 使用
1
find?.?-type?f?-size?+500000c?|?xargs?ls?-lh
圖形搜索法
5.直接iOS7的連續跳轉
-?(void)back
{
[self?dismissViewControllerAnimated:YES
completion:^{if(self.loginCanceled)?{?????????????????????????????????????self.loginCanceled();?????????????????????????????????????self.loginCanceled?=?nil;
}
}];
}
其中loginCanceled的實現
[weakSelf.navigationController?popViewControllerAnimated:YES];
6.去除Preferred Max 的警告
警告的原因:
xib或storyboard中添加了UILabel的控件
UILabel的number lines 大于1
UILabel的preferred max沒有設置值(?@property(nonatomic) CGFloat preferredMaxLayoutWidth NS_AVAILABLE_IOS(6_0);)
解決方法:
1)如果是Storyboard的,右鍵點擊警告
警告
2)查看警告的詳情
詳情
3)復制ID的值在搜索框中進行搜索
搜索
4)點擊搜索到的Label,可以找到label
找到Label
5)設置preferred width為0,并選中explicit
設置
6)警告解決
如果警告的是Xib,直接點擊警告
xib
就會跳轉到對應的UILabel控件,設置preferred width為0,并選中explicit。 警告解決。
7.Cocoa pods更新到1.0 不能用了
更新完cocoa pods后,執行pod install后提示
Errno::ENOTEMPTY - Directory not empty @ dir_s_rmdir - /Users/arthurwang/SVN///*/Pods
[!] Oh no, an error occurred.Search for existing GitHub issues similar to yours:https://github.com/CocoaPods/CocoaPods/search?q=Directory+not+empty+%40+dir_s_rmdir+-+%2FUsers%2Farthurwang%2FSVN%2F59Store%2Fstoreapp-ios%2Fstore%2FPods&type=IssuesIfnone exists, create a ticket, with the template displayed above, on:https://github.com/CocoaPods/CocoaPods/issues/newBesure to first read the contributing guide for details on how to properly submit a ticket:https://github.com/CocoaPods/CocoaPods/blob/master/CONTRIBUTING.md
Don't forget to anonymize any private data!
解決方法:
刪除項目中的Pods文件夾,再進行pod install的安裝
8.interactivepopgesturerecognizer 使用
設置left bar button后,會導致右滑返回的效果失效,查看完美的設置方案。
同時為了獲取到右滑返回的事件,可以執行
[self.navigationController.interactivePopGestureRecognizer addTarget:self action:@selector(back)];
在ViewController中viewDidAppare中添加,在viewWillDisappear中remove。
9.更新Cocoapods上的代碼
1)采用私有的Cocoapods管理代碼,需要添加
pod repo add HXSpec git@code.59store.com:ios/HXSpecs.git
將私有的Spec管理Git添加到pod的specs中。為了方便更新私有庫。
2)在使用Cocoapods管理代碼的時候,如果在GitHut上更新了代碼,希望在project中執行pod install 來刷新代碼,那么需要刪除Pods和Podfile.lock文件
然后在執行pod install 來刷新代碼
使用pod update進行repo的更新(更新私有庫)
3)多次安裝pod install 會出現Build Phase里多個Check Pods Manifest.lock的選項,這些選項可以刪除。
采用直接將specs文件放到HXSpecs的管理庫中,那么需要執行pod update 進行
Updating local specs repositories
不然會報錯
4)刪除這個目錄下的緩存文件,進行第三方庫文件的重新獲取
/Users/arthurwang/Library/Caches/CocoaPods/Pods
5)進行兩個組件相互依賴的時候,會導致報錯:
[!] There is a circular dependency between StoreLocation and StoreBase
10. UICollectionView的數據不夠,無法滑動——解決方案
tableView的數據無論多少,它的界面默認都是可以滑動的。
和tableView相比,當collectionView的數據較少不夠一個屏幕時,它無法滑動。
解決方案:
1
_collectionView.alwaysBounceVertical?=?YES;
設置為總能垂直滑動就OK了。
11.MLeaksFinder 檢查內存泄露
MLeaksFinder 直接用Pod導入就可以。根據DEBUG這個宏,開啟內存泄露的檢查,如果發現內存泄露,將斷言。 So Good
12.刪除String的中文
思路: 采用刪除不用需要保留的字符,來實現刪除中文的目的
//數字和字母
#define?ALPHANUM?@"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
//數字
#define?NUM?@"0123456789"
NSCharacterSet?*cs?=?[[NSCharacterSet?characterSetWithCharactersInString:ALPHANUM]?invertedSet];
NSString?*filteredStr?=?[[textStr?componentsSeparatedByCharactersInSet:cs]?componentsJoinedByString:@""];
另外:UITextField 只能輸入數字和字母
[[NSNotificationCenter?defaultCenter]?addObserver:self
selector:@selector(textFieldChanged:)
name:UITextFieldTextDidChangeNotification
object:nil];
監聽name:UITextFieldTextDidChangeNotification?和?- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
一起使用,來實現。
-?(BOOL)validatePasswordString:(NSString?*)resultMStr
{
BOOL?result?=?YES;
switch(self.mode)?{
caseHXSChangePasswordLogin:?{
NSString?*regex?=?@"^[a-zA-Z0-9]+$";
NSPredicate?*pred?=?[NSPredicate?predicateWithFormat:@"SELF?MATCHES?%@",?regex];
result?=?[pred?evaluateWithObject:resultMStr];
break;
}
caseHXSChangePasswordPay:?{
NSString?*regex?=?@"^[0-9]+$";
NSPredicate?*pred?=?[NSPredicate?predicateWithFormat:@"SELF?MATCHES?%@",?regex];
result?=?[pred?evaluateWithObject:resultMStr];
break;
}
}
returnresult;
}
13.iOS8 以后用WKWebView替代UIWebView
iOS8 之前使用UIWebView進行html的展示,使用UIWebView存在內存占用過大并不釋放的問題。
WKWebView解決了內存占用過大的問題。
14.Xib中UILabel換行
在Xib中輸入很長的文字,需要根據編號進行換行時,按“Enter”鍵無效。
方法:將文字在Text編輯工具編寫好,copy到UILabel上。換行就有了
15.workspace — project — targets 講解
一個工作空間可以包含多個項目,一個項目可以包含多個目標(生成物)。
一個項目中根據運行的targets不同,可以進行不同的編譯設置,project是基礎父類,targets是子類,targets的設置會覆蓋project的設置。
16.繪畫虛線, drawRect繪畫frame未定的情況
[yourView.layer?setBorderWidth:5.0];
[yourView.layer?setBorderColor:
[[UIColor?colorWithPatternImage:[UIImage?imageNamed:@"DotedImage.png"]]?CGColor]];//just?add?image?name?and?create?image?with?dashed?or?doted?drawing?and?add?here
這里只需要添加QuartzCore/QuartzCore.h框架,像下面一樣導入.m文件:
注意:
當使用Autolayout后,繪畫虛線是根據frame進行的,那么在
-?(void)drawRect:(CGRect)rect
{
[self?drawBorderLayer];
}
drawRect方法中,進行繪畫。
17.Array 的深復制
指針的復制
dataArray3=[dataArray2 mutableCopy];
知識對dataArray2 進行了深復制,數組中的內容僅僅是指針的復制。
單層深復制
dataArray3=[[NSMutableArray alloc]initWithArray:dataArray2 copyItems:YES];
dataArray2進行本身和內容的深復制。單僅僅是內容的第一層
完全深復制
dataArray3 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:dataArray2]];
不管多少層都可以進行了深復制
18.企業證書下載版本可在APP中直接打開
在APP中有H5的頁面,可以直接點擊進行其他應用的下載
19.URL中對“#”的處理
NSString?*str?=?@"http://test.fd.com/#/dte{}|||?lsfj=12&sdlfj=34&hao=你好";
NSURL?*url?=?[NSURL?URLWithString:[str?stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet?characterSetWithCharactersInString:@"`%^{}\"[]|\\<>?"].invertedSet]];
NSLog(@"url?is?%@",?url);
輸出:http://test.fd.com/#/dte%7B%7D%7C%7C%7C?lsfj=12&sdlfj=34&hao=%E4%BD%A0%E5%A5%BD
# 沒有被轉義
iOS9版本中需要使用
stringByAddingPercentEncodingWithAllowedCharacters替代之前stringByAddingPercentEscapesUsingEncoding。
NSString?*str?=?@"http://test.fd.com/#/dte{}|||?lsfj=12&sdlfj=34&hao=你好";
NSURL?*url?=?[NSURL?URLWithString:[str?stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSLog(@"[url?scheme]?is?%@.",?[url?scheme]);
NSLog(@"[url?host]?is?%@.",?[url?host]);
NSLog(@"[url?password]?is?%@.",?[url?password]);
NSLog(@"[url?user]?is?%@.",?[url?user]);
NSLog(@"[url?path]?is?%@.",?[url?path]);
NSLog(@"[url?query]?is?%@.",?[url?query]);
NSLog(@"[url?fragment]?is?%@.",?[url?fragment]);
NSLog(@"[url?resourceSpecifier]?is?%@.",?[url?resourceSpecifier]);
NSLog(@"[url?parameterString]?is?%@.",?[url?parameterString]);
NSLog(@"[url?relativePath]?is?%@.",?[url?relativePath]);
輸出:
2016-08-09 18:57:52.913 store[20150:672790] [url scheme] is http.
2016-08-09 18:57:52.913 store[20150:672790] [url host] is test.fd.com.
2016-08-09 18:57:52.914 store[20150:672790] [url password] is (null).
2016-08-09 18:57:52.914 store[20150:672790] [url user] is (null).
2016-08-09 18:57:52.914 store[20150:672790] [url path] is /#/dte{}|||.
2016-08-09 18:57:52.914 store[20150:672790] [url query] is lsfj=12&sdlfj=34&hao=%E4%BD%A0%E5%A5%BD.
2016-08-09 18:57:52.914 store[20150:672790] [url fragment] is (null).
2016-08-09 18:57:52.915 store[20150:672790] [url resourceSpecifier] is //test.fd.com/%23/dte%7B%7D%7C%7C%7C?lsfj=12&sdlfj=34&hao=%E4%BD%A0%E5%A5%BD.
2016-08-09 18:57:52.915 store[20150:672790] [url parameterString] is (null).
2016-08-09 18:57:52.915 store[20150:672790] [url relativePath] is /#/dte{}|||.
20.APP 啟動頁不更新
修改了LaunchScreen.xib 后,模擬器上顯示正常,但是真機上沒有更新。
原因:?應用緩存
解決:真機上刪除APP,重啟手機,重新安裝APP。
21. httpsdns 使用
申請 account id 下載sdk
查看SDK 文檔 初始化,替換域名為IP
https://help.aliyun.com/document_detail/30116.html?spm=5176.product30100.4.28.bLXrJ4
在阿里云 里配置域名
22.打印不出變量的值 都顯示nil
當對某個變量進行調試的并打印值時,一直返回nil。但是界面又能顯示內容。
原因:說明這個變量是在某個線程中,而調試的不在這個線程里。
23.判斷是否為gif/png圖片的正確姿勢
//通過圖片Data數據第一個字節?來獲取圖片擴展名
-?(NSString?*)contentTypeForImageData:(NSData?*)data
{
uint8_t?c;
[data?getBytes:&c?length:1];
switch(c)
{
case0xFF:
return@"jpeg";
case0x89:
return@"png";
case0x47:
return@"gif";
case0x49:
case0x4D:
return@"tiff";
case0x52:
if([data?length]?<?12)?{
returnnil;
}
NSString?*testString?=?[[NSString?alloc]?initWithData:[data?subdataWithRange:NSMakeRange(0,?12)]?encoding:NSASCIIStringEncoding];
if([testString?hasPrefix:@"RIFF"]
&&?[testString?hasSuffix:@"WEBP"])
{
return@"webp";
}
returnnil;
}
returnnil;
}
其實圖片數據的第一個字節是固定的,一種類型的圖片第一個字節就是它的標識, 我們來調用一下這個方法:
//假設這是一個網絡獲取的URL
NSString?*path?=?@"http://pic.rpgsky.net/images/2016/07/26/3508cde5f0d29243c7d2ecbd6b9a30f1.png";
NSData?*data?=?[NSData?dataWithContentsOfURL:[NSURL?URLWithString:path]];
//調用獲取圖片擴展名
NSString?*string?=?[self?contentTypeForImageData:data];
//輸出結果為?png
NSLog(@"%@",string);
24.JSPatch 的convertor 工具使用
左邊輸入
@implementation?HXSAdTableViewCell
+?(CGFloat)getCellHeightWithObject:(HXSStoreAppEntryEntity?*)storeAppEntryEntity
{
CGFloat?scale?=?[storeAppEntryEntity.imageHeightIntNum?floatValue]/[storeAppEntryEntity.imageWidthIntNum?floatValue];
return([UIScreen?mainScreen].bounds.size.width)?/?3?*?scale?+?30;
}
@end
右邊輸出
require('UIScreen');
defineClass('HXSAdTableViewCell',?{}?{
getCellHeightWithObject:function(storeAppEntryEntity)?{
varscale?=?storeAppEntryEntity.imageHeightIntNum().floatValue()?/?storeAppEntryEntity.imageWidthIntNum().floatValue();
return(UIScreen.mainScreen().bounds().size().width())?/?3?*?scale?+?30;
},
});
有一個BUG:?defineClass('HXSAdTableViewCell', {} {?在{}后面少一個“,”。
正確:
require('UIScreen');
defineClass('HXSAdTableViewCell',?{},?{
getCellHeightWithObject:function(storeAppEntryEntity)?{
varscale?=?storeAppEntryEntity.imageHeightIntNum()?/?storeAppEntryEntity.imageWidthIntNum();
return(UIScreen.mainScreen().bounds().width)?/?3?*?scale?+?30;
},
});
25.Navigation bar的left bar button 跳動
-?(void)jumpToViewController:(UIViewController?*)vc
{
//?show?the?navigation?bar?in?other?vcs
[self.navigationController?setNavigationBarHidden:NO];
[self.navigationController?pushViewController:vc?animated:YES];
}
當設置了?self.navigationItem.leftBarButtonItem.imageInsets = self.navigationController.viewControllers.count == 1 ? UIEdgeInsetsZero : UIEdgeInsetsMake(0, -5, 0, 5);
那么進行顯示navigation bar的時候,就引起left bar button的跳動。
可以設置navigation bar hidden在push之前來解決。
26.Xcode8 出現ubsystem: com.apple.UIKit, category: HIDEventFiltered。。。的日志
解決辦法:【product】-【scheme】-【Edit Scheme】-【Run】-【Argument】-【Environment Variable】添加keyValue【OS_ACTIVITY_MODE disable】可以停止輸出打印此日志
27.intrinsic size 同一行有2個可變長度的的UILabel
Content Hugging Priority代表控件拒絕拉伸的優先級。優先級越高,控件會越不容易被拉伸。
而下面的Content Compression Resistance Priority代表控件拒絕壓縮內置空間的優先級。優先級越高,控件的內置空間會越不容易被壓縮
設置Content Hugging Priority 和 Content Compression Resistance Priority, 可實現當2個UILabel的內容都很長的時候,哪個label進行壓縮,哪個Label進行顯示完整。
28.pusher 推送測試
https://github.com/noodlewerk/NWPusher/releases/tag/0.7.0
直接進行推送的測試。
29.float的精度解決
將NSNumber轉化為CGFloat時,精度失真。
NSString?*decimalNumberMutiplyWithString(NSString?*multiplierValue,NSString?*multiplicandValue)
{
NSDecimalNumber?*multiplierNumber?=?[NSDecimalNumber?decimalNumberWithString:multiplierValue];
NSDecimalNumber?*multiplicandNumber?=?[NSDecimalNumber?decimalNumberWithString:multiplicandValue];
NSDecimalNumber?*product?=?[multiplicandNumber?decimalNumberByMultiplyingBy:multiplierNumber];
return[product?stringValue];
}
NSLog(@"%@",decimalNumberMutiplyWithString([NSString?stringWithFormat:@"%f",a],?[NSString?stringWithFormat:@"%d",b]));//輸出結果?999999.99
通過計算每一位的數字,再進行string展示。
-?(NSString?*)convertStringFromFloatNum:(NSNumber?*)floatNum
{
NSNumberFormatter?*numberFormatter?=?[[NSNumberFormatter?alloc]?init];
[numberFormatter?setPositiveFormat:@"0.00"];
NSString?*tempFloatStr?=?[numberFormatter?stringFromNumber:[NSNumber?numberWithDouble:([floatNum?floatValue]?*?100)]];//?yuan?to?fen
NSInteger?tempInt?=?[tempFloatStr?integerValue];
NSInteger?result?=?tempInt?%?100;
if(0?==?result)?{
NSString?*str?=?[NSString?stringWithFormat:@"%zd",?tempInt/100];
returnstr;
}
result?=?tempInt?%?10;
if(0?==?result)?{
NSString?*str?=?[NSString?stringWithFormat:@"%zd.%zd",?tempInt/100,?(tempInt?%?100)/10];
returnstr;
}
NSString?*str?=?[NSString?stringWithFormat:@"%zd.%zd%zd",?tempInt/100,?(tempInt?%?100)/10,?(tempInt?%?100)];
returnstr;
}
30.個推iOS10改動
iOS 10 中 “loc-key”和“body”(我們官網就是“message”)這二個字段的優先級發生了變化,在iOS 10中“body”的優先級大于“loc-key”,在iOS 10以下“loc-key”大于“body”,不推薦使用“body”傳遞數據
將Message(對應body)中的數據放到payload中,將loc-key的數據放到message(對應body)中,在iOS 10中就不會出現顯示代碼了
31.iOS10 默認的frame
32.騰訊手機管家 騷擾攔截 數據庫更新失敗