自动化配置iOS开发者证书

一、自动化工具

首先需要对fastlane的几个自动化组件有一定了解,具体的功能以及文档如下:

  • cert:cert is part of fastlane: The easiest way to automate beta deployments and releases for your iOS and Android apps.
  • pem:Makes sure a valid push profile is active and creates a new one if needed
  • sign:sigh can create, renew, download and repair provisioning profiles (with one command). It supports App Store, Ad Hoc, Development and Enterprise profiles and supports nice features, like auto-adding all test devices.
  • produce:produce creates new iOS apps on both the Apple Developer Portal and iTunes Connect with the minimum required information.

阅读更多

APP Download Link

一、登录 iTunes Connect

点击 iTunes Connect ,输入开发者账号密码登录

二、获取 Apple ID

点击“我的APP”

查看APP信息,获取 Apple ID

三、生成 iOS APP 下载链接

https://itunes.apple.com/cn/app/id1174292562 中 id 后面的那串数字用第二步获取到的Apple ID替换

如:第二步获取到的Apple ID 是1311339172,则对应APP的下载链接是:

https://itunes.apple.com/cn/app/id1311339172

温馨提示:小伙伴们获取到 Apple ID 生成 APP 下载链接后,记得先在浏览器中打开试试,看看是否跳转到对应APP。

阅读更多

Transporter Error Output

更新 fastlane 以后,发现自动化打包上传到 iTuens Connect 报错:

1
[Transporter Error Output]: An error occurred while uploading the package: 1255454103.itmsp

解决思路

打开 Application Loader 中的 偏好设置–高级,然后把 DAV 勾选去掉,如图所示:

阅读更多

Byte数组转化为UIImage

在工作中遇到后台返回的图片数据是64位的Byte数组,需要转化为UIImage后显示,转化关系如下:

1
2
NSData *data = [[NSData alloc] initWithBase64EncodedData:model.data options:NSDataBase64DecodingIgnoreUnknownCharacters];
UIImage *image = [UIImage imageWithData:data];

阅读更多

iOS YTKNetwork 适配 HTTPS

后台配置了https证书,如果直接将项目中的域名的 http 改成 https 会报服务器域名证书无效的错误提示。

如果项目中使用 YTKNetwork 网络框架,适配如下:

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 适配Https
*/
+ (void)configHttps {
YTKNetworkConfig *config = [YTKNetworkConfig sharedInstance];
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
// 允许自建证书
securityPolicy.allowInvalidCertificates = NO;
// 校验域名信息
securityPolicy.validatesDomainName = NO;
[config setSecurityPolicy:securityPolicy];
}

注:最好在封装的网络请求里,每次都调用一下 configHttps 方法。一开始只是在 AppDelegate 中全局适配,发现APP运行在后台一段时间后会出现访问不到数据的情况。

阅读更多

iOS AFNetworking 适配 HTTPS

后台配置了https证书,如果直接将项目中的域名的 http 改成 https 会报服务器域名证书无效的错误提示。

如果项目中使用 AFNetworking 网络框架,适配如下:

1
2
3
4
5
6
7
8
9
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
// 适配HTTPS
manager.securityPolicy = [self configHttps];
[manager GET:URLString parameters:@{} progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}
1
2
3
4
5
6
7
8
9
10
11
/**
* 适配Https
*/
- (AFSecurityPolicy *)configHttps {
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
//如果是需要验证自建证书,需要设置为YES
securityPolicy.allowInvalidCertificates = NO;
//validatesDomainName 是否需要验证域名,默认为YES;
securityPolicy.validatesDomainName = NO;
return securityPolicy;
}

阅读更多

使用Shell脚本批量压缩图片

很多情况下我们都需要对图片进行压缩。在项目中,可以减少安装包的体积;上传到图床,生成链接,可以使用更少的带宽和更快的负载。

一、TinyPng

TinyPng,使用智能有损压缩技术来减少 PNG文件的文件大小。通过选择性地减少图像中的颜色数量,需要较少的字节来存储数据。效果几乎是看不见的,但它在文件大小上有很大差异!

TinyPng 广受好评的同时,也提供相应的API供我们使用。不过TinyPng有个限制,单个账号单月最多压缩500张图片。如果不够用,可以多申请几个账号多获取几个APIKey。

二、实现思路

遍历给定的文件夹,如果是图片,使用 TinyPng 提供的API进行压缩,将压缩后的图片下载并保存到指定的目录;如果是文件夹,再进行更深一层的遍历,查找图片并进行压缩保存。

阅读更多

Objective-C Coding Guidelines

概要

Objective-C 是一门面向对象的动态编程语言,主要用于编写 iOS 和 Mac 应用程序。本文结合苹果 Coding Guidelines 文档,总结出一份通用的 Objective-C 编码规范。

阅读更多

邓白氏码信息查询

在申请iOS开发者账号的过程中遇上点问题,华夏邓白氏回复的邮件里的公司名称和邓白氏D&B后台的公司名称不一致,导致苹果开发者账号申请无法提交。

邓白氏码官方查询:https://www.dandb.com/search/

登录网址,选择所在的国家,根据公司的名称或邓白氏码进行查询,就可以获取到一些相关的信息。

阅读更多

Mac查看端口占用和杀死进程

一、查看端口占用

example:

端口号是8080

1
$ lsof -i tcp:8080

执行命令后会显示占用8080端口的进程,以及 pid,可以通过 pid 关掉该进程

二、杀死进程

根据上一条指令获取到占用该进程的 pid,然后执行命令:

1
$ kill pid

阅读更多

Could not start delivery

iOS自动化打包,使用 deliver 上传APP的过程中遇到一个问题:Could not start delivery: all transports failed diagnostics Transporter transfer failed.

问题描述

1
2
3
Could not start delivery: all transports failed diagnostics
Return status of iTunes Transporter was 1: Could not start delivery: all transports failed diagnostics
The call to the iTMSTransporter completed with a non-zero exit status: 1. This indicates a failure.

解决思路

后来在 pilot 文档 和 deliver/issues/235 中发现解决思路

1
2
3
4
5
6
7
8
9
Firewall Issues
pilot uses the iTunes Transporter to upload metadata and binaries. In case you are behind a firewall, you can specify a different transporter protocol from the command line using
DELIVER_ITMSTRANSPORTER_ADDITIONAL_UPLOAD_PARAMETERS="-t DAV" pilot ...
If you are using pilot via the fastlane action, add the following to your Fastfile
ENV["DELIVER_ITMSTRANSPORTER_ADDITIONAL_UPLOAD_PARAMETERS"] = "-t DAV"
pilot...

在自动化打包脚本中,修改deliver上传APP指令:

DELIVER_ITMSTRANSPORTER_ADDITIONAL_UPLOAD_PARAMETERS="-t DAV" fastlane deliver

参考文档:

  1. deliver/issues/235
  2. fastlane/issues/2294
  3. pilot

阅读更多

Hexo blog 域名解析

使用 hexo 搭建了个人博客,分别配置在 GitHub Pages 和 Coding Pages 上。后来,在万维网上购买了一个域名,也就有了这样的需求:希望在访问这个域名时能自动进入 Pages。

思路

创建一个CNAME纪录来做域名解析跳转。

前提

cd 到你 hexo 博客的根目录,然后 cd 到 source 文件夹,在 source 下添加 CNAME 文件,里面内容就是你购买的域名,eg:shaojunxiao.com,然后执行如下指令,把CNAME文件 Push 到 master 分支上。

1
$ hexo clean && hexo g && hexo d

注:如果 hexo 只配置了 GitHub Pages 和 Coding Pages其中的一种,域名也就只需要解析对应的就OK啦。

方式一:万维网域名解析

购买的就是万维网域名,在控制台进行域名解析配置。有关如何做域名解析,可以参考这里

  • 记录类型:CNAME;
  • 主机记录:设置两个,www 和 @;
  • 解析线路:Github 选择海外,Coding 选择默认;
  • 记录值:分别是 Github Pages 和 Coding Pages 博客网址;

方式二:DnsPod域名解析

域名如果更改DNS,我想选择 Dnspod 一定是不二之选。那么具体该如何操作呢,只要几步就可以轻松搞定dnspod域名解析设置。

2.1 首先把域名的dns更改指向到DNSpod的dns服务器。

免费DNS地址:f1g1ns1.dnspod.net/f1g1ns2.dnspod.net

2.2 登陆DNSpod账号,进入后台管理界面,添加域名

eg:shaojunxiao.com

2.3 域名解析设置

  • 记录类型:CNAME;
  • 主机记录:设置两个,www 和 @;
  • 解析线路:Github 选择国外,Coding 选择默认;
  • 记录值:分别是 Github Pages 和 Coding Pages 博客网址;

阅读更多

Flex 布局

  1. Flex 布局教程:语法篇
  2. Flex 布局教程:实例篇

阅读更多

使用PlistBuddy修改info.plist文件

Plist文件是iOS项目中比较普遍的一种文件格式,类似于XML,都是通过键值对的形式存储数据,而PlistBuddy则是Mac自带的专门解析plist的友好工具。如果有自动化打包,动态修改iOS工程项目中的info.plist文件的需求,会用到PlistBuddy。

1. 查看帮助

1
$ /usr/libexec/PlistBuddy --help

2. 数据类型

  • string
  • array
  • dict
  • bool
  • real
  • integer
  • date
  • data

3. 添加

Example:

添加string类型

1
$ /usr/libexec/PlistBuddy -c "Add :CFBundleGetInfoString string App version 1.0.1" info.plist

如果不存在 dict 类型的CFBundleDocumentTypes则创建一个,并添加键值对,key是name,value是xiao;如果存在,则直接添加键值对:

1
$ /usr/libexec/PlistBuddy -c "Add :CFBundleDocumentTypes:name string xiao" info.plist

如果还想再添加,执行:

1
$ /usr/libexec/PlistBuddy -c "Add :CFBundleDocumentTypes:age string 18" info.plist

如果不存在 array 类型的Application则创建,并添加数组第一个元素为 string 类型的值 hello;如果存在,则直接添加:

1
$ /usr/libexec/PlistBuddy -c "Add :Application:0 string hello" info.plis

添加数组第二个元素:

1
$ /usr/libexec/PlistBuddy -c 'Add :Application:1 string world' info.plist

4. 修改

修改数组Application的第2个元素的值为APP:

1
$ /usr/libexec/PlistBuddy -c "Set :Application:1 APP" info.plist

5. 删除

1
$ /usr/libexec/PlistBuddy -c "Delete :CFBundleGetInfoString" info.plist

阅读更多

Web blog

    阅读更多

    苹果禁止JSPatch引起的审核不通过

    一、禁止JSPatch邮件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    Dear Developer,
    Your app, extension, and/or linked framework appears to contain code designed explicitly with the capability to change your app’s behavior or functionality after App Review approval, which is not in compliance with section 3.3.2 of the Apple Developer Program License Agreement and App Store Review Guideline 2.5.2. This code, combined with a remote resource, can facilitate significant changes to your app’s behavior compared to when it was initially reviewed for the App Store. While you may not be using this functionality currently, it has the potential to load private frameworks, private methods, and enable future feature changes.
    This includes any code which passes arbitrary parameters to dynamic methods such as dlopen(), dlsym(), respondsToSelector:, performSelector:, method_exchangeImplementations(), and running remote scripts in order to change app behavior or call SPI, based on the contents of the downloaded script. Even if the remote resource is not intentionally malicious, it could easily be hijacked via a Man In The Middle (MiTM) attack, which can pose a serious security vulnerability to users of your app.
    Please perform an in-depth review of your app and remove any code, frameworks, or SDKs that fall in line with the functionality described above before submitting the next update for your app for review.
    Best regards,
    App Store Review
    尊敬的开发者,
    您的应用,扩展程序和/或链接框架似乎包含明确设计的代码,能够在应用审核批准后更改应用的行为或功能,这不符合Apple开发人员计划许可协议和应用的第3.3.2节商店审查指南2.5.2。此代码与远程资源相结合,可以帮助对应用程序的行为进行重大更改(与最初对App Store进行审核时相比)。虽然当前可能不使用此功能,但它可能会加载私有框架,私有方法,并支持未来的功能更改。
    这包括将任意参数传递给动态方法(如dlopen(),dlsym(),respondingToSelector :, performSelector :, method_exchangeImplementations())和运行远程脚本以便更改应用程序行为或调用SPI的任何代码,下载的脚本。即使远程资源不是故意恶意的,它也可能很容易被劫持通过中间人(MiTM)攻击,这可能对您的应用程序的用户造成严重的安全漏洞。
    请对您的应用执行深入审核,并删除与上述功能相符的任何代码,框架或SDK,然后再提交下一个更新以供审核。
    最好的祝福,
    App Store评论

    因为项目中集成了JSPatch,收到邮件时也没想太多,那就去掉呗。

    等再次提交时,发现还有问题,再次被打回,收到的邮件如下:

    1
    2
    3
    4
    5
    6
    7
    Your app, extension, and/or linked framework appears to contain code designed explicitly with the capability to change your app’s behavior or functionality after App Review approval, which is not in compliance with App Store Review Guideline 2.5.2 and section 3.3.2 of the Apple Developer Program License Agreement.
    This code, combined with a remote resource, can facilitate significant changes to your app’s behavior compared to when it was initially reviewed for the App Store. While you may not be using this functionality currently, it has the potential to load private frameworks, private methods, and enable future feature changes. This includes any code which passes arbitrary parameters to dynamic methods such as dlopen(), dlsym(), respondsToSelector:, performSelector:, method_exchangeImplementations(), and running remote scripts in order to change app behavior and/or call SPI, based on the contents of the downloaded script. Even if the remote resource is not intentionally malicious, it could easily be hijacked via a Man In The Middle (MiTM) attack, which can pose a serious security vulnerability to users of your app.
    Next Steps
    Perform an in-depth review of your app and remove any code, frameworks, or SDKs that fall in line with the functionality described above and resubmit your app’s binary for review.

    二、再次审核不通过原因:个推SDK集成了JSPatch

    在这儿要小小的吐槽一下个推,在这苹果官方重点审核JSPatch的风口浪尖,集成了JSPatch的个推并未发声。既然集成了,就告知一下用户,集成了个推的APP有可能造成审核不通过,请耐心等待,会尽快处理,在接下来版本中移除JSPatch。移除了以后嘛,也提醒一下用户,去官网更新一下SDK,避免APP审核不通过。而个推呢,只字未提。你想要知道的一切,都得自己去询问官方技术人员。

    在这方面,真没高德地图SDK做的好

    阅读更多

    Mac OS显示隐藏文件

    方法一:

    快捷键:shift + command + .

    方法二:

    打开 Launchpad ,点开 “其他”文件夹中的 终端,然后根据自己的系统版本选择下一步的命令

    Mac OS (10.6~10.8)系统

    显示隐藏文件:

    1
    $ defaults write com.apple.Finder AppleShowAllFiles Yes && killall Finder

    不显示隐藏文件:

    1
    $ defaults write com.apple.Finder AppleShowAllFiles No && killall Finder

    Mac OS 10.9 以上系统

    显示隐藏文件:

    1
    $ defaults write com.apple.finder AppleShowAllFiles Yes && killall Finder

    不显示隐藏文件:

    1
    $ defaults write com.apple.finder AppleShowAllFiles No && killall Finder

    只要在终端中输入对应的指令就OK啦。

    阅读更多

    Mac系统调整Launchpad图标大小

    系统默认 Launchpad 的应用程序图标很大,空间比较拥挤,看起来一点也不精致,那么我们怎样才能调整 Launchpad 的图标大小呢?

    思路:通过调整 Launchpad 每一行和每一列图标的数量,来调整 Launchpad 图标大小。

    用的是 MacBook Pro (Retina, 13-inch),图标 5 x 7 感觉比较合适,具体的可以根据自己的电脑自行设置行和列。

    1. 调整每一列显示图标数量

    5:表示每一列显示5个

    1
    $ defaults write com.apple.dock springboard-rows -int 5

    2. 调整每一行显示图标数量

    7:表示每一行显示7个

    1
    $ defaults write com.apple.dock springboard-columns -int 7

    3. 由于修改了每一页显示图标数量,需要重置 Launchpad

    1
    $ defaults write com.apple.dock ResetLaunchPad -bool TRUE;killall Dock

    阅读更多

    控制iOS状态栏的显示与隐藏

    需求:APP 启动时隐藏状态栏,启动图全屏,进入程序后显示状态栏

    一、启动时隐藏状态栏

    在项目的 info.Plist 文件中添加一项:Status bar is initially hidden,Value 设置为:YES

    OK,在APP启动时,状态栏就隐藏了。接下来我们要做的就是在启动后,显示状态栏。

    二、启动后显示状态栏

    在 info.plist 文件中,添加一项 View controller-based status bar appearance ,Value 设为 YES,意思就是 Status bar 由各自的ViewController控制。

    如果在项目中使用过这几个控制器,分别继承,重写方法。

    2.1 分栏控制器

    继承于 UITabBarController 创建视图,然后重写以下两个方法:

    1
    2
    3
    4
    5
    6
    7
    - (UIViewController *)childViewControllerForStatusBarStyle {
    return self.selectedViewController;
    }
    - (UIViewController *)childViewControllerForStatusBarHidden {
    return self.selectedViewController;
    }

    阅读更多

    iOS状态栏颜色

    修改状态栏显示颜色

    1. 由系统管理状态栏颜色

    info.Plist 文件中添加一项:View controller-based status bar appearance,Value 设置为NO,表示由系统管理状态栏。

    法一:在AppDelegate中添加如下代码:

    1
    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;

    法二:在 info.plist 文件中添加一项:Status bar style,Value 设置为 UIStatusBarStyleLightContent。

    以上两种方法都可以让状态栏变为白色。

    2. 状态栏颜色由各自ViewController控制

    如果不想应用里所有的页面状态栏都是相同的颜色,可以在 info.Plist 中添加一项: View controller-based status bar appearance 并设置为 YES,将 statusBar 的控制权交给各自的控制器,在需要修改状态栏的控制器的 viewDidLoad 方法中添加如下代码:

    1
    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;

    阅读更多

    Cannot proceed with delivery

    使用 delivery 工具上传 app 到 iTunes Connect ,中途上传失败或强行终止,导致 token 被锁定。

    错误描述

    1
    2
    3
    4
    Cannot proceed with delivery: an existing transporter instance is currently uploading this package",
    In the upload error log I can see that it first gives an warning "Failed to obtain exclusive lock on token file.
    Please ensure the following file is not locked by another process:
    /users/xiao/.itmstransporter\UploadTokens\xxxxx.local_itunesConnectUSERxxxxxx.itmsp.token

    解决思路

    1. 进入UploadTokens所在的目录

    :路径,错误信息里可以获取

    1
    $ cd /users/xiao/.itmstransporter\UploadTokens

    2. 然后打开 .token 文件,删除里面的内容,保存。或者,直接把 .token文件删除。

    3. 修改一下构建号,重新上传

    阅读更多

    SecKey API returned: -25308

    钥匙串访问权限解锁

    错误描述

    调用iOS自动化打包脚本时,报错 :

    1
    SecKey API returned: -25308, (null)/Users/xiao/Library/Developer/Xcode/DerivedData/HaiFu-ayuavvcfwmczwkasaoojsrongeax/Build/Intermediates/ArchiveIntermediates/HaiFu/InstallationBuildProductsLocation/Applications/HaiFu.app: unknown error -1=ffffffffffffffff

    原因分析

    由于Xcodebuild命令打包时会调用Codesign进行签名,而此错误就是由于无法使用证书授权签名所致,可以在脚本中添加解锁

    阅读更多

    Your app do not reflect the name

    PLA 1.2

    The Seller and Artist names associated with your app do not reflect the name, “app name,” in the app or its metadata, as required by section 1.2 of the Apple Developer Program License Agreement.

    Next Steps

    Your app must be published under a Seller name and Artist name that reflects the app name brand. If you have developed these apps on behalf of a client, please advise your client to add you to the development team of their Apple Developer account.

    阅读更多

    Shell条件判断

    一、文件类型判断

    选项 作用
    -b 判断文件是否存在,且是否为块设备文件(是块设备文件则为真)
    -c 判断文件是否存在,且是否为字符设备文件(是字符设备文件则为真)
    -d 判断文件是否存在,且是否为目录文件(是目录文件则为真)
    -e 判断文件是否存在(存在则为真)
    -f 判断文件是否存在,且是否为普通文件(是普通文件则为真)
    -L 判断文件是否存在,且是否为符号链接文件(是符号链接文件则为真)
    -p 判断文件是否存在,且是否为管道文件(是管道文件则为真)
    -s 判断文件是否存在,且是否为非空(非空则为真)
    -S 判断文件是否存在,且是否为套接字文件(是套接字文件则为真)

    阅读更多

    Fastlane自动化组件

    fastlane is the tool to release your iOS and Android app. It handles all tedious tasks, like generating screenshots, dealing with code signing, and releasing your application.

    相关文档

    测试

    scan:自动运行测试工具,并生成漂亮的HTML报告

    阅读更多

    App includes an update button

    Design Preamble

    Your app includes an update button or alerts the user to update the app. To avoid user confusion, app version updates must utilize the iOS built-in update mechanism.

    We’ve attached screenshot(s) for your reference.

    Next Steps

    Please remove the update feature from your app. To distribute a new version of your app, upload the new app binary version into the same iTunes Connect record you created for the app’s previous version. Updated versions keep the same Apple ID, iTunes Connect ID (SKU), and bundle ID as the original version, and are available free to customers who purchased a previous version.

    Resources

    To create new versions of your app, please see Replacing Your App with a New Version in the iTunes Connect Developer Guide.

    阅读更多

    小程序相关文章

    1. 摩拜单车微信小程序开发技术总结
    2. 微信小程序—仿芒果 TV(已开源)

    阅读更多

    iOS自动化打包(I):代码签名

    大多数时候代码签名看上去就像是一个难以理解的神秘黑盒。最近在做iOS自动化打包,有许多相似但又不同的APP,一个个打包耗时挺长,浪费人力,如何“快速自动化生成”这样的需求也就应运而生了。

    此篇是iOS自动化打包的第一篇,主要介绍一些重新签名需要了解的一些理论知识。

    • 证书:内容是公钥或私钥,由其他机构对其签名组成的数据包;
    • Entitlements:包含了 App 权限开关列表;
    • CertificateSigningRequest:本地公钥;
    • p12:本地私钥,可以导入到其他电脑;
    • Provisioning Profile:包含了 证书 / Entitlements 等数据,并由苹果后台私钥签名的数据包;

    一、证书和密匙

    iOS 开发者使用的 Mac 应该已经有一个证书,一个公钥,以及一个私钥。这些是代码签名机制的核心。

    在 OS X 上,证书都是由一个叫钥匙串访问的工具来进行管理。打开 Mac 的钥匙串访问应用,选择类别选项下的“我的证书(My Certificates)”,你可以看到所有你持有的私钥相对应的证书。

    阅读更多

    CAReplicatorLayer简介

    CAReplicatorLayer的目的是为了高效生成许多相似的图层。它会绘制一个或多个图层的子图层,并在每个复制体上应用不同的变换。

    阅读更多

    Core Animation

    1. 从零开始完成页面切换形变动画
    2. iOS-Core-Animation-Advanced-Techniques(iOS动画教程)

    阅读更多