cocoapods-kz 0.0.11 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c043498bc76c19c7f49d1b6f64f00f10535f3512b9eb85853e213e4faa9b4d1c
4
- data.tar.gz: e86ca96c094fb8f90d6434d1ce99421c0d4c2d2bca37b0e91f23639f841ea3df
3
+ metadata.gz: e5dcadeaa76d480bc0a06c97d9f07fc514d4f6c6fa6e1321ea60546f9b425a5f
4
+ data.tar.gz: 01ab3e043531cbc9e29d6a73ddc15e63873245c7aa99c8a301ae79dc531f4914
5
5
  SHA512:
6
- metadata.gz: 15a3769ef86e707c147f1d8d0f3b03832c316a895869703e501fdf3efb9f365938548bc73b2db8331624d90c9ba714bb41763755696d42e7e64cf800c80729d0
7
- data.tar.gz: 70b54fcc641af9ae839c916568e6af18444dc42d00054fcae859e64c9639b780a52eab7320582c15a1c392245fb0cad1cc43cc91557c4ae8716de04c419a6086
6
+ metadata.gz: e163e6c506505a9a1cf39ae263a5a40ccaf1ff8aae61d0ac808f1256106409ff7d5fd29de8c52abe9fb93666e42a6ad0db504a759eadb94b2781478a61aa83c9
7
+ data.tar.gz: f678b463d568835f87a1d5d490c8f5096651d94fe7123ce94ac26ea8eee3ea1bd9130e908b7e2c616811e26c804523ef5897b2c69306f8e0ca89160cd3159830
@@ -1,5 +1,5 @@
1
1
  module CocoapodsKz
2
- VERSION = "0.0.11"
2
+ VERSION = "0.0.14"
3
3
  end
4
4
 
5
5
  module Pod
@@ -3,18 +3,41 @@ require_relative 'kz_global_helper'
3
3
 
4
4
  module KZ
5
5
 
6
+ class KZFlexLibInfo
7
+ attr_accessor :have_flexLib_pod
8
+ attr_accessor :have_kzswiftui_pod
9
+ attr_accessor :flexLib_version
10
+
11
+ def initialize
12
+ @have_flexLib_pod = false
13
+ @have_kzswiftui_pod = false
14
+ @flexLib_version = Pod::Version::ZERO
15
+ end
16
+ end
17
+
6
18
  class KZAnalyzer
7
19
  attr_accessor :all_kz_pod_targets
20
+ attr_accessor :pod_of_flexlib_info
8
21
 
9
22
  def initialize(native_pod_targets, development_pods)
10
23
  @native_pod_targets = native_pod_targets
11
24
  @development_pods = development_pods.keys
12
25
  @all_kz_pod_targets = {}
26
+ @pod_of_flexlib_info = KZFlexLibInfo.new
13
27
  end
14
28
 
15
29
  def analyer
16
30
  @native_pod_targets.each { |native_pod_target|
17
31
  create_kz_pod_target_from(native_pod_target, :kz_pod_origin_mode)
32
+
33
+ if native_pod_target.root_spec.name == "FlexLib"
34
+ @pod_of_flexlib_info ||= KZFlexLibInfo()
35
+ @pod_of_flexlib_info.have_flexLib_pod = true
36
+ @pod_of_flexlib_info.flexLib_version = native_pod_target.root_spec.version
37
+ elsif native_pod_target.root_spec.name == "KZSwiftUI"
38
+ @pod_of_flexlib_info ||= KZFlexLibInfo()
39
+ @pod_of_flexlib_info.have_kzswiftui_pod = true
40
+ end
18
41
  }
19
42
 
20
43
  # 检测是否有product名称相同的target
@@ -2,6 +2,7 @@ require_relative 'kz_pod_target'
2
2
  require_relative 'kz_global_helper'
3
3
  require_relative 'kz_config_result'
4
4
  require 'tmpdir'
5
+ require 'shellwords'
5
6
  require_relative 'kz_log'
6
7
 
7
8
  module KZ
@@ -29,7 +30,7 @@ module KZ
29
30
  config_folder = KZ_POD_CONFIG_POD_TARGETS + folder_name
30
31
  if File.directory?(config_folder)
31
32
  Dir.foreach(config_folder) do |version|
32
- next if version == '.' || version == '..' || version == '.DS_Store'
33
+ next if version == '.' || version == '..' || version == '.DS_Store' || version == 'Headers'
33
34
 
34
35
  version_folder = config_folder + version
35
36
  if File.directory?(version_folder)
@@ -50,9 +51,32 @@ module KZ
50
51
  @@all_resources_cache_info
51
52
  end
52
53
 
54
+ def self.handle_origin_library(origin_libraries, kz_pod_target)
55
+ tempdir = Pathname(Dir.mktmpdir)
56
+ lib_frameworks_path = tempdir + "lib_frameworks"
57
+ FileUtils.mkdir_p(lib_frameworks_path)
58
+
59
+ origin_lib_frameworks = []
60
+ origin_libraries.each do |origin_library_path|
61
+ lib_framework_name = origin_library_path.basename(origin_library_path.extname)
62
+ lib_framework_path = lib_frameworks_path + "#{lib_framework_name}.framework"
63
+ FileUtils.mkdir_p(lib_framework_path)
64
+
65
+ FileUtils.cp(origin_library_path, lib_framework_path + lib_framework_name)
66
+ origin_lib_frameworks.append(lib_framework_path)
67
+ end
68
+
69
+ new_frameworks = handle_origin_framework(origin_lib_frameworks, kz_pod_target)
70
+ FileUtils.rm_r(tempdir)
71
+ new_frameworks
72
+ end
73
+
53
74
  def self.handle_origin_framework(origin_frameworks, kz_pod_target)
54
75
  new_frameworks = []
55
- destination_path = kz_pod_target.pod_config_cache_path(false, true)
76
+ old_destination_path = kz_pod_target.pod_config_cache_path(false , true)
77
+ FileUtils.rm_rf(old_destination_path) if File.exist?(old_destination_path)
78
+
79
+ destination_path = kz_pod_target.pod_config_cache_path(true, true)
56
80
  origin_frameworks.each do |origin_framework_path|
57
81
  if kz_pod_target.disable_to_simulator_frameworks.include?(origin_framework_path)
58
82
  new_frameworks.append(origin_framework_path)
@@ -145,7 +169,6 @@ module KZ
145
169
  end
146
170
 
147
171
  temp_framwork_exe_path = tempdir + "#{framework_basename}_arm64_simulator"
148
-
149
172
  if self.is_dynamic_library?(origin_framework_path + framework_basename)
150
173
  xcrun_vtool_show_result = `xcrun vtool -arch arm64 -show #{origin_framework_path + framework_basename}`.lines.map(&:chomp)
151
174
  framework_sdk_version = "16.0"
@@ -179,7 +202,9 @@ module KZ
179
202
  FileUtils.mkdir_p(ar_x_path)
180
203
  ar_x_success = system("cd #{ar_x_path}; ar x #{arm64_framework_exe_path}")
181
204
  if ar_x_success
182
- system("for file in #{ar_x_path}/*.o; do #{ARM64_TO_SIMULATOR_EXECUTE_PATH} $file; done")
205
+ Dir["#{ar_x_path}/*.o"].each do |file|
206
+ system(ARM64_TO_SIMULATOR_EXECUTE_PATH, file)
207
+ end
183
208
  system("ar crv #{temp_framwork_exe_path} #{ar_x_path}/*.o &> /dev/null")
184
209
  else
185
210
  FileUtils.rm_r(tempdir)
@@ -8,6 +8,8 @@ module KZ
8
8
  def initialize(main_project)
9
9
  @all_kz_pod_targets = KZGlobalHelper.instance.kz_analyzer.all_kz_pod_targets
10
10
  @main_project = main_project
11
+ @installation_root = Pod::Config.instance.installation_root
12
+ @on_demand_resources_folder = KZ_POD_CONFIG_ROOT + "OnDemandResources"
11
13
  end
12
14
 
13
15
  def add_framework_generator_build_phase(native_target)
@@ -29,20 +31,27 @@ module KZ
29
31
  end
30
32
 
31
33
  xml_rule = new_build_rule(project, native_target, '[KZ] Custom Xml Build')
34
+ xml_rule.run_once_per_architecture = '0'
32
35
  xml_rule.file_type = 'text.xml'
33
36
  xml_rule.output_files = Array['${KZ_XML_FLEX_DIR}/${INPUT_FILE_BASE}.flex']
34
37
  xml_rule.script = KZ.deal_path_for_xcconfig(KZ_XML_BUILD_PATH, true)
35
38
  end
36
39
 
37
40
  def add_force_load_exe_path_build_phase(native_target, output_path)
38
- return if KZ::KZGlobalHelper.instance.disable_generate_framework
39
-
40
41
  build_phase = native_target.new_shell_script_build_phase('[KZ] Froce Load File Output Path')
41
42
  build_phase.show_env_vars_in_log = '0'
42
43
  build_phase.output_paths = [output_path]
43
44
  build_phase.shell_script = KZ.deal_path_for_xcconfig(KZ_FIX_FORCE_LOAD_EXE, true)
44
45
  end
45
46
 
47
+ def add_improve_yaml_build_phase(project, native_target, output_path)
48
+ build_phase = new_shell_script_build_phase(project, native_target, '[KZ] Improve Custom Yaml', true)
49
+ build_phase.show_env_vars_in_log = '0'
50
+ # build_phase.always_out_of_date = '1'
51
+ build_phase.output_paths = [output_path]
52
+ build_phase.shell_script = KZ.deal_path_for_xcconfig(KZ_IMPROVE_CUSTOM_YAML_PATH, true)
53
+ end
54
+
46
55
  def new_build_rule(project, native_target, name)
47
56
  new_rule = nil
48
57
  native_target.build_rules.each do |build_rule|
@@ -59,6 +68,27 @@ module KZ
59
68
  new_rule
60
69
  end
61
70
 
71
+ def new_shell_script_build_phase(project, native_target, name, before_compile = false)
72
+ new_build_phase = project.new(Xcodeproj::Project::PBXShellScriptBuildPhase)
73
+ new_build_phase.name = name
74
+ if before_compile
75
+ find_compile = false
76
+ native_target.build_phases.each_with_index do |build_phase, index|
77
+ if build_phase.is_a?(Xcodeproj::Project::PBXSourcesBuildPhase)
78
+ find_compile = true
79
+ native_target.build_phases.insert(index, new_build_phase)
80
+ break
81
+ end
82
+ end
83
+ unless find_compile
84
+ native_target.build_phases << new_build_phase
85
+ end
86
+ else
87
+ native_target.build_phases << new_build_phase
88
+ end
89
+ new_build_phase
90
+ end
91
+
62
92
  def create_hamp
63
93
  # 创建壳工程hmap
64
94
  main_sources_path = @main_project.project_dir + @main_project.root_object.display_name
@@ -116,14 +146,25 @@ module KZ
116
146
 
117
147
  # 添加私有头文件引用
118
148
  if kz_pod_target.current_should_build?
119
- private_hamp_info = private_hmap_info(kz_pod_target)
120
- if private_hamp_info.count > 0
149
+ pod_hamp_info = pod_hmap_info(kz_pod_target)
150
+ if pod_hamp_info.count > 0
121
151
  hmap_cache_path = kz_pod_target.pod_config_cache_path(false)
122
152
  FileUtils.mkdir_p(hmap_cache_path) unless File.exist?(hmap_cache_path)
123
153
 
124
- save_hmap_file(private_hamp_info, hmap_cache_path, target_name)
154
+ save_hmap_file(pod_hamp_info, hmap_cache_path, target_name)
125
155
  kz_pod_target.private_header_search_path = hmap_cache_path + "#{target_name}.hmap"
126
156
  end
157
+
158
+ pod_yaml_info = pod_yaml_info(kz_pod_target)
159
+ if pod_yaml_info.count > 0
160
+ yaml_cache_path = kz_pod_target.pod_config_cache_path(false)
161
+ FileUtils.mkdir_p(yaml_cache_path) unless File.exist?(yaml_cache_path)
162
+
163
+ yaml_name = "#{target_name}_origin.yaml"
164
+ save_yaml_file(pod_yaml_info, yaml_cache_path + yaml_name)
165
+ kz_pod_target.custom_origin_yaml_path = yaml_cache_path + yaml_name
166
+ kz_pod_target.custom_yaml_path = yaml_cache_path + "#{target_name}.yaml"
167
+ end
127
168
  end
128
169
  end
129
170
  end
@@ -149,7 +190,7 @@ module KZ
149
190
  Dir.foreach(hmap_cache_path) do |file_name|
150
191
  next if file_name == '.' || file_name == '..' || file_name == '.DS_Store'
151
192
 
152
- if file_name.end_with?(".hmap", ".json")
193
+ if file_name.end_with?(".hmap", ".json", "yaml")
153
194
  FileUtils.rm(hmap_cache_path + file_name) if File.exist?(hmap_cache_path + file_name)
154
195
  end
155
196
  end if File.exist?(hmap_cache_path)
@@ -180,50 +221,105 @@ module KZ
180
221
  end
181
222
  end
182
223
 
183
- def private_hmap_info(kz_pod_target)
184
- header_paths = kz_pod_target.all_headers
185
- # 更新Headers
186
- if kz_pod_target.is_dev_pod
187
- header_paths.each do |header_pathname|
188
- symlink_path = kz_pod_target.local_private_headers_path + header_pathname.basename
189
- File.symlink(header_pathname, symlink_path) unless File.symlink?(symlink_path) || File.exist?(symlink_path)
190
- end
191
- kz_pod_target.use_local_private_headers_path = true
224
+ def pod_hmap_info(kz_pod_target)
225
+ pod_hmap_info = {}
226
+ module_name = kz_pod_target.kz_module_name
227
+
228
+ # public headers
229
+ public_headers = kz_pod_target.public_headers
230
+ public_headers.each do |header_pathname|
231
+ header_pathname_basename = header_pathname.basename.to_s
232
+
233
+ header_hmap_value_quotes = {}
234
+ header_hmap_value_quotes['suffix'] = header_pathname_basename
235
+ header_hmap_value_quotes['prefix'] = module_name + '/'
236
+ pod_hmap_info[header_pathname_basename] = header_hmap_value_quotes
237
+ pod_hmap_info[module_name + '/' + header_pathname_basename] = header_hmap_value_quotes
192
238
  end
193
- header_paths.each_with_object({}) do |header_pathname, hmap_info|
239
+
240
+ # private headers
241
+ all_headers = kz_pod_target.all_headers
242
+ (all_headers - public_headers).each do |header_pathname|
194
243
  header_pathname_basename = header_pathname.basename.to_s
195
244
 
196
245
  header_hmap_value_quotes = {}
197
246
  header_hmap_value_quotes['suffix'] = header_pathname_basename
198
247
  header_hmap_value_quotes['prefix'] = header_pathname.dirname.to_s + '/'
199
- hmap_info[header_pathname_basename] = header_hmap_value_quotes
248
+ pod_hmap_info[header_pathname_basename] = header_hmap_value_quotes
249
+ end
200
250
 
201
- # pch
202
- pchfile_path = kz_pod_target.prefix_header_path
203
- if pchfile_path.exist?
204
- suffix = pchfile_path.basename.to_s
205
- hmap_info[suffix] = { 'suffix' => suffix, 'prefix' => "#{pchfile_path.dirname.to_s}/" }
206
- end
251
+ # pch
252
+ pchfile_path = kz_pod_target.prefix_header_path
253
+ if pchfile_path.exist?
254
+ suffix = pchfile_path.basename.to_s
255
+ pod_hmap_info[suffix] = { 'suffix' => suffix, 'prefix' => "#{pchfile_path.dirname.to_s}/" }
256
+ end
207
257
 
208
- unless kz_pod_target.is_dev_pod
209
- # 个别第三方在使用自己组件文件时,会使用#import <xx/xx.h>的方式
210
- hmap_info[kz_pod_target.product_basename + '/' + header_pathname_basename] = header_hmap_value_quotes
211
- end
258
+ # umbrella
259
+ umbrella_path = kz_pod_target.umbrella_header_path
260
+ if umbrella_path.exist?
261
+ suffix = umbrella_path.basename.to_s
262
+ pod_hmap_info[suffix] = { 'suffix' => suffix, 'prefix' => "#{module_name}/" }
263
+ end
212
264
 
213
- if kz_pod_target.current_uses_swift? && kz_pod_target.is_dev_pod
214
- # 修改SPBoss-Swift.h文件的导入方式
215
- swift_bridge_file_name = "#{kz_pod_target.name}-Swift.h"
216
- hmap_info[swift_bridge_file_name] = { 'suffix' => swift_bridge_file_name, 'prefix' => "#{kz_pod_target.name}/" }
265
+ if kz_pod_target.current_uses_swift? && kz_pod_target.is_dev_pod
266
+ # 修改SPBoss-Swift.h文件的导入方式
267
+ swift_bridge_file_name = "#{module_name}-Swift.h"
268
+ pod_hmap_info[swift_bridge_file_name] = { 'suffix' => swift_bridge_file_name, 'prefix' => "#{module_name}/" }
269
+ end
217
270
 
218
- # 以SPBoss为例,在混编模式中,SPBoss-Swift.h会使用#import <SPBoss/SPBoss.h>方式导入swift需要使用的OC头文件
219
- # SPBoss中头文件会存在当前组件与framework的Headers中,有两份。SPBoss-Swift.h只在framework中
220
- # 编译默认从SPBoss-Swift.h找SPBoss.h,然后找SPBoss.h中的头文件也都会在framework中寻在,会造成与当前组件头文件重复
221
- # 需要重新将#import <SPBoss/SPBoss.h>方式修复为寻找当前组件中的SPBoss.h文件,而不是framework中的SPBoss.h
222
- if header_pathname_basename == "#{kz_pod_target.name}.h"
223
- hmap_info[kz_pod_target.name + '/' + header_pathname_basename] = header_hmap_value_quotes
224
- end
271
+ # 另存一份Headers,用于创建文件与import时的提示信息
272
+ if kz_pod_target.is_dev_pod
273
+ all_headers.each do |header_pathname|
274
+ symlink_path = kz_pod_target.local_private_headers_path + header_pathname.basename
275
+ File.symlink(header_pathname, symlink_path) unless File.symlink?(symlink_path) || File.exist?(symlink_path)
225
276
  end
277
+ kz_pod_target.use_local_private_headers_path = true
226
278
  end
279
+ pod_hmap_info
280
+ end
281
+
282
+ def pod_yaml_info(kz_pod_target)
283
+ built_products_dir = "__built_products_dir__/"
284
+
285
+ pod_yaml_info = {}
286
+ pod_yaml_info["case-sensitive"] = "false"
287
+ pod_yaml_info["version"] = "0"
288
+
289
+ yaml_roots = []
290
+ pod_yaml_info["roots"] = yaml_roots
291
+
292
+ yaml_header_info = {}
293
+ yaml_header_info["type"] = "directory"
294
+ yaml_header_info["name"] = built_products_dir + "#{kz_pod_target.product_name}/Headers"
295
+ yaml_roots.append(yaml_header_info)
296
+
297
+ public_headers = kz_pod_target.public_headers
298
+ yaml_header_contents = []
299
+ yaml_header_info["contents"] = yaml_header_contents
300
+ public_headers.each do |header_pathname|
301
+ yaml_header_content = {}
302
+ yaml_header_content["type"] = "file"
303
+ yaml_header_content["name"] = header_pathname.basename.to_s
304
+ yaml_header_content["external-contents"] = header_pathname.to_s
305
+ yaml_header_contents.append(yaml_header_content)
306
+ end
307
+
308
+ yaml_modulemap_info = {}
309
+ yaml_modulemap_info["type"] = "directory"
310
+ yaml_modulemap_info["name"] = built_products_dir + "#{kz_pod_target.product_name}/Modules"
311
+ yaml_roots.append(yaml_modulemap_info)
312
+
313
+ yaml_modulemap_contents = []
314
+ yaml_modulemap_info["contents"] = yaml_modulemap_contents
315
+
316
+ yaml_modulemap_content = {}
317
+ yaml_modulemap_content["type"] = "file"
318
+ yaml_modulemap_content["name"] = "module.modulemap"
319
+ yaml_modulemap_content["external-contents"] = built_products_dir + "#{kz_pod_target.product_name}/Modules/module.modulemap"
320
+ yaml_modulemap_contents.append(yaml_modulemap_content)
321
+
322
+ pod_yaml_info
227
323
  end
228
324
 
229
325
  def save_hmap_file(hmap_hash, save_path, file_name)
@@ -234,10 +330,240 @@ module KZ
234
330
  return unless json_file
235
331
 
236
332
  json_file.syswrite(hmap_json)
333
+ json_file.close
334
+
237
335
  system "#{HMAP_EXECUTE_PATH} convert #{hmap_json_path} #{hmap_path}"
238
336
 
239
337
  FileUtils.rm(hmap_json_path) unless KZ::KZGlobalHelper.instance.debug
240
338
  end
241
339
 
340
+ def save_yaml_file(yaml_hash, save_path)
341
+ yaml_json = JSON.pretty_generate(yaml_hash)
342
+ json_file = File.new(save_path, 'w')
343
+ return unless json_file
344
+
345
+ json_file.syswrite(yaml_json)
346
+ json_file.close
347
+ end
348
+
349
+ def create_on_demand_resources
350
+ # 清除历史配置
351
+ FileUtils.rm_r(@on_demand_resources_folder) if File.exist?(@on_demand_resources_folder)
352
+ FileUtils.mkdir_p(@on_demand_resources_folder)
353
+
354
+ # 汇总所有配置文件,用于代码中加载资源
355
+ on_demand_resources_all_config = {}
356
+ @all_kz_pod_targets.each do |target_name, kz_pod_target|
357
+ if kz_pod_target.is_dev_pod
358
+ # 寻找配置文件KZOnDemandResourcesConfig.plist
359
+ kz_pod_target.native_pod_target.file_accessors.each do |file_accessor|
360
+ file_accessor.resource_bundles.map do |bundle_name, paths|
361
+ paths.each do |path|
362
+ if path.basename.to_s == "KZOnDemandResourcesConfig.plist"
363
+ plist_hash = Xcodeproj::Plist.read_from_path(path)
364
+ if plist_hash.size > 0
365
+ on_demand_resources_all_config[kz_pod_target.name] = plist_hash
366
+ analyze_on_demand_resources_config_plist(plist_hash, kz_pod_target, paths)
367
+ kz_pod_target.add_on_demand_resources(path)
368
+ end
369
+ end
370
+ end
371
+ end
372
+ end
373
+ end
374
+ end
375
+
376
+ if on_demand_resources_all_config.size > 0
377
+ use_for_code_plist_path = @on_demand_resources_folder + "KZOnDemandResourcesAllConfig.plist"
378
+ Xcodeproj::Plist.write_to_path(on_demand_resources_all_config, use_for_code_plist_path)
379
+ end
380
+ end
381
+
382
+ def analyze_on_demand_resources_config_plist(plist_hash, kz_pod_target, all_resources_paths)
383
+ resources_path = @on_demand_resources_folder + "Bundles/#{kz_pod_target.name}"
384
+ FileUtils.mkdir_p(resources_path)
385
+
386
+ # 生成AssetPackOutputSpecifications.plist,用于Images.xcassets编译
387
+ asset_pack_output_specifications_resources = []
388
+
389
+ # 用于生成OnDemandResources.plist文件,放到main bundle中标记按需加载资源
390
+ on_demand_resources_plist = {}
391
+ bundle_resource_request_tags = {}
392
+ on_demand_resources_plist["NSBundleResourceRequestTags"] = bundle_resource_request_tags
393
+ bundle_resource_request_asset_packs = {}
394
+ on_demand_resources_plist["NSBundleResourceRequestAssetPacks"] = bundle_resource_request_asset_packs
395
+
396
+ # 统计所有的xcassets资源
397
+ have_config_xcassets = false
398
+
399
+ # 从配置plist中读取'Initial Install Tags'资源
400
+ initial_plist_hash = plist_hash["Initial Install Tags"]
401
+ on_deman_resources_from_plist(initial_plist_hash, kz_pod_target, 1, all_resources_paths, resources_path) do |tag, bundle_id, bundle_path, normal_file_names, have_xcassets_paths|
402
+ # 如有配置中有.xcassets资源,需要先标记,等待编译时单独再单独编译
403
+ if have_xcassets_paths
404
+ have_config_xcassets = true
405
+
406
+ resource_item = {}
407
+ resource_item["bundle-id"] = bundle_id
408
+ resource_item["bundle-path"] = bundle_path
409
+ resource_item["tags"] = [tag]
410
+ asset_pack_output_specifications_resources << resource_item
411
+ end
412
+
413
+ bundle_resource_request_tags[tag] = { "NSAssetPacks" => [bundle_id] }
414
+ bundle_resource_request_asset_packs[bundle_id] = normal_file_names if normal_file_names.size > 0
415
+ end
416
+
417
+ # Prefetched Tag Order
418
+ prefetched_plist_hash = plist_hash["Prefetched Tag Order"]
419
+ on_deman_resources_from_plist(prefetched_plist_hash, kz_pod_target, 0.5, all_resources_paths, resources_path) do |tag, bundle_id, bunlde_path, normal_file_names, have_xcassets_paths|
420
+ if have_xcassets_paths
421
+ have_config_xcassets = true
422
+
423
+ resource_item = {}
424
+ resource_item["bundle-id"] = bundle_id
425
+ resource_item["bundle-path"] = bunlde_path
426
+ resource_item["tags"] = [tag]
427
+ asset_pack_output_specifications_resources << resource_item
428
+ end
429
+
430
+ bundle_resource_request_tags[tag] = { "NSAssetPacks" => [bundle_id] }
431
+ bundle_resource_request_asset_packs[bundle_id] = normal_file_names if normal_file_names.size > 0
432
+ end
433
+
434
+ # Download Only On Demand
435
+ download_plist_hash = plist_hash["Download Only On Demand"]
436
+ on_deman_resources_from_plist(download_plist_hash, kz_pod_target, 0, all_resources_paths, resources_path) do |tag, bundle_id, bunlde_path, normal_file_names, have_xcassets_paths|
437
+ if have_xcassets_paths
438
+ have_config_xcassets = true
439
+
440
+ resource_item = {}
441
+ resource_item["bundle-id"] = bundle_id
442
+ resource_item["bundle-path"] = bunlde_path
443
+ resource_item["tags"] = [tag]
444
+ asset_pack_output_specifications_resources << resource_item
445
+ end
446
+
447
+ bundle_resource_request_tags[tag] = { "NSAssetPacks" => [bundle_id] }
448
+ bundle_resource_request_asset_packs[bundle_id] = normal_file_names if normal_file_names.size > 0
449
+ end
450
+
451
+ if asset_pack_output_specifications_resources.size > 0
452
+ write_to_path(asset_pack_output_specifications_resources, resources_path + "AssetPackOutputSpecifications.plist")
453
+ end
454
+
455
+ if bundle_resource_request_tags.size > 0 || bundle_resource_request_asset_packs.size > 0
456
+ Xcodeproj::Plist.write_to_path(on_demand_resources_plist, resources_path + "OnDemandResources.plist")
457
+ end
458
+
459
+ # 一个组件可能有多个xcassets,只要其中一个有配置on demand resources,所有xcassets都需要单独编译
460
+ all_xcassets_paths = []
461
+ if have_config_xcassets
462
+ all_resources_paths.each do |path|
463
+ if path.extname == ".xcassets"
464
+ all_xcassets_paths << path
465
+ end
466
+ end
467
+ end
468
+
469
+ target_bundle_info = {}
470
+ target_bundle_info["name"] = kz_pod_target.name
471
+ target_bundle_info["xcassets_paths"] = all_xcassets_paths
472
+ Xcodeproj::Plist.write_to_path(target_bundle_info, resources_path + "TargetBundleInfo.plist")
473
+
474
+ end
475
+
476
+ def on_deman_resources_from_plist(plist_hash, kz_pod_target, priority, all_resources_paths, resources_path)
477
+ return unless (!plist_hash.nil? && plist_hash.size > 0)
478
+
479
+ plist_hash.each do |tag, file_paths|
480
+ normal_file_names = []
481
+ normal_file_paths = []
482
+ have_xcassets_paths = false
483
+ file_paths.each do |rel_file_path|
484
+ file_path = @installation_root + rel_file_path.strip
485
+ next unless file_path.exist?
486
+
487
+ if file_path.extname == ".imageset"
488
+ # imageset文件配置
489
+ xcassets_path = find_xcassets_path(file_path)
490
+ if all_resources_paths.include?(xcassets_path)
491
+ kz_pod_target.add_on_demand_resources(xcassets_path)
492
+ have_xcassets_paths = true
493
+ end
494
+
495
+ content_json_path = file_path + "Contents.json"
496
+ content_json = JSON.parse(File.read(file_path + "Contents.json"))
497
+ content_json["properties"] = { "on-demand-resource-tags" => [tag] }
498
+ content_json_file = File.new(content_json_path, 'w')
499
+ content_json_file.syswrite(JSON.pretty_generate(content_json))
500
+ else
501
+ # 普通文件配置
502
+ if all_resources_paths.include?(file_path)
503
+ kz_pod_target.add_on_demand_resources(file_path)
504
+ normal_file_paths << file_path
505
+ normal_file_names << file_path.basename
506
+ end
507
+ end
508
+ end
509
+
510
+ create_bundle_info_plist(tag, priority, normal_file_paths, resources_path) do |bundle_id, bundle_path|
511
+ yield(tag, bundle_id, bundle_path, normal_file_names, have_xcassets_paths)
512
+ end
513
+ end
514
+ end
515
+
516
+ def find_xcassets_path(path)
517
+ return "" if path.root?
518
+
519
+ if path.extname == ".xcassets"
520
+ path
521
+ else
522
+ find_xcassets_path(path + "..")
523
+ end
524
+ end
525
+
526
+ def create_bundle_info_plist(tag, priority, normal_file_paths, resource_path)
527
+ # project bundle identifier
528
+ project_bundle_identifier = KZGlobalHelper.instance.on_demand_resources_bundle_id
529
+ tag_md5 = md5_sign(tag)
530
+ # bundle folder
531
+ demand_bundle_folder_name = "#{project_bundle_identifier}.#{tag}-#{tag_md5}.assetpack"
532
+ demand_bundle_folder = resource_path + "OnDemandResources/#{demand_bundle_folder_name}"
533
+ # create bundle folder
534
+ FileUtils.mkdir_p(demand_bundle_folder) unless FileTest::exist?(demand_bundle_folder)
535
+ # copy file
536
+ normal_file_paths.each do |file|
537
+ FileUtils.cp(file, demand_bundle_folder)
538
+ end
539
+
540
+ bundle_info_plist = {}
541
+ bundle_info_plist["Priority"] = priority if priority > 0
542
+ bundle_info_plist["Tags"] = [tag]
543
+ demand_bundle_id = "#{project_bundle_identifier}.asset-pack-#{tag_md5}"
544
+ bundle_info_plist["CFBundleIdentifier"] = demand_bundle_id
545
+ Xcodeproj::Plist.write_to_path(bundle_info_plist, demand_bundle_folder + "Info.plist")
546
+
547
+ yield(demand_bundle_id, demand_bundle_folder_name)
548
+ end
549
+
550
+ def md5_sign(key)
551
+ OpenSSL::Digest::MD5.hexdigest(key)
552
+ end
553
+
554
+ # Xcodeproj::Plist.write_to_path只支持hash,如果是数组需要重写write方法
555
+ def write_to_path(hash, path)
556
+ unless path.is_a?(String) || path.is_a?(Pathname)
557
+ raise TypeError, "The given `#{path}` must be a string or 'pathname'."
558
+ end
559
+ path = path.to_s
560
+ raise IOError, 'Empty path.' if path.empty?
561
+
562
+ File.open(path, 'w') do |f|
563
+ plist = Nanaimo::Plist.new(hash, :xml)
564
+ Nanaimo::Writer::XMLWriter.new(plist, :pretty => true, :output => f, :strict => false).write
565
+ end
566
+ end
567
+
242
568
  end
243
569
  end