11#if UNITY_IOS
2- using System ;
32using System . Collections ;
43using System . Collections . Generic ;
54using System . IO ;
65using System . Text ;
7- using System . Text . RegularExpressions ;
86using UnityEditor . iOS . Xcode ;
97
108namespace GameFrameX . Xcode . Editor
@@ -84,17 +82,17 @@ private static void RunLocalization(PBXProject project, string projectGuid, stri
8482 }
8583 }
8684
87- // 更新 Info.plist,将本地化键的值设置为 $( KEY) 格式
85+ // 更新 Info.plist,将本地化键的值设置为 ${ KEY} 格式
8886 UpdateInfoPlistForLocalization ( path , localizationKeys ) ;
8987
90- // 使用 PBXProjectExtensions 添加本地化支持
91- AddLocalizationToProject ( path , localizations ) ;
88+ // 使用 PBXProject API 添加本地化文件到项目
89+ AddLocalizationToProject ( project , path , localizations ) ;
9290
9391 LogHelper . Log ( "Setting project [Localization] finished" ) ;
9492 }
9593
9694 /// <summary>
97- /// 更新 Info.plist,将本地化键的值设置为 $( KEY) 格式
95+ /// 更新 Info.plist,将本地化键的值设置为 ${ KEY} 格式
9896 /// 这样 iOS 系统会自动从 InfoPlist.strings 中读取对应语言的值
9997 /// </summary>
10098 /// <param name="projectPath">Xcode 项目路径</param>
@@ -133,20 +131,17 @@ private static void UpdateInfoPlistForLocalization(string projectPath, HashSet<s
133131
134132 /// <summary>
135133 /// 添加本地化资源到 Xcode 项目
136- /// 这个方法直接操作 project.pbxproj 文件来添加 VariantGroup
134+ /// 使用 PBXProject API 安全地添加本地化文件引用
137135 /// </summary>
138- private static void AddLocalizationToProject ( string projectPath , ArrayList localizations )
136+ /// <param name="project">PBXProject 实例</param>
137+ /// <param name="projectPath">Xcode 项目路径</param>
138+ /// <param name="localizations">本地化配置列表</param>
139+ private static void AddLocalizationToProject ( PBXProject project , string projectPath , ArrayList localizations )
139140 {
140141 string pbxprojPath = Path . Combine ( projectPath , "Unity-iPhone.xcodeproj/project.pbxproj" ) ;
141- string pbxContent = File . ReadAllText ( pbxprojPath ) ;
142142
143- // 生成唯一的 GUID
144- string variantGroupGuid = GenerateGuid ( ) ;
145- string variantGroupName = "InfoPlist.strings" ;
146-
147- StringBuilder childrenBuilder = new StringBuilder ( ) ;
148- StringBuilder fileRefsBuilder = new StringBuilder ( ) ;
149- StringBuilder buildFileBuilder = new StringBuilder ( ) ;
143+ // 获取主 target 的 GUID
144+ string mainTargetGuid = project . GetUnityMainTargetGuid ( ) ;
150145
151146 foreach ( Hashtable loc in localizations )
152147 {
@@ -161,140 +156,29 @@ private static void AddLocalizationToProject(string projectPath, ArrayList local
161156 continue ;
162157 }
163158
164- string fileRefGuid = GenerateGuid ( ) ;
165159 string lprojName = langCode + ".lproj" ;
166- string relativePath = $ "{ lprojName } /InfoPlist.strings";
167-
168- // 添加到 children 列表
169- childrenBuilder . AppendLine ( $ "\t \t \t \t { fileRefGuid } /* { langCode } */,") ;
170-
171- // 添加 PBXFileReference
172- fileRefsBuilder . AppendLine ( $ "\t \t { fileRefGuid } /* { langCode } */ = {{isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = { langCode } ; path = { relativePath } ; sourceTree = \" <group>\" ; }};") ;
173- }
174-
175- // 创建 PBXVariantGroup
176- string variantGroupSection = $@ "
177- /* Begin PBXVariantGroup section */
178- { variantGroupGuid } /* { variantGroupName } */ = {{
179- isa = PBXVariantGroup;
180- children = (
181- { childrenBuilder . ToString ( ) . TrimEnd ( ) }
182- );
183- name = { variantGroupName } ;
184- sourceTree = ""<group>"";
185- }};
186- /* End PBXVariantGroup section */" ;
187-
188- // 检查是否已经有 PBXVariantGroup section
189- if ( pbxContent . Contains ( "/* Begin PBXVariantGroup section */" ) )
190- {
191- // 在现有的 section 中添加
192- pbxContent = pbxContent . Replace (
193- "/* End PBXVariantGroup section */" ,
194- $@ " { variantGroupGuid } /* { variantGroupName } */ = {{
195- isa = PBXVariantGroup;
196- children = (
197- { childrenBuilder . ToString ( ) . TrimEnd ( ) }
198- );
199- name = { variantGroupName } ;
200- sourceTree = ""<group>"";
201- }};
202- /* End PBXVariantGroup section */" ) ;
203- }
204- else
205- {
206- // 在 PBXSourcesBuildPhase section 之前插入新的 section
207- pbxContent = pbxContent . Replace (
208- "/* Begin PBXSourcesBuildPhase section */" ,
209- variantGroupSection + "\n /* Begin PBXSourcesBuildPhase section */" ) ;
210- }
211-
212- // 添加 PBXFileReference 条目
213- string fileRefInsert = fileRefsBuilder . ToString ( ) ;
214- pbxContent = pbxContent . Replace (
215- "/* End PBXFileReference section */" ,
216- fileRefInsert + "/* End PBXFileReference section */" ) ;
217-
218- // 将 VariantGroup 添加到主 Group 的 children 中
219- // 查找 CustomTemplate 或 Unity-iPhone 组并添加引用
220- string mainGroupPattern = @"(mainGroup = )([A-F0-9]+)" ;
221- Match mainGroupMatch = Regex . Match ( pbxContent , mainGroupPattern ) ;
222- if ( mainGroupMatch . Success )
223- {
224- string mainGroupGuid = mainGroupMatch . Groups [ 2 ] . Value ;
225- // 找到这个 group 并添加 variant group 到 children
226- string groupPattern = $@ "({ mainGroupGuid } \/\* .* \*\/ = \{{\s*isa = PBXGroup;\s*children = \()";
227- pbxContent = Regex . Replace ( pbxContent , groupPattern ,
228- $ "$1\n \t \t \t \t { variantGroupGuid } /* { variantGroupName } */,") ;
229- }
230-
231- // 添加到 Resources build phase
232- string targetGuid = GetUnityMainTargetGuidFromContent ( pbxContent ) ;
233- if ( ! string . IsNullOrEmpty ( targetGuid ) )
234- {
235- string buildFileGuid = GenerateGuid ( ) ;
236-
237- // 添加 PBXBuildFile
238- string buildFileEntry = $ "\t \t { buildFileGuid } /* { variantGroupName } in Resources */ = {{isa = PBXBuildFile; fileRef = { variantGroupGuid } /* { variantGroupName } */; }};\n ";
239- pbxContent = pbxContent . Replace (
240- "/* End PBXBuildFile section */" ,
241- buildFileEntry + "/* End PBXBuildFile section */" ) ;
242-
243- // 添加到 Resources build phase
244- string resourcesPhasePattern = @"(isa = PBXResourcesBuildPhase;[^}]*files = \()" ;
245- pbxContent = Regex . Replace ( pbxContent , resourcesPhasePattern ,
246- $ "$1\n \t \t \t \t { buildFileGuid } /* { variantGroupName } in Resources */,") ;
247- }
160+ string infoPlistStringsPath = Path . Combine ( lprojName , "InfoPlist.strings" ) ;
161+ string fullPath = Path . Combine ( projectPath , infoPlistStringsPath ) ;
248162
249- // 添加 knownRegions
250- foreach ( Hashtable loc in localizations )
251- {
252- if ( ! loc . ContainsKey ( "languageCode" ) )
163+ // 检查文件是否存在
164+ if ( ! File . Exists ( fullPath ) )
253165 {
166+ LogHelper . Log ( $ "InfoPlist.strings not found at: { fullPath } ") ;
254167 continue ;
255168 }
256169
257- string langCode = loc [ "languageCode" ] . ToString ( ) ;
258- if ( string . IsNullOrEmpty ( langCode ) )
259- {
260- continue ;
261- }
262-
263- // 检查是否已有这个区域
264- if ( ! pbxContent . Contains ( $ "\" { langCode } \" ") && ! pbxContent . Contains ( $ "{ langCode } ,") )
265- {
266- string knownRegionsPattern = @"(knownRegions = \()" ;
267- pbxContent = Regex . Replace ( pbxContent , knownRegionsPattern ,
268- $ "$1\n \t \t \t \t { langCode } ,") ;
269- }
270- }
271-
272- File . WriteAllText ( pbxprojPath , pbxContent ) ;
273- LogHelper . Log ( "Added localization variant groups to project.pbxproj" ) ;
274- }
170+ // 使用 PBXProject API 添加文件到项目
171+ string fileGuid = project . AddFile ( infoPlistStringsPath , infoPlistStringsPath , PBXSourceTree . Source ) ;
275172
276- /// <summary>
277- /// 生成一个 Xcode 风格的 24 位十六进制 GUID
278- /// </summary>
279- private static string GenerateGuid ( )
280- {
281- return Guid . NewGuid ( ) . ToString ( "N" ) . Substring ( 0 , 24 ) . ToUpper ( ) ;
282- }
173+ // 将文件添加到主 target 的 Resources 构建阶段
174+ project . AddFileToBuild ( mainTargetGuid , fileGuid ) ;
283175
284- /// <summary>
285- /// 从 pbxproj 内容中获取 Unity-iPhone target 的 GUID
286- /// </summary>
287- private static string GetUnityMainTargetGuidFromContent ( string content )
288- {
289- // 查找 Unity-iPhone target
290- string pattern = @"([A-F0-9]+) \/\* Unity-iPhone \*\/ = \{\s*isa = PBXNativeTarget" ;
291- Match match = Regex . Match ( content , pattern ) ;
292- if ( match . Success )
293- {
294- return match . Groups [ 1 ] . Value ;
176+ LogHelper . Log ( $ "Added localization file to project: { infoPlistStringsPath } ") ;
295177 }
296178
297- return null ;
179+ // 保存项目文件
180+ project . WriteToFile ( pbxprojPath ) ;
181+ LogHelper . Log ( "Localization files added to Xcode project" ) ;
298182 }
299183 }
300184}
0 commit comments