generate_project.rb 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. require 'xcodeproj'
  2. require 'fileutils'
  3. project_path = 'CelestiaTrace.xcodeproj'
  4. # Remove existing project if any
  5. FileUtils.rm_rf(project_path)
  6. # Create a new Xcode project
  7. project = Xcodeproj::Project.new(project_path)
  8. # Create groups
  9. main_group = project.main_group
  10. app_group = main_group.new_group('CelestiaTrace', 'CelestiaTrace')
  11. tests_group = main_group.new_group('CelestiaTraceTests', 'Tests/CelestiaTraceTests')
  12. # Helper to add files recursively
  13. def add_files_recursively(dir, group, target, project)
  14. return unless File.directory?(dir)
  15. Dir.foreach(dir) do |entry|
  16. next if entry == '.' || entry == '..' || entry == '.DS_Store'
  17. path = File.join(dir, entry)
  18. if File.directory?(path)
  19. # Create subgroup with path relative to the parent group
  20. subgroup = group.new_group(entry, entry)
  21. add_files_recursively(path, subgroup, target, project)
  22. elsif entry.end_with?('.swift')
  23. # Add file reference
  24. file_ref = group.new_file(entry)
  25. # Add to build phases
  26. target.add_file_references([file_ref])
  27. end
  28. end
  29. end
  30. # Create iOS App target
  31. app_target = project.new_target(:application, 'CelestiaTrace', :ios, '17.0')
  32. app_target.build_configurations.each do |config|
  33. config.build_settings['SWIFT_VERSION'] = '5.9'
  34. config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '17.0'
  35. config.build_settings['TARGETED_DEVICE_FAMILY'] = '1' # 1 for iPhone, 2 for iPad, 1,2 for both
  36. config.build_settings['SDKROOT'] = 'iphoneos'
  37. config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = 'com.celestia.trace'
  38. config.build_settings['GENERATE_INFOPLIST_FILE'] = 'NO'
  39. config.build_settings['INFOPLIST_FILE'] = 'CelestiaTrace/Resources/Info.plist'
  40. config.build_settings['INFOPLIST_KEY_UILaunchStoryboardName'] = 'LaunchScreen'
  41. config.build_settings['INFOPLIST_KEY_CFBundleDisplayName'] = '星痕 CelestiaTrace'
  42. config.build_settings['INFOPLIST_KEY_UISupportedInterfaceOrientations'] = 'UIInterfaceOrientationPortrait'
  43. config.build_settings['INFOPLIST_KEY_NSMicrophoneUsageDescription'] = '需要麦克风权限以进行会议现场的音轨录音'
  44. config.build_settings['INFOPLIST_KEY_NSLocationWhenInUseUsageDescription'] = '需要定位权限以在笔记和照片记录中插入所在位置'
  45. config.build_settings['INFOPLIST_KEY_NSCameraUsageDescription'] = '需要相机权限以在现场录制中拍摄照片记录'
  46. config.build_settings['INFOPLIST_KEY_NSPhotoLibraryUsageDescription'] = '需要相册权限以选择照片记录'
  47. config.build_settings['INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription'] = '需要蓝牙权限以扫描和绑定 BLE 录音设备'
  48. config.build_settings['INFOPLIST_KEY_NSBluetoothPeripheralUsageDescription'] = '需要蓝牙权限以与录音设备传输数据'
  49. # Keep active microphone recordings running while the app is backgrounded or the device is locked.
  50. config.build_settings['INFOPLIST_KEY_UIBackgroundModes'] = 'audio bluetooth-central'
  51. config.build_settings['MARKETING_VERSION'] = '1.0.0'
  52. config.build_settings['CURRENT_PROJECT_VERSION'] = '1'
  53. config.build_settings['ASSETCATALOG_COMPILER_APPICON_NAME'] = 'AppIcon'
  54. config.build_settings['CODE_SIGN_STYLE'] = 'Automatic'
  55. # Enable SwiftData & SwiftUI previews support
  56. config.build_settings['DEVELOPMENT_ASSET_PATHS'] = '""'
  57. end
  58. # Create the Live Activity widget extension used on the Lock Screen and Dynamic Island.
  59. live_activity_target = project.new_target(
  60. :app_extension,
  61. 'CelestiaTraceLiveActivity',
  62. :ios,
  63. '17.0'
  64. )
  65. live_activity_target.build_configurations.each do |config|
  66. config.build_settings['SWIFT_VERSION'] = '5.9'
  67. config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '17.0'
  68. config.build_settings['TARGETED_DEVICE_FAMILY'] = '1'
  69. config.build_settings['SDKROOT'] = 'iphoneos'
  70. config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = 'com.celestia.trace.live-activity'
  71. config.build_settings['GENERATE_INFOPLIST_FILE'] = 'NO'
  72. config.build_settings['INFOPLIST_FILE'] = 'CelestiaTraceLiveActivity/Info.plist'
  73. config.build_settings['MARKETING_VERSION'] = '1.0.0'
  74. config.build_settings['CURRENT_PROJECT_VERSION'] = '1'
  75. config.build_settings['CODE_SIGN_STYLE'] = 'Automatic'
  76. config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'YES'
  77. config.build_settings['SKIP_INSTALL'] = 'YES'
  78. config.build_settings['LD_RUNPATH_SEARCH_PATHS'] = '$(inherited) @executable_path/../../Frameworks'
  79. end
  80. live_activity_group = main_group.new_group(
  81. 'CelestiaTraceLiveActivity',
  82. 'CelestiaTraceLiveActivity'
  83. )
  84. live_activity_sources = %w[
  85. CelestiaTraceLiveActivityBundle.swift
  86. RecordingLiveActivityWidget.swift
  87. ].map { |filename| live_activity_group.new_file(filename) }
  88. live_activity_target.add_file_references(live_activity_sources)
  89. live_activity_group.new_file('Info.plist')
  90. app_target.add_dependency(live_activity_target)
  91. embed_extensions_phase = app_target.new_copy_files_build_phase('Embed Foundation Extensions')
  92. embed_extensions_phase.dst_subfolder_spec = '13'
  93. embed_extensions_phase.add_file_reference(live_activity_target.product_reference, true)
  94. # Create iOS Test target
  95. test_target = project.new_target(:unit_test_bundle, 'CelestiaTraceTests', :ios, '17.0')
  96. test_target.build_configurations.each do |config|
  97. config.build_settings['SWIFT_VERSION'] = '5.9'
  98. config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '17.0'
  99. config.build_settings['SDKROOT'] = 'iphoneos'
  100. config.build_settings['GENERATE_INFOPLIST_FILE'] = 'YES'
  101. config.build_settings['TEST_TARGET_NAME'] = 'CelestiaTrace'
  102. config.build_settings['BUNDLE_LOADER'] = '$(TEST_HOST)'
  103. config.build_settings['TEST_HOST'] = '$(BUILT_PRODUCTS_DIR)/CelestiaTrace.app/CelestiaTrace'
  104. end
  105. # Set up target dependency: Test target depends on App target
  106. test_target.add_dependency(app_target)
  107. # Add files to targets
  108. add_files_recursively('CelestiaTrace', app_group, app_target, project)
  109. add_files_recursively('Tests/CelestiaTraceTests', tests_group, test_target, project)
  110. shared_activity_ref = project.files.find do |file|
  111. file.path == 'RecordingActivityAttributes.swift'
  112. end
  113. live_activity_target.add_file_references([shared_activity_ref]) if shared_activity_ref
  114. # Add the asset catalog (AppIcon and launch-screen color) to the app target.
  115. assets_ref = app_group.new_file('Resources/Assets.xcassets')
  116. app_target.resources_build_phase.add_file_reference(assets_ref)
  117. launch_screen_ref = app_group.new_file('Resources/LaunchScreen.storyboard')
  118. app_target.resources_build_phase.add_file_reference(launch_screen_ref)
  119. app_group.new_file('Resources/Info.plist')
  120. # Save project
  121. project.save
  122. puts "Successfully created CelestiaTrace.xcodeproj"