专栏首页移动端开发常用开发技巧系列(五)

常用开发技巧系列(五)

前言


前面刚发了这个技巧总结系列的第四篇文章,这篇文章总结的一些日常开发中的技巧或更偏向于Cocos2d方向,因为最近在游戏中有原生的一个客服系统需要加进来,就涉及到一个游戏和原生界面的交互以及各种各样的BUG,游戏是属于在别人代码的基础上进行的二次开发,属于一个非ARC的情况,而我们现在的三方应该都是ARC,还有那些让人头疼的屏幕旋转键盘等等的问题,最近爬的坑有点多,所有这篇就主要来总结这些坑!当然在我们的普通应用中遇到这些问题我们还是同样可以依照这些技巧总结的。

一:__weak typeof(self)报错了


这个问题我也是觉得奇怪,在我们正常的使用中一般是不会出现这种错误的!这个一般是绝大多数的情况,应该和这游戏源码的年代有直接的关系,这个错误我也截图了,如下:

这个问题出现的时候上网找了一下解决的办法,解决是很简单就能解决这个问题,只要是和我的在 build setting 中下面的设置项不一致,你把它改成一致的即可:

前面说了,这个解决起来很简单,但是我们不明不白的设置这东西就是属于稀里糊涂了:

二: 横屏切换竖屏


我们一般的游戏都是横屏的,当然也有竖屏的,在日常的需求中很有可能就涉及到游戏和原生界面的交互,就有了横屏游戏切换竖屏原生界面出来,其实最让人头疼的,是你切换界面之后还有键盘的问题!在自己的游戏中就有这样一个切换是在客服系统当中,横屏的游戏需要你切换到竖屏的一个客服聊天界面!其中就涉及到这个键盘的问题!我们再这里也总结一下在iOS应用中决定键盘的方向因素,在不同iOS版本中是不一样的。

iOS8:

键盘方向是根据一个特定的window决定,打印[UIApplication sharedApplication].windows,最少有两个,第一个为UIWindow,是程序主要的keyWindow;第二个为UITextEffectsWindow,是键盘所在的window。

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.

因为 inputFileListPathsoutputFileListPaths 是 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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 常用开发技巧系列(三)

    热更新衍生出来的问题:   前两天都在说iOS热更新的问题,结果今天就撞枪口上了,真的!审核被拒了,当然这并不是在我自己的项目使用了什么RN,或者JSPath...

    Mr.RisingSun
  • Swift 基础部分(建议掌握OC字符串知识的翻阅)

    更新说明:         Swift 目前已经发布到4.0版本了,以前写的这整个Swift学习系列的文章,有很多的不足之处,我会重新整理整个系列文章,也是相...

    Mr.RisingSun
  • Charts 常见使用类型实例

    Charts是做什么的:        在我们平时的开发中,当使用到一些统计图表的时候,我们该怎样去做那些柱形的统计图、那些折线统计图、扇形统计图,亦或是你在做...

    Mr.RisingSun
  • 更简单的跨域解决方案 - CORS

    跨域问题是前端开发经常遇到的了,大家可能常用的就是JSONP了, JSONP非常方便,只要前后端约定好一个方法名,就可以沟通了,但JSONP也有一定的局限,JS...

    dys
  • Python类与方法的私有化

    学习面向对象的第一步,就是创建一个类。因为类是面向对象的基石。Python类和其他编程语言(Java、C#等)的类差不多,也需要使用class关键字。下面通过一...

    py3study
  • 响铃:Letv超级电视破局之后,究竟会“立”在哪里?

    8月2日,乐融致新与TCL旗下深圳十分到家服务科技有限公司(以下简称“十分到家”)售后服务达成合作。这又引起行业人士对智能电视行业的走向开始了一番讨论,这个时候...

    曾响铃
  • Kali Linux Web渗透测试手册(第二版) - 8.8 - 使用CMSmap扫描Drupal

    另一个流行的CMS是Drupal,它也是开源的并且基于PHP,与之前的一样。 虽然没有那么广泛,但根据其官方网站

    7089bAt@PowerLi
  • 窥探比特币核心机制如何运转 原

    比特币真的很酷。当然,有人在想它是否是一种有用的技术,无论我们目前是否处于加密货币泡沫中,或者它目前面临的治理问题是否会得到解决......但在纯粹的技术层面上...

    笔阁
  • 微服务与Serverless对决,谁才是未来之主?

    近两年里,微服务的突然崛起让人仿佛看到了架构开发的新世界。摒弃繁杂而不稳定的巨型系统架构城堡,轻装上阵,应用单个开发,基于业务构建,自动化独立部署,不仅缩短了开...

    程序猿DD
  • C++继承和派生练习(一)--关于从people(人员)类派生出student(学生)类等

    Enterprise_

扫码关注云+社区

领取腾讯云代金券