APNS测试与部署

APNS即Apple Push Notification Service,中文翻译为苹果推送通知服务。特点是稳定、方便,不足是没有送达结果的统计,所以衍生了针对此服务的第三方推送。比如极光推送leancloud等,很大程度上减少了服务端的开发量。本文主要介绍APNS的开发调试及部署上线的流程。客户端准备工作如下:

创建Certificates

进入苹果开发者中心,打开App IDs,找到Xcode工程对应的Bundle ID,即可看到Push Notifications选项开发与生产配置分别为Configurable,点击Edit,进入下一步Create Certificate,如下图所示。

生成Cer文件的过程中需要本地生成一个.certSigningRequest文件上传

如何生成 Certificate Signing Request

打开mac系统中的Keychain,在证书助理中选择从证书颁发机构请求证书,填写邮箱保存本地即可。如下图:

生成CSR文件后上传,即可生成Developerment版的cer证书,下载证书到本地,双击安装到钥匙串中,然后打开钥匙串找到刚在安装的cer证书,点击导出,选择个人信息交换(.p12)格式。

完成上述操作后,打开终端,进入p12文件所在文件夹,执行以下命令,生成服务端push所用的pem证书就可以了。

1
openssl pkcs12 -in XXX.p12 -out XXX.pem -nodes

查看证书有效期:

1
openssl x509 -in xxx.pem -noout -dates

返回结果:

1
2
notBefore=Nov  6 07:55:33 2015 GMT
notAfter=Nov 5 07:55:33 2016 GMT

连接APNS测试证书是否合法:

1
2
3
4
// Development 环境
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert xxx.pem -key xxx.pem
// Distribution 环境
openssl s_client -connect gateway.push.apple.com:2195 -cert xxx.pem -key xxx.pem

合法返回结果:

1
2
3
4
5
6
7
8
9
Protocol  : TLSv1
Cipher : AES256-SHA
Session-ID:
Session-ID-ctx:
Master-Key: 30AF233C50CBEB51B7358BA47E6B4D556CC962BC288F6D51E68300D86400F927925077B5B90C4938B189146E0A4897B2
Key-Arg : None
Start Time: 1446972326
Timeout : 300 (sec)
Verify return code: 0 (ok)

如何测试

Developer环境下的测试推荐一个mac上的app,Cocoa-APNS-Test,部署简单方便。Production环境下的测试则需要Adhoc证书的支持了,具体操作请参考这里

iOS应用内付费(IAP)提交审核一波三折

App Store的审核众所周知是一个耗时耗力的活儿,尤其是第一个版本的提交,如果App又包含的内付费的功能,那就更需要耐心了。为期一个半月的审核终于通过,简单记录下期间的经验,希望能帮助到大家。

首先汇总下被拒的官方回复:

  • 2.2 - Apps that exhibit bugs will be rejected
  • 2.9 - Apps that are “demo”, “trial”, or “test” versions will be rejected. Beta Apps may only be submitted through TestFlight and must follow the TestFlight guidelines
  • 3.3 - Apps with names, descriptions, screenshots, or previews not relevant to the content and functionality of the App will be rejected
  • 11.4 - Apps that use IAP to purchase credits or other currencies must consume those credits within the App
  • 14.1 - Any App that is defamatory, offensive, mean-spirited, or likely to place the targeted individual or group in harm’s way will be rejected
  • 14.3 - Apps that display user generated content must include a method for filtering objectionable material, a mechanism for users to flag offensive content, and the ability to block abusive users from the service
  • 17.2 - Apps that require users to share personal information, such as email address and date of birth, in order to function will be rejected

针对以上问题的分析与解决:

  • 2.2,苹果测试人员在审核期间会使用最新的iOS系统来测试应用,但不一定是最新的硬件。所以在提审之前要保证App在最新的系统下运行流畅,如果是iPhone的版本,也需要确保在iPad上不出问题才行。当时我们提交的时候官方最新的iOS版本是8.4.1,我们以为在8.4.0上运行没问题就好,忽略了iOS小版本的某些特性差异。

  • 2.9,由于我们的App是做了日文的本地化,在首页banner图片上有细小的测试字样,提审的时候没有去除,苹果对这方面的审核非常严格,会认为你的产品当前仍处于测试版,所以不能上架。提醒开发者留意这些细节。

  • 3.3,此项是关于iTunes Connect 中App介绍说明的,建议说明文案宁少勿多,不要涉及等等、更多字样,只列举明确包含的功能即可。

  • 11.4,苹果关于IAP的规则是虚拟货币不可以在app内流通且只能在平台内消费,更不允许有送礼+分成等方式,关于收入的分成十分严格,请开发者谨慎对待。在产品初期制定好使用规则,不然以后改动成本巨大。

  • 14.1/14.3,建议开发者对应用的评级有一个合理的定位,尤其是UGC、视频方面的App,在不清楚的情况下级别勾选越高越对审核有帮助。详细请参考官方审核指南。如果是UGC内容要有非常明显的举报入口,及一定范围内的敏感词过滤功能。

  • 17.2,在App集成第三方登录时会经常遇到,苹果建议开发者有自己的帐号系统,如果是使用Facebook/Twitter/Weibo/Weixin做认证,除了拉取用户个人资料和分享,App必须包含显著的FB和TW特定账户功能。特定功能比如同步Feed至第三方系统,获取粉丝及关注列表等。针对此条款我们专门做了申诉,大家可以作为参考:

    Sorry but I am afraid you misunderstood the function of our application. Actually wedo not force users to share personal information in order to function, we justpull our users’ profile information when they login from Facebook and Twitter.And for the account-based features from Facebook and Twitter, users can share streaming to The-third Party platform, andafter sharing success, there will be link on the-third Party platform which can click and jump to our app. Userscan also share their clips to Facebook and Twitter and these message will besynchronized. we made screenshots to explain this functionality of ourapplication. I hope it works to help you know more about our app.

    另外还配了应用内使用Facebook功能的配图,比如分享、同步Feed,最后才审核通过。下图为数次被拒的原因。

Purchases

重点说一下IAP审核遇到的问题

  • 先说购买凭证的验证,在苹果审核期间只会再Sandbox环境购买,所以购买凭证需要链接苹果测试服务器(https://sandbox.itunes.apple.com/verifyReceipt )来验证,等审核通过,后端部署到苹果正式服务器(https://buy.itunes.apple.com/verifyReceipt)即可。我们在这方面犯了一个错误就是在期间后段链接的是苹果的测试服务器造成购买失败,应用被拒绝。
  • 如果应用被拒了一次,再次提交时的如果IAP商品的状态为Developer Action Needed(如下图所示),需要手动刷新下,编辑下商品名称,加个空格即可。然后状态会变为正在等待审核,再上传二进制文件。

Purchases

One more thing - 合理申诉

  • 如果应用被拒后,第一时间先确认是由于二进制文件的问题,还是文案的描述问题,或者是苹果审核团队的疑问未得到解答。如果是二进制文件被拒,则需要修复问题后重新打包上传,等待审核结果。
  • 如果是提审文案或者配图的问题只需要修改下再次提交审核即可,无需二次打包。
  • 还有一种情况是审核被拒,可以不做任何改动,直接申诉。在iTunes Connect解决方案中心会收到来自苹果审核团队的站内信,只需要详细逐条回复即可。最好绘声绘色,图文并茂,一般24小时内会得到苹果的二次确认。如果审核人员认可了你的申诉,那么你的App很快就会进入In Review的状态,离上架就只有一步之遥了。心酸经历附个图:

Purchases

相关引用:

https://blog.coding.net/blog/ios-testFlight
http://blog.devtang.com/blog/2013/04/07/tricks-in-iap/

使用Github发布iOS应用(OTA)

OTA (Over The Air)是苹果很早就支持的功能,目的是让企业用户脱离Appstore通过网页来发布app,想要实现OTA发布,首页要购买一个企业证书,价格是$299/年。申请企业证书:https://developer.apple.com/programs/enterprise/

发布流程如下:

1,使用Xcode生成ipa安装包

  • 首先在TARGETS的General配置中,将Bundle Identifier设置为该企业帐号对应的App ID,如com.baidu.XXX;
  • 然后在Build Setting的Code signing一栏,选择企业帐号对应的Distribution证书;
  • 接下来选择Xcode->Product->Archive,即可开始打包了。
  • 生成xcarchive,接下来Export时,需要选择Save for Enterprise Deployment一项,点击next即可导出ipa文件了。

Enterprise

2,将ipa、plist、html文件、icon上传至新建的根目录

首先新建一个空白的github仓库,将打包好的ipa文件及空白install.plist、install.html文件及app Icon图片上传至仓库根目录。这样就有了每个文件在github上的链接地址。

然后配置install.plist文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>items</key>
<array>
<dict>
<key>assets</key>

<array>
<dict>
<key>kind</key>
<string>software-package</string>
<key>url</key>
<string>https://***/XXX.ipa</string>
</dict>

<dict>
<key>kind</key>
<string>display-image</string>
<key>needs-shine</key>
<true/>
<key>url</key>
<string>https://***/Icon57.png</string>
</dict>

<dict>
<key>kind</key>
<string>full-size-image</string>
<key>needs-shine</key>
<true/>
<key>url</key>
<string>https://***/Icon57.png</string>
</dict>
</array>

<key>metadata</key>

<dict>
<key>bundle-identifier</key>
<string>com.baidu.***</string>
<key>bundle-version</key>
<string>1.0.0</string>
<key>kind</key>
<string>software</string>
<key>title</key>
<string>Hiclub</string>
</dict>

</dict>
</array>
</dict>
</plist>

pist文件中需要注意:

  • software-package对应的链接即github上ipa文件所在地址
  • display-image为安装过程中iphone桌面上显示的图标
  • bundle-identifier为打包ipa中所配置的id
  • bundle-version为当前app版本

3,配置install.html文件,用来生成安装页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Install</title>
</head>
<body>
<p align=center>
<font size="10">
<a style="color:#69DEDA" href="itms-services://?action=download-manifest&url=***/install.plist">点击安装</a>
</font>
</p>
</body>
</html>

install.plist即为该文件在github上的链接地址,然后将全部文件push到github。

4,生成在线安装链接

htmlpreview
由于github上的安装页面install.html无法直接预览,通过一个非常使用的小工具htmlpreview,将install.html原链接转换为可预览的链接,如上图所示。最后用iPhone Safari 打开新生成的链接就可以安装了。