前言javascript
前面剛發了這個技巧總結系列的第四篇文章,這篇文章總結的一些平常開發中的技巧或更偏向於Cocos2d方向,由於最近在遊戲中有原生的一個客服系統須要加進來,就涉及到一個遊戲和原生界面的交互以及各類各樣的BUG,遊戲是屬於在別人代碼的基礎上進行的二次開發,屬於一個非ARC的狀況,而咱們如今的三方應該都是ARC,還有那些讓人頭疼的屏幕旋轉鍵盤等等的問題,最近爬的坑有點多,全部這篇就主要來總結這些坑!固然在咱們的普通應用中遇到這些問題咱們仍是一樣能夠依照這些技巧總結的。前端
一:__weak typeof(self)報錯了java
這個問題我也是以爲奇怪,在咱們正常的使用中通常是不會出現這種錯誤的!這個通常是絕大多數的狀況,應該和這遊戲源碼的年代有直接的關係,這個錯誤我也截圖了,以下:web
這個問題出現的時候上網找了一下解決的辦法,解決是很簡單就能解決這個問題,只要是和個人在 build setting 中下面的設置項不一致,你把它改爲一致的便可:swift
前面說了,這個解決起來很簡單,可是咱們不明不白的設置這東西就是屬於稀裏糊塗了:windows
二: 橫屏切換豎屏 瀏覽器
咱們通常的遊戲都是橫屏的,固然也有豎屏的,在平常的需求中頗有可能就涉及到遊戲和原生界面的交互,就有了橫屏遊戲切換豎屏原生界面出來,其實最讓人頭疼的,是你切換界面以後還有鍵盤的問題!在本身的遊戲中就有這樣一個切換是在客服系統當中,橫屏的遊戲須要你切換到豎屏的一個客服聊天界面!其中就涉及到這個鍵盤的問題!咱們再這裏也總結一下在iOS應用中決定鍵盤的方向因素,在不一樣iOS版本中是不同的。ruby
iOS8:網絡
鍵盤方向是根據一個特定的window決定,打印[UIApplication sharedApplication].windows,最少有兩個,第一個爲UIWindow,是程序主要的keyWindow;第二個爲UITextEffectsWindow,是鍵盤所在的window。app
iOS9:
鍵盤方向由最後一層window決定,這裏有點複雜,由於iOS9新增了一個UIRemoteKeyboardWindow。那麼應用可能就有3個window,依次是UIWindow,UITextEffectsWindow,UIRemoteKeyboardWindow。UIRemoteKeyboardWindow成爲決定鍵盤方向的window了,而UITextEffectsWindow控制了鍵盤頂部欄的方向,以下如:
iOS10:
和iOS9相似,可是,若是要強制旋轉鍵盤的話,它的座標計算方法又和以前的系統有區別。區別在於計算window的原點座標(x,y),iOS10是(0,0,width,height),iOS9的x和y須要這樣計算:CGFloat keyBoardWindowXY = (viewSize.height - viewSize.width) / 2
具體的推薦你們看這篇:[iOS]終極橫豎屏切換解決方案
這篇文章能解決大部分你們的需求。包括一些webView的屏幕旋轉等等。
三:ARC和非ARC混編
有維護一個之前的Cocos-lua的遊戲,這份代碼也是比較的老了,是非ARC的環境,在維護中有給這個遊戲當中添加其餘第三方的框架進去,但如今的iOS的框架幾乎沒有非ARC環境的,就會有各類各樣的錯誤,這時候你就的進行他們的混編了,其實單純混編這一點設置很簡單,關鍵的實際上是咱們得有這樣的一個清晰的認知,知道這裏須要ARC的環境,而不是你拉進去其餘的三方以後看到報錯,就一個勁的糾結在哪一個錯誤上!!這纔是我這裏說這一點的最重要的東西,設置的的很簡單,我直接截一張圖給你們,相信都能看明白!
下面是你給遊戲中添加了MJ以後,你把MJ設置成ARC環境:
四:無線真機測試
在iOS中咱們常常會進行真機測試的,不知道小夥伴們是否是都找一根數據線而後鏈接上測試機以後測試的,有時候可能還得用本身的手機,一誇張一插就是一成天,誰都知道這樣對手機電池很差....
其實咱們是能夠能夠無線真機測試的,我估計也應該有不少小夥伴是知道的,按下面步驟就能夠進行測試,很簡單的,兩張圖搞定:
接下來以下:
是否是OK了。是的,要是手機已經設置了密碼就OK了。要是測試的手機沒有設置手機密碼這時候就會提醒你 Passcode Required 那你就乖乖設置一個手機密碼就能夠啦!
五:JS 和 Swift WKWebView 的最基本交互
這個點要是往大了說。能夠寫一篇原生和JS交互的文章,但之前我寫過這樣的文章,就不想在作重複的工做了,這裏咱們就提一下JS 和 Swift WK的交互,也是剛有一點點需求寫了,就記錄一下吧,代碼具體的看下面,須要注意的地方我都寫在代碼裏面了:
Swift 代碼:
//MARK: JS Swift 交互 func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { let Url = message.body //MARK: 喚起瀏覽器 if message.name == "Model" { let url = URL.init(string: Url as! String) //根據iOS系統版本,分別處理 if #available(iOS 10, *) { UIApplication.shared.open(url!, options: [:], completionHandler:nil) }else{ UIApplication.shared.openURL(url!) } } }
NOTE: 須要注意的是記得在初始化WK的時候給WKWebViewConfiguration 添加交互的信息,否則會調用不成功的:
let webConfiguration = WKWebViewConfiguration() // 給webview與swift交互起名字,webview給swift發消息的時候會用到 webConfiguration.userContentController.add(self, name: "Model")
JS 端的代碼就簡簡單單的一句:
window.webkit.messageHandlers.Model.postMessage("https://www.baidu.com")
NOTE: 這個Model其實就是一個你和前端相約好的一個identify,這樣容易理解,不論是有些文章說的方法名也好仍是要傳值的對象也好,其實起的做用就是一個identify的做用!
OC調用JS方法最簡單的就是: stringByEvaluatingJavaScriptFromString
JavaScriptCore也是徹底能夠的,這個咱們就不細說,下面是我給webView寫的一個類別代碼:
-(void)callJavascriptMethod:(NSString *)methName andCallHandleComplete:(CallComplete)callComplete{ NSString * respondString = [self stringByEvaluatingJavaScriptFromString:methName]; if (!respondString || [respondString isEqualToString:@""]) { debugLog(@"OC調用JS方法:%@ 返回數據爲空",methName); } NSData *respondData = [respondString dataUsingEncoding:NSUTF8StringEncoding]; NSError *err; NSDictionary * respondDic = [NSJSONSerialization JSONObjectWithData:respondData options:NSJSONReadingMutableContainers error:&err]; if(err){ debugLog(@"OC調用JS方法:%@ 返回JOSN解析出錯",methName); }else callComplete(respondDic); }
NOTE: 這裏你只須要注意一點,JS要有返回值,返回值只能是字符串!!固然也能夠是JSON字符串,JSON就能知足通常的需求了,要是JS返回的是一個Objcet,對不起你沒辦法處理!你能夠叫JS把對象處理成JSON字符串給你。
六:AppDelegate 怎麼彈出 UIAlertController 提示
不知道一些朋友會不會有這樣的需求產生,須要你在AppDelegate中提示一些信息,可能許多人都會想到這句代碼:
self.window?.rootViewController?
首先能夠確定的是確定和這句是有關係的,這個無可爭議!但關鍵點可能還不是在這裏,你要直接添加我相信你log中會有這麼一句:
Warning: Attempt to present <UIAlertController: 0x10684d200> on <PCDD.ViewController: 0x106014100> whose view is not in the window hierarchy!
這句話咱們說的直白點的意思就是你要present UIAlertController的ViewController還不在當中
解決這個問題在stackoverflow有這樣的答案 stackoverflow解答 最後咱們直接上代碼:
DispatchQueue.global().async { DispatchQueue.main.async { let alertCtr = UIAlertController(title: "鏈接錯誤", message: "請檢查網絡或者請求配置是否正確", preferredStyle: .alert); alertCtr.addAction(UIAlertAction(title: "肯定", style: .default, handler: { (action) in })) self.window?.rootViewController?.present(alertCtr, animated: true, completion: nil) } }
七:禁止某一個控制器側滑
其實你不用寫太多代碼的,你獲取一下導航欄測滑動target,而後你把它action置一下nil就能夠了
// 禁止側滑返回 id traget = self.navigationController.interactivePopGestureRecognizer.delegate; UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc]initWithTarget:traget action:nil]; [self.view addGestureRecognizer:pan];
八:XCode 10 CocoaPods 升級 bad response Not Found 404 問題
咱們在升級了Xcode10以後使用CocoaPods,在執行了pod install 以後就出了問題:
RuntimeError - [!] Xcodeproj doesn't know about the following attributes {"inputFileListPaths"=>[], "outputFileListPaths"=>[]} for the 'PBXShellScriptBuildPhase' isa.
由於 inputFileListPaths
和 outputFileListPaths
是 Xcode 10 中新增的屬性, 所以舊版本的 CocoaPods 沒法解析,因此咱們升級CocoaPods,結果通常 gem 源是 ruby 中國都會出現這個問題,覺得它換域名了:
它從新提供 .com 代替 .org 的域名,其餘一切不變!因此咱們換一下域名就OK了。終端中執行:
gem sources --add https://gems.ruby-china.com --remove https://gems.ruby-china.org
要是又出現沒有寫入的權限提示,You don't have write permissions for the /usr/bin directory. 這是在說/usr/bin
沒有寫權限, 這是因爲 macOS 10.11 以後增長了 rootless 機制, 致使即便在 root 權限下依然沒法修改文件. 解決辦法,即修改 CocoaPods 安裝目錄:
sudo gem install cocoapods --pre -n /usr/local/bin
最後你能夠查看一下本身pod版本是否升級成功: pod -- version