iOS 使用指令碼自動化複製target,iostarget

來源:互聯網
上載者:User

iOS 使用指令碼自動化複製target,iostarget

有些項目成熟以後,就會有需求自動化配置產生一個全新的項目,不需要再讓開發人員手動修改工程檔案,將配置化工作直接移交給營運或者配置團隊去做

其實按照普通的做法,無非就是在xcode裡將目標target duplicate一下,然後修改相關的項目名稱、target名稱、bundleid等等,這些內容其實在xcodeproj檔案中都有對應的配置資訊,所以我們可以通過直接修改Xcodeproj直接檔案的方式實現

首先感謝蝦神 提供了詳細的原理解說和工具介紹,在實現時少走了很多彎路,有興趣的同學可以前往 蝦神 的文章學習,這裡我把最終實現貼出來供大家參考~~

希望進一步學習ios工程配置和指令碼相關的同學建議去這裡:

ruby doc

xcodeproj相關API文檔

github樣本

巧用指令碼解決 Target 管理問題

 

#!/usr/bin/env rubyrequire 'rubygems'require 'xcodeproj'require 'fileutils'#----------------------------------- 目標項目配置內容----------------------------#name = "newyorktoon"displayname = "紐約通"target_toonType = 10001target_pushType = "hello"target_channel = "hello"target_mapKey = "hello"target_schemeType = "hello"#----------------------------------- 目標項目配置內容----------------------------## 模板項目                   # srcname = "tzhqtoon"                                                                      # srcdisplayname = "後勤通"                                                 #projectproject_path = "Hello.xcodeproj"# 複製資源檔,注意:# 1. 複製資源檔時需要排除源資源檔# 2. 在此檔案的最後面將複製出來的資源檔添加到目標targettargetdir = "TNTarget/#{name}"srcroot = "TNTarget/#{srcname}"# 複製資源檔夾,將源target下的圖片資源檔夾複製到目標target目錄if !Dir.exists?(targetdir)  Dir.mkdir(targetdir)endcodeDirs = [  "#{srcroot}/Resources",  "#{srcroot}/NetWork",  "#{srcroot}/TabbarSetDataSource",  "#{srcroot}/TNHQHome"]#複製源target目錄下的定製化代碼目錄到目標target目錄hasAllListFiles = falsecodeDirs.each do |d|  hasAllListFiles = Dir.exists?(d)#-> 此處假設所有的code file為一個整體,一有具有  if hasAllListFiles    FileUtils.cp_r  d, targetdir  endend# 尋找模板targetproj = Xcodeproj::Project.open(project_path)src_target = proj.targets.find { |item| item.to_s == srcname }# 建立目標targettarget = proj.new_target(src_target.symbol_type, name, src_target.platform_name, src_target.deployment_target)target.product_name = name# create schemescheme = Xcodeproj::XCScheme.newscheme.add_build_target(target)scheme.set_launch_target(target)scheme.save_as(project_path, name)#  build_configurationstarget.build_configurations.map do |item|#設定target相關配置  item.build_settings.update(src_target.build_settings(item.name))  # puts "-"*30 + "#{item.build_settings}" +"_"*30  item.build_settings["PRODUCT_BUNDLE_IDENTIFIER"] = "com.abc.aa.#{name}"  item.build_settings["PRODUCT_NAME"] =displayname  targetInfoPlist = item.build_settings["INFOPLIST_FILE"]  item.build_settings["INFOPLIST_FILE"] = targetInfoPlist.sub(srcname, name)  puts "-"*30 + "#{item.build_settings['PRODUCT_BUNDLE_IDENTIFIER']}" +"_"*30  puts "-"*30 + "#{item.build_settings['PRODUCT_NAME']}" +"_"*30end# build_phasesphases = src_target.build_phases.reject { |x| x.instance_of? Xcodeproj::Project::Object::PBXShellScriptBuildPhase }.collect(&:class)#複製源target引用的source和resource檔案引用phases.each do |klass|puts "||---------------------> copy phases #{klass}--------------------||"  src = src_target.build_phases.find { |x| x.instance_of? klass }  dst = target.build_phases.find { |x| x.instance_of? klass }  unless dst    dst ||= proj.new(klass)    target.build_phases << dst  end  dst.files.map { |x| x.remove_from_project }idx = 1  src.files.each do |f|# 排除檔案,將源target中的檔案排除,不引用該檔案    if f.file_ref and f.file_ref.hierarchy_path.index(srcroot) != nil      puts "\n................... ignore file:  #{f.file_ref}, #{f.file_ref.hierarchy_path}...................\n"        next    end    file_ref = proj.new(Xcodeproj::Project::Object::PBXFileReference)    if f.settings      puts ">>file.settings:  #{idx} > file: " + f.file_ref.to_s + " settings: " + f.settings.to_s    end    idx = idx+1    if f.file_ref      if f.file_ref.name        puts ">> file_ref name: #{f.file_ref.name} path: #{f.file_ref.path} source_tree: #{f.file_ref.source_tree}"      end      # puts ">> file path: #{f.file_ref.hierarchy_path}-- #{f.file_ref.real_path}"      file_ref.name = f.file_ref.name      file_ref.path = f.file_ref.path      file_ref.source_tree = f.file_ref.source_tree      file_ref.last_known_file_type = f.file_ref.last_known_file_type      # file_ref.fileEncoding = f.file_ref.fileEncoding      begin        file_ref.move(f.file_ref.parent)      rescue    end    end    build_file = proj.new(Xcodeproj::Project::Object::PBXBuildFile)    build_file.file_ref = f.file_ref# 檔案屬性配置,如no-arc    if f.settings    build_file.settings = f.settings  end    dst.files << build_file  endend#設定目標target檔案組projTargetGroup = proj.main_group.groups.find { |x| x.path == 'TNTarget' }targetGroup =  projTargetGroup.new_group(name, name)# resourceresourceGroup = targetGroup.new_group("Resources", "./Resources")supportingGroup=resourceGroup.new_group("Supporting Files")# 添加資源檔引用,注意和代碼檔案引用方式不同target.add_resources(  [    resourceGroup.new_reference("areaCode.plist"),    resourceGroup.new_reference("login_toon_bg@2x.png"),    resourceGroup.new_reference("login_toon_bg@3x.png"),    resourceGroup.new_reference("tab_item_home_highlight@2x.png"),    resourceGroup.new_reference("tab_item_home_highlight@3x.png"),    resourceGroup.new_reference("tab_item_home_normal@2x.png"),    resourceGroup.new_reference("tab_item_home_normal@3x.png"),    resourceGroup.new_reference("Toon_logo@2x.png"),    resourceGroup.new_reference("Toon_logo@3x.png"),    resourceGroup.new_reference("toon_serviceProtocol.html"),    resourceGroup.new_reference("user_protocol.html"),    resourceGroup.new_reference("NewFunction.html"),    supportingGroup.new_reference("Supporting Files/configuration.plist"),    supportingGroup.new_reference("Supporting Files/Info.plist"),    supportingGroup.new_reference("Supporting Files/Images.xcassets"),    supportingGroup.new_reference("Supporting Files/InfoPlist.strings"),    supportingGroup.new_reference("Supporting Files/Localizable.strings")  ])  if hasAllListFiles# 添加代碼檔案組code1 = targetGroup.new_group("NetWork", "./NetWork")code2 = targetGroup.new_group("TabbarSetDataSource", "./TabbarSetDataSource")code3 = targetGroup.new_group("TNHQHome", "./TNHQHome")# 添加代碼檔案引用    target.add_file_references(      [        code1.new_reference("NetworkRequestURL.h"),        code1.new_reference("NetworkRequestURL.m"),        code2.new_reference("TNTabSettingDataSource.h"),        code2.new_reference("TNTabSettingDataSource.m"),        code3.new_reference("TNHomeViewController.m")        ])  end  # 修改檔案通用內容  infoplistfile = "#{targetdir}/Resources/Supporting Files/Info.plist"  files = [    "#{targetdir}/Resources/areaCode.plist",    "#{targetdir}/Resources/toon_serviceProtocol.html",    "#{targetdir}/Resources/user_protocol.html",    "#{targetdir}/Resources/NewFunction.html",    infoplistfile,    "#{targetdir}/Resources/Supporting Files/InfoPlist.strings",    "#{targetdir}/Resources/Supporting Files/Localizable.strings"  ]  if hasAllListFiles     files << "#{targetdir}/TabbarSetDataSource/TNTabSettingDataSource.m"  endfiles.each do |f1|  File.open(f1) do |fr|      buffer = fr.read.gsub(srcdisplayname, displayname)      buffer= buffer.gsub("項目名", displayname)      buffer= buffer.gsub("大同", displayname)       File.open(f1, "w") { |fw| fw.write(buffer) }  endend# 修改info.plist  File.open(infoplistfile) do |fr|    if hasAllListFiles      puts "*************************** 1"      buffer = fr.read.gsub("<string>10024</string>", "<string>#{target_pushType}</string>")      buffer= buffer.gsub("<integer>124</integer>", "<integer>#{target_toonType}</integer>")      buffer= buffer.gsub("<string>1241002</string>", "<string>#{target_channel}</string>")      buffer= buffer.gsub("<string>8058bda8c0ad5a7cfb8742cfbac4ecb8</string>", "<string>#{target_mapKey}</string>")      buffer= buffer.gsub("<string>toon124</string>", "<string>#{target_schemeType}</string>")    else      puts "*************************** 2"      buffer = fr.read.gsub("<string>10016</string>", "<string>#{target_pushType}</string>")      buffer= buffer.gsub("<integer>116</integer>", "<integer>#{target_toonType}</integer>")      buffer= buffer.gsub("<string>10035</string>", "<string>#{target_channel}</string>")      buffer= buffer.gsub("<string>e851d7df83d59f143bff1ad5a3a8e554</string>", "<string>#{target_mapKey}</string>")      buffer= buffer.gsub("<string>toon116</string>", "<string>#{target_schemeType}</string>")    end    puts "*************************** updating InfoPlist"    File.open(infoplistfile, "w") { |fw| fw.write(buffer) }  endproj.save# 修改Podfileputs ">> prepare loading pods ..."podTarget = "target '#{name}' do shared_pods  end"File.open("Podfile") do |file|  if file.read().index(podTarget) ==nil    File.open(infoplistfile, "w") { |fw| fw.puts podTarget }    puts ">> add pod item"  else    puts ">> pod has been added"  endend# file.close# 更新pod依賴exec 'pod install'

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.