iOS 开发问与答(16-27)

原创 2017年01月03日 09:18:44

16.如何一次性删除表格中所有单元格?

        var allIndexPath = [NSIndexPath]()
        let nSections = tableView.numberOfSections()
        for j in 0 ..< nSections {
            let nRows = tableView.numberOfRowsInSection(j)
            for i in 0 ..< nRows {
                let indexPath = NSIndexPath(forRow: i, inSection: j)
                allIndexPath.append(indexPath)
            }
        }
        tableView.beginUpdates()
        tableView.deleteRowsAtIndexPaths(allIndexPath, withRowAnimation: UITableViewRowAnimation.None)
        tableView.endUpdates()

要获得所有当前可见的 Cell,使用:

let indexPaths = tableView.indexPathsForVisibleRows()

17.如何将 swift 代码导入到 O-C?

在O-C 文件中使用 import “项目名称-Swift.h” 语句。其中“项目名称”是你的项目名称,例如:#import “ProductName-Swift.h”。
这个文件是 Xcode 自动生成的,它把项目中所有的 Swift 类的接口文件都定义到这个文件中了。注意这些类必须是用 @objc 声明或者继承了 NSObject 的 swift 类。

18.iOS 中有类似于 Java 中的 Synchroized() 的语句吗?

在多线程操作中,经常要保护某一语句块让它同步执行,iOS 中也有类似 Java 的 Synchronized() 语句。要向同步执行语句,将要同步执行的语句包裹在 objc_sync_enter()/objc_sync_exit() 中即可:

// 同步块,防止打印异常
objc_sync_enter(self)
let progress: NSProgress = object as! NSProgress
println("progress:\(progress.fractionCompleted)")
objc_sync_exit(self)

19.如何获取生产环境的 Device Token?

在沙盒环境,我们可以将 device token 打印到控制台,从而获得 device token。但更换到生产环境(production)后就没有这么方便了。如果想获得生产环境的 device token,可以依照以下步骤:

  1. 打开以下 url: http://developer.apple.com/library/ios/#technotes/tn2265/_index.html
  2. 在页面右上角,有一个 Companion File 连接,点击以下载 Companion File 文件。下载后得到一个 tn2265_PersistentConnectionLogging.zip 文件。
  3. 解压缩,获得一个 PersistentConnectionLogging.mobileconfig 文件。将它以附件的方式发送给自己的邮箱。
  4. 在设备上,用系统的“邮件”程序打开这个邮件(注意必须是系统的邮件程序,不能是“邮箱大师”等第三方邮件客户端)。
  5. 点击附件中的 PersistentConnectionLogging.mobileconfig 文件,这将在设备上安装一个 APS/PC Logging 描述文件。在安装过程中,需要输入锁屏密码。
  6. 安装完毕,重启设备。
  7. 在 Xcode 中,打开 Window/Devices,查看设备的控制台日志,可以看到类似 handleReceivedPublicToken:<282aae5d 52978299 134078ed 2702ea16 ddfbd208 10d6fb01 9353c601 4ad773e4> 的字样,这个就是设备的 device token(将空格删除)。

20.如何校验服务器PUSH证书是否有效?

判断 cer 格式的PUSH证书是否有效非常简单,使用 PushMeBaby\SmartPush 之类的 Mac 应用程序向设备推一条推送通知就可以了。
但是服务器使用的PUSH 证书往往是 .pem(PHP/GoLang服务端)或 .p12(Java/C#服务端)格式的,我们可以用以下 OpenSSL 命令判断服务器 PUSH 证书是否有效,然后再确定是否是服务端代码的问题:

  1. 将 PKCS#12 (.pfx .p12) 转成 PEM:

    用以下命令转换成同时包含私钥和证书的 pem 文件:

    openssl pkcs12 -in apns_production_privatekey.p12 -out apns_production_privatekey.pem -nodes
    

    期间会提示输入密码,请输入 p12 文件导出时的密码。

    注意:如果只导出私钥可以加上 -nocerts 参数,只导出证书则可以加上 -nokeys 参数。

  2. 测试生产证书:

    openssl s_client -connect gateway.push.apple.com:2195 -cert apns_production_privatekey.pem
    

    如果输出如下信息(),表明证书是正常的:

CONNECTED(00000003) depth=1 /C=US/O=Entrust,
Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009
Entrust, Inc./CN=Entrust Certification Authority - L1C verify
error:num=20:unable to get local issuer certificate verify return:0
— Certificate chain 0 s:/C=US/ST=California/L=Cupertino/O=Apple Inc./CN=gateway.push.apple.com i:/C=US/O=Entrust,
Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009
Entrust, Inc./CN=Entrust Certification Authority - L1C 1
s:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by
reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority
- L1C i:/O=Entrust.net/OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net
Certification Authority (2048)
— Server certificate
—–BEGIN CERTIFICATE—– MIIFIzCCBAugAwIBAgIETCMvvjANBgkqhkiG9w0BAQUFADCBsTELMAkGA1UEBhMC …
… de7tGJEmdBgmtX2Wn0r0Erg+9nnjOEQ=
—–END CERTIFICATE—– subject=/C=US/ST=California/L=Cupertino/O=Apple
Inc./CN=gateway.push.apple.com issuer=/C=US/O=Entrust,
Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009
Entrust, Inc./CN=Entrust Certification Authority - L1C
— Acceptable client certificate CA names /C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA /C=US/O=Apple Inc./OU=Apple
Worldwide Developer Relations/CN=Apple Worldwide Developer Relations
Certification Authority /C=US/O=Apple Inc./OU=Apple Certification
Authority/CN=Apple Application Integration Certification Authority
— SSL handshake has read 3144 bytes and written 2168 bytes
— New, TLSv1/SSLv3, Cipher is AES256-SHA Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion:
NONE SSL-Session:
Protocol : TLSv1
Cipher : AES256-SHA
Session-ID:
Session-ID-ctx:
Master-Key: 9E737F1BD1AC1D41A2D6486B9F2DD08EF3B87EC9A91EBB42396D9664B34FF534DA2DCF4A897688ECBEFE00B069C481BC
Key-Arg : None
Start Time: 1452222166
Timeout : 300 (sec)
Verify return code: 0 (ok)

21.如何向设备中写入/读出应用日志?

在 Xcode 中调试 App 时,当我们使用 NSLog、printf 语句时,可以向控制台打印一些信息。
如果 App 是以 release 的方式安装(无论以何种方式:App Store、Ad-Hoc 或者 OTA)到设备上,则只有 NSLog 语句打印的信息能够通过 Xcode 的 Devices 进行查看。
如果没有安装 Xcode,则可以通过 iTunes 的文件共享功能查看控制台日子,方法如下(只能查看 NSLog 输出的日志)。

  1. 在 App 的 info.plist 中增加一个 Application supports iTunes file sharing 为 true 的键。
  2. 在 application(_, didFinishLaunchingWithOptions:) 方法中加入代码:

    let documents = NSHomeDirectory().stringByAppendingPathComponent("Documents")
    
    let logFileName = "\(NSDate()).log"
    
    let logFilePath = documents.stringByAppendingPathComponent(logFileName)
    
    freopen(logFilePath.cStringUsingEncoding(NSASCIIStringEncoding)!, "a+", stderr)
  3. 打开 iTunes,连上设备,通过“应用 / 文件共享”将日志文件下载到 Mac。

22.为什么我的 App 在 iOS 8 中可以但在 iOS 9 中却不可以使用定位服务?

在 iOS 9.x 的“设置>定位服务”中,甚至看不到 App 的名字。奇怪的是,在 iOS 8 中却正常。这是因为代码中的 requestAlwaysAuthorization/requestWhenInUseAuthorization 方法和 Info.plist 中的 NSLocationAlwaysUsageDescription/NSLocationWhenInUseUsageDescription 不对应。例如,在代码中使用的是 requestAlwaysAuthorization(总是使用定位服务,哪怕在后台),而 Info.plist 中却只声明了 NSLocationWhenInUseUsageDescription(只有 App 在前台时才使用定位服务),没声明 NSLocationAlwaysUsageDescription 字串。
所以最好是在 Info.plist 文件中同时声明 NSLocationAlwaysUsageDescription 和 NSLocationWhenInUseUsageDescription 字串,这样无论调用的是 requestAlwaysAuthorization 还是 requestWhenInUseAuthorization 方法,都不会出错。

23.为什么 presentOpenInMenuFromXXX 方法在 iOS 9 中不能显示菜单?

iOS 8下没有问题。在 iOS 9 中,用 presentOptionsMenuFromXXX 方法代替。

24.将一个 TabBarController 嵌入到 NavigationController 后,setTitle 无法设置导航栏标题。

这种情况下,必须用 self.tabBarController?.title=”xxx” 来修改导航栏标题。
同理,要修改右按钮使用 :

self.tabBarController?.navigationItem.rightBarButtonItem=UIBarButtonItem(customView: btn)

25.在模拟器(iOS 9)中调试 MapKit 时,出现“Error Domain=kCLErrorDomain Code=2 “(null)”

Product -> Scheme -> Edit Scheme -> Options 中,勾选 Allow Location Simulation ,同时在这里提供一个模拟器坐标,不能是 “none”。

26.如何在多个 ViewController 中共用一个模板单元格

  1. 新建一个空的 xib 文件:CustomCell.xib。
  2. 从故事板中将要共享的模板单元格拷贝到 xib 文件的根下(顶级元素)。
  3. 删除故事板中原来的模板单元格(因为我们不需要它了)。
  4. 在要用到这个单元格的 ViewController 中,在 viewDidLoad 方法(或者别的什么地方)中加入:

    self.tableView.registerNib(UINib(nibName: “CustomCell”, bundle: NSBundle.mainBundle()), forCellReuseIdentifier: “CustomCellIdentifier”)

  5. 然后在 tableView(_, cellForRowAtIndexPath:) 方法中:

    let cell = tableView.dequeueReusableCellWithIdentifier(“CustomCellIdentifier”) as! CustomCell

27.Xcode 打包错误: Missing IOS Distribution Signing Identity

Apple WWDR 证书过期(2016年2月15日过期)。

  1. 下载 https://developer.apple.com/certificationauthority/AppleWWDRCA.cer
  2. 双击下载的 WWDR 证书,将它安装到 Keychain
  3. 在 Keychain 中,选择 视图 -> “显示已过期的证书”
  4. 在 Keychain 中,选择“证书”(注意,不是“我的证书”),找到过期的那个 “Apple Worldwide Developer Relations Certificate Authority certificates” 并删除(包括“登录”和“系统两个账号中的都要删除)。
  5. 重新 Archive
版权声明:本文为博主原创文章,未经博主允许不得转载。

IOS8解决获取位置坐标信息出错(Error Domain=kCLErrorDomain Code=0)

前几天解决了在ios8上无法使用地址位置服务的问题,最近在模拟器上调试发现获取位置坐标信息的时候会报错,错误信息: didFailWithError: Error Domain=kCLErrorDom...
  • JJMM2009
  • JJMM2009
  • 2014年12月17日 11:39
  • 21920

Error Domain=kCLErrorDomain Code=0 "(null)"

IOS百度定位错误:  Error Domain=kCLErrorDomain Code=0 "(null)" 解决: Product -> Scheme -> Edit Sche...
  • smilebigdear
  • smilebigdear
  • 2016年03月28日 10:36
  • 301

Xcode后台打印出现:[Client] Geocode error: Error Domain=GEOErrorDomain Code=-8 "(null)”

分析原因:在使用反地理编码,遇到了Error Domain=kCLErrorDomain Code=8 问题 这个是因为 didUpdateLocations:方法的参数 错误所以要注意如果有这个问题...
  • yuhao309
  • yuhao309
  • 2017年07月05日 18:14
  • 1006

iOS[问题解决] Error Domain=kCLErrorDomain Code=0 "The operation couldn’t be completed.

错误:Error Domain=kCLErrorDomain Code=0 "The operation couldn’t be completed. 环境:XCODE6.0.1 + i...
  • s133315202
  • s133315202
  • 2015年06月24日 11:58
  • 872

iOS 开发问与答(56-84)

56. iOS 9 以后的 Push 通知注册(swift 1) 57.如何创建一个纯色构成的背景图片,并用于设置按钮的背景色? 58. 按钮的倒计时效果 59. 如何单...
  • kmyhy
  • kmyhy
  • 2017年03月15日 09:30
  • 913

iOS 开发问与答(1-15)

iOS 开发问与答(FAQ)1.集成SQLite.swift框架出错:“sqlite3.h not found”由于Xcode编译SDK时,模块映射只能使用绝对路径而不能使用相对路径,所以Xcode....
  • kmyhy
  • kmyhy
  • 2016年12月29日 11:51
  • 2084

iOS开发----百度地图定位之KCLErrorDomain Code = 0的解决方法

最近使用百度地图的SDK,真机调的时候总是会出现问题,于是就在网上找答案,终于找到下面一篇很好的解释,我的原因也在此。 转载自:点击[百度地图] kCLErrorDomain Code=0终极解决方案...
  • RunIntoLove
  • RunIntoLove
  • 2015年12月18日 17:17
  • 2263

AVAudioPlayer 的 Error Domain=NSOSStatusErrorDomain Code=-10875 "未能完成操作。(“OSStatus”错误 -10875。)"

今天在做一个项目,因为要播放一个音频,就选择用 AVAudioPlayer来来做,因为以前用过,也没有注意太多后来就直接写,但是写好之后运行看效果,怎么也播放不出来,本来是因为本地音频文件有问题,后来...
  • shangshang1029
  • shangshang1029
  • 2015年04月08日 16:54
  • 6088

iOS 开发问与答(28-38)

28.LocalSubstitionCache 不生效AMapLocation 和 LocalSubstitutionCache 有冲突,无法和后者同时使用。将 AMapLocation 换成苹果的 ...
  • kmyhy
  • kmyhy
  • 2017年01月22日 13:27
  • 1229

iOS 开发问与答(85-102)

85. 获取当前时间的几种方法效率由高到低分别是: CACurrentMediaTime“`swiftimport QuartzCorelet now:Double = CACurrentMediaT...
  • kmyhy
  • kmyhy
  • 2017年03月15日 09:35
  • 586
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iOS 开发问与答(16-27)
举报原因:
原因补充:

(最多只允许输入30个字)