Repository navigation
Expand file tree
/
Copy pathindex.js
More file actions
545 lines (540 loc) · 132 KB
/
Copy pathindex.js
File metadata and controls
545 lines (540 loc) · 132 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
// /xcode/en/ and /xcode/zh/ force a language (<html lang>); /xcode/ follows the browser language
const ROOT=new URL('.',document.currentScript.src).href;
const autoLang=document.documentElement.hasAttribute('data-auto-lang');
let mode=(autoLang?(navigator.languages?.[0]||navigator.language||''):document.documentElement.lang).toLowerCase().startsWith('zh')?'zh':'en';
let heroShader;
let respondentWallObserver;
let lifecycleDetailCleanup;
const bi=(zh,en)=>({zh,en});
const text=v=>mode==='en'?v.en:v.zh;
const insightPrefix=()=>`<b class="insight-prefix">${text(bi('洞察:','Insight:'))}</b>`;
const labelTranslations={
'中国大陆':'Mainland China','大中华区(含港澳台)':'Greater China (incl. Hong Kong, Macao & Taiwan)','欧洲':'Europe','日本':'Japan','美国':'United States','东南亚':'Southeast Asia','韩国':'South Korea','中国香港 / 澳门 / 台湾':'Hong Kong, Macao & Taiwan','印度及南亚':'India & South Asia','加拿大':'Canada','澳大利亚 / 新西兰':'Australia & New Zealand',
'不满 1 年':'Under 1 year','1–3 年':'1–3 years','4–6 年':'4–6 years','7–10 年':'7–10 years','10–15 年':'10–15 years','15 年以上':'15+ years',
'独立开发者 / Solo Developer':'Independent / solo developer','小型科技 / 初创公司开发者':'Small technology / startup company developer','大型科技 / 互联网公司开发者':'Large technology / internet company developer','中型软件 / 互联网公司开发者':'Medium software / internet company developer','教师 / 研究人员':'Educator / researcher','目前不以开发为主要职业,但持续进行软件开发':'Develops software outside a primary development role','外包 / 咨询 / Agency 开发者':'Outsourcing / consulting / agency developer','非科技行业的大型企业开发者':'Large non-technology enterprise developer','学生':'Student',
'个人项目 / Solo Project':'Solo project','小型团队(约 2–5 人)':'Small team (about 2–5 people)','中型团队(约 6–100 人)':'Medium team (about 6–100 people)','大型团队(100+ 人、多团队协作或大型代码库)':'Large team (100+ people, multiple teams, or a large codebase)',
'大部分代码在 Xcode 外,Xcode 主做工具链':'Most code outside Xcode; Xcode mainly handles the toolchain','主要在其他编辑器 / AI 工具中写代码':'Mostly code in other editors / AI tools',
'主要或几乎全在 Xcode 中写代码':'Mostly or almost entirely code in Xcode','Xcode 与其他工具各占一半':'Xcode and other tools split evenly',
'每天高频,已成核心方式':'High-frequency daily use; a core practice','几乎每天':'Almost daily','每周几次或更少':'A few times weekly or less',
'编写新代码':'Writing new code','技术方案 / 架构设计':'Technical planning / architecture','理解需求 / 分析问题':'Understanding requirements / analyzing problems',
'修改现有代码':'Modifying existing code','重构代码':'Refactoring','Debug / 运行时定位':'Debugging / runtime diagnosis','Xcode 内置 AI':'Built-in Xcode AI',
'代码生成质量':'Code-generation quality','复杂问题推理':'Reasoning on complex problems','项目架构与上下文理解':'Project architecture and context understanding',
'代码库理解':'Codebase understanding','Agent 自主完成任务':'Agent autonomy for completing tasks','代码编辑':'Code editing',
'公司内部 / 自部署模型':'Company-internal / self-hosted model','中国公司开发的通用对话产品':'General chat products developed by Chinese companies','独立桌面 Agent 应用':'Standalone desktop agent app',
'IDE / 编辑器中的 Agent':'Agent in an IDE / editor','网页交互式 Agent':'Web-based interactive agent','DeepSeek(近 30 天仍在使用)':'DeepSeek (used in the past 30 days)',
'GLM(近 30 天仍在使用)':'GLM (used in the past 30 days)','Kimi(近 30 天仍在使用)':'Kimi (used in the past 30 days)','豆包 / Seed(近 30 天仍在使用)':'Doubao / Seed (used in the past 30 days)'
};
const heroIntro=bi('SwiftGG 邀请了全球 100 位资深 Apple 生态开发者,了解他们如何使用 Xcode、如何在应用开发中使用 AI,以及他们对新时代下软件开发工具与工作流的期待。','SwiftGG invited 100 experienced Apple ecosystem developers to understand how they use Xcode, how they use AI in app development, and what they expect from software development tools and workflows in the new era.');
const profile={
region:[['大中华区(含港澳台)',60],['欧洲',14],['日本',11],['美国',7],['东南亚',3],['韩国',2],['印度及南亚',1],['加拿大',1],['澳大利亚 / 新西兰',1]],
softwareExperience:[['15 年以上',21],['10–15 年',30],['7–10 年',26],['4–6 年',18],['1–3 年',5],['不满 1 年',0]],
appleExperience:[['15 年以上',6],['10–15 年',29],['7–10 年',26],['4–6 年',20],['1–3 年',17],['不满 1 年',2]],
roles:[['独立开发者 / Solo Developer',52],['小型科技 / 初创公司开发者',31],['大型科技 / 互联网公司开发者',21],['中型软件 / 互联网公司开发者',9],['教师 / 研究人员',8],['目前不以开发为主要职业,但持续进行软件开发',7],['外包 / 咨询 / Agency 开发者',4],['非科技行业的大型企业开发者',2],['学生',1]],
scale:[['个人项目 / Solo Project',35],['小型团队(约 2–5 人)',42],['中型团队(约 6–100 人)',10],['大型团队(100+ 人、多团队协作或大型代码库)',13]]
};
const part2={
stages:[
{label:bi('产品设计','Product design'),value:84,expandable:false,items:[[bi('理解需求 / 分析问题','Understanding requirements / analyzing problems'),84]]},
{label:bi('界面设计','Interface design'),value:5,expandable:false,items:[[bi('设计补充(5 条“其他”回答)','Design additions (5 “Other” responses)'),5]]},
{label:bi('技术设计','Technical design'),value:86,items:[[bi('技术方案 / 架构设计','Technical planning / architecture'),86],[bi('学习陌生技术或 API','Learning unfamiliar technology or APIs'),77],[bi('编写文档 / 注释','Writing documentation / comments'),67],[bi('查找文档 / 示例代码','Finding documentation / sample code'),64]]},
{label:bi('开发实现','Development implementation'),value:93,items:[[bi('编写新代码','Writing new code'),93],[bi('修改现有代码','Modifying existing code'),83],[bi('重构代码','Refactoring'),80],[bi('Code Review','Code review'),71],[bi('性能分析 / 优化','Performance analysis / optimization'),69],[bi('多文件 / 跨模块修改','Multi-file / cross-module modification'),67],[bi('代码补全','Code completion'),38]]},
{label:bi('测试验收','Testing & acceptance'),value:86,items:[[bi('Debug / 定位运行时问题','Debugging / runtime diagnosis'),74],[bi('分析编译错误','Analyzing compile errors'),70],[bi('编写测试','Writing tests'),64],[bi('执行 / 修复测试','Running / fixing tests'),61]]},
{label:bi('发布上线','Release'),value:64,items:[[bi('发布 / Release 相关工作','Release-related work'),57],[bi('Build / CI / 自动化','Build / CI / automation'),56]]}
],
workflows:[
{label:bi('完全托管给 AI,包括写代码、验证等','Fully delegated to AI, including code and validation'),value:34},
{label:bi('AI 主导写代码,人工审核','AI writes code; people review'),value:25},
{label:bi('没有固定方式,视具体情况','No fixed approach; it depends'),value:14}
],
frequency:[
{label:bi('几乎不用','Hardly ever'),value:1,color:'#9cb5c4'},
{label:bi('每月几次','A few times a month'),value:0,color:'#7fbed2'},
{label:bi('每周几次','A few times a week'),value:4,color:'#54acc9'},
{label:bi('每天使用','Daily use'),value:17,color:'#238fb6'},
{label:bi('每天高频使用','High-frequency daily use'),value:78,color:'#087fa8'}
],
selectionTop:[[bi('生成代码的质量','Code-generation quality'),83],[bi('对复杂问题的推理能力','Reasoning on complex problems'),75],[bi('对项目架构和上下文的理解能力','Project architecture and context understanding'),60],[bi('对整个代码库的理解能力','Understanding the whole codebase'),56],[bi('Agent 自主完成任务的能力','Agent autonomy for completing tasks'),41]],
selectionBottom:[[bi('企业内部使用政策','Internal enterprise policy'),1],[bi('所在地区是否容易使用','Availability in the respondent’s region'),1],[bi('中文或其他本地语言支持','Chinese or other local-language support'),1],[bi('可以自由选择不同 AI 模型','Freedom to choose different AI models'),2],[bi('测试能力','Testing capability'),3]],
codeLocations:[
{workshare:bi('不足 10%','Under 10%'),respondentShare:63,detail:bi('Xcode 主要承担 Build / Debug / Simulator / Signing 等工具链职责','Xcode mainly handles toolchain responsibilities such as Build, Debug, Simulator, and Signing')},
{workshare:bi('20–40%','20–40%'),respondentShare:18,detail:bi('工作重心已转向其他 AI 工具,Xcode 不再是主要工作入口','Work centers on other AI tools; Xcode is no longer primary')}
],
roles:[[bi('Build / Compile','Build / Compile'),61],[bi('Simulator','Simulator'),58],[bi('Debug','Debug'),46],[bi('Signing / Provisioning','Signing / Provisioning'),30],[bi('Profiling / Instruments','Profiling / Instruments'),27],[bi('Archive / Distribution / Release','Archive / Distribution / Release'),27],[bi('代码浏览 / Navigation','Code browsing / Navigation'),25],[bi('使用 Apple SDK、Framework 和平台能力','Using Apple SDKs, frameworks, and platform capabilities'),20],[bi('SwiftUI Preview','SwiftUI Preview'),17],[bi('代码编辑','Code editing'),16],[bi('Package / Dependency Management','Package / Dependency Management'),11],[bi('AI-assisted Coding','AI-assisted coding'),10],[bi('Testing','Testing'),5],[bi('Xcode 基本承担了我完整的开发工作流','Xcode covers my complete development workflow'),5]]
};
const chinaUsage={
models:[
[bi('OpenAI GPT / Codex 系列模型','OpenAI GPT / Codex models'),95.8,71.9],
[bi('Anthropic Claude 系列模型','Anthropic Claude models'),66.2,81.2],
[bi('DeepSeek(DeepSeek V4 系列)','DeepSeek (DeepSeek V4 series)'),38.0,18.8],
[bi('GLM / 智谱(GLM-5 系列)','GLM / Z.ai (GLM-5 series)'),25.4,6.2],
[bi('xAI Grok 系列模型','xAI Grok models'),25.4,18.8],
[bi('公司内部或自行部署的模型','Company-internal or self-hosted models'),14.1,3.1],
[bi('Kimi / 月之暗面(Kimi K3 / K2.5 系列)','Kimi / Moonshot AI (Kimi K3 / K2.5 series)'),11.3,9.4],
[bi('Google Gemini 系列模型','Google Gemini models'),11.3,9.4],
[bi('Qwen / 通义千问(阿里)系列模型','Qwen models'),8.5,6.2],
[bi('混元(腾讯)系列模型','Tencent HY models'),5.6,0.0]
],
tools:[
[bi('OpenAI Codex(CLI / App / Cloud)','OpenAI Codex (CLI / App / Cloud)'),91.5,65.6],
[bi('ChatGPT','ChatGPT'),60.6,56.2],
[bi('Claude Code','Claude Code'),50.7,81.2],
[bi('Cursor','Cursor'),31.0,9.4],
[bi('Claude','Claude'),28.2,46.9],
[bi('中国公司开发的通用对话产品','General chat products developed by Chinese companies'),18.3,3.1],
[bi('Xcode 内置 AI / Coding Intelligence','Built-in Xcode AI / Coding Intelligence'),12.7,40.6],
[bi('DeepSeek Harness','DeepSeek Harness'),12.7,3.1],
[bi('Gemini','Gemini'),12.7,18.8],
[bi('WorkBuddy','WorkBuddy'),11.3,0.0]
],
entryPoints:[
[bi('独立桌面 Agent 应用,例如 Codex App、Qoder、WorkBuddy 等','Standalone desktop agent apps, such as Codex App, Qoder, and WorkBuddy'),76.1,71.9],
[bi('CLI / Terminal Agent,例如 Claude Code、Codex CLI、Gemini CLI、Aider、OpenCode','CLI / terminal agents, such as Claude Code, Codex CLI, Gemini CLI, Aider, and OpenCode'),53.5,50.0],
[bi('IDE / 代码编辑器中的 Agent,例如 Cursor、Windsurf、Xcode、VS Code / GitHub Copilot、JetBrains Junie','Agents in IDEs / code editors, such as Cursor, Windsurf, Xcode, VS Code / GitHub Copilot, and JetBrains Junie'),25.4,34.4],
[bi('网页中的交互式 Agent,例如 ChatGPT、Claude、Gemini、Manus 等','Interactive web agents, such as ChatGPT, Claude, Gemini, and Manus'),18.3,9.4],
[bi('协作或消息工具中的 Agent,例如 Slack、Teams、飞书、企业微信、Telegram、Discord 等入口','Agents in collaboration or messaging tools, such as Slack, Teams, Feishu, WeCom, Telegram, and Discord'),9.9,9.4],
[bi('CI/CD、代码审查、测试、发布等自动化流程中运行的 Agent','Agents running in automated CI/CD, code-review, testing, or release workflows'),9.9,9.4],
[bi('云端异步 Coding Agent,例如 Devin、Google Jules、OpenHands Cloud、Codex Cloud 等','Cloud-based asynchronous coding agents, such as Devin, Google Jules, OpenHands Cloud, and Codex Cloud'),8.5,0.0],
[bi('自托管或本地运行的 Agent / Harness,例如 OpenClaw、OpenHands、本地模型 Agent 等','Self-hosted or locally run agents / harnesses, such as OpenClaw, OpenHands, and local-model agents'),8.5,12.5],
[bi('公司内部开发者平台或企业 Agent 平台','Internal developer platforms or enterprise agent platforms'),8.5,9.4],
[bi('通过 API / SDK 嵌入自己产品、脚本或内部系统中的 Agent','Agents embedded in products, scripts, or internal systems through APIs / SDKs'),5.6,9.4]
],
extensionMethods:[
[bi('Skills / Agent Skills(可复用的任务能力包或工作方法)','Skills / Agent Skills (reusable task-capability packages or work methods)'),78.9,81.2],
[bi('MCP Server(通过 Model Context Protocol 连接外部工具、数据或服务)','MCP Servers (connecting external tools, data, or services through Model Context Protocol)'),76.1,71.9],
[bi('Browser / Computer Use(让 Agent 操作浏览器、桌面应用或设备)','Browser / Computer Use (letting agents operate browsers, desktop apps, or devices)'),74.6,62.5],
[bi('Tools / Function Calling(让 Agent 调用内置或自定义工具)','Tools / Function Calling (letting agents call built-in or custom tools)'),63.4,65.6],
[bi('Rules / Instructions / AGENTS.md / Prompt 配置(向 Agent 提供项目规则和工作约束)','Rules / Instructions / AGENTS.md / prompt configuration (providing project rules and work constraints)'),46.5,53.1],
[bi('Plugins / Extensions(通过插件或扩展安装新能力)','Plugins / Extensions (adding capabilities through plugins or extensions)'),43.7,50.0],
[bi('Subagents / Multi-Agent / Handoffs(拆分任务或让多个 Agent 协作)','Subagents / Multi-Agent / Handoffs (splitting work or coordinating multiple agents)'),43.7,43.8],
[bi('Memory / 长期上下文(让 Agent 记住偏好、项目背景或历史任务)','Memory / long-term context (letting agents retain preferences, project context, or task history)'),38.0,40.6],
[bi('外部知识库、RAG、Repo Wiki、代码索引或项目记忆','External knowledge bases, RAG, repo wikis, code indexes, or project memory'),33.8,21.9],
[bi('自定义脚本、Shell / CLI 工具或自动化工作流','Custom scripts, shell / CLI tools, or automated workflows'),22.5,31.2]
]
};
const xcodeQuestionReports=[
{
id:'q19',
title:bi('为什么会在 Xcode 之外使用 AI 编程工具?','Why do you use AI coding tools outside Xcode?'),
insight:bi('选择 Xcode 之外工具的首要原因集中在<strong>更强的 Agent 能力</strong>与<strong>外部工具的模型能力</strong>。两项均高于任务自主完成、Terminal / 脚本易用性与编辑 / 交互体验,表明受访者转向外部工具的核心诉求是<strong>更高的智能化能力</strong>,而非效率、交互或样式。','The leading reasons for using tools outside Xcode are <strong>stronger agent capabilities</strong> and <strong>stronger model capabilities in external tools</strong>. Both rank above end-to-end task completion, Terminal / script access, and editing / interaction experience, indicating that the core draw is <strong>greater intelligence</strong>, rather than efficiency, interaction, or styling.'),
items:[
[bi('Agent 能力更强','Stronger agent capabilities'),56],
[bi('外部工具的模型能力更强','Stronger model capabilities in external tools'),50],
[bi('更容易自主完成完整任务','Easier to independently complete end-to-end tasks'),38],
[bi('更容易使用 Terminal、脚本或其他工具','Easier to use the Terminal, scripts, or other tools'),35],
[bi('编辑 / 交互体验更好','Better editing and interaction experience'),28],
[bi('多文件 / 跨模块修改更方便','Easier multi-file and cross-module changes'),26],
[bi('对大型代码库理解得更好','Better understanding of large codebases'),22],
[bi('可以直接在已有工作流中使用','Fits directly into existing workflows'),15],
[bi('Xcode 中的 AI 能力在我的地区不可用或使用受限','Xcode AI is unavailable or constrained in my region'),13],
[bi('Debug / Fix 问题的效果更好','Better debugging and issue-fixing results'),8]
]
},
{
id:'q20',
title:bi('使用 Xcode 时,哪些非 AI 问题最影响开发体验?','When using Xcode, which non-AI issues most affect your development experience?'),
insight:bi('在非 AI 体验问题中,<strong>Build / Compile 速度</strong>的提及略高;其后的整体稳定性、Indexing和大型工程性能相对接近。整体分布较为均匀,说明本样本中尚未出现高度集中的一致痛点,也未显示出某一项特别突出的短板。','Among non-AI experience issues, <strong>Build / compile speed</strong> is mentioned somewhat more often. Overall stability, Indexing, and large-project performance follow closely. The distribution is fairly even overall, suggesting that this sample does not reveal either a highly concentrated consensus pain point or a single especially pronounced weakness.'),
items:[
[bi('Build / Compile 速度','Build / compile speed'),38],
[bi('Xcode 整体稳定性 / Crash','Overall Xcode stability / crashes'),29],
[bi('Indexing 速度或稳定性','Indexing speed or stability'),27],
[bi('大型工程性能','Large-project performance'),27],
[bi('UI / 操作效率','UI and interaction efficiency'),22],
[bi('SwiftUI Preview','SwiftUI Preview'),17],
[bi('Simulator','Simulator'),14],
[bi('我对目前 Xcode 的整体体验比较满意,没有明显问题','I am generally satisfied with Xcode and see no major issues'),14],
[bi('Package / Dependency Management','Package / dependency management'),12],
[bi('与其他开发工具协作不够顺畅','Collaboration with other development tools is not smooth enough'),12]
]
},
{
id:'q21',
title:bi('不论 AI 以何种方式参与,Xcode 的 AI 能力本身最该补齐什么?','How do you most want Xcode’s AI coding capabilities to improve?'),
insight:bi('对 Xcode AI 而言,开发者最希望补齐的并非单一的代码生成能力,而是<strong>复杂问题推理</strong>与<strong>项目级理解</strong>。两项选择比例接近且均位居前列,表明开发者更在意 AI 能否在真实工程语境中理解问题、判断影响范围并给出可靠行动。<strong>Agent 自主执行能力</strong>紧随其后,进一步反映出开发者期待的不是更快地产生代码片段,而是能够基于工程上下文推进任务的 AI。','For Xcode AI, developers most want to strengthen not a single code-generation capability, but <strong>reasoning on complex problems</strong> and <strong>project-level understanding</strong>. The two are closely ranked and both lead the results, suggesting that developers care more about whether AI can understand a problem in its real engineering context, judge its scope of impact, and take reliable action. <strong>Agent autonomy for completing tasks</strong> follows closely, further indicating that developers expect not merely faster code snippets, but AI that can advance work based on project context.'),
items:[
[bi('更强的推理 / 复杂问题处理能力','Stronger reasoning and complex-problem handling'),38],
[bi('更好地理解整个项目 / Repository','Better understanding of the full project / repository'),37],
[bi('更强的 Agent 自主执行能力','Stronger autonomous agent execution'),34],
[bi('更强的代码生成能力','Stronger code generation'),30],
[bi('更好地理解项目架构和业务上下文','Better understanding of project architecture and business context'),27],
[bi('更好的 Swift / SwiftUI / Apple SDK 理解','Better Swift / SwiftUI / Apple SDK understanding'),27],
[bi('可以调用 Instruments / 性能分析工具','Can use Instruments and performance-analysis tools'),22],
[bi('可以使用 Simulator','Can use the Simulator'),16],
[bi('可以分析 UI / App Runtime 状态','Can analyze UI and app runtime state'),14],
[bi('可以使用 Debugger 协助定位问题','Can use the debugger to help diagnose issues'),13]
]
},
{
id:'q22',
type:'treemap',
title:bi('假设 AI 已能够更自主地完成开发任务,开发者愿意优先授权它做哪些具体工作?','If Xcode’s AI could complete development tasks more autonomously, which three capabilities should it prioritize?'),
insight:bi('如果暂且把<strong>“根据需求直接生成完整功能”</strong>视为开发者对 AI 的基础期待,那么其后的三项选择更值得关注:<strong>理解项目和架构</strong>、<strong>自动 Build 并修复编译错误</strong>、<strong>操作 Simulator 并理解界面状态</strong>。它们共同指向一组开发者更愿意交给 AI 独立推进的验证型工作:AI 不仅要理解工程和完成代码,还应能自行构建、运行、观察结果并处理可发现的问题。这也呼应了 AI 编程从生成代码,进一步进入测试与验证流程的方向。','If <strong>generating a complete feature from requirements</strong> is treated as developers’ baseline expectation of AI, the next three choices are especially notable: <strong>understanding the project and architecture</strong>, <strong>automatically building and fixing compile errors</strong>, and <strong>operating Simulator and understanding UI state</strong>. Together, they point to a set of verification-oriented work that developers are more willing to let AI advance independently. AI is expected not only to understand the project and write code, but also to build, run, inspect results, and address discoverable issues. This echoes the direction of AI coding moving beyond code generation and further into testing and verification workflows.'),
note:bi('每位受访者最多选择 3 项。每个方块的面积按选择比例近似呈现;选项可重叠,因此比例不相加为 100%。','Each respondent selected up to three capabilities. Tile area approximately represents selection share; choices overlap, so percentages do not sum to 100%.'),
items:[
[bi('根据需求直接生成完整功能','Generate a complete feature from requirements'),47.6],
[bi('理解整个项目和架构','Understand the full project and architecture'),37.9],
[bi('自动 Build,并修复编译错误','Build automatically and fix compile errors'),24.3],
[bi('操作 Simulator 并理解界面状态','Operate Simulator and understand UI state'),24.3],
[bi('分析 Crash 和运行日志','Analyze crashes and runtime logs'),20.4],
[bi('使用 Instruments 定位性能问题','Use Instruments to identify performance issues'),19.4],
[bi('自主修改多个文件和模块','Autonomously modify multiple files and modules'),18.4],
[bi('自动运行 App 并根据运行结果继续修改','Run the app and iterate from runtime results'),18.4],
[bi('使用 Debugger 定位和修复 Bug','Use Debugger to locate and fix bugs'),18.4],
[bi('自动完成较长时间、多步骤的开发任务','Complete longer, multi-step development tasks'),12.6],
[bi('与其他 AI Agent / Developer Tool 协同工作','Work with other AI agents / developer tools'),10.7],
[bi('自动生成、执行和修复 Tests','Generate, run, and fix tests'),7.8],
[bi('自动查找 Apple Documentation 和 API','Find Apple documentation and APIs'),5.8],
[bi('协助解决 Signing / Provisioning / Release 问题','Help with signing, provisioning, and release'),2.9]
]
}
];
const q15={
tools:[
[bi('OpenAI Codex(CLI / App / Cloud)','OpenAI Codex (CLI / App / Cloud)'),67.5,50.0],
[bi('Claude Code','Claude Code'),48.2,66.7],
[bi('DeepSeek Harness','DeepSeek Harness'),26.5,0.0],
[bi('Xcode 内置 AI / Coding Intelligence','Built-in Xcode AI / Coding Intelligence'),25.3,38.9],
[bi('Cursor','Cursor'),22.9,16.7],
[bi('TRAE','TRAE'),12.0,5.6],
[bi('WorkBuddy','WorkBuddy'),10.8,0.0],
[bi('Kimi Code','Kimi Code'),9.6,5.6],
[bi('GitHub Copilot','GitHub Copilot'),8.4,5.6],
[bi('Qoder(含 Qoder CN / 原通义灵码)','Qoder (including Qoder CN / TONGYI Lingma)'),8.4,0.0],
[bi('CodeBuddy','CodeBuddy'),7.2,0.0],
[bi('Gemini CLI / Gemini Code Assist','Gemini CLI / Gemini Code Assist'),6.0,5.6],
[bi('ZCode(含 ZCode Agent)','ZCode (including ZCode Agent)'),6.0,0.0],
[bi('模型官方网页 / App(直接对话,如 ChatGPT、Claude、DeepSeek)','Official model web / app (direct chat, such as ChatGPT, Claude, or DeepSeek)'),4.8,2.8],
[bi('其他工具','Other tools'),3.6,5.6],
[bi('Windsurf','Windsurf'),2.4,2.8],
[bi('Step Code','Step Code'),1.2,0.0],
[bi('文心快码 Comate','Comate'),1.2,0.0],
[bi('其他国产工具','Other China-based tools'),0.0,2.8]
],
models:[
[bi('OpenAI GPT / Codex 系列模型','OpenAI GPT / Codex models'),71.1,55.6],
[bi('Anthropic Claude 系列模型','Anthropic Claude models'),57.8,72.2],
[bi('DeepSeek(DeepSeek V4 系列)','DeepSeek (DeepSeek V4 family)'),54.2,11.1],
[bi('GLM / 智谱(GLM-5 系列)','GLM / Z.ai (GLM-5 family)'),28.9,8.3],
[bi('Kimi / 月之暗面(Kimi K3 / K2.5 系列)','Kimi / Moonshot AI (Kimi K3 / K2.5 family)'),24.1,13.9],
[bi('xAI Grok 系列模型','xAI Grok models'),15.7,2.8],
[bi('Google Gemini 系列模型','Google Gemini models'),14.5,5.6],
[bi('Qwen / 通义千问(阿里)','Qwen'),9.6,5.6],
[bi('混元(腾讯)','Tencent HY'),7.2,0.0],
[bi('MiniMax(MiniMax-M3 / M2.7 系列模型)','MiniMax (MiniMax-M3 / M2.7 family)'),4.8,2.8],
[bi('豆包 / Seed(字节跳动)','Doubao / Seed (ByteDance)'),3.6,0.0],
[bi('MiniCPM / 面壁智能(MiniCPM5 / V / o 系列)','MiniCPM / ModelBest (MiniCPM5 / V / o family)'),1.2,0.0],
[bi('文心 / ERNIE(百度)','ERNIE (Baidu)'),1.2,0.0],
[bi('阶跃星辰 / Step(Step 5 / 3.7 / 3.5 系列)','StepFun / Step (Step 5 / 3.7 / 3.5 family)'),1.2,0.0],
[bi('自动选择 / 不清楚','Automatic selection / not sure'),0.0,5.6],
[bi('其他国际模型','Other international models'),0.0,2.8]
]
};
const q15CombinationCounts=[["OpenAI Codex(CLI / App / Cloud)","OpenAI GPT / Codex 系列模型",67.5,50.0],["OpenAI Codex(CLI / App / Cloud)","Anthropic Claude 系列模型",54.2,38.9],["Claude Code","OpenAI GPT / Codex 系列模型",45.8,30.6],["Claude Code","Anthropic Claude 系列模型",43.4,58.3],["OpenAI Codex(CLI / App / Cloud)","DeepSeek(DeepSeek V4 系列)",34.9,5.6],["Claude Code","DeepSeek(DeepSeek V4 系列)",31.3,5.6],["DeepSeek Harness","DeepSeek(DeepSeek V4 系列)",26.5,0.0],["Xcode 内置 AI / Coding Intelligence","OpenAI GPT / Codex 系列模型",24.1,16.7],["OpenAI Codex(CLI / App / Cloud)","GLM / 智谱(GLM-5 系列)",21.7,5.6],["Cursor","OpenAI GPT / Codex 系列模型",20.5,8.3],["Xcode 内置 AI / Coding Intelligence","Anthropic Claude 系列模型",19.3,27.8],["Cursor","DeepSeek(DeepSeek V4 系列)",19.3,2.8],["Cursor","Anthropic Claude 系列模型",18.1,13.9],["Claude Code","GLM / 智谱(GLM-5 系列)",18.1,5.6],["OpenAI Codex(CLI / App / Cloud)","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",18.1,5.6],["DeepSeek Harness","OpenAI GPT / Codex 系列模型",16.9,0.0],["Xcode 内置 AI / Coding Intelligence","DeepSeek(DeepSeek V4 系列)",15.7,5.6],["OpenAI Codex(CLI / App / Cloud)","xAI Grok 系列模型",15.7,0.0],["Claude Code","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",14.5,5.6],["Claude Code","xAI Grok 系列模型",14.5,2.8],["DeepSeek Harness","Anthropic Claude 系列模型",14.5,0.0],["OpenAI Codex(CLI / App / Cloud)","Google Gemini 系列模型",13.3,2.8],["Claude Code","Google Gemini 系列模型",12.0,2.8],["TRAE","DeepSeek(DeepSeek V4 系列)",10.8,5.6],["Xcode 内置 AI / Coding Intelligence","GLM / 智谱(GLM-5 系列)",10.8,5.6],["Cursor","xAI Grok 系列模型",10.8,2.8],["Kimi Code","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",9.6,5.6],["Xcode 内置 AI / Coding Intelligence","Google Gemini 系列模型",9.6,5.6],["Xcode 内置 AI / Coding Intelligence","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",9.6,5.6],["Claude Code","Qwen / 通义千问(阿里)",9.6,2.8],["Cursor","GLM / 智谱(GLM-5 系列)",9.6,2.8],["Xcode 内置 AI / Coding Intelligence","xAI Grok 系列模型",8.4,2.8],["DeepSeek Harness","GLM / 智谱(GLM-5 系列)",8.4,0.0],["GitHub Copilot","OpenAI GPT / Codex 系列模型",8.4,0.0],["OpenAI Codex(CLI / App / Cloud)","Qwen / 通义千问(阿里)",8.4,0.0],["Qoder(含 Qoder CN / 原通义灵码)","DeepSeek(DeepSeek V4 系列)",8.4,0.0],["WorkBuddy","DeepSeek(DeepSeek V4 系列)",8.4,0.0],["WorkBuddy","OpenAI GPT / Codex 系列模型",8.4,0.0],["GitHub Copilot","Anthropic Claude 系列模型",7.2,5.6],["Cursor","Google Gemini 系列模型",7.2,2.8],["Cursor","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",7.2,2.8],["TRAE","OpenAI GPT / Codex 系列模型",7.2,2.8],["OpenAI Codex(CLI / App / Cloud)","混元(腾讯)",7.2,0.0],["Qoder(含 Qoder CN / 原通义灵码)","OpenAI GPT / Codex 系列模型",7.2,0.0],["WorkBuddy","GLM / 智谱(GLM-5 系列)",7.2,0.0],["Gemini CLI / Gemini Code Assist","OpenAI GPT / Codex 系列模型",6.0,2.8],["TRAE","Anthropic Claude 系列模型",6.0,2.8],["TRAE","GLM / 智谱(GLM-5 系列)",6.0,2.8],["Xcode 内置 AI / Coding Intelligence","Qwen / 通义千问(阿里)",6.0,2.8],["CodeBuddy","DeepSeek(DeepSeek V4 系列)",6.0,0.0],["Qoder(含 Qoder CN / 原通义灵码)","Anthropic Claude 系列模型",6.0,0.0],["Qoder(含 Qoder CN / 原通义灵码)","Qwen / 通义千问(阿里)",6.0,0.0],["ZCode(含 ZCode Agent)","GLM / 智谱(GLM-5 系列)",6.0,0.0],["Gemini CLI / Gemini Code Assist","Google Gemini 系列模型",4.8,5.6],["Claude Code","MiniMax(MiniMax-M3 / M2.7 系列模型)",4.8,2.8],["Gemini CLI / Gemini Code Assist","Anthropic Claude 系列模型",4.8,2.8],["GitHub Copilot","Google Gemini 系列模型",4.8,2.8],["Kimi Code","Anthropic Claude 系列模型",4.8,2.8],["Kimi Code","GLM / 智谱(GLM-5 系列)",4.8,2.8],["Kimi Code","OpenAI GPT / Codex 系列模型",4.8,2.8],["OpenAI Codex(CLI / App / Cloud)","MiniMax(MiniMax-M3 / M2.7 系列模型)",4.8,2.8],["Xcode 内置 AI / Coding Intelligence","MiniMax(MiniMax-M3 / M2.7 系列模型)",4.8,2.8],["模型官方网页 / App(直接对话,如 ChatGPT、Claude、DeepSeek)","Anthropic Claude 系列模型",4.8,2.8],["Claude Code","混元(腾讯)",4.8,0.0],["CodeBuddy","GLM / 智谱(GLM-5 系列)",4.8,0.0],["CodeBuddy","OpenAI GPT / Codex 系列模型",4.8,0.0],["Cursor","Qwen / 通义千问(阿里)",4.8,0.0],["DeepSeek Harness","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",4.8,0.0],["Gemini CLI / Gemini Code Assist","DeepSeek(DeepSeek V4 系列)",4.8,0.0],["Qoder(含 Qoder CN / 原通义灵码)","GLM / 智谱(GLM-5 系列)",4.8,0.0],["Qoder(含 Qoder CN / 原通义灵码)","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",4.8,0.0],["WorkBuddy","Anthropic Claude 系列模型",4.8,0.0],["ZCode(含 ZCode Agent)","DeepSeek(DeepSeek V4 系列)",4.8,0.0],["ZCode(含 ZCode Agent)","OpenAI GPT / Codex 系列模型",4.8,0.0],["模型官方网页 / App(直接对话,如 ChatGPT、Claude、DeepSeek)","DeepSeek(DeepSeek V4 系列)",4.8,0.0],["模型官方网页 / App(直接对话,如 ChatGPT、Claude、DeepSeek)","OpenAI GPT / Codex 系列模型",4.8,0.0],["GitHub Copilot","xAI Grok 系列模型",3.6,2.8],["Kimi Code","DeepSeek(DeepSeek V4 系列)",3.6,2.8],["TRAE","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",3.6,2.8],["Claude Code","豆包 / Seed(字节跳动)",3.6,0.0],["CodeBuddy","Anthropic Claude 系列模型",3.6,0.0],["Cursor","混元(腾讯)",3.6,0.0],["DeepSeek Harness","Google Gemini 系列模型",3.6,0.0],["DeepSeek Harness","Qwen / 通义千问(阿里)",3.6,0.0],["DeepSeek Harness","xAI Grok 系列模型",3.6,0.0],["Gemini CLI / Gemini Code Assist","GLM / 智谱(GLM-5 系列)",3.6,0.0],["Gemini CLI / Gemini Code Assist","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",3.6,0.0],["Gemini CLI / Gemini Code Assist","Qwen / 通义千问(阿里)",3.6,0.0],["GitHub Copilot","DeepSeek(DeepSeek V4 系列)",3.6,0.0],["GitHub Copilot","GLM / 智谱(GLM-5 系列)",3.6,0.0],["Kimi Code","Google Gemini 系列模型",3.6,0.0],["Kimi Code","MiniMax(MiniMax-M3 / M2.7 系列模型)",3.6,0.0],["Kimi Code","Qwen / 通义千问(阿里)",3.6,0.0],["OpenAI Codex(CLI / App / Cloud)","豆包 / Seed(字节跳动)",3.6,0.0],["Qoder(含 Qoder CN / 原通义灵码)","Google Gemini 系列模型",3.6,0.0],["TRAE","xAI Grok 系列模型",3.6,0.0],["WorkBuddy","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",3.6,0.0],["WorkBuddy","混元(腾讯)",3.6,0.0],["Xcode 内置 AI / Coding Intelligence","混元(腾讯)",3.6,0.0],["ZCode(含 ZCode Agent)","Anthropic Claude 系列模型",3.6,0.0],["ZCode(含 ZCode Agent)","Qwen / 通义千问(阿里)",3.6,0.0],["模型官方网页 / App(直接对话,如 ChatGPT、Claude、DeepSeek)","Google Gemini 系列模型",3.6,0.0],["CodeBuddy","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",2.4,0.0],["CodeBuddy","Qwen / 通义千问(阿里)",2.4,0.0],["CodeBuddy","xAI Grok 系列模型",2.4,0.0],["CodeBuddy","混元(腾讯)",2.4,0.0],["CodeBuddy","豆包 / Seed(字节跳动)",2.4,0.0],["Cursor","MiniMax(MiniMax-M3 / M2.7 系列模型)",2.4,0.0],["Cursor","豆包 / Seed(字节跳动)",2.4,0.0],["DeepSeek Harness","MiniMax(MiniMax-M3 / M2.7 系列模型)",2.4,0.0],["GitHub Copilot","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",2.4,0.0],["GitHub Copilot","Qwen / 通义千问(阿里)",2.4,0.0],["Kimi Code","xAI Grok 系列模型",2.4,0.0],["Qoder(含 Qoder CN / 原通义灵码)","MiniMax(MiniMax-M3 / M2.7 系列模型)",2.4,0.0],["Qoder(含 Qoder CN / 原通义灵码)","混元(腾讯)",2.4,0.0],["Qoder(含 Qoder CN / 原通义灵码)","豆包 / Seed(字节跳动)",2.4,0.0],["TRAE","Google Gemini 系列模型",2.4,0.0],["TRAE","Qwen / 通义千问(阿里)",2.4,0.0],["TRAE","混元(腾讯)",2.4,0.0],["TRAE","豆包 / Seed(字节跳动)",2.4,0.0],["Windsurf","DeepSeek(DeepSeek V4 系列)",2.4,0.0],["Windsurf","OpenAI GPT / Codex 系列模型",2.4,0.0],["WorkBuddy","Google Gemini 系列模型",2.4,0.0],["WorkBuddy","Qwen / 通义千问(阿里)",2.4,0.0],["WorkBuddy","xAI Grok 系列模型",2.4,0.0],["Xcode 内置 AI / Coding Intelligence","豆包 / Seed(字节跳动)",2.4,0.0],["ZCode(含 ZCode Agent)","Google Gemini 系列模型",2.4,0.0],["ZCode(含 ZCode Agent)","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",2.4,0.0],["ZCode(含 ZCode Agent)","MiniMax(MiniMax-M3 / M2.7 系列模型)",2.4,0.0],["ZCode(含 ZCode Agent)","xAI Grok 系列模型",2.4,0.0],["Gemini CLI / Gemini Code Assist","xAI Grok 系列模型",1.2,2.8],["Claude Code","MiniCPM / 面壁智能(MiniCPM5 / V / o 系列)",1.2,0.0],["Claude Code","文心 / ERNIE(百度)",1.2,0.0],["Claude Code","阶跃星辰 / Step(Step 5 / 3.7 / 3.5 系列)",1.2,0.0],["CodeBuddy","Google Gemini 系列模型",1.2,0.0],["CodeBuddy","文心 / ERNIE(百度)",1.2,0.0],["Cursor","MiniCPM / 面壁智能(MiniCPM5 / V / o 系列)",1.2,0.0],["Cursor","文心 / ERNIE(百度)",1.2,0.0],["Cursor","阶跃星辰 / Step(Step 5 / 3.7 / 3.5 系列)",1.2,0.0],["DeepSeek Harness","MiniCPM / 面壁智能(MiniCPM5 / V / o 系列)",1.2,0.0],["DeepSeek Harness","混元(腾讯)",1.2,0.0],["DeepSeek Harness","阶跃星辰 / Step(Step 5 / 3.7 / 3.5 系列)",1.2,0.0],["Gemini CLI / Gemini Code Assist","MiniCPM / 面壁智能(MiniCPM5 / V / o 系列)",1.2,0.0],["Gemini CLI / Gemini Code Assist","MiniMax(MiniMax-M3 / M2.7 系列模型)",1.2,0.0],["Gemini CLI / Gemini Code Assist","文心 / ERNIE(百度)",1.2,0.0],["Gemini CLI / Gemini Code Assist","混元(腾讯)",1.2,0.0],["Gemini CLI / Gemini Code Assist","豆包 / Seed(字节跳动)",1.2,0.0],["Gemini CLI / Gemini Code Assist","阶跃星辰 / Step(Step 5 / 3.7 / 3.5 系列)",1.2,0.0],["GitHub Copilot","MiniCPM / 面壁智能(MiniCPM5 / V / o 系列)",1.2,0.0],["GitHub Copilot","MiniMax(MiniMax-M3 / M2.7 系列模型)",1.2,0.0],["GitHub Copilot","文心 / ERNIE(百度)",1.2,0.0],["GitHub Copilot","混元(腾讯)",1.2,0.0],["GitHub Copilot","豆包 / Seed(字节跳动)",1.2,0.0],["GitHub Copilot","阶跃星辰 / Step(Step 5 / 3.7 / 3.5 系列)",1.2,0.0],["Kimi Code","MiniCPM / 面壁智能(MiniCPM5 / V / o 系列)",1.2,0.0],["Kimi Code","混元(腾讯)",1.2,0.0],["Kimi Code","豆包 / Seed(字节跳动)",1.2,0.0],["Kimi Code","阶跃星辰 / Step(Step 5 / 3.7 / 3.5 系列)",1.2,0.0],["OpenAI Codex(CLI / App / Cloud)","MiniCPM / 面壁智能(MiniCPM5 / V / o 系列)",1.2,0.0],["OpenAI Codex(CLI / App / Cloud)","文心 / ERNIE(百度)",1.2,0.0],["OpenAI Codex(CLI / App / Cloud)","阶跃星辰 / Step(Step 5 / 3.7 / 3.5 系列)",1.2,0.0],["Qoder(含 Qoder CN / 原通义灵码)","xAI Grok 系列模型",1.2,0.0],["Qoder(含 Qoder CN / 原通义灵码)","文心 / ERNIE(百度)",1.2,0.0],["Step Code","Anthropic Claude 系列模型",1.2,0.0],["Step Code","DeepSeek(DeepSeek V4 系列)",1.2,0.0],["Step Code","GLM / 智谱(GLM-5 系列)",1.2,0.0],["Step Code","Google Gemini 系列模型",1.2,0.0],["Step Code","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",1.2,0.0],["Step Code","MiniCPM / 面壁智能(MiniCPM5 / V / o 系列)",1.2,0.0],["Step Code","MiniMax(MiniMax-M3 / M2.7 系列模型)",1.2,0.0],["Step Code","OpenAI GPT / Codex 系列模型",1.2,0.0],["Step Code","Qwen / 通义千问(阿里)",1.2,0.0],["Step Code","xAI Grok 系列模型",1.2,0.0],["Step Code","阶跃星辰 / Step(Step 5 / 3.7 / 3.5 系列)",1.2,0.0],["TRAE","文心 / ERNIE(百度)",1.2,0.0],["Windsurf","Anthropic Claude 系列模型",1.2,0.0],["Windsurf","GLM / 智谱(GLM-5 系列)",1.2,0.0],["Windsurf","Qwen / 通义千问(阿里)",1.2,0.0],["Windsurf","xAI Grok 系列模型",1.2,0.0],["Windsurf","文心 / ERNIE(百度)",1.2,0.0],["Windsurf","混元(腾讯)",1.2,0.0],["Windsurf","豆包 / Seed(字节跳动)",1.2,0.0],["WorkBuddy","文心 / ERNIE(百度)",1.2,0.0],["WorkBuddy","豆包 / Seed(字节跳动)",1.2,0.0],["Xcode 内置 AI / Coding Intelligence","MiniCPM / 面壁智能(MiniCPM5 / V / o 系列)",1.2,0.0],["Xcode 内置 AI / Coding Intelligence","阶跃星辰 / Step(Step 5 / 3.7 / 3.5 系列)",1.2,0.0],["ZCode(含 ZCode Agent)","MiniCPM / 面壁智能(MiniCPM5 / V / o 系列)",1.2,0.0],["ZCode(含 ZCode Agent)","文心 / ERNIE(百度)",1.2,0.0],["ZCode(含 ZCode Agent)","混元(腾讯)",1.2,0.0],["ZCode(含 ZCode Agent)","豆包 / Seed(字节跳动)",1.2,0.0],["ZCode(含 ZCode Agent)","阶跃星辰 / Step(Step 5 / 3.7 / 3.5 系列)",1.2,0.0],["其他工具:OpenCode","Anthropic Claude 系列模型",1.2,0.0],["其他工具:OpenCode","DeepSeek(DeepSeek V4 系列)",1.2,0.0],["其他工具:OpenCode","GLM / 智谱(GLM-5 系列)",1.2,0.0],["其他工具:OpenCode","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",1.2,0.0],["其他工具:OpenCode","OpenAI GPT / Codex 系列模型",1.2,0.0],["其他工具:OpenCode","Qwen / 通义千问(阿里)",1.2,0.0],["其他工具:Pi","Anthropic Claude 系列模型",1.2,0.0],["其他工具:Pi","DeepSeek(DeepSeek V4 系列)",1.2,0.0],["其他工具:Pi","GLM / 智谱(GLM-5 系列)",1.2,0.0],["其他工具:Pi","Google Gemini 系列模型",1.2,0.0],["其他工具:Pi","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",1.2,0.0],["其他工具:Pi","MiniMax(MiniMax-M3 / M2.7 系列模型)",1.2,0.0],["其他工具:Pi","OpenAI GPT / Codex 系列模型",1.2,0.0],["其他工具:Pi","Qwen / 通义千问(阿里)",1.2,0.0],["其他工具:Pi","混元(腾讯)",1.2,0.0],["其他工具:Pi","豆包 / Seed(字节跳动)",1.2,0.0],["其他工具:pi和opencode","Anthropic Claude 系列模型",1.2,0.0],["其他工具:pi和opencode","DeepSeek(DeepSeek V4 系列)",1.2,0.0],["其他工具:pi和opencode","OpenAI GPT / Codex 系列模型",1.2,0.0],["其他工具:pi和opencode","xAI Grok 系列模型",1.2,0.0],["文心快码 Comate","Anthropic Claude 系列模型",1.2,0.0],["文心快码 Comate","OpenAI GPT / Codex 系列模型",1.2,0.0],["模型官方网页 / App(直接对话,如 ChatGPT、Claude、DeepSeek)","GLM / 智谱(GLM-5 系列)",1.2,0.0],["模型官方网页 / App(直接对话,如 ChatGPT、Claude、DeepSeek)","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",1.2,0.0],["模型官方网页 / App(直接对话,如 ChatGPT、Claude、DeepSeek)","MiniMax(MiniMax-M3 / M2.7 系列模型)",1.2,0.0],["模型官方网页 / App(直接对话,如 ChatGPT、Claude、DeepSeek)","Qwen / 通义千问(阿里)",1.2,0.0],["模型官方网页 / App(直接对话,如 ChatGPT、Claude、DeepSeek)","xAI Grok 系列模型",1.2,0.0],["Claude Code","自动选择 / 不清楚",0.0,5.6],["Claude Code","其他国际模型",0.0,2.8],["Cursor","自动选择 / 不清楚",0.0,2.8],["Windsurf","自动选择 / 不清楚",0.0,2.8],["Xcode 内置 AI / Coding Intelligence","其他国际模型",0.0,2.8],["Xcode 内置 AI / Coding Intelligence","自动选择 / 不清楚",0.0,2.8],["其他国产工具","Anthropic Claude 系列模型",0.0,2.8],["其他国产工具","OpenAI GPT / Codex 系列模型",0.0,2.8],["其他工具","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",0.0,2.8],["其他工具:OpenClaw","Anthropic Claude 系列模型",0.0,2.8],["其他工具:OpenClaw","DeepSeek(DeepSeek V4 系列)",0.0,2.8],["其他工具:OpenClaw","GLM / 智谱(GLM-5 系列)",0.0,2.8],["其他工具:OpenClaw","Kimi / 月之暗面(Kimi K3 / K2.5 系列)",0.0,2.8],["其他工具:OpenClaw","OpenAI GPT / Codex 系列模型",0.0,2.8],["其他工具:OpenClaw","Qwen / 通义千问(阿里)",0.0,2.8]];
const q15CombinationLabel=(tool,model)=>{
const toolLabel=q15.tools.find(([label])=>label.zh===tool)?.[0]||bi(tool,tool);
const modelLabel=q15.models.find(([label])=>label.zh===model)?.[0]||bi(model,model);
return bi(`${toolLabel.zh} + ${modelLabel.zh}`,`${toolLabel.en} + ${modelLabel.en}`);
};
q15.combinations=q15CombinationCounts.map(([tool,model,chinaRate,overseasRate])=>[q15CombinationLabel(tool,model),chinaRate,overseasRate]);
const priorities=[
{label:bi('Xcode 的性能与稳定性','Xcode performance and stability'),count:17,rate:16.5},
{label:bi('AI 与 Build、Debug、Test、Simulator 等 Xcode 工具的深度结合','Deep AI integration with Xcode tools such as Build, Debug, Test, and Simulator'),count:16,rate:15.5},
{label:bi('Build / Indexing 效率','Build / indexing efficiency'),count:14,rate:13.6},
{label:bi('AI Agent 自主完成任务的能力','AI-agent autonomy for completing tasks'),count:13,rate:12.6},
{label:bi('Simulator / Runtime Tooling','Simulator / runtime tooling'),count:8,rate:7.8},
{label:bi('SwiftUI / UI 开发体验','SwiftUI / UI development experience'),count:6,rate:5.8},
{label:bi('Debugging','Debugging'),count:4,rate:3.9},
{label:bi('AI 的模型能力','AI model capabilities'),count:4,rate:3.9},
{label:bi('AI 对整个代码库和项目上下文的理解','AI understanding of the entire codebase and project context'),count:3,rate:2.9},
{label:bi('代码编辑、搜索和导航体验','Code editing, search, and navigation'),count:1,rate:1.0},
{label:bi('AI 模型选择与开放性','AI model choice and openness'),count:1,rate:1.0},
{label:bi('Testing','Testing'),count:2,rate:1.9},
{label:bi('Package / Dependency Management','Package / dependency management'),count:2,rate:1.9},
{label:bi('企业安全 / 隐私 / 团队协作能力','Enterprise security, privacy, and team collaboration'),count:1,rate:1.0}
];
const voiceModules=[
{
title:bi('开放工具链与可验证的 Agent 工作流','Open toolchains and verifiable agent workflows'),
tags:[bi('开放工具链','Open toolchains'),bi('Agent 工作流','Agent workflows'),bi('可验证性','Verifiability')],
quotes:[
{quote:bi('希望 Xcode 在 AI 时代定位为 Agent 的「本地工具层」而非竞争者:将构建、调试、签名、设备管理等能力以稳定的 CLI 开放,让 Agent 能自主调用,并重做插件系统。签名与 Profile 管理建议整合为一个稳定、低内存占用的统一模块。另外 xcstrings 等文件每次构建都产生无意义变更、反复引发 Git 冲突,希望构建过程避免写入源控文件。目前 Xcode 与终端 Agent 同时工作会互相干扰,不打开 Xcode 时 Agent 表现反而更好——希望解决文件锁与索引冲突,让两者顺畅共存。','Xcode should position itself in the AI era as an agent’s “local tool layer,” not as a competitor: expose build, debugging, signing, and device-management capabilities through a stable CLI so agents can call them independently, and rethink the plug-in system. Signing and profile management should be unified into a stable, low-memory module. Files such as xcstrings also create meaningless changes on every build and repeatedly cause Git conflicts; the build should not write to source-controlled files. Today Xcode and terminal agents interfere with each other—agents can work better when Xcode is closed. Please resolve file-locking and indexing conflicts so both can coexist smoothly.'),tags:[bi('Agent 本地工具层','Agent local tool layer'),bi('稳定 CLI 开放','Stable CLI access'),bi('共存与稳定性','Coexistence & stability')],meta:bi('中国大陆 · Apple 平台开发 7–10 年 · 小型科技 / 初创公司开发者','Mainland China · 7–10 years on Apple platforms · Small technology / startup company developer')},
{quote:bi('我希望 Xcode 成为更广泛 Agent 工作空间的一等组成部分,连接研究、设计、规划、实现和反馈。AI 编程关乎端到端流程和持续迭代:从 Linear 接收议题、理解上下文、实现改动、构建和测试、检查运行中的 App、审查结果,并将学到的内容带入下一轮迭代。MCP 提供工具访问;下一步关键是让整条闭环可持久化、可观察、易于引导。云端 Agent 往往运行在 Linux 容器中,而验证 Apple App 需要 macOS、Xcode、Simulator,有时还需要 Metal 或真机。希望能把工作无缝交给远程 Mac,收集构建结果、截图、测试失败和性能数据,再把这些证据交回 Agent 继续迭代,并保留清晰的人工审核节点。','I’d like Xcode to become a first-class part of a broader agent workspace, connecting research, design, planning, implementation, and feedback. AI coding is about an end-to-end pipeline and continuous iteration: take an issue from Linear, understand the context, implement a change, build and test it, inspect the running app, review the result, and feed what we learn into the next iteration. MCP provides tool access; what matters next is making that whole loop persistent, observable, and easy to steer. Cloud agents commonly run in Linux containers, while verifying Apple apps requires macOS, Xcode, simulators, and sometimes Metal or physical devices. I’d love a seamless way to hand work to a remote Mac, collect build results, screenshots, test failures, and performance data, and return that evidence to the agent so it can keep iterating—with clear points for human review.'),meta:bi('欧洲 · Apple 平台开发 15 年以上 · 外包 / 咨询 / Agency 开发者','Europe · 15+ years on Apple platforms · Outsourcing / consulting / agency developer')},
{quote:bi('整套 iOS 工具链对 Agent 的友好程度远远低于 ADB。我让 Agent 实现一个功能或页面时,Codex、Claude 可以通过 ADB dump 出页面结构来分析问题;iOS 往往只能靠截图,再让多模态去理解。一个是准确的布局结构和 App 运行状态,一个是语义层面的相似,最终自动跑出来的结果就大相径庭。也许 Apple 每年更新功能,模型知识库又跟不上,那么官方能不能提供一套 skills 来给 Agent 做指导。','The iOS toolchain is far less agent-friendly than ADB. When asking an agent to implement a feature or screen, Codex and Claude can use ADB to dump the page structure and diagnose problems; on iOS, they often only have screenshots and multimodal inference. Accurate layout structure and app state are very different from semantic resemblance, and the resulting automation differs dramatically. Perhaps Apple’s annual changes outpace model knowledge bases; could Apple provide a set of skills to guide agents?'),meta:bi('中国大陆 · Apple 平台开发 7–10 年 · 独立开发者 / Solo Developer','Mainland China · 7–10 years on Apple platforms · Independent / solo developer')},
{quote:bi('如果 Xcode 不能做到最好,我希望能够拆分出原子能力,提供类似目前内置在其中的各种 skill 一样,供外部 Agent 灵活调用,成为一个平台。','If Xcode cannot be best-in-class at everything, I hope it can break out its capabilities into atomic pieces—like the skills built into it today—for external agents to call flexibly, becoming a platform.'),meta:bi('中国大陆 · Apple 平台开发 7–10 年 · 独立开发者 / Solo Developer','Mainland China · 7–10 years on Apple platforms · Independent / solo developer')},
{quote:bi('Xcode 拥有丰富的工具链、Build / Signing 优化以及 Instruments 调优功能,完全可以基于这些能力重新设计一个适应主流 Agent 的新开发工具,通过 MCP、CLI 等方式让开发者快速接入 Xcode 的进阶能力。','Xcode has a rich toolchain, build and signing optimization, and Instruments tuning. It could use those strengths to redesign a development tool for mainstream agents, giving developers quick access to Xcode’s advanced capabilities through MCP and a CLI.'),meta:bi('中国大陆 · Apple 平台开发 10–15 年 · 中型软件 / 互联网公司开发者','Mainland China · 10–15 years on Apple platforms · Medium software / internet company developer')}
]
},
{
title:bi('性能、稳定性与日常开发效率','Performance, stability, and everyday development efficiency'),
tags:[bi('性能与稳定性','Performance & stability'),bi('开发效率','Developer productivity'),bi('Preview / Build','Preview / Build')],
quotes:[
{quote:bi('作为长期使用 Xcode 的独立开发者,我希望团队关注几个每天都会影响效率的问题:String Catalog(.xcstrings)在字符串变多后浏览、搜索和编辑明显卡顿,已经难以成为高效的本地化工具;SwiftUI Preview 的准备、编译和启动也常常很慢,有时改一个小的 UI 细节,直接编译并运行 Simulator 反而更快。对每天真正使用 Xcode 开发 App 的人来说,更快的 Preview 和更好的本地化工作流会直接决定开发效率。','As an independent developer who has used Xcode for years, I hope the team addresses several issues that affect daily efficiency: once String Catalogs (.xcstrings) grow, browsing, searching, and editing become visibly sluggish, making them difficult to use as an effective localization tool. SwiftUI Preview preparation, compilation, and launch are also often slow; for a small UI adjustment, compiling and running the Simulator can sometimes be faster. For people who use Xcode to build apps every day, faster previews and a better localization workflow directly determine development efficiency.'),meta:bi('中国大陆 · Apple 平台开发 1–3 年 · 独立开发者 / Solo Developer','Mainland China · 1–3 years on Apple platforms · Independent / solo developer')},
{quote:bi('在使用 Reality Composer Pro 时,Build 耗时尤其长,编译索引已经接近 60–70 GB。希望 Xcode 的编译速度能快很多。','Why does it take so long to build, especially when using Reality Composer Pro? The compilation index has started taking close to 60–70 GB. I would love for Xcode to be much faster in compilation.'),meta:bi('印度及南亚 · Apple 平台开发 10–15 年 · 小型科技 / 初创公司开发者','India & South Asia · 10–15 years on Apple platforms · Small technology / startup company developer')},
{quote:bi('我曾在 Xcode 内部主力使用 Claude Code:短对话还好,长了之后整个 UI 就会明显卡顿,直接让我回到 CLI。希望 Xcode 改善使用 Agent 时的 UI 性能,也希望能直接使用系统中安装的 Claude Code,把企业的 AWS Bedrock 认证和设置直接迁移过来。SwiftUI Preview 和较为 Legacy 的 XIB 预览性能若能改善也会很好。','I used Claude Code primarily inside Xcode for a time: short conversations were fine, but longer ones made the whole UI noticeably laggy and drove me back to the CLI. I hope Xcode improves UI performance when using agents, and can use the Claude Code installed on the system, carrying over enterprise AWS Bedrock authentication and settings. Better SwiftUI Preview and legacy XIB preview performance would also help.'),meta:bi('日本 · Apple 平台开发 7–10 年 · 中型软件 / 互联网公司开发者','Japan · 7–10 years on Apple platforms · Medium software / internet company developer')},
{quote:bi('请让大型代码库的 Build 更快。','Quite an ask … make it much faster to build large code bases.'),meta:bi('东南亚 · Apple 平台开发 4–6 年 · 大型科技 / 互联网公司开发者','Southeast Asia · 4–6 years on Apple platforms · Large technology / internet company developer')},
{quote:bi('请改善 SwiftUI Preview。它们本可以节省大量时间(也包括改进 AI 生成的代码时),但几乎总会报错或加载很久。','Please improve SwiftUI previews. They could save a lot of time, including when improving AI-generated code, but they almost always have an error or take super long to load.'),meta:bi('欧洲 · Apple 平台开发 7–10 年 · 独立开发者 / Solo Developer','Europe · 7–10 years on Apple platforms · Independent / solo developer')}
]
},
{
title:bi('UI 开发、Preview 与运行时理解','UI development, Preview, and runtime understanding'),
tags:[bi('UI 开发','UI development'),bi('Preview','Preview'),bi('运行时理解','Runtime understanding')],
quotes:[
{quote:bi('在 AI 时代,IDE 的存在感正在下降,但与交互、设计相关的操作,仍为人类开发者保留着一片空间。Xcode 在 UIKit 时代曾提供过 Storyboard 这样试图连接设计与逻辑的优秀工具,但在 SwiftUI 与 AI 的时代,我们依然只能对着碎片化的 Preview 管中窥豹。Xcode 应该作出改变了——它不应只服务于写代码的人,程序员、设计师与产品经理之间的界限,正在被 AI 迅速抹平。Xcode 不应被 code 所拘束。','In the AI era, IDEs are becoming less central, but interaction- and design-related work still leaves room for human developers. In the UIKit era, Xcode offered strong tools such as Storyboard that attempted to connect design and logic. Yet in the age of SwiftUI and AI, we are still only peering through fragmented Preview panes. Xcode should change: it should not serve only people who write code. AI is rapidly erasing the boundaries between programmers, designers, and product managers. Xcode should not be constrained by code.'),meta:bi('中国大陆 · Apple 平台开发 4–6 年 · 独立开发者 / Solo Developer','Mainland China · 4–6 years on Apple platforms · Independent / solo developer')},
{quote:bi('我希望有更高效的 UI 编辑能力,并配备一个能进行实时设计调整的专门 AI Agent。现在的工作流很慢:Agent 先截取 Simulator 屏幕,再从截图开始反复迭代,非常繁琐。','I’d like more efficient UI editing with a dedicated AI agent that can make live design adjustments. The workflow is very slow today: the agent takes screenshots of the Simulator, and we iterate from there. It is very tedious.'),meta:bi('欧洲 · Apple 平台开发 1–3 年 · 独立开发者 / Solo Developer','Europe · 1–3 years on Apple platforms · Independent / solo developer')},
{quote:bi('非常建议 Xcode 向 Agent 提供 SwiftUI / UIKit 的界面 Debug 工具,并提升 SwiftUI Preview 的稳定性和速度,从而提高 Agent 独立进行 UI 开发的工具链效率。','I strongly recommend that Xcode provide SwiftUI / UIKit UI-debugging tools for agents and improve the stability and speed of SwiftUI Preview, making the toolchain more effective for agents working independently on UI development.'),meta:bi('中国大陆 · Apple 平台开发 10–15 年 · 大型科技 / 互联网公司开发者','Mainland China · 10–15 years on Apple platforms · Large technology / internet company developer')},
{quote:bi('AI 在编写 iOS / macOS 客户端 UI 上仍不擅长。如何在 Xcode 中让 SOTA 模型更容易一次生成符合预期的界面效果?','AI is still not good at writing client UI for iOS and macOS. How can Xcode make it easier for state-of-the-art models to one-shot an interface that matches the intended result?'),meta:bi('中国大陆 · Apple 平台开发 10–15 年 · 大型科技 / 互联网公司开发者','Mainland China · 10–15 years on Apple platforms · Large technology / internet company developer')},
{quote:bi('希望 Xcode 能了解其他 App 使用的模式,并在考虑应用适配最佳实践的前提下,复刻相同的模式、UX 和行为。','It would be great if Xcode could know patterns used by other apps and replicate the same pattern, UX, and behavior while keeping app-adaptability best practices in mind.'),meta:bi('欧洲 · Apple 平台开发 7–10 年 · 独立开发者 / Solo Developer','Europe · 7–10 years on Apple platforms · Independent / solo developer')}
]
},
{
title:bi('从开发到上架的完整闭环','The complete path from development to release'),
tags:[bi('端到端工作流','End-to-end workflow'),bi('测试与分发','Testing & distribution'),bi('平台能力','Platform capabilities')],
quotes:[
{quote:bi('请让 Xcode 真正懂「一个 App 从写完到上架」的全过程,不只是懂代码。还有一个很实际的期待:文档要跟上 AI。现在还有不少 API 页面写着 “No overview available”。人看不懂,AI 也只能瞎猜。如果 Xcode 里的 AI 能读到的只有这种空文档,“AI-native”也很难做好;社区也很难通过这个官方来源帮助开发者提供更多 AI 能力。','Please make Xcode truly understand the whole path “from an app being written to being shipped,” not just the code. One very practical expectation is that documentation must keep up with AI. Many API pages still say “No overview available.” If people cannot understand them, AI can only guess. If Xcode’s AI can read only empty documentation, it will be difficult to make “AI-native” work well, and it will be difficult for the community to use this official source to give developers more AI capabilities.'),meta:bi('美国 · Apple 平台开发 4–6 年 · 独立开发者 / Solo Developer','United States · 4–6 years on Apple platforms · Independent / solo developer')},
{quote:bi('Xcode 本身是很强的 Apple 开发工具。如果原生 AI 能直接处理签名、打包、SDK、内存泄漏和性能排查这些 Xcode 专属问题,第三方 AI 很难搞定、现在基本都要手动排查的麻烦就会顺很多。','Xcode is already a powerful Apple-development tool. If its native AI could directly handle Xcode-specific problems such as signing, packaging, SDKs, memory leaks, and performance diagnosis—areas where third-party AI struggles and developers now investigate manually—the workflow would become much smoother.'),meta:bi('中国大陆 · Apple 平台开发 1–3 年 · 小型科技 / 初创公司开发者','Mainland China · 1–3 years on Apple platforms · Small technology / startup company developer')},
{quote:bi('Xcode 就是给创造者用的,不需要把自己变成通用 Agent,也不需要变成 ChatGPT Work。做好它该做的事,更加自动化、更加智能,特别是在分发这个环节尽可能自动化;现在这一段实在太麻烦了。','Xcode is for creators. It does not need to become a general-purpose agent or ChatGPT Work. It should do its own job better—more automated and more intelligent—especially by automating as much as possible in distribution, which is far too troublesome today.'),meta:bi('中国大陆 · Apple 平台开发 7–10 年 · 教师 / 研究人员','Mainland China · 7–10 years on Apple platforms · Educator / researcher')},
{quote:bi('我期待 AI 驱动的动态分析与运行中问题解决能力,也期待通过测试代码来维持质量。','I look forward to improved capabilities in dynamic analysis and issue resolution during program execution, as well as quality maintenance through test code, driven by AI.'),meta:bi('日本 · Apple 平台开发 7–10 年 · 小型科技 / 初创公司开发者','Japan · 7–10 years on Apple platforms · Small technology / startup company developer')},
{quote:bi('能回来使用 Xcode 的可能性,或许在于:具备可与顶级 AI Agent 媲美的自主工作流和更快的更新速度,并把 App Store Connect 整合进 Xcode;现在最后一公里太烦了。','The chance that I return to Xcode may depend on it offering an autonomous workflow comparable to top AI agents, faster updates, and App Store Connect integration. That last mile is far too troublesome today.'),meta:bi('中国大陆 · Apple 平台开发 1–3 年 · 独立开发者 / Solo Developer','Mainland China · 1–3 years on Apple platforms · Independent / solo developer')}
]
},
{
title:bi('Xcode 的未来定位与开放生态','Xcode’s future role and open ecosystem'),
tags:[bi('未来定位','Future positioning'),bi('开放生态','Open ecosystem'),bi('AI-native','AI-native')],
quotes:[
{quote:bi('Xcode 是我过去很多年最熟悉、也最喜欢的工具。直到两年前开始,我不再打开它;不是因为 Xcode 不好,我的 AI 依旧使用 Instruments、Xcode Cloud、Simulator 等能力,只是我作为人类不再打开它。范式改变最残酷的地方,是让过去好用的工具变得矛盾。我期待的不是 Xcode 愈发臃肿地内置 Agent,而是它应该服务好外部 AI Agent,作为一个得力辅助;或者不破不立,做一个真正 AI-native 的 Xcode,而不是让目前已经过度复杂的 Xcode 变得更加复杂。','Xcode has been the tool I know best and like most for many years. But I stopped opening it two years ago—not because Xcode is bad. My AI still uses capabilities such as Instruments, Xcode Cloud, and Simulator; it is simply that I, the human, no longer open it. The cruel part of a paradigm shift is that it can make once-useful tools feel contradictory. What I expect is not an increasingly bloated Xcode with an agent built in. It should serve external AI agents well as a capable assistant; or, if necessary, start over and build a truly AI-native Xcode rather than making an already over-complex Xcode even more complex.'),meta:bi('中国大陆 · Apple 平台开发 7–10 年 · 小型科技 / 初创公司开发者','Mainland China · 7–10 years on Apple platforms · Small technology / startup company developer')},
{quote:bi('我完全理解一个历史悠久的大型软件在转型和创新中的挑战。AI 一方面迅速摧毁原有软件的护城河,另一方面也给了开发者足够的力量和工具去重建它们。过去理所当然的事——例如 Apple 平台开发选择 Xcode 作为 IDE——正在变得不再理所当然。希望 Xcode 团队以一种前所未有的开放心态,面对未来的可能性。','I fully understand the challenge of transforming and innovating a large piece of software with a long history. AI is rapidly tearing down the old moats of software, while also giving developers enough power and tools to rebuild them. Things that once felt self-evident—such as choosing Xcode as the IDE for Apple-platform development—are no longer self-evident. I hope the Xcode team approaches future possibilities with an unprecedented openness.'),meta:bi('日本 · Apple 平台开发 15 年以上 · 大型科技 / 互联网公司开发者','Japan · 15+ years on Apple platforms · Large technology / internet company developer')},
{quote:bi('Xcode 应该有差异化的定位。通用能力上,其他 AI 已经具备;真正值得聚焦的是 Apple 新能力、新框架和新技术场景下更合适的推荐,让开发者能在 Apple 生态里做出更好的产品,而不是与通用模型比泛化能力。','Xcode should have a differentiated role. Other AI tools already offer general-purpose capabilities; Xcode should focus on better recommendations for Apple’s new capabilities, frameworks, and technical scenarios, helping developers build better products in the Apple ecosystem rather than competing with general models on breadth.'),meta:bi('中国大陆 · Apple 平台开发 4–6 年 · 小型科技 / 初创公司开发者','Mainland China · 4–6 years on Apple platforms · Small technology / startup company developer')},
{quote:bi('是否愿意推出一个没有代码编辑器、而完全专注于 Agent 开发的 Xcode 版本?也许是一款在 Xcode 之外、从头围绕 Agent 开发构建的新应用。','Would you be willing to ship a version of Xcode that has no code editor but fully focuses on agentic development? Maybe a new app alongside Xcode, built from scratch around agentic development.'),meta:bi('欧洲 · Apple 平台开发 15 年以上 · 独立开发者 / Solo Developer','Europe · 15+ years on Apple platforms · Independent / solo developer')},
{quote:bi('我现在基本上不用 Xcode,本质原因是我不会写代码。建议重新思考“代码”这件事:代码编译或许已经过去,需要思考如何让创造力在 Xcode 或 Apple 生态里释放出来。','I barely use Xcode now. Fundamentally, I do not write code. I suggest rethinking code itself: coding and compiling may have passed, and we need to consider how to unleash creativity in Xcode and the Apple ecosystem.'),meta:bi('中国大陆 · Apple 平台开发 10–15 年 · 小型科技 / 初创公司开发者','Mainland China · 10–15 years on Apple platforms · Small technology / startup company developer')}
]
}
];
/* ===== Rendering layer (survey data above is untouched) ===== */
const partNumber={profile:1,global:2,china:3,difference:4,xcode:5};
const mk=s=>`<mark>${s}</mark>`;
const hexLum=hex=>{const c=[1,3,5].map(i=>parseInt(hex.slice(i,i+2),16)/255).map(v=>v<=.03928?v/12.92:((v+.055)/1.055)**2.4);return .2126*c[0]+.7152*c[1]+.0722*c[2]};
const inkFor=hex=>{const l=hexLum(hex);return (l+.05)/.07>1.05/(l+.05)?'#0f172a':'#f1f5f9'};
const stripPrefix=html=>html.replace(/^<strong>(洞察:|Insight:)<\/strong>\s*/,'');
const markEvidence=html=>html.replace(/[((]\s*[\d.]+%[^(())]*[))]/g,m=>`<span class="ev">${m}</span>`);
const insightBlock=(html,label)=>html?`<aside class="insight"><span class="insight-label">${label||text(bi('洞察','Insight'))}</span><p>${markEvidence(html)}</p></aside>`:'';
const icons={
chevron:'<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M4 6l4 4 4-4" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>',
cpu:'<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="5" y="5" width="14" height="14" rx="2" fill="none" stroke="currentColor" stroke-width="1.6"/><rect x="9" y="9" width="6" height="6" rx="1" fill="none" stroke="currentColor" stroke-width="1.6"/><path d="M9 2v3M15 2v3M9 19v3M15 19v3M2 9h3M2 15h3M19 9h3M19 15h3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>',
wrench:'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M14.7 6.3a4 4 0 0 0 5 5L21 12.6 12.6 21a2.1 2.1 0 0 1-3-3L18 9.6M14.7 6.3l-3-3A4 4 0 0 0 6 8.5l3.4 1.1" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>',
layers:'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 2l9 5-9 5-9-5 9-5zM3 12l9 5 9-5M3 16.5l9 5 9-5" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round" stroke-linecap="round"/></svg>'
};
const socialIcons={
wechat:'<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M8.691 2.188C3.891 2.188 0 5.476 0 9.53c0 2.212 1.17 4.203 3.002 5.55a.59.59 0 0 1 .213.665l-.39 1.48c-.019.07-.048.141-.048.213 0 .163.13.295.29.295a.326.326 0 0 0 .167-.054l1.903-1.114a.864.864 0 0 1 .717-.098 10.16 10.16 0 0 0 2.837.403c.276 0 .543-.027.811-.05-.857-2.578.157-4.972 1.932-6.446 1.703-1.415 3.882-1.98 5.853-1.838-.576-3.583-4.196-6.348-8.596-6.348ZM5.785 5.991c.642 0 1.162.529 1.162 1.18a1.17 1.17 0 0 1-1.162 1.178A1.17 1.17 0 0 1 4.623 7.17c0-.651.52-1.18 1.162-1.18Zm5.813 0c.642 0 1.162.529 1.162 1.18a1.17 1.17 0 0 1-1.162 1.178 1.17 1.17 0 0 1-1.162-1.178c0-.651.52-1.18 1.162-1.18Zm5.34 2.867c-1.797-.052-3.746.512-5.28 1.786-1.72 1.428-2.687 3.72-1.78 6.22.942 2.453 3.666 4.229 6.884 4.229.826 0 1.622-.12 2.361-.336a.722.722 0 0 1 .598.082l1.584.926a.272.272 0 0 0 .14.047c.134 0 .24-.111.24-.247 0-.06-.023-.12-.038-.177l-.327-1.233a.582.582 0 0 1-.023-.156.49.49 0 0 1 .201-.398C23.024 18.48 24 16.82 24 14.98c0-3.21-2.931-5.837-6.656-6.088v-.003c-.135-.01-.27-.027-.406-.032Zm-2.53 3.274c.535 0 .969.44.969.982a.976.976 0 0 1-.969.983.976.976 0 0 1-.969-.983c0-.542.434-.982.97-.982Zm4.844 0c.535 0 .969.44.969.982a.976.976 0 0 1-.968.983.976.976 0 0 1-.969-.983c0-.542.433-.982.968-.982Z"/></svg>',
x:'<svg viewBox="0 0 30 30" aria-hidden="true"><path fill="currentColor" d="M26.37,26l-8.795-12.822l0.015,0.012L25.52,4h-2.65l-6.46,7.48L11.28,4H4.33l8.211,11.971L12.54,15.97L3.88,26h2.65 l7.182-8.322L19.42,26H26.37z M10.23,6l12.34,18h-2.1L8.12,6H10.23z"/></svg>',
github:'<svg viewBox="0 0 30 30" aria-hidden="true"><path fill="currentColor" d="M15,3C8.373,3,3,8.373,3,15c0,5.623,3.872,10.328,9.092,11.63C12.036,26.468,12,26.28,12,26.047v-2.051 c-0.487,0-1.303,0-1.508,0c-0.821,0-1.551-0.353-1.905-1.009c-0.393-0.729-0.461-1.844-1.435-2.526 c-0.289-0.227-0.069-0.486,0.264-0.451c0.615,0.174,1.125,0.596,1.605,1.222c0.478,0.627,0.703,0.769,1.596,0.769 c0.433,0,1.081-0.025,1.691-0.121c0.328-0.833,0.895-1.6,1.588-1.962c-3.996-0.411-5.903-2.399-5.903-5.098 c0-1.162,0.495-2.286,1.336-3.233C9.053,10.647,8.706,8.73,9.435,8c1.798,0,2.885,1.166,3.146,1.481C13.477,9.174,14.461,9,15.495,9 c1.036,0,2.024,0.174,2.922,0.483C18.675,9.17,19.763,8,21.565,8c0.732,0.731,0.381,2.656,0.102,3.594 c0.836,0.945,1.328,2.066,1.328,3.226c0,2.697-1.904,4.684-5.894,5.097C18.199,20.49,19,22.1,19,23.313v2.734 c0,0.104-0.023,0.179-0.035,0.268C23.641,24.676,27,20.236,27,15C27,8.373,21.627,3,15,3z"/></svg>',
email:'<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M 4 4 C 2.895 4 2 4.895 2 6 L 2 18 C 2 19.105 2.895 20 4 20 L 20 20 C 21.105 20 22 19.105 22 18 L 22 6 C 22 4.895 21.105 4 20 4 L 4 4 z M 4 6 L 20 6 L 20 7.0019531 L 12 12 L 4 7.0019531 L 4 6 z M 4 9.0019531 L 12 14 L 20 9.0019531 L 20 18 L 4 18 L 4 9.0019531 z"/></svg>',
};
function section(id,part,title,ledes,body){const n=partNumber[id];return `<section id="chapter-${n}" class="section report-part part-${id}"><div class="section-inner"><header class="part-head"><div class="part-meta"><span class="part-no">0${n}</span><span class="part-label">${text(part)}</span></div><div class="part-title"><h2>${text(title)}</h2><div class="part-ledes">${ledes.map(l=>`<p>${text(l)}</p>`).join('')}</div></div></header>${body}</div></section>`}
function questionType(type){return `<span class="badge">${text(bi(type==='single'?'单选题':'多选题',type==='single'?'Single choice':'Multiple choice'))}</span>`}
function card({cls='',id='',eyebrow='',title,type,insight='',insightLabel,body,foot='',tools=''}){return `<article class="card ${cls}"${id?` id="${id}"`:''}><header class="card-head"><div class="card-titles">${eyebrow?`<span class="eyebrow">${eyebrow}</span>`:''}<h3>${text(title)}</h3></div>${type?questionType(type):''}</header>${insight?`<div class="card-insight">${insightBlock(insight,insightLabel)}</div>`:''}${tools?`<div class="card-tools">${tools}</div>`:''}<div class="card-body">${body}</div>${foot?`<footer class="card-foot">${foot}</footer>`:''}</article>`}
const note=html=>`<p class="note"><strong>${text(bi('注意:','Note: '))}</strong>${html}</p>`;
/* ---- Pie charts (Part 1) ---- */
const blueRamp=['#bfdbfe','#93c5fd','#60a5fa','#3b82f6','#2563eb','#1d4ed8'];
function pieChart(items,ramp,rich=false){
const total=items.reduce((a,[,v])=>a+v,0);const R=96,C=100;let a0=-Math.PI/2;
const pt=(a,r=R)=>[C+r*Math.cos(a),C+r*Math.sin(a)];
const slices=items.map(([label,value],i)=>{
if(!value)return '';
const a1=a0+value/total*2*Math.PI;const mid=(a0+a1)/2;const [x0,y0]=pt(a0),[x1,y1]=pt(a1);
const d=`M${C} ${C}L${x0.toFixed(2)} ${y0.toFixed(2)}A${R} ${R} 0 ${a1-a0>Math.PI?1:0} 1 ${x1.toFixed(2)} ${y1.toFixed(2)}Z`;
const [tx,ty]=pt(mid,R*.66);a0=a1;
const localized=bi(label,labelTranslations[label]||label);
return `<g data-slice="${i}"><path d="${d}" fill="${ramp[i]}"><title>${text(localized)}: ${value}%</title></path>${value>=7?`<text x="${tx.toFixed(1)}" y="${ty.toFixed(1)}" fill="${inkFor(ramp[i])}">${value}%</text>`:''}</g>`}).join('');
const legend=items.map(([label,value],i)=>{const localized=bi(label,labelTranslations[label]||label);return `<li data-slice="${i}"><i style="background:${ramp[i]}"></i><span>${text(localized)}</span><strong>${value}%</strong>${rich?`<em class="pie-bar"><u style="width:${value}%;background:${ramp[i]}"></u></em>`:''}</li>`}).join('');
return `<div class="pie-wrap${rich?' is-rich':''}"><svg class="pie" viewBox="0 0 200 200" role="img">${slices}</svg><ul class="pie-legend">${legend}</ul></div>`}
function setupPies(){document.querySelectorAll('.pie-wrap').forEach(wrap=>{const nodes=[...wrap.querySelectorAll('[data-slice]')];const set=i=>nodes.forEach(n=>n.classList.toggle('is-dim',i!==null&&n.dataset.slice!==i));nodes.forEach(n=>{n.addEventListener('mouseenter',()=>set(n.dataset.slice));n.addEventListener('mouseleave',()=>set(null))})})}
/* ---- Part 3 usage rankings ---- */
const segLabel=(long,short)=>`<span class="seg-long">${text(long)}</span><span class="seg-short">${text(short)}</span>`;
const usageSegment=()=>`<div class="seg" role="group" aria-label="${text(bi('按地区查看','Filter by region'))}"><button type="button" class="is-active" data-usage-group="all" aria-pressed="true">${text(bi('全部','All'))}<small>100</small></button><button type="button" data-usage-group="china" aria-pressed="false"><i class="dot is-china"></i>${segLabel(bi('大中华区(含港澳台)开发者','Greater China (incl. HK, MO & TW)'),bi('中国','China'))}<small>60</small></button><button type="button" data-usage-group="overseas" aria-pressed="false"><i class="dot is-overseas"></i>${segLabel(bi('海外地区开发者','Overseas developers'),bi('海外','Overseas'))}<small>40</small></button></div>`;
const usageRows=items=>items.map(([label,chinaRate,overseasRate],index)=>`<div class="u-row${index>4?' is-extra':''}"><h4>${text(label)}</h4><div class="u-bar is-china" style="--rate:${chinaRate}%"><i></i><b>${chinaRate.toFixed(1)}%</b></div><div class="u-bar is-overseas" style="--rate:${overseasRate}%"><i></i><b>${overseasRate.toFixed(1)}%</b></div></div>`).join('');
const usageToggle=extra=>extra?`<button class="more-toggle" type="button" aria-expanded="false"><span class="show-more">${text(bi(`加载更多(后 ${extra} 项)`,`Show more (next ${extra})`))}</span><span class="show-less">${text(bi(`收起后 ${extra} 项`,`Collapse ${extra} items`))}</span></button>`:'';
function chinaUsageRanking(id,title,description,items,insight,takeaway,type='multiple'){
const config=usageRankingConfigs[id];const value=(key,fallback)=>config&&Object.hasOwn(config,key)?config[key]:fallback;
const resolvedItems=value('items',items);const resolvedTakeaway=value('takeaway',takeaway);const resolvedInsight=value('insight',insight);
const extra=Math.max(0,resolvedItems.length-5);const body=`<div class="u-list">${usageRows(resolvedItems)}</div>${usageToggle(extra)}`;
const insightHtml=text(resolvedTakeaway||resolvedInsight||bi('',''));
return card({cls:'usage-card',id,title:value('title',title),type,insight:insightHtml,tools:usageSegment(),body}).replace('<article class="card usage-card"','<article data-group="all" class="card usage-card"')}
const q15Views=[['models','models',icons.cpu,bi('模型','Models'),bi('仅从模型维度出发,不考虑与工具 / 使用入口的组合','Consider models only, not their combinations with tools or entry points')],['tools','tools',icons.wrench,bi('工具 / 使用入口','Tools & Entry Points'),bi('仅从工具 / 使用入口维度出发,不考虑与模型的组合','Consider tools and entry points only, not their combinations with models')],['both','combinations',icons.layers,bi('工具 / 使用入口 + 模型','Tools & Entry Points + Models'),bi('从工具 / 使用入口与模型的组合维度出发','Consider combinations of tools, entry points, and models')]];
function q15Panel(kind,items,view){const visible=items.slice(0,10);const extra=Math.max(0,visible.length-5);return `<div class="q15-panel" data-q15-panel="${view}" hidden>${insightBlock(stripPrefix(text(q15Insights[kind])))}<div class="u-list">${usageRows(visible)}</div>${usageToggle(extra)}</div>`}
function q15PreferenceRanking(){
const tabs=q15Views.map(([view,,icon,label,description])=>`<button type="button" role="tab" data-q15-view="${view}" data-q15-label="${text(label)}" aria-selected="false"><span class="tab-icon">${icon}</span><span class="tab-copy"><b>${text(label)}</b><small>${text(description)}</small></span></button>`).join('');
const title=bi('基于实际体验,你最看好<span class="q15-choice"></span>配合 Xcode 进行研发?','Based on actual experience, which <span class="q15-choice"></span> do you rate most highly for development alongside Xcode?');
const ctx=note(text(bi('受访者普遍拥有较长开发经验,且大部分开发者的技术栈不止于 Apple 平台;前述工具排序反映的是通用开发背景下的使用情况,而本题聚焦与 Xcode 协作的 Apple 开发场景。','Respondents generally have substantial development experience, and most work across technical stacks beyond Apple platforms. The earlier tool ranking reflects use in general development contexts, while this question focuses on Apple development alongside Xcode.')));
const body=`${ctx}<div class="q15-tabs" role="tablist">${tabs}</div>${q15Panel('models',q15.models,'models')}${q15Panel('tools',q15.tools,'tools')}${q15Panel('combinations',q15.combinations,'both')}<div class="q15-pager"><button type="button" data-q15-step="-1">← ${text(bi('上一个维度','Previous view'))}</button><span class="q15-count"></span><button type="button" data-q15-step="1">${text(bi('下一个维度','Next view'))} →</button></div>`;
return card({cls:'usage-card q15-card',title,type:'grouped',tools:usageSegment(),body}).replace('<article class="card usage-card q15-card"','<article data-group="all" data-q15-view="models" class="card usage-card q15-card"')}
function setupChinaUsageRankings(){
document.querySelectorAll('.usage-card').forEach(cardEl=>{
cardEl.querySelectorAll('.more-toggle').forEach(toggle=>toggle.addEventListener('click',()=>{const container=toggle.closest('.q15-panel')||cardEl;const expanded=!container.classList.contains('is-expanded');container.classList.toggle('is-expanded',expanded);toggle.setAttribute('aria-expanded',String(expanded))}));
cardEl.querySelectorAll('[data-usage-group]').forEach(button=>button.addEventListener('click',()=>{cardEl.dataset.group=button.dataset.usageGroup;cardEl.querySelectorAll('[data-usage-group]').forEach(b=>{const on=b===button;b.classList.toggle('is-active',on);b.setAttribute('aria-pressed',String(on))})}));
if(cardEl.classList.contains('q15-card')){
const views=q15Views.map(v=>v[0]);const choice=cardEl.querySelector('.q15-choice');
const show=view=>{cardEl.dataset.q15View=view;const index=views.indexOf(view);cardEl.querySelectorAll('.q15-tabs [data-q15-view]').forEach(tab=>{const on=tab.dataset.q15View===view;tab.classList.toggle('is-active',on);tab.setAttribute('aria-selected',String(on))});cardEl.querySelectorAll('[data-q15-panel]').forEach(panel=>panel.hidden=panel.dataset.q15Panel!==view);choice.textContent=cardEl.querySelector(`.q15-tabs [data-q15-view="${view}"]`).dataset.q15Label;cardEl.querySelector('.q15-count').textContent=`${index+1} / ${views.length}`;cardEl.querySelector('[data-q15-step="-1"]').disabled=index===0;cardEl.querySelector('[data-q15-step="1"]').disabled=index===views.length-1};
cardEl.querySelectorAll('.q15-tabs [data-q15-view]').forEach(tab=>tab.addEventListener('click',()=>show(tab.dataset.q15View)));
cardEl.querySelectorAll('[data-q15-step]').forEach(button=>button.addEventListener('click',()=>show(views[views.indexOf(cardEl.dataset.q15View)+Number(button.dataset.q15Step)])));
show('models')}
})}
/* ---- Part 1 ---- */
const profileCard=(title,type,body,cls='')=>card({cls,title,type,body});
function experiencePie(title,items){return profileCard(title,'single',pieChart(items,blueRamp),'pie-card')}
function scalePie(items){return pieChart(items,['#bfdbfe','#60a5fa','#3b82f6','#1d4ed8'],true)}
/* ---- Part 2 ---- */
function aiLifecycle(){
const stages=part2.stages.map((stage,index)=>({...stage,index}));
const firstOpen=stages.filter(stage=>stage.expandable!==false).reduce((a,b)=>b.value>a.value?b:a).index;
const rows=stages.map(stage=>{
const expandable=stage.expandable!==false;
const head=`<span class="lc-name">${text(stage.label)}</span><span class="lc-track"><i style="--fill:${stage.value}%"></i></span><strong class="lc-val">${stage.value}%</strong>${expandable?`<span class="lc-chev">${icons.chevron}</span>`:'<span class="lc-chev"></span>'}`;
if(!expandable)return `<div class="lc-item is-static"><div class="lc-row">${head}</div></div>`;
const open=stage.index===firstOpen;
const sub=stage.items.map(([label,value])=>`<div class="lc-sub"><span>${text(label)}</span><span class="lc-track"><i style="--fill:${value}%"></i></span><strong>${value}%</strong></div>`).join('');
return `<div class="lc-item${open?' is-open':''}"><button class="lc-row" type="button" aria-expanded="${open}">${head}</button><div class="lc-detail"><div class="lc-detail-inner"><p class="lc-sub-title">${text(stage.label)}${text(bi('的细分类别',' details'))}</p>${sub}</div></div></div>`}).join('');
return card({cls:'lifecycle',title:bi('你目前会在哪些开发环节使用 AI?','Where do you use AI in development?'),type:'multiple',body:`<p class="lc-hint">${icons.chevron}<span>${text(bi('点击带箭头的环节,展开查看细分占比。','Tap a stage with an arrow to see its breakdown.'))}</span></p><div class="lc-list">${rows}</div>`,foot:`<span class="hint-chip">${icons.chevron}</span>${text(bi('点击右侧带箭头的环节,展开更详细的开发环节占比。按研发流程顺序排列。','Select a stage with an arrow to expand its detailed shares. Stages follow the order of the development process.'))}`})}
function workflowPodium(){
const [first,second,third]=part2.workflows;const max=first.value;
const podium=[{item:second,rank:2},{item:first,rank:1},{item:third,rank:3}];
const insight=text(bi('<b>12%</b> 受访者坚持以自己为主导来完成开发与验证,主要采用讨论、补全、手动添加代码等方式;<b>1%</b> 的开发者基本不使用 AI 编程。','<b>12%</b> of respondents remain developer-led for development and validation, primarily using discussion, completion, and manually adding code; <b>1%</b> of developers hardly use AI coding.'));
const body=`<div class="podium">${podium.map(({item,rank})=>`<div class="pod place-${rank}"><div class="pod-stage"><div class="pod-bar" style="--h:${Math.round(item.value/max*190)}px"><b>${item.value}%</b><span>${rank}</span></div></div><p>${text(item.label)}</p></div>`).join('')}</div>`;
return card({cls:'workflow',eyebrow:'Q13',title:bi('开发者与 AI 的合作方式','How Developers Collaborate with AI'),type:'single',insight,body})}
const frequencyColors=['#52525b','#155e75','#0e7490','#22b8d9','#a5f3fc'];
function frequencyMatrix(){
const order=part2.frequency.map((item,index)=>({item,index})).reverse();let offset=0;
const cells=order.flatMap(({item,index})=>Array.from({length:item.value},()=>`<i class="f-cell" data-frequency-index="${index}" style="--c:${frequencyColors[index]};--o:${offset++}"></i>`)).join('');
const controls=order.map(({item,index})=>`<button type="button" class="f-control" data-frequency-index="${index}" aria-pressed="false"><i style="background:${frequencyColors[index]}"></i><span>${text(item.label)}</span><strong>${item.value}%</strong></button>`).join('');
return card({cls:'frequency',eyebrow:'Q8',title:bi('过去 30 天的 AI 使用频率','AI use frequency in the past 30 days'),type:'single',body:`<div class="f-layout"><div class="f-controls" role="group" aria-label="${text(bi('AI 使用频率','AI use frequency'))}">${controls}</div><div class="f-grid" aria-label="${text(bi('100 位受访者的 AI 使用频率方块图','100-respondent AI-use frequency matrix'))}">${cells}</div></div>`,foot:text(bi('每个方块代表 1 位受访者;点击左侧选项可高亮对应人群。','Each square represents one respondent; select an option on the left to highlight that group.'))})}
function selectionRanking(){
const side=(label,value,muted)=>`<div class="sel-cell${muted?' is-muted':''}"><div class="sel-label"><span>${text(label)}</span><strong>${value}%</strong></div><i class="bar"><em style="--fill:${value}%"></em></i></div>`;
const rows=part2.selectionTop.map(([top,topValue],index)=>{const [bottom,bottomValue]=part2.selectionBottom[index];return `<div class="sel-row">${side(top,topValue,false)}<span class="sel-rank">${index+1}</span>${side(bottom,bottomValue,true)}</div>`}).join('');
const compactList=(head,items,muted)=>`<div class="sel-compact-group${muted?' is-least':''}"><p class="sel-compact-head">${text(head)}</p>${items.map(([label,value],index)=>`<div class="sel-compact-row"><span class="sel-rank">${index+1}</span>${side(label,value,muted)}</div>`).join('')}</div>`;
const compact=`<div class="sel-compact">${compactList(bi('最看重 · 排名前五','Most valued · Top five'),part2.selectionTop,false)}${compactList(bi('最不看重','Least valued'),part2.selectionBottom,true)}</div>`;
const body=`<div class="sel-wide"><div class="sel-head"><span>${text(bi('最看重 · 排名前五','Most valued · Top five'))}</span><span></span><span>${text(bi('最不看重','Least valued'))}</span></div><div class="sel-table">${rows}</div></div>${compact}`;
return card({cls:'selection',eyebrow:'Q18',title:bi('选择 AI 编程工具时,最看重什么?','What matters most when choosing an AI coding tool?'),type:'multiple',body})}
function codeLocation(){
const [primary,secondary]=part2.codeLocations;
const tile=(item,cls)=>`<div class="loc-tile ${cls}"><strong class="loc-share">${text(item.workshare)}</strong><p><b>${item.respondentShare}%</b><span>${text(bi(cls==='is-primary'?'受访者选择此项':'受访者选择此档',cls==='is-primary'?'of respondents selected this':'of respondents'))}</span></p></div>`;
const insight=text(bi('开发重心已转向其他工具,Xcode 不再是主要入口。','Development has shifted to other tools; Xcode is no longer the primary entry point.'));
return card({cls:'code-location',eyebrow:'Q6',title:bi('开发工作有多少仍在 Xcode 中完成?','How much work still happens in Xcode?'),type:'single',body:`<div class="loc-hero"><img src="${ROOT}assets/xcode-icon.png" alt="Xcode" loading="lazy"></div><div class="loc-stack">${tile(primary,'is-primary')}${tile(secondary,'is-secondary')}</div>${insightBlock(insight)}`})}
function xcodeRoles(){
const first=3,trailing=3;
const insight=text(bi('<b>Build / Compile</b>、<b>Simulator</b>、<b>Debug</b>与<b>Signing / Provisioning</b>构成受访者最常归于 Xcode 的关键工具链职责。相比之下,<b>AI 辅助编程</b>与<b>测试</b>较少被视为 Xcode 的角色。仅 <b>5%</b> 认为 Xcode 基本承担完整开发工作流;这可能说明 Xcode 已不是多数受访者开发 Apple 应用的唯一选择,搭配 Xcode 之外的工具完成全流程已成为主流工作方式。','<b>Build / Compile</b>, <b>Simulator</b>, <b>Debug</b>, and <b>Signing / Provisioning</b> are the key toolchain responsibilities respondents most often assign to Xcode. In contrast, <b>AI-assisted coding</b> and <b>testing</b> are rarely attributed to it. Only <b>5%</b> say Xcode essentially covers their complete workflow. This may suggest that Xcode is no longer the only choice for most respondents building Apple apps, and that pairing it with tools outside Xcode has become the mainstream way to complete the full workflow.'));
const rows=part2.roles.map(([label,value],index)=>`${index===first?`<button class="more-toggle role-more" type="button" aria-expanded="false">${text(bi('+ 查看更多','+ View more'))}</button>`:''}<div class="role-row${index>=first&&index<part2.roles.length-trailing?' role-extra':''}"><div class="sel-label"><span>${text(label)}</span><strong>${value}%</strong></div><i class="bar"><em style="--fill:${value}%"></em></i></div>`).join('');
return card({cls:'xcode-roles',eyebrow:'Q7',title:bi('如今,Xcode 在你的开发工作中主要承担哪些角色?','What roles does Xcode mainly play in your development work today?'),type:'multiple',insight,body:`<div class="role-list">${rows}<button class="more-toggle role-collapse" type="button" aria-expanded="true">${text(bi('− 收起','− Collapse'))}</button></div>`})}
function setupPart2Interactions(){
const lifecycle=document.querySelector('.lifecycle');
lifecycle?.querySelectorAll('button.lc-row').forEach(button=>button.addEventListener('click',()=>{const item=button.closest('.lc-item');const open=!item.classList.contains('is-open');lifecycle.querySelectorAll('.lc-item').forEach(node=>{node.classList.remove('is-open');node.querySelector('button.lc-row')?.setAttribute('aria-expanded','false')});if(open){item.classList.add('is-open');button.setAttribute('aria-expanded','true')}}));
const matrix=document.querySelector('.frequency');
const setFrequency=index=>{matrix?.classList.toggle('has-active',index!==null);matrix?.querySelectorAll('.f-control').forEach(node=>{const on=Number(node.dataset.frequencyIndex)===index;node.classList.toggle('is-active',on);node.setAttribute('aria-pressed',String(on))});matrix?.querySelectorAll('.f-cell').forEach(cell=>cell.classList.toggle('is-active',Number(cell.dataset.frequencyIndex)===index))};
let pinned=null;
matrix?.querySelectorAll('.f-control').forEach(button=>{const index=Number(button.dataset.frequencyIndex);button.addEventListener('mouseenter',()=>setFrequency(index));button.addEventListener('mouseleave',()=>setFrequency(pinned));button.addEventListener('focus',()=>setFrequency(index));button.addEventListener('blur',()=>setFrequency(pinned));button.addEventListener('click',()=>{pinned=pinned===index?null:index;setFrequency(pinned)})});
const roles=document.querySelector('.xcode-roles');const setExpanded=expanded=>{roles?.classList.toggle('is-expanded',expanded);roles?.querySelector('.role-more')?.setAttribute('aria-expanded',String(expanded));roles?.querySelector('.role-collapse')?.setAttribute('aria-expanded',String(expanded))};
roles?.querySelector('.role-more')?.addEventListener('click',()=>setExpanded(true));roles?.querySelector('.role-collapse')?.addEventListener('click',()=>setExpanded(false));
}
/* ---- Part 4 ---- */
const waffleCells=value=>Array.from({length:100},(_,index)=>`<i class="w-cell${index<value?' is-filled':''}" aria-hidden="true"></i>`).join('');
function setupWaffleScrollers(){document.querySelectorAll('.waffle-scroller').forEach(scroller=>{const row=scroller.querySelector('.waffle-row');const [prev,next]=scroller.querySelectorAll('[data-paddle]');const sync=()=>{prev.disabled=row.scrollLeft<=2;next.disabled=row.scrollLeft+row.clientWidth>=row.scrollWidth-2};scroller.querySelectorAll('[data-paddle]').forEach(button=>button.addEventListener('click',()=>{const item=row.querySelector('.waffle-item');const step=item?item.getBoundingClientRect().width*2:row.clientWidth*.8;row.scrollBy({left:Number(button.dataset.paddle)*step,behavior:'smooth'})}));row.addEventListener('scroll',sync,{passive:true});new ResizeObserver(sync).observe(row);sync()})}
function xcodeQuestionReport(report){
if(report.type==='treemap')return xcodeQuestionTreemap(report);
const waffles=`<div class="waffle-scroller"><div class="waffle-row" role="list" tabindex="0" aria-label="${text(report.title)}">${report.items.map(([label,value])=>`<article class="waffle-item" role="listitem"><div class="waffle" role="img" aria-label="${text(label)}: ${value}%">${waffleCells(value)}</div><div class="waffle-copy"><strong>${value}%</strong><p>${text(label)}</p></div></article>`).join('')}</div><div class="paddles"><button type="button" class="paddle" data-paddle="-1" aria-label="${text(bi('向左滚动','Scroll left'))}">${icons.chevron}</button><button type="button" class="paddle" data-paddle="1" aria-label="${text(bi('向右滚动','Scroll right'))}">${icons.chevron}</button></div></div>`;
const body=waffles+`<ol class="rank-list">${report.items.map(([label,value],index)=>`<li class="rank-row"><span class="rank-no">${index+1}</span><span class="rank-label">${text(label)}</span><strong>${value}%</strong><i class="bar"><em style="--fill:${value}%"></em></i></li>`).join('')}</ol>`;
return card({cls:'q-card',id:report.id,title:report.title,type:report.questionType||'multiple',insight:stripPrefix(text(report.insight)),body})}
function squarify(items,x,y,w,h){
const out=[];let rest=items.slice();
const worst=(row,s)=>{const sum=row.reduce((a,b)=>a+b.a,0);const mx=Math.max(...row.map(r=>r.a)),mn=Math.min(...row.map(r=>r.a));return Math.max(s*s*mx/(sum*sum),sum*sum/(s*s*mn))};
while(rest.length){
const short=Math.min(w,h);let row=rest.length===2?rest.slice():[rest[0]];let i=row.length;
while(i<rest.length){const next=[...row,rest[i]];if(worst(next,short)<=worst(row,short)){row=next;i++}else break}
const sum=row.reduce((a,b)=>a+b.a,0);
if(w>=h){const rw=sum/h;let cy=y;row.forEach(r=>{const rh=r.a/rw;out.push({...r,x,y:cy,w:rw,h:rh});cy+=rh});x+=rw;w-=rw}
else{const rh=sum/w;let cx=x;row.forEach(r=>{const rw=r.a/rh;out.push({...r,x:cx,y,w:rw,h:rh});cx+=rw});y+=rh;h-=rh}
rest=rest.slice(row.length)}
return out}
/* Purple tiles: deeper background → paler, still violet-tinted, text. Never pure black or white. */
function treemapTone(t){
const steps=[[.75,30,96],[.45,42,95],[.3,76,26],[.0,90,30]];
const [,bgL,fgL]=steps.find(([min])=>t>=min);
const s=t>=.45?52:62;
return `--bg:hsl(262 ${s}% ${bgL}%);--fg:hsl(262 ${t>=.45?95:60}% ${fgL}%)`}
function xcodeQuestionTreemap(report){
const W=100,H=56;const max=Math.max(...report.items.map(i=>i[1]));/* Shares under 7% sit in a full-width strip along the bottom so their labels have room. */
const main=report.items.filter(i=>i[1]>=7),tail=report.items.filter(i=>i[1]<7);const SH=tail.length?6:0;
const sum=main.reduce((a,i)=>a+i[1],0),tailSum=tail.reduce((a,i)=>a+i[1],0);
const laid=squarify(main.map(([label,value])=>({label,value,a:value/sum*W*(H-SH)})),0,0,W,H-SH);
let tx=0;tail.forEach(([label,value])=>{const w=value/tailSum*W;laid.push({label,value,x:tx,y:H-SH,w,h:SH});tx+=w});
const tiles=laid.map(t=>{const size=t.value>=30?'is-l':t.value>=15?'is-m':t.value>=4?'is-s':'is-xs';const row=t.w/t.h>3?' is-row':'';return `<article class="tile ${size}${row}" role="listitem" tabindex="0" title="${text(t.label)}: ${t.value}%" aria-label="${text(t.label)}: ${t.value}%" style="left:${t.x}%;top:${t.y/H*100}%;width:${t.w}%;height:${t.h/H*100}%;${treemapTone(t.value/max)}"><strong>${t.value}%</strong><p>${text(t.label)}</p></article>`}).join('');
return card({cls:'q-card is-treemap',id:report.id,title:report.title,type:report.questionType||'multiple',insight:stripPrefix(text(report.insight)),body:`<div class="treemap" role="list">${tiles}</div>`,tools:note(text(bi('列表按选择比例从高到低排序,颜色越深占比越高;每位受访者最多选择 3 项,选项可重叠,因此比例不相加为 100%。','Ranked by selection share, with darker rows indicating higher shares. Each respondent selected up to three capabilities; choices overlap, so percentages do not sum to 100%.'))),foot:note(text(report.note))})}
function prioritySpotlight(){
const ranked=priorities.map((p,i)=>({...p,i})).sort((a,b)=>b.rate-a.rate||a.i-b.i);
const top=ranked.slice(0,3);const remaining=ranked.slice(3);
const deckColors=['#8b5cf6','#7c3aed','#6d28d9','#a78bfa','#9061f9','#5b21b6'];
const leaders=top.map((p,index)=>`<article class="leader"><span class="leader-rank">0${index+1}</span><strong>${text(p.label)}</strong><b>${p.rate.toFixed(1)}%</b></article>`).join('');
const deck=remaining.map((p,index)=>`<div class="deck-card" data-priority-index="${index}"><span class="deck-rate">${p.rate.toFixed(1)}%</span><span class="deck-title">${text(p.label)}</span></div>`).join('');
return `<article class="card priority" aria-labelledby="q23-title"><header class="card-head"><div class="card-titles"><h3 id="q23-title">${text(bi('未来一年,开发者最希望 Xcode 优先改善什么?','Over the next year, what do developers most want Xcode to improve first?'))}</h3></div>${questionType('single')}</header><div class="priority-layout"><div class="priority-leaders"><span class="chip">${text(bi('呼声最高的三项','Three most requested improvements'))}</span>${leaders}</div><div class="priority-more"><span class="chip is-muted">${text(bi('更多改善方向','More improvement areas'))}</span><div class="deck" data-priority-deck aria-live="polite">${deck}</div><div class="deck-pager"><button type="button" data-deck-step="-1">← ${text(bi('上一项','Previous'))}</button><span class="deck-count"></span><button type="button" data-deck-step="1">${text(bi('下一项','Next'))} →</button></div></div></div></article>`}
function setupPriorityDeck(){document.querySelectorAll('[data-priority-deck]').forEach(deck=>{const cards=[...deck.querySelectorAll('.deck-card')];const pager=deck.parentElement.querySelector('.deck-pager');let offset=0;const update=()=>{cards.forEach((c,index)=>{const position=(index-offset+cards.length)%cards.length;c.style.setProperty('--pos',Math.min(position,3));c.dataset.pos=Math.min(position,3);c.classList.toggle('is-top',position===0);c.setAttribute('aria-hidden',String(position!==0))});pager.querySelector('.deck-count').textContent=`${offset+1} / ${cards.length}`};const step=n=>{offset=(offset+n+cards.length)%cards.length;update()};pager.querySelectorAll('[data-deck-step]').forEach(b=>b.addEventListener('click',()=>step(Number(b.dataset.deckStep))));deck.addEventListener('click',event=>{if(event.target.closest('.deck-card.is-top'))step(1)});update()})}
function voiceLibrary(){return `<section class="voice-library voice-editorial" data-voice-library><div class="voice-editorial-layout"><header class="voice-editorial-heading"><h3>${text(bi('五类真实声音,分别指向 Xcode 的不同期待','Five themes of direct developer feedback'))}</h3></header><div class="voice-editorial-body"><nav class="voice-topic-list" role="tablist" aria-label="${text(bi('Q24 反馈主题','Q24 feedback themes'))}">${voiceModules.map((module,index)=>`<button class="voice-topic${index===0?' is-active':''}" type="button" role="tab" data-voice-topic="${index}" aria-selected="${index===0}" aria-controls="voice-transcript"><span>0${index+1}</span><strong>${text(module.title)}</strong></button>`).join('')}</nav><article id="voice-transcript" class="voice-transcript" role="tabpanel" aria-live="polite"></article></div></div></section>`}
const q15Insights={tools:bi('<strong>洞察:</strong>工具层面,OpenAI 与 Anthropic 仍居前列;但中国样本在这一场景下会优先考虑 DeepSeek Harness,这与前题中 Cursor 排在 DeepSeek Harness 之前的结果相反。海外样本则无人选择 Xcode + DeepSeek Harness。除此之外,Xcode 内置 AI / Coding Intelligence 是两组在 OpenAI 与 Anthropic 之外较受信赖的选项之一,尽管它在前述通用场景中的排序较低。','<strong>Insight:</strong> At the tool level, OpenAI and Anthropic remain the leading choices. In the China sample, however, DeepSeek Harness is prioritized in this context—reversing the earlier result where Cursor ranked above it. No overseas respondents selected Xcode + DeepSeek Harness. Beyond OpenAI and Anthropic, Xcode’s built-in AI / Coding Intelligence is one of the more trusted options across the two groups, despite ranking lower in the earlier general-use context.'),models:bi('<strong>洞察:</strong>模型层面,OpenAI 与 Anthropic 仍居前列;但在与 Xcode 结合的中国模型选择上,海外样本的排序为 Kimi、DeepSeek、GLM,国内样本则为 DeepSeek、GLM、Kimi。这一差异显示,Kimi 在国内外样本中的偏好呈现较明显分化。','<strong>Insight:</strong> At the model level, OpenAI and Anthropic remain the leading choices. For China-based models used alongside Xcode, however, the overseas sample ranks Kimi, DeepSeek, then GLM, while the China sample ranks DeepSeek, GLM, then Kimi. This difference indicates a clear divergence in Kimi preference between the two samples.'),combinations:bi('<strong>洞察:</strong>工具与模型的组合中,头部仍以 OpenAI 和 Anthropic 为主。海外样本的其他选择较少,也主要集中于二者;中国样本的组合选择则更趋多元化,其中 DeepSeek Harness 是较多中国开发者的选择,且优于 Xcode 内置 AI / Coding Intelligence。','<strong>Insight:</strong> Across tool-and-model combinations, OpenAI and Anthropic still lead. Overseas respondents make relatively few other choices, with most concentrated around these two; the China sample shows more diverse combinations, with DeepSeek Harness selected by more respondents than Xcode’s built-in AI / Coding Intelligence.')};
const usageRankingConfigs={
'china-model-usage':{items:chinaUsage.models},
'china-tool-usage':{title:bi('过去 30 天内,受访者最常用的 AI Coding / Agent 工具是什么?','Which AI coding / agent tools did respondents use most in the past 30 days?'),description:'',items:chinaUsage.tools,insight:'',takeaway:bi('中国开发者实际使用率最高的<strong>国产</strong> AI Coding / Agent 工具为<strong>中国公司开发的通用对话产品</strong>、<strong>DeepSeek Harness</strong>和<strong>WorkBuddy</strong>;使用率最高的<strong>海外</strong>工具为<strong>OpenAI Codex</strong>、<strong>ChatGPT</strong>和<strong>Claude Code</strong>。<br><br>海外开发者实际使用率最高的<strong>国产</strong>工具为<strong>Kimi Code</strong>;<strong>TRAE</strong>、<strong>Manus</strong>、<strong>DeepSeek Harness</strong>和<strong>中国公司开发的通用对话产品</strong>均为<strong>3.1%</strong>,并列其后。使用率最高的<strong>海外</strong>工具为<strong>Claude Code</strong>、<strong>OpenAI Codex</strong>和<strong>ChatGPT</strong>。','Among developers in China, the most-used <strong>China-based</strong> AI coding / agent tools are <strong>general chat products developed by Chinese companies</strong>, <strong>DeepSeek Harness</strong>, and <strong>WorkBuddy</strong>. The most-used <strong>overseas</strong> tools are <strong>OpenAI Codex</strong>, <strong>ChatGPT</strong>, and <strong>Claude Code</strong>.<br><br>Among overseas developers, <strong>Kimi Code</strong> is the most-used <strong>China-based</strong> tool. <strong>TRAE</strong>, <strong>Manus</strong>, <strong>DeepSeek Harness</strong>, and <strong>general chat products developed by Chinese companies</strong> are tied next at <strong>3.1%</strong>. The most-used <strong>overseas</strong> tools are <strong>Claude Code</strong>, <strong>OpenAI Codex</strong>, and <strong>ChatGPT</strong>.')},
'china-entry-point-usage':{title:bi('开发者通常在哪里使用或运行 AI Coding / Agent?','Where do developers usually use or run AI coding / agents?'),description:'',items:chinaUsage.entryPoints,insight:'',takeaway:bi('中国与海外开发者的入口结构大体一致:<strong>独立桌面 Agent 应用</strong>、<strong>CLI / Terminal Agent</strong>与<strong>IDE / 代码编辑器中的 Agent</strong>均位列两组的前三大入口。值得关注的是,在<strong>云端异步 Coding Agent</strong>上,<strong>8.5%</strong> 的中国开发者已尝试,海外开发者为<strong>0.0%</strong>。','Entry-point patterns are broadly similar in China and overseas: <strong>standalone desktop agent apps</strong>, <strong>CLI / terminal agents</strong>, and <strong>agents in IDEs / code editors</strong> are the top three entry points in both groups. One notable observation is <strong>cloud-based asynchronous coding agents</strong>: <strong>8.5%</strong> of developers in China reported trying them, compared with <strong>0.0%</strong> overseas.')},
'china-extension-method-usage':{title:bi('开发者使用过哪些方式扩展 Agent 的能力、上下文或自动化?','Which methods have developers used to extend an agent’s capabilities, context, or automation?'),description:'',items:chinaUsage.extensionMethods,insight:'',takeaway:bi('中国与海外开发者在扩展 Agent 的方式上呈现相近偏好:<strong>Skills / Agent Skills</strong>、<strong>MCP Server</strong>、<strong>Browser / Computer Use</strong>与<strong>Tools / Function Calling</strong>均处于较高使用水平,<strong>Rules / Instructions</strong>等项目规则配置也进入两组前五。','Developers in China and overseas show similar preferences for extending agents: <strong>Skills / Agent Skills</strong>, <strong>MCP Servers</strong>, <strong>Browser / Computer Use</strong>, and <strong>Tools / Function Calling</strong> all have high usage in both groups, while project-rule configuration such as <strong>Rules / Instructions</strong> also ranks in the top five.')}
};
function regionProfile(items){const max=Math.max(...items.map(([,value])=>value));return `<article class="profile-region glass-bevel"><div class="region-stack"><div class="region-map-wrap"><div id="profile-map" role="img" aria-label="${text(bi('全球受访者地区分布。悬停地区选项查看对应区域。','Respondent locations worldwide. Hover a region to view its area on the map.'))}"></div></div><div class="region-list-wrap"><div class="region-list" tabindex="0">${items.map(([label,value],index)=>{const localized=bi(label,labelTranslations[label]||label);return `<div class="region-row" data-region-index="${index}"><div><span>${text(localized)}</span></div><strong>${value}%</strong><i><em data-fill="${value/max*100}"></em></i></div>`}).join('')}</div><div class="region-scroll-hint" aria-hidden="true"><span>${text(bi('向下滚动查看全部地区','Scroll for more regions'))}</span><b>↓</b></div></div></div></article>`}
function identityProfile(items){return `<article class="identity-card"><div class="identity-cloud-panel"><div class="identity-word-cloud" aria-label="${text(bi('按选择占比缩放的开发者身份标签。','Developer identity labels scaled by selection share.'))}">${items.map(([label,value],index)=>{const localized=bi(label,labelTranslations[label]||label);return `<span class="identity-word word-${index}" data-weight="${value}">${text(localized)}</span>`}).join('')}</div><p class="note context-note identity-note"><strong>${text(bi('注意:','Note: '))}</strong>${text(bi('同一位受访者可同时拥有多个身份标签,因此右侧占比之和可能超过 100%。例如,一位在企业任职的开发者,也可能在业余时间开发自己的独立 App,并同时选择“独立开发者”。','A respondent may have multiple identity labels, so the shares on the right can total more than 100%. For example, a developer employed by a company may also build an independent app in their spare time and select “Independent / solo developer.”'))}</p></div><div class="identity-data">${items.map(([label,value])=>{const localized=bi(label,labelTranslations[label]||label);return `<div><p>${text(localized)}</p><b>${value}%</b></div>`}).join('')}</div></article>`}
function respondentWall(){const localize=label=>text(bi(label,labelTranslations[label]||label));const rows=[profile.region.map(([label])=>localize(label)),profile.roles.map(([label])=>localize(label)),profile.appleExperience.filter(([,value])=>value).map(([label])=>text(bi(`Apple 平台开发 ${label}`,`${labelTranslations[label]||label} on Apple platforms`))),profile.scale.map(([label])=>localize(label)),profile.softwareExperience.filter(([,value])=>value).map(([label])=>text(bi(`软件开发 ${label}`,`${labelTranslations[label]||label} in software development`)))];const tracks=rows.map(labels=>{const chips=labels.map(label=>`<span class="wall-chip"><i></i>${label}</span>`).join('');return chips+chips});return `<section class="respondent-wall-closing"><section class="respondent-wall" aria-label="${text(bi('受访开发者的地区、身份与经验分布。','Regions, roles, and experience of respondents.'))}"><div class="respondent-wall-tracks" aria-hidden="true">${tracks.map((track,index)=>`<div class="respondent-wall-track track-${index}"><div class="respondent-wall-strip">${track}${track}</div></div>`).join('')}</div><div class="respondent-wall-scrim"><div class="respondent-wall-copy"><p class="respondent-wall-kicker">${text(bi('来自全球的开发者','DEVELOPERS FROM AROUND THE WORLD'))}</p><h4>${text(bi('每一份回答,都来自真实开发者。','Every response comes from a real developer.'))}</h4><p>${text(bi('跨越 10 多个国家和地区,不同经验、角色与团队背景共同构成本次调研样本。','Across more than 10 countries and regions, developers with different experience, roles, and team contexts make up this survey sample.'))}</p></div></div></section></section>`}
function applyDataStyles(){document.querySelectorAll('[data-fill]').forEach(node=>node.style.setProperty('--fill',`${node.dataset.fill}%`));document.querySelectorAll('[data-weight]').forEach(node=>node.style.setProperty('--weight',node.dataset.weight));document.querySelectorAll('[data-size]').forEach(node=>node.style.setProperty('--size',node.dataset.size))}
function setupRespondentWall(){respondentWallObserver?.disconnect();const wall=document.querySelector('.respondent-wall');if(!wall||!('IntersectionObserver'in window))return;respondentWallObserver=new IntersectionObserver(([entry])=>wall.classList.toggle('is-visible',entry.isIntersecting),{threshold:.16});respondentWallObserver.observe(wall)}
function renderProfileMap(){if(!window.svgMap||!document.querySelector('#profile-map'))return;const regions=[['CN','HK','MO','TW'],['AD','AL','AT','BA','BE','BG','BY','CH','CY','CZ','DE','DK','EE','ES','FI','FR','GB','GR','HR','HU','IE','IS','IT','LI','LT','LU','LV','MC','MD','ME','MK','MT','NL','NO','PL','PT','RO','RS','SE','SI','SK','SM','UA','VA'],['JP'],['US'],['BN','KH','ID','LA','MY','MM','PH','SG','TH','TL','VN'],['KR'],['IN','BD','BT','LK','NP','PK'],['CA'],['AU','NZ']];new svgMap({targetElementID:'profile-map',allowInteraction:false,showContinentSelector:false,showZoomReset:false,mouseWheelZoomEnabled:false,hideFlag:true,colorNoData:'#b9cada',data:{data:{share:{name:'Share',format:'{0}%'}},applyData:'share',values:{CN:{share:60},JP:{share:11},US:{share:7},KR:{share:2},IN:{share:1},CA:{share:1},AU:{share:1},NZ:{share:1}}}});const map=document.querySelector('#profile-map');const mapImage=map.querySelector('.svgMap-map-image');const profileRegion=map.closest('.profile-region');const syncListHeight=()=>{const height=mapImage?.getBoundingClientRect().height;if(height)profileRegion?.style.setProperty('--profile-map-height',`${height}px`)};syncListHeight();if(mapImage)new ResizeObserver(syncListHeight).observe(mapImage);const rows=[...document.querySelectorAll('.region-row[data-region-index]')];const setActive=index=>{map.querySelectorAll('.region-highlight').forEach(node=>node.classList.remove('region-highlight'));if(index===null)return;regions[index].forEach(code=>map.querySelector(`[data-id="${code}"]`)?.classList.add('region-highlight'))};rows.forEach(row=>{const index=Number(row.dataset.regionIndex);row.addEventListener('mouseenter',()=>setActive(index));row.addEventListener('mouseleave',()=>setActive(null))});const regionList=profileRegion?.querySelector('.region-list');const regionListWrap=profileRegion?.querySelector('.region-list-wrap');const syncScrollHint=()=>{if(!regionList||!regionListWrap)return;const scrollable=regionList.scrollHeight>regionList.clientHeight+2;const atEnd=!scrollable||regionList.scrollTop+regionList.clientHeight>=regionList.scrollHeight-2;regionListWrap.classList.toggle('is-scrollable',scrollable);regionListWrap.classList.toggle('is-at-end',atEnd)};regionList?.addEventListener('scroll',syncScrollHint,{passive:true});if(regionList)new ResizeObserver(syncScrollHint).observe(regionList);requestAnimationFrame(syncScrollHint)}
function setupVoiceLibrary(){const library=document.querySelector('[data-voice-library]');if(!library)return;const topics=[...library.querySelectorAll('[data-voice-topic]')];const transcript=library.querySelector('.voice-transcript');let activeTopic=0;let activeQuote=0;const formatMeta=meta=>mode==='en'?text(meta).replace(/\/\s*([a-z])/g,(_,letter)=>`/ ${letter.toUpperCase()}`):text(meta);const slides=voiceModules.flatMap((module,topicIndex)=>module.quotes.map(({quote,tags,meta},quoteIndex)=>`<div class="voice-slide" data-topic="${topicIndex}" data-quote="${quoteIndex}"><blockquote><p>${text(quote)}</p></blockquote><div class="voice-transcript-tags"><span class="voice-transcript-tags-label">${text(bi('标签','Tags'))}</span><div class="voice-transcript-tag-list">${(tags||module.tags).map(tag=>`<span>${text(tag)}</span>`).join('')}</div></div><footer class="voice-transcript-footer"><span class="voice-transcript-attribution">${formatMeta(meta)}</span></footer></div>`)).join('');transcript.innerHTML=`<div class="voice-stack">${slides}</div><div class="voice-transcript-controls"><button type="button" data-voice-prev>${text(bi('← 上一条','← Previous'))}</button><span class="voice-transcript-progress"></span><button type="button" data-voice-next>${text(bi('下一条 →','Next →'))}</button></div>`;const prev=transcript.querySelector('[data-voice-prev]');const next=transcript.querySelector('[data-voice-next]');const progress=transcript.querySelector('.voice-transcript-progress');const update=()=>{const total=voiceModules[activeTopic].quotes.length;topics.forEach((topic,index)=>{const isActive=index===activeTopic;topic.classList.toggle('is-active',isActive);topic.setAttribute('aria-selected',String(isActive));topic.tabIndex=isActive?0:-1});transcript.querySelectorAll('.voice-slide').forEach(slide=>{const on=Number(slide.dataset.topic)===activeTopic&&Number(slide.dataset.quote)===activeQuote;slide.classList.toggle('is-active',on);slide.setAttribute('aria-hidden',String(!on))});prev.disabled=activeQuote===0;next.disabled=activeQuote===total-1;progress.textContent=`${String(activeQuote+1).padStart(2,'0')} / ${String(total).padStart(2,'0')}`};topics.forEach((topic,index)=>topic.addEventListener('click',()=>{activeTopic=index;activeQuote=0;update()}));prev.addEventListener('click',()=>{activeQuote-=1;update()});next.addEventListener('click',()=>{activeQuote+=1;update()});update()}
function siteFooter(){
const lock='<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="11" width="18" height="11" rx="2" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M7 11V7a5 5 0 0 1 10 0v4" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>';
const privacy=`<a href="https://swiftgg.team/privacy" target="_blank" rel="noopener noreferrer">${text(bi('隐私政策','Privacy Policy'))}</a>`;
const statement=text(bi('本报告中的所有数据均已脱敏。问卷为匿名填写,我们不收集姓名、邮箱、手机号等任何可识别个人身份的信息,结果仅以匿名汇总的形式发布,原始回答不会被出售或提供给任何第三方。','All data in this report has been de-identified. The survey was anonymous: we do not collect names, email addresses, phone numbers or any other personally identifying information, results are published only as anonymous aggregates, and raw responses are never sold or provided to any third party.'));
const credits=[[bi('问卷方法与整理分析','Survey method & analysis'),'Siqi','https://x.com/swiftsiqi'],[bi('网站开发','Web development'),'Kim','https://jin.cr'],[bi('设计','Design'),'Amber','https://www.xiaohongshu.com/user/profile/60e14d2c00000000010080bb']].map(([role,name,url])=>`<li><span>${text(role)}</span>${url?`<a href="${url}" target="_blank" rel="noopener noreferrer">${name}</a>`:`<b>${name}</b>`}</li>`).join('');
const links=[['x','X','https://x.com/TheSwiftGGTeam'],['rednote',text(bi('小红书','RedNote')),'https://www.xiaohongshu.com/user/profile/6627df6e000000000700607b','<span class="social-text">小红书</span>'],['github','GitHub','https://github.com/SwiftGGTeam'],['email','hello@swiftgg.team','mailto:hello@swiftgg.team']].map(([icon,label,url,glyph])=>`<a class="social" href="${url}"${url.startsWith('mailto:')?'':' target="_blank" rel="noopener noreferrer"'} aria-label="${label}" title="${label}">${glyph||socialIcons[icon]}</a>`).join('');
const wechat=`<span class="social-qr"><button class="social" type="button" aria-label="${text(bi('微信公众号','WeChat Official Account'))}" aria-expanded="false">${socialIcons.wechat}</button><span class="qr-pop" role="tooltip"><img src="${ROOT}assets/wechat-qr.png" alt="${text(bi('SwiftGG 公众号二维码','SwiftGG WeChat QR code'))}" loading="lazy"><small>${text(bi('微信扫码关注 SwiftGG','Scan with WeChat'))}</small></span></span>`;
return `<footer class="site-footer"><div class="site-footer-inner"><div class="footer-top"><ul class="footer-credits">${credits}</ul><nav class="footer-socials" aria-label="${text(bi('SwiftGG 社交媒体','SwiftGG on social media'))}">${wechat}${links}</nav></div><div class="footer-privacy"><span class="footer-icon">${lock}</span><p>${statement} ${text(bi('详见','See our'))} ${privacy}${text(bi('。','.'))}</p></div></div></footer>`}
document.addEventListener('click',event=>{const qr=document.querySelector('.social-qr');if(!qr)return;const open=!!event.target.closest('.social-qr button')&&!qr.classList.contains('is-open');qr.classList.toggle('is-open',open);qr.querySelector('button').setAttribute('aria-expanded',String(open))});
function render(){
document.documentElement.lang=mode==='en'?'en':'zh-CN';
document.title=mode==='en'?'Xcode Global Developer Survey Report by SwiftGG':'Xcode 全球开发者调研报告 by SwiftGG';
document.querySelector('#hero').innerHTML=`<div class="hero-bar"><img class="hero-logo" src="${ROOT}assets/swiftgg-logo-mono.png" alt="SwiftGG"><div class="lang-toggle" role="group" aria-label="Language display"><button type="button" data-language="zh" aria-pressed="false">中文</button><button type="button" data-language="en" aria-pressed="false">English</button></div></div><div class="hero-inner"><span class="hero-eyebrow">DEVELOPER RESEARCH 2026</span><h1>${text(bi('<span class="title-line">AI 时代,Apple 生态开发者</span><span class="title-line">眼中的开发工具</span>','<span class="title-line">How Apple Developers See</span><span class="title-line">Dev Tools in the AI Era</span>'))}</h1><p class="hero-intro">${text(heroIntro)}</p><div class="metric-row"><div class="metric"><b>100</b><span>${text(bi('位受邀开发者','invited developers'))}</span></div><div class="metric"><b>10+</b><span>${text(bi('个国家和地区','countries and regions'))}</span></div><div class="metric"><b>81%</b><span>${text(bi('至少 4 年 Apple 平台经验','with 4+ years on Apple platforms'))}</span></div><div class="metric"><b>95%</b><span>${text(bi('至少几乎每天使用 AI','use AI at least almost daily'))}</span></div></div></div>`;
document.querySelectorAll('[data-language]').forEach(b=>b.setAttribute('aria-pressed',String(b.dataset.language===mode)));
let html='';
html+=section('profile',bi('Part 1 · 受邀开发者画像','Part 1 · Who We Surveyed'),bi('我们邀请了哪些开发者参与调研?','Which developers did we invite to participate?'),[
bi(`本次调研面向来自 ${mk('10 多个国家和地区')}的 ${mk('100 位')}受邀开发者。`,`This survey invited ${mk('100 developers')} from ${mk('more than 10 countries and regions')}.`),
bi(`受访者包括但不限于:获得 Apple Developer Recognition 表彰的社区开发者;LET’S VISION、try! Swift、iOS Conf SG、Deep Dish Swift 等知名 Apple 行业活动的讲者;NSLodan、Create With Swift、SwiftLee 等开发者社区的技术代表;来自 TikTok、Alibaba、miHoYo 等大型互联网公司的开发者;以及曾获 ${mk('Apple Design Award')} 的独立开发者。他们共同构成了本次调研的受访群体。`,`Participants include, but are not limited to: community developers recognized through Apple Developer Recognition; speakers at prominent Apple-industry events including LET’S VISION, try! Swift, iOS Conf SG, and Deep Dish Swift; technical representatives from developer communities such as NSLodan, Create With Swift, and SwiftLee; developers from major internet companies including TikTok, Alibaba, and miHoYo; and independent developers who have received an ${mk('Apple Design Award')}. Together, they make up this survey’s respondent group.`)
],
card({cls:'region-card',title:bi('受访者主要在哪里工作或学习?','Where do respondents primarily work or study?'),type:'single',body:regionProfile(profile.region)})+
`<div class="grid-2">${experiencePie(bi('从事软件开发多少年?','Years in software development'),profile.softwareExperience)}${experiencePie(bi('从事 Apple 平台开发多少年?','Years developing for Apple platforms'),profile.appleExperience)}</div>`+
card({cls:'identity-wrap',title:bi('受访开发者有哪些身份标签?','What identity labels describe respondents?'),type:'multiple',body:identityProfile(profile.roles)})+
card({cls:'pie-card',title:bi('受访者所在应用开发团队规模','Application development team size at respondents’ companies'),type:'single',body:scalePie(profile.scale)}));
html+=section('global',bi('Part 2 · AI 浪潮下的开发者','Part 2 · Developers in the Age of AI'),bi('AI 已成为开发工作的核心方式','AI Has Become a Core Way of Working'),[
bi(`在 100 位受访开发者中,${mk('95%')} 表示至少几乎每天使用 AI,${mk('78%')} 表示每天高频使用。AI 已从辅助能力延伸至开发流程的关键环节,成为${mk('核心工作方式')}之一。`,`Among 100 surveyed developers, ${mk('95%')} report using AI at least almost every day and ${mk('78%')} report high-frequency daily use. AI has moved beyond an assistive capability into key stages of the development process, becoming a ${mk('core way of working')}.`),
bi(`与此同时,开发者对 Xcode 单一入口的${mk('依赖正在减弱')},对 AI 生成代码的${mk('信任与采纳程度持续提升')},手写代码不再是唯一的实现路径。这些变化表明,AI 正在${mk('重塑')}开发者长期形成的工作习惯与软件开发模式。`,`At the same time, developers are ${mk('becoming less dependent on Xcode')} as a single entry point, while ${mk('trust in and adoption of AI-generated code continue to rise')}. Handwritten code is no longer the only path to implementation—signaling a broader ${mk('reshaping')} of established development habits and software practices.`)
],`${aiLifecycle()}<div class="grid-5-7">${workflowPodium()}${frequencyMatrix()}</div>${selectionRanking()}<div class="grid-4-8">${codeLocation()}${xcodeRoles()}</div>`);
html+=section('china',bi('Part 3 · AI 编程的共识与分化','Part 3 · Consensus and Divergence in AI Coding'),bi('AI 编程实践中的共同方法与多元选择','Shared Practices and Diverse Choices in AI Coding'),[
bi(`基于 100 位开发者的调研回答,我们发现中国与海外开发者在扩展 AI 与 Agent 能力、多文件协作等工作思路上${mk('具有高度相似性')};但在模型与工具选择上,中国开发者呈现出更明显的${mk('本土化偏好')}与更丰富的多元尝试。`,`Based on responses from 100 developers, we find that developers in China and overseas ${mk('share highly similar approaches')} to extending AI and agent capabilities and collaborating across multiple files. But model and tool choices differ: developers in China show clearer ${mk('local preferences')} and a broader range of experimentation.`),
bi(`这些差异可能与${mk('工具可获得性、服务环境及本土模型生态')}等因素相关,反映出不同区域开发者所处的技术与服务环境存在差异。`,`These differences may relate to ${mk('tool availability, service environments, and local model ecosystems')}, reflecting the distinct technical and service contexts developers work within across regions.`)
],`${chinaUsageRanking('china-model-usage',bi('过去 30 天内,受访者最常用的 AI 模型是什么?','Which AI models did respondents use most in the past 30 days?'),'',chinaUsage.models,'',bi('中国开发者最喜欢的<strong>国产</strong> AI 模型前三分别是 <strong>DeepSeek</strong>、<strong>GLM</strong> 和 <strong>公司内部或自行部署的模型</strong>,最喜欢的<strong>海外</strong> AI 模型前三位是 <strong>OpenAI GPT / Codex</strong>、<strong>Anthropic Claude</strong> 和 <strong>xAI Grok</strong>。<br><br>海外开发者最喜欢的<strong>国产</strong> AI 模型前三位是 <strong>DeepSeek</strong>、<strong>Kimi</strong> 和 <strong>GLM</strong>,最喜欢的<strong>海外</strong> AI 模型前三位是 <strong>Anthropic Claude</strong>、<strong>OpenAI GPT / Codex</strong> 和 <strong>xAI Grok</strong>。','Among developers in China, the top three <strong>China-based</strong> AI models are <strong>DeepSeek</strong>, <strong>GLM</strong>, and <strong>company-internal or self-hosted models</strong>. The top three <strong>overseas</strong> AI models are <strong>OpenAI GPT / Codex</strong>, <strong>Anthropic Claude</strong>, and <strong>xAI Grok</strong>.<br><br>Among overseas developers, the top three <strong>China-based</strong> AI models are <strong>DeepSeek</strong>, <strong>Kimi</strong>, and <strong>GLM</strong>. The top three <strong>overseas</strong> AI models are <strong>Anthropic Claude</strong>, <strong>OpenAI GPT / Codex</strong>, and <strong>xAI Grok</strong>.'))}${chinaUsageRanking('china-tool-usage',bi('Q11. 过去 30 天内,实际使用过哪些 AI Coding / Agent 工具?','Q11. Which AI coding / agent tools were actually used in the past 30 days?'),'',chinaUsage.tools,'')}${chinaUsageRanking('china-entry-point-usage',bi('开发者通常在哪里使用或运行 AI Coding / Agent?','Where do developers usually use or run AI coding / agents?'),'',chinaUsage.entryPoints,'')}${chinaUsageRanking('china-extension-method-usage',bi('Q12B. 你使用过哪些方式来扩展 Agent 的能力、上下文或自动化?','Q12B. Which methods have you used to extend an agent’s capabilities, context, or automation?'),'',chinaUsage.extensionMethods,'')}${q15PreferenceRanking()}`);
html+=section('difference',bi('Part 4 · AI 时代下的 Xcode','Part 4 · Xcode in the AI Era'),bi('Xcode 在 AI 时代需要怎样的进化?','How Does Xcode Need to Evolve in the AI Era?'),[
bi(`基于受访者的回答,开发者在 Xcode 之外使用 AI 工具,主要看重${mk('更强的 Agent、模型能力')}与任务执行体验。`,`Based on respondents’ answers, developers use AI tools outside Xcode mainly for ${mk('stronger agent and model capabilities')}, as well as a more complete task-execution experience.`),
bi(`他们期待 Xcode 的 AI 不止于代码生成,还能${mk('理解项目')}、连接 Build、Debug、Test 与 Simulator;同时,性能稳定性及 Build、Indexing 效率仍是基础诉求。开发者期待的,是一个${mk('由 AI 贯通真实开发流程')}的 Xcode。`,`They expect Xcode AI to go beyond code generation: to ${mk('understand projects')} and connect with Build, Debug, Test, and Simulator. At the same time, performance and stability, along with Build and Indexing efficiency, remain foundational needs. Developers are looking for an Xcode where ${mk('AI runs through the real development workflow')}.`)
],`<div class="q-stack">${xcodeQuestionReports.map(xcodeQuestionReport).join('')}${prioritySpotlight()}</div>`);
html+=section('xcode',bi('Part 5 · 写给 Xcode 团队','Part 5 · To Xcode Team'),bi('写给 Xcode 团队','To Xcode Team'),[
bi(`Xcode 曾是许多 Apple 生态开发者${mk('最熟悉、最信赖')}的伙伴。在这个快速变化的时代,大家对它有了更高的期待与更多的要求。`,`Xcode has long been a ${mk('trusted companion')} for many Apple-platform developers. In a time of rapid change, expectations and demands have grown.`),
bi(`有些声音或许尖锐,但${mk('正因为在乎')},才希望它能走得更远。`,`Some voices may be sharp, but they come from people who ${mk('care deeply')} and want Xcode to go further.`)
],voiceLibrary());
html+=respondentWall();html+=siteFooter();
document.querySelector('#report').innerHTML=html;
applyDataStyles();try{renderProfileMap()}catch(error){console.warn(error)}setupRespondentWall();setupPies();setupPart2Interactions();setupChinaUsageRankings();setupPriorityDeck();setupVoiceLibrary();setupWaffleScrollers();
const chapters=[['chapter-1',bi('01 受邀开发者画像','01 Who We Surveyed')],['chapter-2',bi('02 AI 浪潮下的开发者','02 Developers & AI')],['chapter-3',bi('03 AI 编程的共识与分化','03 Consensus & Divergence')],['chapter-4',bi('04 AI 时代下的 Xcode','04 Xcode in the AI Era')],['chapter-5',bi('05 写给 Xcode 团队','05 To the Xcode Team')]];
document.querySelector('.chapter-nav').innerHTML=chapters.map(([id,label],index)=>{const chapterLabel=text(label);return `<a href="#${id}" data-target="${id}" data-part="${index+1}" title="${chapterLabel.slice(2).trimStart()}"><span class="nav-number">${chapterLabel.slice(0,2)}</span><span class="nav-label">${chapterLabel.slice(2).trimStart()}</span></a>`}).join('');
updateReadingState();
}
document.addEventListener('click',event=>{const button=event.target.closest('[data-language]');if(!button||button.dataset.language===mode)return;mode=button.dataset.language;history.replaceState(null,'',ROOT+mode+'/'+location.hash);render()});
function updateReadingState(){const heroEl=document.getElementById('hero');document.querySelector('.sidebar')?.classList.toggle('is-visible',!!heroEl&&heroEl.getBoundingClientRect().bottom<window.innerHeight*.55);const max=document.documentElement.scrollHeight-window.innerHeight;const progress=max>0?Math.max(0,Math.min(100,window.scrollY/max*100)):0;document.documentElement.style.setProperty('--reading-progress',progress);let active='';const navLinks=[...document.querySelectorAll('[data-target]')];navLinks.forEach(link=>{const target=document.getElementById(link.dataset.target);if(target&&target.getBoundingClientRect().top<window.innerHeight*.42)active=link.dataset.target});navLinks.forEach(link=>{const isActive=link.dataset.target===active;link.classList.toggle('is-active',isActive);link.toggleAttribute('aria-current',isActive)})}
window.addEventListener('scroll',updateReadingState,{passive:true});window.addEventListener('resize',updateReadingState);
render();