iOS應用自動推送的方法研究與實踐

DevOps訂閱號發表於2020-10-19


iOS應用自動推送的方法研究與實踐


本文作者:系統支援部 霍曉楠


摘要

iOS應用自動推送的方法研究與實踐



自動推送指透過自動的方式將移動端應用推送至相應的釋出平臺供客戶下載使用。目前研發中心已經完成了開放平臺、主機平臺以及移動平臺等主流開發語言的集中構建,隨著移動端應用逐漸成為人們生活中使用最頻繁的程式,研發中心移動端應用也呈井噴式的增長,iOS平臺作為移動端重要的組成部分之一,由於其本身產品系統的獨特性以及移動應用迭代頻繁的特點,在實現了集中構建以後,推送至蘋果商店這一環節一直處於手工上傳的方式。
為了適應專案投產需要與中心構建釋出整體發展思路保持一致,在進行了大量專案實踐的基礎上本文提出了可借鑑的自動構建推送方法,旨在幫助專案實現完全自動化的構建推送,將目標碼直接推送至蘋果商店,有效管理專案證照和程式碼的同時,減少不必要的互動,提高投產效率併為後續的測試和自動化部署積累豐富的經驗。
關鍵詞:自動推送、TFS、目標碼、持續整合

一、研究背景

iOS應用自動推送的方法研究與實踐



蘋果作業系統主要包括OSX和iOS,其主要的開發語言為Objective-C、Swift以及Javascript,使用LLVM編譯器框架系統,前端使用Clang編譯器。目前研發中心投產執行的蘋果應用主要使用Objective-C和Javascript語言開發,蘋果公司為每一個應用都設定了證照以保證資訊在網際網路中安全傳輸,分為公司版證照程式和企業版證照程式,這兩類證照對程式的釋出途徑起著至關重要的作用:

  • 公司版證照:屬於“組織”類別,功能用途與個人版證照一致,允許多個開發者協作開發,只能用於將應用釋出至蘋果App Store。
  • 企業版證照:屬於“組織”類別,允許多個開發者協作開發,只能用於將應用釋出至企業內部使用。

由於iOS應用具有上述特點,證照對於iOS應用的投產和上線起到了至關重要的作用並且與研發中心現有投產體系存在較大差異,目前大多采用手動釋出的模式。面對移動端應用投產上線的實際情況,在完成集中構建工作以後,將應用釋出至蘋果App Store這一環節的自動化方式成為亟待解決的問題。

二、技術術語

iOS應用自動推送的方法研究與實踐



2.1 編譯
一般來說編譯過程主要分為以下四部分:

  • 預處理(Pre-process),把宏替換,刪除註釋資訊,將標頭檔案進行展開,產生.i檔案。
  • 編譯(Compliling),把.i檔案轉換成組合語言產生.s檔案。
  • 彙編(Asembly),將.s檔案轉換成機器編碼檔案,產生.o檔案。
  • 連結(Link),對.o檔案中的所提到的的庫檔案進行引用(包括多個.o檔案進行link),生成最後的可執行檔案。

2.2 開發語言
iOS開發語言主要包括:C語言基礎、Objective-C、Swift以及Javascript程式語言。

  • Objective-C:是擴充C的物件導向程式語言,它是一個用C寫成很小的執行庫,令應用程式尺寸增加很小,完全相容C語言,可以使用GCC和Clang執行的系統上進行編譯,目前研發中心主要使用該語言進行開發。
  • Swift:於2014年WWDC釋出的新開發語言,可與Objective-C共同執行於Mac OS和iOS平臺,為了使Swift語言易用性和功能性更加出色,蘋果公司也在不斷的對編譯器進行最佳化和改進。以目前最新版本Xcode7版本為例,使用LLVM7.1(Xcode7.3)編譯器,該編譯器是自Xcode5將GCC編譯器取消後一直使用的,LLVM編譯器的前端是Clang,支援C、C++、Objective-C和Objective-C++等程式語言。
  • JavaScript:該指令碼語言是蘋果公司在iOS7之後推出的基於JavaScriptCore.framework框架的開發方式,實現Objective-C與Javascript相互呼叫並傳參的方法,使用此框架可以在iOS應用中執行JavaScript指令碼,也就是HybirdApp混合模式移動應用,即其中包含原生的結構有內嵌有web元件,這種App不僅效能和使用者體驗可以達到和原生所差無幾的程度,更大的優勢在於bug修復快,版本迭代無需重新編譯釋出,目前研發中心越來越多的專案開始採用此種開發模式。

2.3 iOS構建釋出要素
iOS應用從構建到釋出應用一般會經歷三個階段:在Xcode(蘋果程式開發工具)上執行除錯、在裝置上執行除錯和編譯釋出。蘋果為了防止非法裝置和非開發人員除錯和釋出應用,需要使用配置概要檔案(Provisioning Profiles)控制應用在裝置上執行除錯和編譯釋出。配置概要檔案由證照(certificates)、專案標識(Identifiers)以及裝置(Devices)組成,具體的編譯釋出流程如下:
iOS應用自動推送的方法研究與實踐
圖1

  • 證照(Certificates):蘋果官方頒佈的證照,分為開發證照和釋出證照兩種,蘋果是釋出者,然後安裝,這個證照的Mac就是擁有者。蘋果就會給電腦授予這個證照所對應的權利,簡單來說,證照是iOS應用開發的基礎,也是構建的必要組成部分。
  • 專案標識(Identifiers):Identifiers即“識別符號”,約等於是專案的身份證,用於區別蘋果應用,每個應用都有各自唯一的識別符號,專案標識包括:App ID其實就是一個App的身份證,一個App的位置標識。在Project中稱為Bundle ID。在Member Center、Project、ITunes Connect都是需要此ID去標識APP的唯一性。Bundle ID在不同環境下的表現關係,如下圖所示:

iOS應用自動推送的方法研究與實踐
圖2
在建立App ID過程中可以配置該應用的許可權,比如是否用到了PassBook,GameCenter,以及更常見的push服務,如果選中了push服務,那麼就可以建立生成具有推送服務的App ID,所以,在所有和推送相關的配置中,首先要做的就是先開通支援推送服務的App ID。

  • 裝置(Devices):Devices作用為建立測試裝置,只有在此列表中的裝置才能安裝真機除錯階段的蘋果應用,未在該列表中的裝置則不能安裝,一般情況下該列表中裝置總數不能超過100個。
  • 配置概要檔案(Provisioning Profiles):配置概要檔案是很有蘋果特點的設定,該檔案將證照(Certificates) 、專案標識(Identifiers)、裝置(Devices)結合起來,形成一個描述證照、識別符號的描述檔案。透過Xcode編譯的過程將配置概要檔案與程式關聯起來從而形成待發布蘋果App。


三、問題描述

iOS應用自動推送的方法研究與實踐



推送是將構建並測試透過的蘋果應用釋出到應用市場等待稽核的過程,對於蘋果應用而言,一般分為兩部分:

  • 第一部分是將待投產的程式包上傳至蘋果伺服器進行程式及配置檔案的自動掃描,主要在程式碼層面進行檢查。
  • 第二部分是在機器掃描透過後進行應用市場釋出的最後檢測,主要針對程式的功能和效能進行人為測試。

透過前期集中構建情況分析和經驗總結,在實現了全行蘋果應用集中構建的基礎上,如何替代人工上傳方式,將待投產程式自動推送至蘋果伺服器進行稽核,成為了影響蘋果持續整合效率的關鍵點,經前期手動推送應用的情況分析和經驗總結,對專案癥結有了大致的分類和判斷,總體來說iOS自動推送主要問題集中在如下幾點:
1)推送方式多樣
iOS分為兩種方式推送方式:

  • 一種是透過開發工具Xcode在手動完成構建後直接透過介面上傳至蘋果商店。
  • 第二種是透過Xcode中自帶的上傳工具Application Loader進行上傳,雖然介面不同,但其最終上傳介面和程式碼沒有本質區別。

2)推送環境特殊 
iOS專案開發需在蘋果作業系統macOS中進行,開發工具一般採用Xcode,目前研發中心蘋果集中構建在內網環境中解決,雖然構建環境統一,但由於兩網隔離的制約,推送至蘋果商店及相關釋出平臺方式不盡相同。
3)推送管理工具多樣
iOS專案開發大多在蘋果筆記本上進行,配置庫採用GIT版本控制系統較多,釋出結果除了蘋果平臺以外,沒有統一的管理機制,在程式碼質量、版本穩定性以及版本追溯等方面對專案投產上線產生極大的影響。
4)釋出操作複雜人工成本高
蘋果公司對每一個釋出的iOS應用都採用證照授權機制,透過編譯將證照進行注入,起到認證和管理的目的,但由於證照的唯一性,在日常開發過程中是無法使用蘋果授權證照進行打包並生成iOS應用的,尤其這對需要進行大規模測試的專案來說影響較大,專案上線則需要將程式碼複製至組織級構建管理員處進行編譯後釋出。
為了更好的解決iOS專案推送問題,應從推送方式入手,梳理iOS應用推送特點的同時,總結出適用於不同專案情況的推送方法,解決由於釋出方式和釋出途徑不同對蘋果應用投產產生的影響,提升整體整合效率,降低投產風險。

四、解決方案

iOS應用自動推送的方法研究與實踐



4.1 構建推送日誌分析
經過大量的手工編譯和推送並對日誌進行分析總結得出目前研發中心iOS應用推送一共分為兩種情況:

  • 一種是釋出至蘋果商店對客進行下載,這種專案需要釋出至蘋果商店供蘋果裝置客戶進行下載。
  • 第二種是企業內部需求直接在企業內部發放使用的應用。

透過檢視Build日誌可以進一步的瞭解蘋果程式編譯推送過程的工作原理提升開發及管理工作效率,在多數情況下Build編譯日誌隱藏了大量的資訊,其中經常會有一些通用的編譯命令,以這些命令為基礎可以更好的對編譯日誌進行模組化的解讀和研究。
CompileC...:主要用來編譯.m和.c檔案,在每一個target中被廣泛使用,生成中間檔案.o,一般出現在Compile步驟的行首位置。
iOS應用自動推送的方法研究與實踐
圖3
Libtool...:主要是從目標檔案中構建library,即生成.a檔案,一般出現在建立.a檔案的過程中。
iOS應用自動推送的方法研究與實踐
圖4
CreateUniversalBinary...:將上階段生成.a檔案合併為一個通用的二進位制檔案。
iOS應用自動推送的方法研究與實踐
圖5
Ld:與Libtool功能相似是一個linker的工具,被用來構建可執行檔案,即生成最終的.ipa檔案,該命令一般較長出現在構建目標碼階段。
根據上述命令分析就可以很清晰的瞭解蘋果程式的編譯過程,以專案中某一target為例,如下圖所示,該target作用是生成可執行檔案需要的.a檔案,即libDZNEmptyDataSet.a,其中使用了CompileC、Libtool以及CreateUniversalBinary等命令對原始碼進行處理。
iOS應用自動推送的方法研究與實踐
圖6
在編譯完成後Xcode自帶的Application Loader提供了一整套命令列工具 altool,幫助專案解決專案目標碼檔案的驗證和上傳工作。
altool --validate-app -f file -u username [-p password] [--output-format xml]
altool --upload-app -f file -u username [-p password] [--output-format xml]
4.2 自動推送方法研究
透過對上述日誌進行逐字逐句分析可以看出iOS專案雖然編譯過程比較複雜,編譯命令數量繁多,編譯方法豐富多樣,但總體來說都會遵循一定的規則進行,每一個target之間存在相互的主次關係,透過呼叫主target就可以實現整個專案構建並生成目標碼(.IPA)檔案。自動推送當中最為關鍵的是ExportOptions.plist檔案,檔案中記錄了兩個配置概要檔案對應規則,在自動推送的過程中,程式直接呼叫該plist檔案就可正確進行匹配,減少手工干預過程,最終實現應用的自動推送。
專案的配置和規則資訊都儲存於工程檔案(.xcodeproj)當中,透過自動構建可以實現生成目標碼,但核心問題是,在隨後的推送應用過程當中,需要手動對上傳目標碼進行匹配,上傳過程和命令基本不可見,需要對推送過程中使用的命令進行整理和分析才能最終形成自動推送命令列方法。透過對手工過程中所遇到情況進行總結,結合Xcode命令引數,目前形成了兩種可以覆蓋研發中心現有專案模式的自動推送方案。
1)呼叫plist檔案實現自動推送
這類推送模式相對比較簡單,只需要對推送過程中的操作命令進行排列組合並找到專案所對應的plist檔案即可實現自動推送過程,目前研發中心主要使用該種方式進行應用的自動推送,經測試和實際使用經驗總結,比較常用的命令如下所示:
表1 推送引數解析
iOS應用自動推送的方法研究與實踐
為了更好對iOS推送過程進行解析,將上述命令列帶入專案執行可以看出實際效果如下:

project_path=/Users/abc/ipa
project_name=AutoDeployTest
scheme_name=ABCDeploy
development_mode=Release
build_path=${project_path}/build
exportOptionsPlistPath=${project_path}/ExportOptions.plist
exportIpaPath=${project_path}/ABCDir/${development_mode}
altoolPath="/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool"
"$altoolPath" --validate-app -f ${exportIpaPath}/${scheme_name}.ipa -u 123 -p 123 ios --output-format xml
"$altoolPath" --upload-app -f ${exportIpaPath}/${scheme_name}.ipa -u 123 -p 123 ios --output-format xml

在實際呼叫的plist檔案中已經將證照、配置檔案、釋出方式等引數進行了匹配記錄,直接呼叫即可,減少了很多不必要的互動,實現最簡潔的iOS應用的自動釋出。
iOS應用自動推送的方法研究與實踐
圖7
最後透過引數將上傳過程中的資訊進行儲存並生成xml檔案解析其中的key值來判斷上傳步驟是否成功。key值為即上傳成功,key值為則為上傳失敗,可繼續在xml檔案中檢視報錯資訊。
iOS應用自動推送的方法研究與實踐
圖8
iOS應用自動推送的方法研究與實踐
圖9
2)使用Fastlane實現自動推送
這類自動推送相對複雜,Fastlane是一套使用Ruby編寫的自動化工具集,旨在簡化Android和iOS的部署過程,自動化工作流,對於Fastlane的安裝配置,這裡就不過多贅述了,它一套工具的集合,每一個工具叫做action,包括程式碼簽名、構建、打包、推送等功能,由於構建打包功能已經在TFS中實現,這裡只會用到Fastlane推送功能。
iOS應用自動推送的方法研究與實踐
圖10
iOS應用自動推送的方法研究與實踐
圖11
這裡我們會使用到deliver這個action當中的上傳功能實現自動化將應用上傳至App Store當中,由於Fastlane中每一個action都提供了十分強大的命令列功能,這裡就不做展開,僅簡要進行介紹。
表2 常用action解析
iOS應用自動推送的方法研究與實踐
安裝完成後,在進行上傳應用前,需要對本次上傳的應用資訊進行維護,以便在上傳過程中對應用的資訊進行更新,並保證上傳過程不會因為資訊錯誤而導致失敗,具體維護方式主要是對安裝目錄下的Deliverfile檔案中的資訊進行填寫,目的是利用該檔案提前維護好ITunes Store需要填寫的應用相關資訊,保證上傳過程的自動化。

# The Deliverfile allows you to store various iTunes Connect metadata
# For more information, check out the docs
#
# 根據iTunes Store 資訊設定
username "123"  # Apple ID email address
app_identifier("com.abc.test") # bundle identifier
#ipa("/Users/abc/ipa/ABCDeploy.ipa") # 沒有這個選項,只有metadata會被上傳
copyright("版權資訊") #版權資訊
#submit_for_review(false) #是否提交稽核,true表示立馬提交稽核
screenshots_path("./fastlane/screenshots") # 截圖圖片展示
price_tier 0 #app 出售價格
trade_representative_contact_information(  #iTunes store 資訊
 first_name: "yinhang", #名
 last_name: "nongye", #姓
 address_line1: "123", #地址
 address_line2: "",
 address_line3: "",
 city_name: "BeiJing", # 城市
 state: "BeiJing", # 省
 country: "China", #國家
 postal_code: "100000", # 郵編
 phone_number: "+86 13700000000", # 手機
 email_address: "abc.abchina.com", #郵箱
)
app_review_information( # app稽核資訊
 first_name: "yinhang", # 名
 last_name: "nongye", #姓
 phone_number: "+86 13700000000", #聯絡資訊電話號碼
 email_address: "abc.abchina.com", #聯絡資訊郵箱
 demo_user: "123",  #稽核測試賬號
 demo_password: "123", # 稽核測試密碼
 notes: "備註資訊" # iTunes Store 稽核資訊備註
)
#提交稽核資訊:加密, idfa 等
submission_information(
export_compliance_encryption_updated: false,
   export_compliance_uses_encryption: false,
   content_rights_contains_third_party_content: false,
   add_id_info_uses_idfa: false
)
name({
'zh-Hans' => "nongyeyinhang"  # app名稱
})
description({ #iTunes Store 中描述資訊
 'zh-Hans' => "APP的描述資訊,用於APP功能的描述和介紹不能少於10個字元"
})
release_notes({
 'zh-Hans' => "第一個版本測試"
})
keywords( # 收縮關鍵詞
 "zh-Hans" => "農業, 銀行"
)
promotional_text(
 "zh-Hans" => "宣傳文字資訊介紹",
)
support_url({ # 技術支援網址(URL)
 'zh-Hans' => "
})
marketing_url({ #營銷網址
 'zh-Hans' => "
})
privacy_url({
 'zh-Hans' => "
})
app_icon('./fastlane/metadata/AppIcon.png') #應用圖示
primary_category("Utilities")
# primary_first_sub_category "Card"
# primary_second_sub_category "Casino"
# 要設定的次要類別 無
# secondary_category  
# 設定的次要第一個子類別 無
# secondary_first_sub_category  
# 設定的次要第二個子類別 無
# secondary_second_sub_category

automatic_release true #稽核過之後自動釋出

Deliverfile檔案維護完成後,需要對fastlane/metadate/下建立名為itunesratingconfig.json檔案,按照ITunes Store要求對應用進行評級供應稽核時使用。

{
 "CARTOON_FANTASY_VIOLENCE": 0,#卡通或幻想暴力
 "REALISTIC_VIOLENCE": 0,#現實暴力
 "PROLONGED_GRAPHIC_SADISTIC_REALISTIC_VIOLENCE": 0,#大量露骨或殘暴的現實暴力
 "PROFANITY_CRUDE_HUMOR": 0,#低俗笑話
 "MATURE_SUGGESTIVE": 0,#成人/性暗示題材
 "HORROR": 0,#恐怖/驚悚題材
 "MEDICAL_TREATMENT_INFO": 0,#醫學/醫療資訊
 "ALCOHOL_TOBACCO_DRUGS": 0,#使用或提及煙、酒或毒品
 "GAMBLING": 2,#模擬賭博
 "SEXUAL_CONTENT_NUDITY": 0,#色情或裸露內容
 "GRAPHIC_SEXUAL_CONTENT_NUDITY": 0,#色情及裸體畫面
 "UNRESTRICTED_WEB_ACCESS": 0,#無限制的網站訪問
 "GAMBLING_CONTESTS": 0#賭博和競賽
}

上述工作全部完成後,就可以透過Fastlane中的action進行應用的自動上傳,實現應用自動構建釋出的全流程自動化。

default_platform(:ios)
platform :ios do
desc "上傳至 App Store"
  lane :release do
scheme_name="ABCDeploy"  
output_directory="/Users/abc/ipa"
scheme_version="1.0.0"
output_name="#{scheme_name}_#{scheme_version}.ipa"
     gym(
export_method: "app-store",
export_xcargs: "-allowProvisioningUpdates",
scheme: scheme_name,
clean: true,
output_directory: output_directory,
output_name: output_name,
)
     deliver(
           Ipa:"output_name"
           submit_for_review: true,
       ignore_language_directory_validation:true,
       force:true
       skip_screenshots:true
            )
     end


五、總結

iOS應用自動推送的方法研究與實踐



自動推送可以說是在iOS集中構建完成後急需解決的一個流程貫通環節,以往手動上傳需要人工干預較多,效率相對較低,iOS應用實現了標準化構建模式後急需一個自動推送模式進行銜接。
本次研究制定“呼叫plist檔案實現自動推送”以及“使用Fastlane實現自動推送”的推送方法,相比較這兩種方法:

  • “呼叫plist檔案實現自動推送”中所使用到的ExportOptions.plist檔案是透過集中構建自動生成的,不需要人工干預和維護,對於已經發布過的iOS應用來說十分的便利快捷,目前研發中心專案大多使用該種方式進行應用的自動推送。
  • “使用Fastlane實現自動推送”由於提供了一整套action的工具集,實現的功能比較強大,但所需維護的蘋果商店資訊比較複雜,初次使用很容易出現資訊錯誤的情況適合多次投產的“老手”使用,並且可以對自動推送進行定製化開發,靈活性較高。

這兩種方法主要目的是幫助專案解決iOS應用測試和釋出環節效率低下的問題,提升了釋出效率,降低了互動時長,提升了工作質量並建立標準化的自動推送流程,是向持續整合,持續部署,持續交付等開發實踐又邁出堅實的一步,相信在後續工作開展當中仍能一如既往的披荊斬棘不斷深化擴充套件集中構建成果,積極探索後續開發實踐過程,為研發中心DevOps以及持續整合和持續部署等工作提供技術力量支援。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31558019/viewspace-2727701/,如需轉載,請註明出處,否則將追究法律責任。

相關文章