SSH

SSH(全称 Secure Shell)是一种加密的网络协议。使用该协议的数据将被加密,如果在传输中间数据泄漏,也可以确保没有人能读取出有用信息。要使用 SSH,目标机器应该安装 SSH 服务端应用程序,因为 SSH 是基于客户-服务模式的。 当你想安全的远程连接到主机,可中间的网络(比如因特网)并不安全,通常这种情况下就会使用 SSH

一.安装SSH

1.安装ssh的服务端,需要在目标服务器安装

1
sudo apt-get install openssh-server

2.安装ssh的客户端,需要在客户端安装

1
sudo apt-get install openssh-client

由于Mac系统已经安装了ssh,所以可以直接使用。

一.SSH简单命令

1.无选项参数运行 SSH

1
ssh 192.168.40.140

2.指定登陆用户

1
2
ssh wuxian@192.168.40.140或者下面
ssh -l wuxian 192.168.40.140

3.上传本地文件到服务器

1
2
3
**注意这里不能先通过ssh登陆到服务器后再操作如下的:
scp /path/filename username@servername:/path
iMac-tortoise% scp /Users/tianww/Desktop/beibei_work/小工具/renameDeliver/renameDeliver.sh wuxian@192.168.40.140:/Users/wuxian/.jenkins/jobs/iOS_BeiBei_Appstore_FastLane/

4.从服务器上下载文件

1
2
3
**注意这里不能先通过ssh登陆到服务器后再操作如下的:
scp username@servername:/path/filename /var/www/local_dir(本地目录)
iMac-tortoise% scp wuxian@192.168.40.140:/Users/wuxian/.jenkins/jobs/iOS_BeiBei_Appstore_FastLane/renameDeliver.sh /Users/tianww/Desktop/iOS

5.上传目录到服务器

1
2
3
**注意这里不能先通过ssh登陆到服务器后再操作如下的:
scp -r local_dir username@servername:remote_dir
iMac-tortoise% scp -r /Users/tianww/Desktop/iOS wuxian@192.168.40.140:/Users/wuxian/.jenkins/jobs/iOS_BeiBei_Appstore_FastLane/

6.从服务器下载整个目录

1
2
3
**注意这里不能先通过ssh登陆到服务器后再操作如下的:
scp -r username@servername:/var/www/remote_dir/(远程目录) /var/www/local_dir(本地目录)
iMac-tortoise% scp -r wuxian@192.168.40.140:/Users/wuxian/.jenkins/jobs/iOS_BeiBei_Appstore_FastLane/ /Users/tianww/Desktop/iOS

FTP

FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。在FTP的使用当中,用户经常遇到两个概念:”下载”(Download)和”上传”(Upload)。”下载”文件就是从远程主机拷贝文件至自己的计算机上;”上传”文件就是将文件从自己的计算机中拷贝至远程主机上。用Internet语言来说,用户可通过客户机程序向(从)远程主机上传(下载)文件。

一. FTP常用的命令

  1. 用户连接远程FTP服务器
1
2
ftp 主机名称
eg:ftp v0.ftp.upyun.com
  1. 进入对应的ftp的目录,将目录下面的文件下载到本地文件夹中,或者本地的文件上传到服务端
1
2
3
4
5
6
7
首先需要在本地创建目录,登录成功后进入ftp目录,lcd进入本地创建的目录
lcd 本地的目录
eg:lcd /Users/tianww/Desktop/NewiOS
get ftp文件名称
eg:get Install.html
put 本地文件名称
put Install.html

二. FTP常用的Mac端工具

  1. Mac自带的FTP工具,连接服务器即可
  2. Mac的FTP工具集合

Jenkins+Git+Fastlane+Fir CI集成

上一篇有讲关于fastlane自动化部署,本篇将会着重讲关于fastlane的实际应用。

目标:

  • 利用自动化jenkins打包工具,自动拉取git仓库代码
  • 不需要通过手动检查修改xcode中项目配置修改(provisioning,codesigning)
  • 支持多渠道(chanel,appstore,enterprise,develop,adhoc)
  • 支持一键上传appstore(首次需要输入账户,密码)
  • 企业版本自动上传序号dsym文件到对应平台(fir的hdbug平台)

创建fastlane文件

进入项目目录在终端输入fastlane init命令,会要求输入Apple ID信息按照提示输入即可,选择是否deliver等初始化工作按照上篇讲解即可。操作完成即可看到下图所示的基本内容,下面会对图中文件一一讲解:

General preferences pane

fastlane源码解析

一. 统一管理fastlane操作脚本文件

1.外界控制版本号,并且控制渠道AdHoc AppStore Develop InHouse

1
2
3
4
versionNumber=$2 # 1.0.0
outLaneName=$1 #"AdHoc AppStore Develop InHouse"其中的一种,外界传入
curDir=`pwd`
distDir="$curDir/build"

2.根据外界传递的数据控制,调用fastlane的lane操作

1
2
3
4
5
6
7
8
9
basicLanes="AdHoc Release Develop InHouse"
for laneName in $basicLanes
do
if [ $outLaneName == $laneName ]
then
echo "outer setValue is:$outLaneName"
fastlane $laneName version:$versionNumber
fi
done

二. Appfile文件修改

1.同一个app,appfile控制渠道(appstore非appstore的)。当然也可以通过控制多个app区分不同的lane即可

1
2
3
4
5
6
app_identifier "com.tww.test" # App Store的版本的app_idendifier
apple_id "2501046883@qq.com" # 对应的账号appid
for_lane :InHouse do #企业及账号的
app_identifier "com.tww.test.enterprise" # 企业及账号app_idendifier
apple_id "2501046883@qq.com"" # 对应的账号的密码
end

三. Deliverfile文件修改

1.上传appstore的deliver文件

1
2
app_identifier "com.tww.test" # The bundle identifier of your app
username "2501046883@qq.com" # your Apple ID user

四. Fastfile文件修改

1.修改app identifier(就是bundle id,例如:com.husor.beibei)注意xcode7.0以上苹果改了CFBundleIdentifier or PRODUCT_BUNDLE_IDENTIFIER

1
2
3
4
5
update_app_identifier(
xcodeproj:PROJECT_FILE_PATH ,#project路径
plist_path:"#{PLIST_FILE_PATH}" ,#plist文件的路径
app_identifier:app_id
)

2.修改team(teamid)

1
2
3
4
5
6
7
def prepare_update_project_team(team_id)

update_project_team(
path:PROJECT_FILE_PATH,
teamid: "K4W62VQT27"
)
end

3.修改info_plist(就是bundle id,例如:com.tww.test)

1
2
3
4
5
6
7
8
def prepare_update_info_plist(app_id)
update_info_plist(
xcodeproj:PROJECT_FILE_PATH ,
plist_path:"#{PLIST_FILE_PATH}" ,
app_identifier:app_id

)
end

4.修改版本号和build号(修改为外部传入的版本,例如:1.0.0和100)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def prepare_version(options)
#say 'version number:'
#say options[:version]
increment_version_number(
version_number: options[:version],
xcodeproj: PROJECT_FILE_PATH,
)

#say 'build number:'
#say options[:build]
increment_build_number(
build_number: options[:version],
xcodeproj: PROJECT_FILE_PATH,
)
end

5.修改签名的配置,配置对应的provision file,事先将个provisioning放入provision文件内容,关于怎么找到对应的provison可以通过xcode配置正确后,查看project文件(/Users/tianww/Library/MobileDevice/Provisioning Profiles/)找到后复制到这里。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def prepare_version(options)
#say 'version number:'
#say options[:version]
increment_version_number(
version_number: options[:version],
xcodeproj: PROJECT_FILE_PATH,
)

#say 'build number:'
#say options[:build]
increment_build_number(
build_number: options[:version],
xcodeproj: PROJECT_FILE_PATH,
)
end

6.编译打包为ipa使用gym,当然首先要安装gym。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def generate_ipa(typePrefix,options,exportMethod,codeSignID)
#say 'generate ipa'
fullVersion = options[:version]
gym(
workspace: './BeiBeiAPP.xcworkspace',
configuration: "#{typePrefix}",
scheme: "#{SCHEME_NAME}",
output_directory: "./build",
output_name: "#{APP_NAME}.ipa",
archive_path: './build/',
clean: true,
codesigning_identity: "#{codeSignID}",
provisioning_profile_path: "./fastlane/provision/#{typePrefix}.mobileprovision",
include_symbols: 'true',
include_bitcode: 'false',
export_method: "#{exportMethod}"
)
end

或者使用shenzhen ,但是发现使用shenzhen比gym的要大

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def generate_ipa(typePrefix,options,exportMethod,codeSignID)
#say 'generate ipa'
fullVersion = options[:version] + '.' + options[:build]
channelId = options[:channel_id]
ipa(
configuration: typePrefix,
scheme:"#{SCHEME_NAME}",
clean: true,
destination:"./build",
ipa:"#{APP_NAME}_#{fullVersion}_#{typePrefix}.ipa",
archive:false
)

end

7.构建不同的lane,处理不同的包。

1
2
3
4
5
6
7
8
9
10
11
12
13
# 企业版 证书打包
desc "InHouse by personal apple account"
lane :InHouse do |options|
typePrefix = 'InHouse'
exportMethod = 'enterprise'
codeSigningIdentify = 'iPhone Distribution:tww'
prepare_version(options)
update_provision(typePrefix)
prepare_update_project_team('K4W62VQT27')
prepare_update_app_identifier("#{INHOUSE_IDENTIFIER}")
prepare_update_info_plist("#{INHOUSE_IDENTIFIER}")
generate_ipa(typePrefix,options,exportMethod,codeSigningIdentify)
end

参考

  • fastlane actions所有的actions的详细讲解。当然我们也可以在terminate中输入以下命令:

    1
    2
    fastlane actions(会列出所有的action)
    fastlane action deliver(单独详细的列出deliver的action对应的所有的内容)

Fastlane自动化部署

在上一篇中有讲过使用Jenkins+Git+Xcode+Fir的使用进行CI集成工作,但是会存在一些问题,对于开发者测试版本,企业版版本是可行的。如果想同时集成app store也自动化,越狱版本的话,那样就不能满足了。接下来的fastlane这一神器工具将会满足需求,一起进入fastlane的神奇世界吧!

What’s fastlane?

fastlane是一键式自动化部署,CI集成工具,能够极大的简化app的部署和发布流程。

为什么要使用fastlane?

我们可以回顾一下,一般发布一个appstore所需要的流程,其中大概流程如下:

  1. 创建appID
  2. 创建cert和provision
  3. 下载provision并安
  4. 使用Xcode的archive工具进行打包
  5. 在itunnesConnect上创建此app的相关信息(包括多张截图),编辑相关信息等

除开上面的1,2,3步骤后(当然这些内容还必须要依赖机器的特定的环境),就是进行每次的4,5步骤也是极其复杂的流程,并且会阻塞当前工作流程。

fastlane只要安装了相关的环境后,即可远程一键式发布。fastlane工作的方式是通过不同的lane的任务来进行工作,并且其本身就是由许多工具集组合而成,每一个独立的工具即可实现一项特有的功能(eg:screenshot,deliver,gym等)。接下来我们会一步步的熟悉fastlane工具。

安装fastlane

fastlane dependency
  • OS X系统:Mavericks以上
  • Ruby 2.0或2.0以上
  • Xcode
  • 已付费的个人开发者帐号或在公司的开发者帐号里

由于fastlane是一由一套Ruby脚本实现,你必须有正确的相对应的Ruby版本,OSX Mavericks之后的操作系统默认都安装了Ruby 2.0,可以通过以下命令来查看Ruby的版本号

1
ruby -v

我们还需确认安装了Xcode的Command Line Tools工具(CLT)git, xcrun, xcodebuild等等,C complier,输入以下命令来查看

1
xcode-select --install

如果xcode的CLT已经安装了,你会看到以下错误

1
command line tools are already installed, use "Software Update" to install updates

如果CLT未安装,Terminal将会继承提示你安装Xcode CLT

一旦以上条件准备好了,我们就可以安装fastlane了,输入以下命令

1
sudo gem install fastlane -v 1.48.0 --verbose

千万注意以上的版本号,以下的步骤在1.48.0能编译通过,但如果你升级到了最新的版本,可能会造成以下lane步骤出错,到时请查看官网,按最新的步骤来做

以上安装可能需要花费几分钟,请耐心等待,一旦安装好了,你就可以让你的工程使用fastlane啦,相信你已经跃跃欲试了吧, 不过在开始之前,我们先整体看看fastlane的工具链吧

fastlane Toolchain
  • produce:在iTunes Connect和Apple Developer创建新的app
  • cert:自动创建维护iOS的代码签名证书
  • sign:创建,刷新,下载,修复provision mobile profile
  • snapshot:自动帮你在每一台指定的机型上创建每一张本地化的screenshot
  • frameit:将你的截图添加上相应机器的外框
  • gym:编译并打包iOS app
  • deliver:上传screenshots,metadata(应用描述等)和你的app到appstore上
  • pem:自动生成并刷新app的apns证书
  • ……

fastlane init

进入你的工程根目录下,执行以下命令

1
fastlane init

注意:如果提示permission denied错误,你需要在此命令前加sudo

几分钟后,fastlane将显示以下步骤来让你设置初始步骤

  1. Do you want to get started? This will move your Deliverfile and Snapfile (if they exist) (y/n)
    Enter y

  2. Do you have everything committed in version control? If not please do so!
    Enter y

  3. App Identifier (com.krausefx.app):
    Enter a unique app ID. Keep this app ID handy, as you will need it later!

  4. Your Apple ID (fastlane@krausefx.com):
    Enter your Apple ID
  5. Do you want to setup ‘deliver’, which is used to upload app screenshots, app metadata and app updates to the App Store or Apple TestFlight? (y/n)
    Enter n
  6. Do you want to setup ‘snapshot’, which will help you to automatically take screenshots of your iOS app in all languages/devices? (y/n)
    Enter y
  7. Do you want to use ‘sigh’, which will maintain and download the provisioning profile for your app? (y/n)
    Enter y
  8. Optional: The scheme name of your app: (If you don’t need one, just hit Enter.)
    Press enter

执行完以上步骤后,打开mZone的工程文件夹,你会注意到工程下已经有了fastlane的文件夹了

Smaller icon

fastlane Toolchain

  • provision lane

在你的fastlane的文件夹下的fastlane加入provision lane

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
platform :ios do

# 1
desc "Creating a code signing certificate and provisioning profile"
# 2
lane :provision do
# 3
produce(
app_name: 'ENTER_A_UNIQUE_APP_NAME_HERE',
language: 'English',
app_version: '1.0',
sku: '123abc'
)
# 4
cert
# 5
sigh(force: true)
end

error do |lane, exception|
# This block is called, if there was an error running a specific lane.
end

end

ENTER_A_UNIQUE_APP_NAME_HERE替换成一个新的app名字(此名字不能和已知的重名),你的itunesConnect的用户名和app identifier自动从Appfile中加载,所以你无需在这里指定它们

如果你从来没用过Ruby,以上的语法看起来可能有点奇怪,让我们一条条过一下

  1. lane指定了相应的描述,一个lane是一个按顺序工作的工作流
  2. 为这个lane指定一个名字
  3. 在指定app identifier,名字,语言和version number后,使用produce来在ITC和Developer Portal创建一个app
  4. 使用cert来创建私钥和签名申请文件,下载并安装生成的certificate并将所有文件安装到keychain中
  5. 使用sigh来生成一个provision profile,指定force: true,在每一次运行的时候都会创建一个新的provision profile

注意:sigh每次默认都会创建App Store Distribution,如果你想创建一个adhoc的profile,你可以指定sigh(adhoc:true),如果想指定一个开发证书, 可以指定sigh(development:true)为简单起见,在此教程中,我们只创建distribution profile

好啦!我们已经创建了第一个lane了,打开终端,进入你的工程根目录下,输入以下命令

1
fastlane provision

它让fastlane运行你的provision lane

一两分钟后,fastlane会请求你的ITC密码,不必担心,此密码会安全地保存在电脑的keychain里,输入你的密码,一旦成功后,你的终端窗口看起来应该如下图

produce

注意:如果你碰到一些错误,特别是Creation of apps of this type is not available这样的错误时,登录ITC,确保没有任何需要签名的agreements

现在你可以登录iTunes Connect,可以看到你已经创建了app,怎么样 ,是不是很神奇

itunesConnect

  • Screeshots lane

当提交app时,app的截图是必不可少,可是人工截图又是如此无趣,特别是如果你要针对多语言开发时,会浪费很多宝贵的时间做这种无聊的截图工作,幸运的是,fastlane可以帮你搞定这些工作!
在fastlane文件夹下打开Snapfile文件,替换成以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
devices([
"iPhone 6",
"iPhone 6 Plus",
"iPhone 5",
"iPhone 4s",
])

languages([
"en-US",
"de-DE",
"it-IT"
])

snapshot#launch_arguments

screenshots before creating new ones

以是内容指定了你想支持的机型和语言,clear_previous_screenshots将清除之前已创建好的screenshots

保存文件并关掉它

打开Fastfile文件,在error do |lane, exception|上添加以下内容

1
2
3
4
desc "Take screenshots"
lane :screenshot do
snapshot
end

我们创建了一个新的名叫screenshotlane,它使用snapshot来截你在Snapfile中指定支持的设备和语言的截图

保存文件,打开终端输入

1
fastlane screenshot

神奇的事情发生了,所有的截图操作都自动帮你搞定啦

screenshot

注意:这版的教程中的snapshot使用了UI AutomationJavaScript来驱动模拟器,但snapshot 1.0使用了Xcode 7的UI Testing,也就是说你可以用Swift或OC来写自动化脚本了

需要特别注意的是:为了让snapshot正常截图,它需要首先能正常访问在Snapfile中列举的设备列表,如果Xcode中少了其中的某些devices,你需要在Xcode中的Window\Devices中的左下角下,点击+来添加新的模拟器

一旦此过程结束,我们可以到fastlane文件夹下找到一下screenshots的文件夹

screenshotresult

现在你有EnglishFrench这两语言支持的所有设备截图了,你也会注意到一个screenshots.html的文件,打开它可以看到所有的screenshot!

  • gym

好了,现在我们可以准备创建IPA文件了
打开Fastfile文件并且在screenshotend后面添加以下内容

1
2
3
4
desc "Create ipa"
lane :build do
gym
end

以上创建了一个buildlane,它使用gym来创建一个签名的ipa文件

在终端中保存Fastfile,在mZone工程根目录下输入以下命令

1
fastlane build

一旦完成,你可以在mZone工程根目录下看到一个签名的ipa文件

ipa

  • …..

其它的工具需要你自己去探索了

fastlane一键式发布

为了将screenshots,metadata,ipa文件发送到iTunes Connect,我们可以使用deliver这个工具

首先,我们需要初始化工程以让它使用deliver这个工具,进入工程文件夹下,输入以下命令

1
deliver init

一旦完成,你的终端窗口看起来应该像以下这样

delivery

我们可以看到deliver自动检测到了ipa文件和screenshots的位置

它也创建了一个metadata文件夹和一堆text文件,这些文件包含了常见的App Store items如description, keywords, categories等等

通常你应该填完这些信息,但教程为方便起见只添加了一句简单的描述,打开en-US/description.txt添加以下文字:

1
mZone is a simple poker calculator for No Limit Texas Hold’em tournaments that displays a recommended course of action based on your chip count and the current big blind level.

不过在我们继续之前,我们需要修复一个issue,打开metadata文件夹,注意到尽管我们的应该支持FrenchEnglish,只有en-US文件夹存在

为了解决这个问题,我们对en-US文件夹作一份copy,并将它命名为fr-FR.现在你的工程看起来应该如下

prepare

打开Fastfile并在buildlane的end之后添加以下内容

1
2
3
4
desc "Upload to App Store"
lane :upload do
deliver
end

打开终端,输入以下命令

1
fastlane upload

这个命令,fastlane以HTML的形式展现了一个它最终将要上传的内容的preview

如果所有看起来都OK,在“Does the Preview on path ‘./Preview.html’ look okay for you? (y/n)”此问题后面输入y,好了,现在静静地喝杯咖啡吧,fastlane将会把所以该上传的都上传到appstore

进入iTunesConnect,现在看看,所有显示的内容是不是都与你本地的一一对应啦!

需要注意以下文件

  • Appfile: 记录了app的idenfifier和你的appleID
  • Fastfile:管理你需要执行actions的所有lanes
  • Snapfile:让你指定对所有语言对应的设备尺寸进行截图

参考

  1. fastlane官网
  2. fastlane Tutorial: Getting Started
  3. fastlane git开源项目
  4. Xcode中Command Line Tools安装方法
  5. 下一篇Jenkins+Git+Fastlane+Fir CI集成,将会详细介绍具体项目中使用

问题

  1. 不要随便更新版本,如果更新了版本会导致相关lane存在问题,那这个时候需要看最新的官网的更新。现在fastlane更新的速度较快,需要持续关注。

ClangFormat代码格式化

在一个团队中如何保证所有的开发人员的代码风格一致,并且符合一定的规范,也许ClangFormat-Xcode插件可以帮助你解决该问题。

定制ClangFormat-Xcode

如何需要定制你自己的格式化插件,下载ClangFormat-Xcode需要修改项目根本目录相面的.clang-format不可见文件(“defaults write com.apple.finder AppleShowAllFiles -bool true”)。修改完成后,然后将该项目运行,运行的时候会提示「Skip Bundle」和「Load Bundle」选择「Load Bundle」后插件即可安装成功后重新启动xcode,在你的~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/目录下面可看到插件安装成功。

其中.clang-format如下,参考ClangFormatStyleOptions

1
2
3
4
5
6
7
8
9
10
AccessModifierOffset: 0
AlignEscapedNewlinesLeft: false
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
......

使用

Edit->HBClang Format

Format Selected Text // 格式化选中的内容 快捷键为Ctrl+U

Enable Format on Save //当保存的时候自动格式化。

Markdown preferences pane

提交代码检测

如果我们想要在提交之前做些检测代码规范的工作,那么接下来的操作就很重要了,通过下面的脚本,这个检测的规范就是上面ClangFormat中制定的规范内容。

安装方法
  1. 打开命令行,进入项目目录,执行命令:
1
curl https://gist.githubusercontent.com/dorentus/387fbaa28de22ce8f34e157c0d1ecfe9/raw/clang-format-githook-install.sh | sh
  1. 或者手动下载保存为项目目录下的 .git/hooks/pre-commit,并修改文件权限为可执行。
1
https://gist.githubusercontent.com/dorentus/387fbaa28de22ce8f34e157c0d1ecfe9/raw/pre-commit-clang-format

这种方法并不会自动使用 [HBClangFormat-Xcode] 里面自带的 clang-format,而是写死了用 /usr/local/bin/clang-format,如果需要用其它路径的话可以自己修改文件头部的路径

提交代码
  1. 我们提交代码通过sourceTree或者命令行提交代码,通过检测如果代码不符合规范,会出现提示信息,无法提交代码。

问题

  1. Xcode 安装插件手误选择了「Skip Bundle」后需要重新允许「Load Bundle」的解决方法。参考
  2. 在使用代码提交检测的时候,由于在别人的代码基础上面做的修改,而检测的范围是提交的整个文件,这个时候不想改其它人的代码。我们可以修改项目目录下的 .git/hooks/pre-commit的exit为1,或者删除该文件。

参考

1.iOS代码规范自动化

iOS开发工具

iOS开发过程中,我们经常会需要使用一些小技巧来优化的我们的开发工作,下面的一些小技巧会极大提供我们的开发效率。

下面一些iOS开发的工具技巧能够极大的提高开发人员的效率

  • 用的那个代码格式化的工具 ClangFormat代码格式化,找到了一个 git commit-hook 脚本,可以在每次提交的时候自动调用它检查格式,因为这种 hook 是每个想用的人要自己在本地项目里面装的,于是我搞了一个一键安装的脚本安装使用

  • 在使用fastlane的时候我们实际上只是会通过fastlane上传ipa文件,由于截图文件不是使用fastlane的frameit来截图操作,会出现产品等人员等独立提供截图,和日志更新文件,为了达到也能够一键上传截图或者日志(按照fastlane的规范),手动操作还是很麻烦,所以写了一个renameDeliver脚本可以支持根据设计[640x960 640x1136 750x1334 1242x2208]文件夹的图片(1,2,3,4,5)自动命名成fastlane的deliver screenshots的规范的内容,实现一键上传的操作。

  • 在使用xib的过程中,苹果默认的将opaque设置为YES,防止有的被设置为NO。如果设为YES, 渲染系统就认为这个view是完全不透明的,这使得渲染系统优化一些渲染过程和提高性能。下面的脚本能够自动检测并修改。当然修改后为了防止view为黑色需要修改backgroundcolor为clear color。

    1
    2
    3
    4
    5
    #!/bin/bash
    for f in $(find . -name '*.xib'); do
    echo $f
    sed 's/opaque="NO"/opaque="YES"/g' $f > temp.xib && mv temp.xib $f
    done
  • 在iOS版本迭代的过程中,每个迭代版本需要替换icon图片,如果手动的替换起来,同时如果设计提供的命名不规范还需要修改名称,非常麻烦。现在只需要通过一个sips的mac命令就可以对png的图片进行剪裁,我们只需要放置最大的1024*1024的图片即可实现全套规范的图片,然后替换掉本地Images.xcassets里面的图片的名称,暂且这个不支持jpg的格式。脚本下载

iOS知识点

  • 苹果谷歌OC标准命名规范,比较详细规范,大家可以参考看看,里面有些相关的内容是我们这边存在遗漏的。
  • 减少我们的工程文件编译的时间,由于当前我们的pod工程文件包含了其它多pod库,为了减少工程编译时间,可以做以下的优化,比喻在终端输入:
1
pod update beibei_oversea && find . -iname "*.pch" -exec touch -t 01010000 "{}"

1.因为每个pod都有一个pch文件,每次pod update或者pod install都会导致pch的时间戳改变,这样这个pch文件就会导致整个pod重新编译,上面一行的意思是将工程中所有的pch文件的时间戳改为01010000,这样pch的时间戳不变,就不会导致整个pod需要重新编译了!

2.以上方式建议使用iterm2进行操作。

1
2
3
4
5
6
7
8
9
10
11
12
然后把这两个函数放到你的~/.zshrc下

function pod_dev {
command="export PODFILE_TYPE=DEV && pod $@ && find Pods -iname '*.pch' -exec touch -t 01010000 '{}' \;";
echo $command;
eval $command;
}

function pod_online {
command="export PODFILE_TYPE=ONLINE && pod $@ && find Pods -iname '*.pch' -exec touch -t 01010000 '{}' \;";
eval $command;
}

只要pod_dev update —no-repo-update beibei_oversea就行了

注意:如果使用了pod_dev,此时PODFILE_TYPE被改成了DEV,如果要用线上的,请务必用pod_online(而非pod),这样会把PODFILE_TYPE改为ONLINE,就可以正常使用线上的pod了

  • lldb的e命令小技巧可以在调试程序时立即暂时地修改一个视图的颜色,不用去改代码
1
2
3
(lldb) e button.backgroundColor = [UIColor redColor]
(UICachedDeviceRGBColor *) $0 = 0x00007f9f13290c30
(lldb) e (void)[CATransaction flush]
  • lldb的expression命令小技巧可以在调试程序时暂时地修改内容,不用去改代码
1
(lldb) expression target = @"tuan_list"
  • po [[UIWindow keyWindow] recursiveDescription]可以打印当前window对象的所有视图层级,方便快速定位。

Jenkins+Github+Xcode+Fir CI实战

上一篇:iOS使用Jenkins进行持续集成详细的讲了Mac上面搭建jenkins,接下来将会详细介绍jenkins的实际应用案例。

配置build jenkins

  1. 进入jenkins主页登录成功后,选择(新建),输入item的名称,选择(构建一个自由风格的软件项目),填写必要的描述信息。
  2. 源码管理,我这里选择git(我的代码在git上面),(1)Repository URL填写项目的git地址 (2)Credentials选择add添加git的账号,(3)Branch to build 选择当前项目构建的分支。这样每次构建都会从git上拉取对应分支的最新代码到本地对应job的工作空间中。
  3. 构建触发器,选择触发的条件,我这里选择的是 Build when a change is pushed to GitHub,也就是只要有开发人员提交代码到对应的项目分支,就会立即打包操作。当然你也可以选择其它的条件 Poll SCM 日程表可以填写H/15 ,15分支检查一次是否有提交,如果有提交的就会自动打包。
  4. 选择增加构建步骤,里面有一些基本的构建步骤也包含自己当前所需要安装的插件,这里使用的xcode构建项目,当然你也可以自己写打包脚本或者通过fastlane 持续集成工具gym或者shengzhen进行打包操作。

    (1) General build settings (build的基本配置)

    1
    target:选择targets中当前项目需要对应的target

(2) Code signing & OS X keychain options (code sign及钥匙串keychain信息访问,主要是为了打包签名等使用)

1
2
3
4
5
6
7
Change bundle ID:勾选后,表示打包操作中需要更改当前对应info.plist文件中对应bundle id。主要方便企业版本,appstore版等不同的bundle id需要。
Code Signing Identify:也就是当前code sign的标示,(这个可以通过设置当前正确的code sign identify及code sign后,
通过xcode打包各环境成功后,表示这些配置是正确的),然后通过当前项目中.xcodeproj文件的包含内容查找对应的Code Signing
Identify
Embedded Profile:也就是打包的provision file文件,也可以通过上述方式在配置文件中找到。证书安装后的地址
/Users/tianww/Library/MobileDevice/Provisioning Profiles/中可以找到对应的证书,在这里填写正确即可。
Unlock Keychain:由于签名等需要访问钥匙串,所以这里要勾选上,填写钥匙串的地址,访问钥匙串的密码。

(3) Advanced Xcode build options (配置xcode build options)

1
2
3
4
Xcode Schema File:选择schema,填写当前需要执行的schema的名称。
Xcode Workspace File:如果当前的项目是基于workspace的那么这里就填写workspace(pod项目)的名称路径,不要. xcworkspace
Xcode Project Directory:如果当前的项目是基于Project的,那么这里填写Project的路径名称,不要.xcodeproj。
Build output directory:也就是项目的ipa的输出路径。

(4) Versioning

1
2
Marketing version:CFBundleShortVersionString
Technical version:CFBundleVersion

上传ipa文件

一.通过蒲公英Fir上传

1.通过Fir蒲公英上传ipa到账号,这里可以通过脚本,当然也可以通过使用安装fir提供的jenkins插件下载.hpi)配置上传ipa到fir。

以下使用脚本方式:你需要安装fir的命令fir.im-cli,安装fir.im-cli命令可以通过terminal的gem直接安装,参考

1
gem install fir-cli

2.选择添加构建步骤Execute shell,填写以下脚本:

1
2
3
4
5
6
7
8
9
#进入ipa生成的目录
${WORKSPACE}/Enterprise_ipa/
#登录fir这里的需要填写你的 API Token
fir login 858b83d2f15f5f
curDir=`pwd`
# 下面上传dsym文件到fir上面对应,这个需要在项目中集成fir的bughd错误日志收集,-p 表示项目的token -v当前的时间
#fir mapping /${WORKSPACE}/build/beibei.app.dSYM.zip -v `date "+%Y-%m-%d/%H:%M:%S"` -P 56528e39a1de52
#上传ipa文件,并且上传变更日志,这个是当前job的build的修改记录的地址
fir publish "beibei.ipa" -c "如需要查看修改记录点击下面地址....:http://192.168.44.132:8080/job/${JOB_NAME}/${BUILD_NUMBER}/changes"

3.如果你需要通过fir提供的jenkins插件上传到fir相关的,那就在构建步骤添加插件的名称,填写必要的配置信息。可以参考fir jenkins的各种参数配置

二.通过FTP上传到自己的服务器

1.在构建步骤中选择Send build artifacts over FTP前提是你安装了该jenkins插件,具体参考这里

问题

  1. jenkins 1.656版本会并且在由于xcode 7出来没多久,且在xcode 7上build setting中多了一个Product Bundle Idenitfier的项,且jenkins没有修改此处的bundle id,导致无法编译通过。所以为了避免这个问题我们可以在对应的configuration下面设置bundle id而不影响其它人,但同时也不允许其它人更改对应configuration的内容。这样限制就会比较麻烦,我们可以通过编写脚本修改bundle id,或者采用接下来的fastlane方式。新版本估计jenkins会将这个问题修复。

参考

1.Jenkins+GitHub+Xcode+fir搭了一个持续集成环境

2.fir.im Jenkins 插件使用方法

3.Jenkins Plugins这里有各种各样的插件

4.如果你觉得以上的配置内容不够详细,可以下载详细的配置信息Demohtml查看吧

创建私有pod库

一, 创建Github的

在Gitthub创建一个pod工程的名称martshow的项目,使用git clone到本地

1
iMac-tortoise:martshow tianww$ git clone https://github.com/Tweiwei497435786/martshow.git

二, 创建本地pod工程

只要输入pod lib create <项目名称>命令即可完成初始项目的搭建:

1.执行命令pod lib create martshow_public,具体操作如下实例:
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
iMac-8:martshow tianww$ pod lib create martshow_public
Cloning `https://github.com/CocoaPods/pod-template.git` into `martshow`.
Configuring martshow template.

------------------------------

To get you started we need to ask a few questions, this should only take a minute.

If this is your first time we recommend running through with the guide:
- http://guides.cocoapods.org/making/using-pod-lib-create.html
( hold cmd and double click links to open in a browser. )


What language do you want to use?? [ ObjC / Swift ]
> objc

Would you like to include a demo application with your library? [ Yes / No ]
> yes

Which testing frameworks will you use? [ Specta / Kiwi / None ]
> no

Possible answers are [ Specta / Kiwi / None ]
> none

Would you like to do view based testing? [ Yes / No ]
> no

What is your class prefix?
> BB

以上操作后,一个简单的私有pod库项目搭建完成。进入目录,我们会看到如下目录文件:

1
2
Example			Pod			_Pods.xcodeproj
LICENSE README.md martshow.podspec

我们添加的文件需要放在Pod/Classes目录,我们可以打开Exaple文件,双击.xcworkspace文件,这个就是我们的pod工作工程,也可以在如下图中加入文件:

Editor preferences pane

三, 提交本地pod库到远端

就这样我们的一个私有pod库创建成功了,然后通过git命令或者git命令工具SourceThree上传代码到远端,其它pod工程需要引用当前的私有pod库可直接在podfile中添加引用

1
2
3
iMac-tortoise:martshow tianww$ git add marshow/
iMac-tortoise:martshow tianww$ git commit -a -m "添加文件"
iMac-tortoise:martshow tianww$ git push

相关参考:

  1. 使用CocoaPods开发并打包静态库
  2. CocoaPods版本升级

.xcodeproj配置技巧

作为一名iOS开发人员,关于.xcodeproj一些简单使用的配置技巧,以下的一些内容你必须要知道:

1.给你当前的项目Configurations配置不同的configuration Xcode-Env-Configuration环境,比喻说你当前需要(AdHoc,AppStore,Debug,Release)各configuration的条件下配置不同的代码操作。这个有点类似targets的概念,但是这个要比其更简单,具体操作如下图:

Markdown preferences pane

添加好configuration后,在scheme中可以选择不同的configuration,运行代码:

Markdown preferences pane

当然,如果想要在不同的configuration条件下,代码的运行内容不一致,我们还需要在在build setting中定义一些在不同的configuration条件下的表示内容,我们可以在build setting中搜索“Preprocessor Macros”,然后在不同的条件下做一些差异化的内容。如下图:

Markdown preferences pane

在代码中具体操作如下,表示当前仅仅在越狱环境下才其左右,那样在不同的打包操作情况下不同的操作:

1
2
3
4
#if defined (CONFIGURATION_Develop)
//仅用于越狱渠道
[NBSAppAgent startWithAppID:@"cba82ccbb7fb43eb8ad1b1c71"];
#endif

2.为了开发人员测试,而不影响其它人员开发使用证书的问题,大家统一在Build Settings中Product Bundle Identifier修改Debug当前开发证书,而不要在General的Bundle Identifier中设置,对其它人工作造成影响。

3.在有些情况下,我们在无法区分ipa文件是那种Configuration情况的的ipa文件,为了解决这个问题,我们可以在Build Settings中选择自定义一些参数,选择“+” Add User Defined Settings,定义用户setting选项BUNDLE_DISPLAY_NAME_SUFFIX对不同Configuration进行图标展示不同的环境,如下图。

Markdown preferences pane

Markdown preferences pane