肇鑫的技术博客

业精于勤,荒于嬉

制作上架应用的视频预览

为了展示产品功能,我们可以制作并上传视频。

视频规范

我们可以通过真机录制视频,也可以通过模拟器录制。真机录制视频很简单,只需要在设备的控制中心选择录制屏幕就可以了。录完之后,经过剪辑就可以直接上传。

如果你没有特定型号的真机,也可以通过模拟器来录制视频。模拟器录制视频与真机相比,存在一些限制,本文后面会讲到如何解决这些问题。

推荐使用H.264格式。虽然它会比ProRes 422格式的文件大一些。但是这个格式现有的设备都支持硬件加速。因此保存(转码)速度最快,工作效率最高。

模拟器录制视频

录制视频

先打开Xcode,加载项目,然后选择你需要录制视频的模拟器,运行项目。当项目成功在模拟器中运行后,在终端中输入

xcrun simctl io booted recordVideo record.mov

最后的record.mov是录制的视频的文件名。它会自动保存在终端当前的文件夹。录制完成后按ctrl+c结束录制。

  • 如果你开了多个模拟器,那么可能不会录制到你当前使用的模拟器。关闭掉其余的模拟器,仅保留你需要录制的模拟器。
  • 模拟器录制的视频不完全与你的操作同步。如果你操作完成就立即结束录制,可能结尾部分会没有路上。因此,建议结尾之后进行额外的操作,比如点击按钮之类的。然后在后期制作中,将多余的部分删除,这样可以保证视频录制的完整性。
  • 虽然Xcode可以在Scheme中修改语言,来改变运行时应用的语言,但是这个对于语言的修改,是应用级别的。在录制演示文件时,应该在模拟器/设备中修改系统的语言偏好。这是因为,一些提示,比如通知权限/地理位置权限的提示窗口,是基于系统语言的。如果你只在Xcode中设置,那么就会遇到系统权限提示窗口的语言与应用语言不一致的情况。

转码

根据苹果的规范(见下图),存在两个不同的分辨率,前一个叫原生分辨率(Native resolutions),后一个叫接受的分辨率(Accepted resolutions)。前者是模拟器录制视频时得到视频的分辨率,后一个是App Store Connect上传视频时,所接受的视频分辨率。如果二者分辨率不同,就需要转码。

App Preview Resolutions

当真机录制视频时,得到的视频直接就是接受的分辨率。通过模拟器录制得到的视频,是原生分辨率,需要转码。
转码可以通过你喜欢的任意软件进行。我用的是HandBrake

添加空音轨

转码完成后,如果你直接上传模拟器录制的视频,App Store Connect会在上传后错误提示:音频不符合规范。原因是模拟器录制的视频,只有视频的部分,没有音频。因此,你需要添加额外的音轨。可以使用FFmpeg添加空音轨。

安装FFmpeg

brew install ffmpeg
brew link ffmpeg

添加空音轨

ffmpeg -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 -i video.mov \
  -shortest -c:v copy -c:a aac output.mov

video.mov是源文件,output.mov是目标文件。

剪辑

剪辑我推荐使用Quicktime Player。它的保存速度是最快的。

当剪辑完成之后,有时保存按钮是灰色的。这时可以直接点击关闭,就会弹出保存对话框。

思路改变编程:记一次思路改变节省大量编程时间的小事

使用微博RestAPI一直存在一条人为的限制,就是必须要在文章末尾添加一个验证链接。

比如你发微博“这是我的第一条微博。”,用微博RestAPI是没法直接发的,必须发成“这是我的第一条微博。https://poster.parussoft.com/index.html”。

如果你不加上这个链接,微博服务器就会提示错误,不让发微博。

这个链接对于用户其实是没有意义的。并且直接加在微博末尾,就会有人点击它,然后奇怪为什么会有一个跟内容没什么关系的链接在那里。

为了尽量减少用户点击这个链接的可能,咕唧从2018年3月底发布的1.7.13版开始,增加了一个折叠隐藏该链接的功能。利用的原理是,微博官方微博网页版和客户端,会在内容过长时,自动折叠微博,而咕唧会在字数允许的情况下,添加空行,将该链接隐藏起来。

但是这个功能存在限制,因为只有官方的网页版和客户端才有折叠的功能。其它第三方的客户端,官方的html5版以及国际版,都不具备折叠的功能。在这些微博客户端中,咕唧发布的微博就会变得特别长。因此,时不时的,我就会收到评论或者私信,问为什么我发的微博会那么长?

咕唧2决定彻底解决这个问题

我的思路是,既然这个链接必不可少,那么我可以将其从无用的链接,转换为有用的链接。这样用户点击了也不会显得突兀。类似这样的查询“https://poster.parussoft.com/jumping.php?query_string”。

weibo_forcing_ur

思路1

思路确定好之后,我发现,生成的链接必须经过服务器的处理才可以。那么就有两个思路:

  1. 直接保存对应的html文件到磁盘。(这样占用磁盘较多)
  2. 将查询条件和结果保存的数据库,动态查询。(这样占用磁盘少,但是CPU占用高。因此还需要缓存查询结果。)

我觉得第2条更好。这样就需要在服务器端使用PHP和Sqlite。思路总结完,我在服务器远程安装好PHP和Sqlite3之后,就睡觉了。

思路2

第二天,开始继续前一天的工作。我发现微博账户的用户页,其实是需要和其它链接分开的。因为微博账户的用户页,可以直接根据微博用户的id自动生成。我又想到,既然可以自动生成,那么该项就不用保存到数据库,直接通过id生成并跳转就可以了。

之后,我又想到,链接的跳转也是同样的道理,可以直接将链接做为查询的字段,这样就能直接跳转了。

这样一来,思路1中的PHP、数据库、缓存就都不需要了,服务器端只需要写一个能判断查询类型并生成跳转链接的Javascript网页就全搞定。

结论

不同的思路,需要的工作量完全不同。多思考,比埋头苦干,效率更高。

iOS项目CocoaPods的安装与使用

安装

网上看了好几篇文章,综合起来才成功,这个是在macOS Sierra 10.12.4 (16E195)下正确安装CocoaPods的步骤:

1. 替换源为镜像

gem sources -l

查看当前的gem源的地址,由于墙的缘故,如果源是https://rubygems.org/,我们需要将它删除。

gem sources --remove https://rubygems.org/

然后替换为ruby china的镜像。

gem sources --add https://gems.ruby-china.org/

确认源替换是否成功

gem sources -l

2. 升级gem

系统自带的gem版本较低,使用时会出现莫名其妙的问题,因此要把它升级到最新版

sudo gem update --system

如果上面代码提示没有权限,改成

sudo gem update -n /usr/local/bin --system

3. 安装cocoapods

在macOS 10.11和10.12中安装时,安装到/usb/bin会提示错误,因此需要安装到/usb/local/bin里

sudo gem install -n /usr/local/bin cocoapods

4. 替换源

默认的源更新起来很慢,需要替换才能变快。如果你想使用默认的,可以跳过这一步。

查看当前的源:

pod repo 

删除master:

pod repo remove master

添加清华的源:

git clone https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git ~/.cocoapods/repos/master

更新源:

pod repo update

5. 更新pod

如果你做过上一步,可以跳过这一步。

pod setup

这步时间较长,需要耐心等待。

使用

如果你使用了第4步的替换源,那么需要在你的每个Podfile的最前面,添加一行。

source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'
  1. 新建一个iOS的项目。
  2. 在终端,进入到该项目的文件夹。
  3. 执行pod init
  4. 打开自动生成的Podfile文件
  5. 在其中添加你要使用的框架的名称
  6. 保存好Podfile文件
  7. 执行pod install
  8. 在Xcode中,关闭你的项目
  9. 在文件夹,找到pod生成的.xcworkspace文件,打开它。
  10. 像平常一样使用框架就可以了。

比如我新建的项目叫PodTest,添加了RealmSwift,最终的Podfile如下:

这其中大部分的内容都是pod自动生成的,我需要修改/添加的只有第三行,iOS的版本。第四行,去除警告。以及pod 'RealmSwift'的那一行。

最后的那段,是RealmSwift网站要求的。你需要什么框架,就到那个框架的官网,按照提示复制粘贴上去就可以了。

最后记得,每次修改完Podfile之后,都要记得运行一遍pod install

# Uncomment the next line to define a global platform for your project
platform :ios, '10.3'
inhibit_all_warnings!

target 'PodTest' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!
  pod 'RealmSwift'

  # Pods for PodTest

  target 'PodTestTests' do
    inherit! :search_paths
    # Pods for testing
  end

  target 'PodTestUITests' do
    inherit! :search_paths
    # Pods for testing
  end

end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = '3.1'
    end
  end
end

小技巧

  1. 第四行的inhibit_all_warnings!,可以使得Xcode不对框架中不当的帮助说明生成警告。因为框架是第三方的,我们即便看到了,也不会修改它。
  2. 有时会由于网络问题导致下载的框架不全,此时可以使用这个命令重新下载。
pod deintegrate && pod install

参考资料