pindo 5.8.2 → 5.9.0

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: 3e2206bcec0036a22ba789cc964911c5fcf167832095f8ddfd60c0c44f146d2f
4
- data.tar.gz: 02771de2bf5981c1e61c7f9f1d04f0cbb0a0ba04b468bf8d753b99893635be04
3
+ metadata.gz: e26747a73dfa47b5379d698b521f08edfe4daa0fb72d1b298eeacb45db40d0c5
4
+ data.tar.gz: 6c1cdd4dd46bdca0107da545916c1f8caf7300eba9883010e383d7897d5472ed
5
5
  SHA512:
6
- metadata.gz: b55fc4b766fcf131a3f84e79f041c95d8571eaeb6d8a7605d3a42d9d55e99728e14bfb0056885fb06f8c0f2d3d0e439e844aef0714c419595b71ab5884c30db4
7
- data.tar.gz: f3d928279be2eae39ed8600b24c7371644c51267834617351c9c73a6365a869b23a9b7e51a17df6b90094e5c8fea987ff713746ca8139df4ab8dc3749c8f2af9
6
+ metadata.gz: 2bfa1a08f4bfca1704f240d4ee4517e1a45684dc38c84b91262f87203cf0768445834b75f2c951950782a93a66beb7e616e5c38329f8c38795d92e4b4c93e1d4
7
+ data.tar.gz: 395233f028b3df2350a442ab8ddebbe8514ced5f56f7d14229a6dd09b044dbffc4900848a43fe9b0e3ce8a66f63248e9e9635fe0b8cde32275e799070b644e62
@@ -160,14 +160,16 @@ module Pindo
160
160
  # ===== 使用 workflow 配置更新项目 =====
161
161
  if workflow_info && workflow_info[:package_name]
162
162
  package_name = workflow_info[:package_name]
163
+ project_id = app_info_obj ? app_info_obj["id"] : nil
163
164
 
164
165
  puts "\n使用工作流配置更新 iOS 项目:"
165
166
  puts " Package Name: #{package_name}"
166
167
 
167
- # 一次性更新 Display Name、Bundle ID 和 URL Schemes
168
+ # 一次性更新 Display Name、Bundle ID、URL Schemes JPS 快捷操作
168
169
  Pindo::XcodeBuildConfig.update_project_with_packagename(
169
170
  project_dir: pindo_project_dir,
170
- package_name: package_name
171
+ package_name: package_name,
172
+ project_id: project_id
171
173
  )
172
174
  else
173
175
  raise Informative, "未获取到工作流信息"
@@ -124,14 +124,16 @@ module Pindo
124
124
  # ===== 使用 workflow 配置更新项目 =====
125
125
  if workflow_info && workflow_info[:package_name]
126
126
  package_name = workflow_info[:package_name]
127
+ project_id = app_info_obj ? app_info_obj["id"] : nil
127
128
 
128
129
  puts "\n使用工作流配置更新 iOS 项目:"
129
130
  puts " Package Name: #{package_name}"
130
131
 
131
- # 一次性更新 Display Name、Bundle ID 和 URL Schemes
132
+ # 一次性更新 Display Name、Bundle ID、URL Schemes JPS 快捷操作
132
133
  Pindo::XcodeBuildConfig.update_project_with_packagename(
133
134
  project_dir: pindo_project_dir,
134
- package_name: package_name
135
+ package_name: package_name,
136
+ project_id: project_id
135
137
  )
136
138
  else
137
139
  raise Informative, "未获取到工作流信息"
@@ -3,7 +3,6 @@
3
3
  require 'highline/import'
4
4
  require 'fileutils'
5
5
  require 'json'
6
- require "pindo/base/xcodeconst"
7
6
  require 'pindo/module/xcode/xcodereshelper'
8
7
 
9
8
  module Pindo
@@ -206,7 +206,7 @@ module Pindo
206
206
 
207
207
  project_obj.targets.each do |target|
208
208
 
209
- if target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:framework]) || target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:dynamic_library]) ||
209
+ if target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:framework]) || target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:dynamic_library]) ||
210
210
  target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:static_library]) || target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:bundle])
211
211
  next
212
212
  end
@@ -236,7 +236,19 @@ module Pindo
236
236
  if !temp_info.nil? && !temp_info.empty?
237
237
  info_plist_path = File.join(new_project_dir, temp_info)
238
238
  if !File.exist?(info_plist_path)
239
- raise Informative, "Missing Target #{target.name.to_s} Info.plist!!! #{info_plist_path} Modify Info.plist Error !!!"
239
+ raise Informative, "Missing Target #{target.name.to_s} Info.plist!!! #{info_plist_path} Modify Info.plist Error !!!"
240
+ end
241
+
242
+ # 修改 Info.plist 中的 CFBundleIdentifier 使用宏变量
243
+ # 由于 PRODUCT_BUNDLE_IDENTIFIER 已在 config_project_cert 中设置
244
+ # Info.plist 应该引用宏变量而非硬编码
245
+ info_plist_dict = Xcodeproj::Plist.read_from_path(info_plist_path)
246
+ current_bundle_id = info_plist_dict["CFBundleIdentifier"]
247
+
248
+ # 如果不是宏变量,则设置为使用 PRODUCT_BUNDLE_IDENTIFIER 宏
249
+ if current_bundle_id != "$(PRODUCT_BUNDLE_IDENTIFIER)"
250
+ info_plist_dict["CFBundleIdentifier"] = "$(PRODUCT_BUNDLE_IDENTIFIER)"
251
+ Xcodeproj::Plist.write_to_path(info_plist_dict, info_plist_path)
240
252
  end
241
253
 
242
254
  if target.product_type.to_s.eql?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) then
@@ -12,8 +12,9 @@ module Pindo
12
12
  # 优化版本:只读写一次plist文件,提高性能
13
13
  # @param project_dir [String] iOS项目目录路径
14
14
  # @param package_name [String] 工作流的package_name(如:"Test Demo")
15
+ # @param project_id [String] JPS项目ID(可选,用于添加快捷操作)
15
16
  # @return [Boolean] 是否成功更新
16
- def self.update_project_with_packagename(project_dir: nil, package_name: nil)
17
+ def self.update_project_with_packagename(project_dir: nil, package_name: nil, project_id: nil)
17
18
  raise ArgumentError, "项目目录不能为空" if project_dir.nil?
18
19
  raise ArgumentError, "Package Name不能为空" if package_name.nil?
19
20
 
@@ -66,10 +67,36 @@ module Pindo
66
67
  puts " ✓ 已添加URL Scheme: #{bundle_scheme} (基于 Bundle ID)"
67
68
  end
68
69
 
70
+ # 4. 添加 JPS 快捷操作(UIApplicationShortcutItems)
71
+ if project_id && !project_id.to_s.empty?
72
+ # 创建或获取 UIApplicationShortcutItems 数组
73
+ info_plist_dict["UIApplicationShortcutItems"] ||= []
74
+
75
+ # 构建快捷操作类型
76
+ shortcut_type = "jps_project?#{project_id}"
77
+
78
+ # 检查是否已存在相同的快捷操作
79
+ existing_shortcut = info_plist_dict["UIApplicationShortcutItems"].find do |item|
80
+ item["UIApplicationShortcutItemType"] == shortcut_type
81
+ end
82
+
83
+ unless existing_shortcut
84
+ jps_shortcut = {
85
+ "UIApplicationShortcutItemType" => shortcut_type,
86
+ "UIApplicationShortcutItemTitle" => "访问 JPS 详情",
87
+ "UIApplicationShortcutItemIconType" => "UIApplicationShortcutIconTypeBookmark"
88
+ }
89
+ info_plist_dict["UIApplicationShortcutItems"] << jps_shortcut
90
+ puts " ✓ 已添加 JPS 快捷操作: #{shortcut_type}"
91
+ else
92
+ puts " ✓ JPS 快捷操作已存在: #{shortcut_type}"
93
+ end
94
+ end
95
+
69
96
  # 一次性写入plist
70
97
  Xcodeproj::Plist.write_to_path(info_plist_dict, info_plist_path)
71
98
 
72
- # 4. 更新 Xcode 项目中的 PRODUCT_BUNDLE_IDENTIFIER
99
+ # 5. 更新 Xcode 项目中的 PRODUCT_BUNDLE_IDENTIFIER
73
100
  if app_target
74
101
  app_target.build_configurations.each do |config|
75
102
  config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = final_bundle_id
@@ -380,7 +407,7 @@ module Pindo
380
407
  replace_success = false
381
408
  ensure
382
409
  # 清理临时文件(无论成功失败都清理)
383
- FileUtils.rm_rf(temp_icon_dir) if temp_icon_dir && File.exist?(temp_icon_dir)
410
+ # FileUtils.rm_rf(temp_icon_dir) if temp_icon_dir && File.exist?(temp_icon_dir)
384
411
  end
385
412
 
386
413
  return replace_success
@@ -1,7 +1,6 @@
1
1
  require 'fileutils'
2
2
  require 'xcodeproj'
3
3
  require 'json'
4
- require 'pindo/module/xcode/xcoderesconstant'
5
4
 
6
5
  module Pindo
7
6
 
@@ -62,11 +61,30 @@ module Pindo
62
61
 
63
62
  def validate_icon_res()
64
63
  icon_path = get_xcodeproj_icon_path()
65
- xcode_ios_icon_json = XcodoeResConst.xcode_ios_icon_json
66
- xcode_ios_icon_json["images"].each do |image_data|
67
- image_name = image_data["filename"]
68
- if !File.exist?(File.join(icon_path, image_name))
69
- raise Informative, "Xcode生成icon 有缺失文件:#{File.join(icon_path, image_name)}"
64
+ contents_json_path = File.join(icon_path, "Contents.json")
65
+
66
+ # 检查 Contents.json 是否存在
67
+ if !File.exist?(contents_json_path)
68
+ raise Informative, "Contents.json 文件不存在: #{contents_json_path}"
69
+ end
70
+
71
+ # 读取实际的 Contents.json 文件
72
+ begin
73
+ actual_json = JSON.parse(File.read(contents_json_path))
74
+ rescue JSON::ParserError => e
75
+ raise Informative, "Contents.json 文件格式错误: #{e.message}"
76
+ end
77
+
78
+ # 基于实际的 Contents.json 验证对应的图标文件
79
+ if actual_json["images"] && actual_json["images"].is_a?(Array)
80
+ actual_json["images"].each do |image_data|
81
+ # 只验证有 filename 字段的条目
82
+ if image_data["filename"] && !image_data["filename"].empty?
83
+ image_file_path = File.join(icon_path, image_data["filename"])
84
+ if !File.exist?(image_file_path)
85
+ raise Informative, "Xcode icon 缺失文件: #{image_file_path}"
86
+ end
87
+ end
70
88
  end
71
89
  end
72
90
  end
@@ -120,11 +138,30 @@ module Pindo
120
138
 
121
139
  def validate_imessage_icon_res()
122
140
  icon_path = get_xcodeproj_imessage_icon_path
123
- xcode_ios_icon_json = XcodoeResConst.xcode_ios_imessage_icon_json
124
- xcode_ios_icon_json["images"].each do |image_data|
125
- image_name = image_data["filename"]
126
- if !File.exist?(File.join(icon_path, image_name))
127
- raise Informative, "Xcode生成icon 有缺失文件:#{File.join(icon_path, image_name)}"
141
+ contents_json_path = File.join(icon_path, "Contents.json")
142
+
143
+ # 检查 Contents.json 是否存在
144
+ if !File.exist?(contents_json_path)
145
+ raise Informative, "iMessage Contents.json 文件不存在: #{contents_json_path}"
146
+ end
147
+
148
+ # 读取实际的 Contents.json 文件
149
+ begin
150
+ actual_json = JSON.parse(File.read(contents_json_path))
151
+ rescue JSON::ParserError => e
152
+ raise Informative, "iMessage Contents.json 文件格式错误: #{e.message}"
153
+ end
154
+
155
+ # 基于实际的 Contents.json 验证对应的图标文件
156
+ if actual_json["images"] && actual_json["images"].is_a?(Array)
157
+ actual_json["images"].each do |image_data|
158
+ # 只验证有 filename 字段的条目
159
+ if image_data["filename"] && !image_data["filename"].empty?
160
+ image_file_path = File.join(icon_path, image_data["filename"])
161
+ if !File.exist?(image_file_path)
162
+ raise Informative, "iMessage icon 缺失文件: #{image_file_path}"
163
+ end
164
+ end
128
165
  end
129
166
  end
130
167
  end
@@ -2,6 +2,7 @@ require 'fileutils'
2
2
  require 'xcodeproj'
3
3
  require 'json'
4
4
  require 'pindo/module/xcode/xcodereshandler'
5
+ require 'pindo/module/xcode/xcoderesconstant'
5
6
 
6
7
  module Pindo
7
8
 
@@ -76,7 +77,7 @@ module Pindo
76
77
 
77
78
  def self.create_icons(icon_name:nil, new_icon_dir:nil)
78
79
  begin
79
- FileUtils.mkdir_p(new_icon_dir)
80
+ FileUtils.mkdir_p(new_icon_dir)
80
81
  rescue => e
81
82
  puts e
82
83
  end
data/lib/pindo/version.rb CHANGED
@@ -6,7 +6,7 @@ require 'time'
6
6
 
7
7
  module Pindo
8
8
 
9
- VERSION = "5.8.2"
9
+ VERSION = "5.9.0"
10
10
 
11
11
  class VersionCheck
12
12
  RUBYGEMS_API = 'https://rubygems.org/api/v1/gems/pindo.json'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pindo
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.8.2
4
+ version: 5.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - wade
@@ -303,7 +303,6 @@ files:
303
303
  - lib/pindo/base/plaininformative.rb
304
304
  - lib/pindo/base/plistbuddyexecutable.rb
305
305
  - lib/pindo/base/standarderror.rb
306
- - lib/pindo/base/xcodeconst.rb
307
306
  - lib/pindo/client/applovinclient.rb
308
307
  - lib/pindo/client/aws3sclient.rb
309
308
  - lib/pindo/client/bossclient.rb
@@ -1,251 +0,0 @@
1
- require 'openssl'
2
-
3
- module Pindo
4
-
5
-
6
- module XcodoeConst
7
-
8
- def self.xcode_ios_icon_json
9
- model_data = {
10
- "images" => [
11
- {
12
- "size" => "20x20",
13
- "idiom" => "iphone",
14
- "filename" => "icon20@2x.png",
15
- "scale" => "2x"
16
- },
17
- {
18
- "size" => "20x20",
19
- "idiom" => "iphone",
20
- "filename" => "icon20@3x.png",
21
- "scale" => "3x"
22
- },
23
- {
24
- "size" => "29x29",
25
- "idiom" => "iphone",
26
- "filename" => "icon29@2x.png",
27
- "scale" => "2x"
28
- },
29
- {
30
- "size" => "29x29",
31
- "idiom" => "iphone",
32
- "filename" => "icon29@3x.png",
33
- "scale" => "3x"
34
- },
35
- {
36
- "size" => "40x40",
37
- "idiom" => "iphone",
38
- "filename" => "icon40@2x.png",
39
- "scale" => "2x"
40
- },
41
- {
42
- "size" => "40x40",
43
- "idiom" => "iphone",
44
- "filename" => "icon40@3x.png",
45
- "scale" => "3x"
46
- },
47
- {
48
- "size" => "60x60",
49
- "idiom" => "iphone",
50
- "filename" => "icon60@2x.png",
51
- "scale" => "2x"
52
- },
53
- {
54
- "size" => "60x60",
55
- "idiom" => "iphone",
56
- "filename" => "icon60@3x.png",
57
- "scale" => "3x"
58
- },
59
- {
60
- "size" => "20x20",
61
- "idiom" => "ipad",
62
- "filename" => "icon20@1x.png",
63
- "scale" => "1x"
64
- },
65
- {
66
- "size" => "20x20",
67
- "idiom" => "ipad",
68
- "filename" => "icon20@2x.png",
69
- "scale" => "2x"
70
- },
71
- {
72
- "size" => "29x29",
73
- "idiom" => "ipad",
74
- "filename" => "icon29@1x.png",
75
- "scale" => "1x"
76
- },
77
- {
78
- "size" => "29x29",
79
- "idiom" => "ipad",
80
- "filename" => "icon29@2x.png",
81
- "scale" => "2x"
82
- },
83
- {
84
- "size" => "40x40",
85
- "idiom" => "ipad",
86
- "filename" => "icon40@1x.png",
87
- "scale" => "1x"
88
- },
89
- {
90
- "size" => "40x40",
91
- "idiom" => "ipad",
92
- "filename" => "icon40@2x.png",
93
- "scale" => "2x"
94
- },
95
- {
96
- "size" => "76x76",
97
- "idiom" => "ipad",
98
- "filename" => "icon76@1x.png",
99
- "scale" => "1x"
100
- },
101
- {
102
- "size" => "76x76",
103
- "idiom" => "ipad",
104
- "filename" => "icon76@2x.png",
105
- "scale" => "2x"
106
- },
107
- {
108
- "size" => "83.5x83.5",
109
- "idiom" => "ipad",
110
- "filename" => "icon83_5@2x.png",
111
- "scale" => "2x"
112
- },
113
- {
114
- "size" => "1024x1024",
115
- "idiom" => "ios-marketing",
116
- "filename" => "icon1024@1x.png",
117
- "scale" => "1x"
118
- }
119
- ],
120
- "info" => {
121
- "version" => 1,
122
- "author" => "xcode"
123
- }
124
- }
125
- return model_data
126
- end
127
-
128
- def self.xcode_ios_imessage_icon_json
129
- model_data = {
130
- "images" => [
131
- {
132
- "size" => "29x29",
133
- "idiom" => "iphone",
134
- "filename" => "icon29@2x.png",
135
- "scale" => "2x"
136
- },
137
- {
138
- "size" => "29x29",
139
- "idiom" => "iphone",
140
- "filename" => "icon29@3x.png",
141
- "scale" => "3x"
142
- },
143
- {
144
- "size" => "60x45",
145
- "idiom" => "iphone",
146
- "filename" => "icon60_45@2x.png",
147
- "scale" => "2x"
148
- },
149
- {
150
- "size" => "60x45",
151
- "idiom" => "iphone",
152
- "filename" => "icon60_45@3x.png",
153
- "scale" => "3x"
154
- },
155
- {
156
- "size" => "29x29",
157
- "idiom" => "ipad",
158
- "filename" => "icon29@2x.png",
159
- "scale" => "2x"
160
- },
161
- {
162
- "size" => "67x50",
163
- "idiom" => "ipad",
164
- "filename" => "icon67_50@2x.png",
165
- "scale" => "2x"
166
- },
167
- {
168
- "size" => "74x55",
169
- "idiom" => "ipad",
170
- "filename" => "icon74_55@2x.png",
171
- "scale" => "2x"
172
- },
173
- {
174
- "size" => "1024x1024",
175
- "idiom" => "ios-marketing",
176
- "filename" => "icon1024@1x.png",
177
- "scale" => "1x"
178
- },
179
- {
180
- "size" => "27x20",
181
- "idiom" => "universal",
182
- "filename" => "icon27_20@2x.png",
183
- "scale" => "2x",
184
- "platform" => "ios"
185
- },
186
- {
187
- "size" => "27x20",
188
- "idiom" => "universal",
189
- "filename" => "icon27_20@3x.png",
190
- "scale" => "3x",
191
- "platform" => "ios"
192
- },
193
- {
194
- "size" => "32x24",
195
- "idiom" => "universal",
196
- "filename" => "icon32_24@2x.png",
197
- "scale" => "2x",
198
- "platform" => "ios"
199
- },
200
- {
201
- "size" => "32x24",
202
- "idiom" => "universal",
203
- "filename" => "icon32_24@3x.png",
204
- "scale" => "3x",
205
- "platform" => "ios"
206
- },
207
- {
208
- "size" => "1024x768",
209
- "idiom" => "ios-marketing",
210
- "filename" => "icon1024_768@1x.png",
211
- "scale" => "1x",
212
- "platform" => "ios"
213
- }
214
- ],
215
- "info" => {
216
- "version" => 1,
217
- "author" => "xcode"
218
- }
219
- }
220
- return model_data
221
- end
222
-
223
-
224
-
225
- XCODE_IOS_LAUNCHIMG_JSON = {
226
- "images" => [
227
- {
228
- "idiom" => "universal",
229
- "scale" => "1x"
230
- },
231
- {
232
- "idiom" => "universal",
233
- "filename" => "w768_h1024@2x.png",
234
- "scale" => "2x"
235
- },
236
- {
237
- "idiom" => "universal",
238
- "scale" => "3x"
239
- }
240
- ],
241
- "info" => {
242
- "version" => 1,
243
- "author" => "xcode"
244
- }
245
- }
246
-
247
-
248
- end
249
-
250
-
251
- end