100Years 2 тижнів тому
батько
коміт
f868d41e9b
100 змінених файлів з 3223 додано та 43 видалено
  1. 92 0
      .gitignore
  2. 475 29
      AIPlayRingtones.xcodeproj/project.pbxproj
  3. 1 1
      AIPlayRingtones.xcodeproj/xcuserdata/100years.xcuserdatad/xcschemes/xcschememanagement.plist
  4. 10 0
      AIPlayRingtones.xcworkspace/contents.xcworkspacedata
  5. 27 0
      AIPlayRingtones/APConfig/APConfig+Color.swift
  6. 7 0
      AIPlayRingtones/APConfig/APConfig.swift
  7. 72 13
      AIPlayRingtones/AppDelegate.swift
  8. 10 0
      AIPlayRingtones/AppPage/APAudioToRingVC/APAudioToRingVC.swift
  9. 125 0
      AIPlayRingtones/AppPage/APLaunchVC/APLaunchVC.swift
  10. 10 0
      AIPlayRingtones/AppPage/APMyRingVC/APMyRingVC.swift
  11. 192 0
      AIPlayRingtones/AppPage/APRingTonesVC/APRingStyleVC/APRingStyleVC.swift
  12. 28 0
      AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/APRingTonesVC+Duration.swift
  13. 29 0
      AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/APRingTonesVC+StackView.swift
  14. 11 0
      AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/APRingTonesVC+Style.swift
  15. 21 0
      AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/APRingTonesVC+TextView.swift
  16. 78 0
      AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/APRingTonesVC+View.swift
  17. 78 0
      AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/APRingTonesVC.swift
  18. 32 0
      AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/Model/ASGenerateStyleModel.swift
  19. 16 0
      AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/Model/ASRingGenerateSecModel.swift
  20. 62 0
      AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/VM/APRingTonesVM.swift
  21. 132 0
      AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/View/ASDurationColView.swift
  22. 206 0
      AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/View/ASPromptTextView.swift
  23. 10 0
      AIPlayRingtones/AppPage/APSettingVC/APSettingVC.swift
  24. 192 0
      AIPlayRingtones/AppPage/ASCommonView/ASBtnView/ASAppBtnView.swift
  25. 84 0
      AIPlayRingtones/AppPage/ASCommonView/ASBtnView/ASLeftHeaderView.swift
  26. 299 0
      AIPlayRingtones/AppPage/ASRingGeneratorVC/ASRingGeneratorBaseVC.swift
  27. 306 0
      AIPlayRingtones/AppPage/ASRingGeneratorVC/ASRingGeneratorVC.swift
  28. 88 0
      AIPlayRingtones/AppPage/ASTabBarVC/ASTabBarVC.swift
  29. 6 0
      AIPlayRingtones/Assets.xcassets/AIRingtone/Contents.json
  30. 22 0
      AIPlayRingtones/Assets.xcassets/AIRingtone/nav_title_aiRingtone.imageset/Contents.json
  31. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/nav_title_aiRingtone.imageset/nav_title_aiRingtone@2x.png
  32. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/nav_title_aiRingtone.imageset/nav_title_aiRingtone@3x.png
  33. 22 0
      AIPlayRingtones/Assets.xcassets/AIRingtone/sec_selected_bg.imageset/Contents.json
  34. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/sec_selected_bg.imageset/sec_selected_bg@2x.png
  35. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/sec_selected_bg.imageset/sec_selected_bg@3x.png
  36. 22 0
      AIPlayRingtones/Assets.xcassets/AIRingtone/sec_unSelected_bg.imageset/Contents.json
  37. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/sec_unSelected_bg.imageset/sec_unSelected_bg@2x.png
  38. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/sec_unSelected_bg.imageset/sec_unSelected_bg@3x.png
  39. 6 0
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/Contents.json
  40. 22 0
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Disco.imageset/Contents.json
  41. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Disco.imageset/ring_style_Disco@2x.png
  42. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Disco.imageset/ring_style_Disco@3x.png
  43. 22 0
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Dubstep.imageset/Contents.json
  44. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Dubstep.imageset/ring_style_Dubstep@2x.png
  45. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Dubstep.imageset/ring_style_Dubstep@3x.png
  46. 22 0
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Electro.imageset/Contents.json
  47. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Electro.imageset/ring_style_Electro@2x.png
  48. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Electro.imageset/ring_style_Electro@3x.png
  49. 22 0
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Funk.imageset/Contents.json
  50. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Funk.imageset/ring_style_Funk@2x.png
  51. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Funk.imageset/ring_style_Funk@3x.png
  52. 22 0
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_HipHop.imageset/Contents.json
  53. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_HipHop.imageset/ring_style_HipHop@2x.png
  54. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_HipHop.imageset/ring_style_HipHop@3x.png
  55. 22 0
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Jazz.imageset/Contents.json
  56. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Jazz.imageset/ring_style_Jazz@2x.png
  57. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Jazz.imageset/ring_style_Jazz@3x.png
  58. 22 0
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Normal.imageset/Contents.json
  59. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Normal.imageset/ring_style_Normal@2x.png
  60. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Normal.imageset/ring_style_Normal@3x.png
  61. 22 0
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Pop.imageset/Contents.json
  62. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Pop.imageset/ring_style_Pop@2x.png
  63. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Pop.imageset/ring_style_Pop@3x.png
  64. 22 0
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Rock.imageset/Contents.json
  65. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Rock.imageset/ring_style_Rock@2x.png
  66. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Rock.imageset/ring_style_Rock@3x.png
  67. 22 0
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_selected_bg.imageset/Contents.json
  68. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_selected_bg.imageset/ring_text_selected_bg@2x.png
  69. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_selected_bg.imageset/ring_text_selected_bg@3x.png
  70. 22 0
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_selected_board.imageset/Contents.json
  71. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_selected_board.imageset/ring_text_selected_board@2x.png
  72. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_selected_board.imageset/ring_text_selected_board@3x.png
  73. 22 0
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_unSelect_bg.imageset/Contents.json
  74. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_unSelect_bg.imageset/ring_text_unSelect_bg@2x.png
  75. BIN
      AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_unSelect_bg.imageset/ring_text_unSelect_bg@3x.png
  76. 6 0
      AIPlayRingtones/Assets.xcassets/AudioToRingtone/Contents.json
  77. 22 0
      AIPlayRingtones/Assets.xcassets/AudioToRingtone/nav_titile_audioRingtone.imageset/Contents.json
  78. BIN
      AIPlayRingtones/Assets.xcassets/AudioToRingtone/nav_titile_audioRingtone.imageset/nav_titile_audioRingtone@2x.png
  79. BIN
      AIPlayRingtones/Assets.xcassets/AudioToRingtone/nav_titile_audioRingtone.imageset/nav_titile_audioRingtone@3x.png
  80. 6 0
      AIPlayRingtones/Assets.xcassets/Common/Contents.json
  81. 22 0
      AIPlayRingtones/Assets.xcassets/Common/PRO.imageset/Contents.json
  82. BIN
      AIPlayRingtones/Assets.xcassets/Common/PRO.imageset/PRO@2x.png
  83. BIN
      AIPlayRingtones/Assets.xcassets/Common/PRO.imageset/PRO@3x.png
  84. 22 0
      AIPlayRingtones/Assets.xcassets/Common/clear_gary_text.imageset/Contents.json
  85. BIN
      AIPlayRingtones/Assets.xcassets/Common/clear_gary_text.imageset/clear_gary_text@2x.png
  86. BIN
      AIPlayRingtones/Assets.xcassets/Common/clear_gary_text.imageset/clear_gary_text@3x.png
  87. 22 0
      AIPlayRingtones/Assets.xcassets/Common/clear_text.imageset/Contents.json
  88. BIN
      AIPlayRingtones/Assets.xcassets/Common/clear_text.imageset/clear_text@2x.png
  89. BIN
      AIPlayRingtones/Assets.xcassets/Common/clear_text.imageset/clear_text@3x.png
  90. 22 0
      AIPlayRingtones/Assets.xcassets/Common/submit_btn_bg.imageset/Contents.json
  91. BIN
      AIPlayRingtones/Assets.xcassets/Common/submit_btn_bg.imageset/submit_btn_bg@2x.png
  92. BIN
      AIPlayRingtones/Assets.xcassets/Common/submit_btn_bg.imageset/submit_btn_bg@3x.png
  93. 22 0
      AIPlayRingtones/Assets.xcassets/Common/submit_btn_dis_bg.imageset/Contents.json
  94. BIN
      AIPlayRingtones/Assets.xcassets/Common/submit_btn_dis_bg.imageset/submit_btn_dis_bg@2x.png
  95. BIN
      AIPlayRingtones/Assets.xcassets/Common/submit_btn_dis_bg.imageset/submit_btn_dis_bg@3x.png
  96. 22 0
      AIPlayRingtones/Assets.xcassets/Common/textView_bg.imageset/Contents.json
  97. BIN
      AIPlayRingtones/Assets.xcassets/Common/textView_bg.imageset/textView_bg@2x.png
  98. BIN
      AIPlayRingtones/Assets.xcassets/Common/textView_bg.imageset/textView_bg@3x.png
  99. 22 0
      AIPlayRingtones/Assets.xcassets/Common/textView_board.imageset/Contents.json
  100. BIN
      AIPlayRingtones/Assets.xcassets/Common/textView_board.imageset/textView_board@2x.png

+ 92 - 0
.gitignore

@@ -0,0 +1,92 @@
+# Xcode
+#
+# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
+
+## User settings
+xcuserdata/
+
+## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
+*.xcscmblueprint
+*.xccheckout
+
+## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
+build/
+DerivedData/
+*.moved-aside
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+
+## Obj-C/Swift specific
+*.hmap
+
+## App packaging
+*.ipa
+*.dSYM.zip
+*.dSYM
+
+## Playgrounds
+timeline.xctimeline
+playground.xcworkspace
+
+# Swift Package Manager
+#
+# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
+# Packages/
+# Package.pins
+# Package.resolved
+# *.xcodeproj
+#
+# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
+# hence it is not needed unless you have added a package configuration file to your project
+# .swiftpm
+
+.build/
+
+# CocoaPods
+#
+# We recommend against adding the Pods directory to your .gitignore. However
+# you should judge for yourself, the pros and cons are mentioned at:
+# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
+
+Pods/
+!Podfile.lock
+
+# Add this line if you want to avoid checking in source code from the Xcode workspace
+# *.xcworkspace
+
+# Carthage
+#
+# Add this line if you want to avoid checking in source code from Carthage dependencies.
+# Carthage/Checkouts
+
+Carthage/Build/
+
+# Accio dependency management
+Dependencies/
+.accio/
+
+# fastlane
+#
+# It is recommended to not store the screenshots in the git repo.
+# Instead, use fastlane to re-generate the screenshots whenever they are needed.
+# For more information about the recommended setup visit:
+# https://docs.fastlane.tools/best-practices/source-control/#source-control
+
+fastlane/report.xml
+fastlane/Preview.html
+fastlane/screenshots/**/*.png
+fastlane/test_output
+
+# Code Injection
+#
+# After new code Injection tools there's a generated folder /iOSInjectionProject
+# https://github.com/johnno1962/injectionforxcode
+
+iOSInjectionProject/
+

+ 475 - 29
AIPlayRingtones.xcodeproj/project.pbxproj

@@ -6,47 +6,166 @@
 	objectVersion = 77;
 	objects = {
 
+/* Begin PBXBuildFile section */
+		A800FEB22DDAC100009DABDC /* ASGeneratorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A800FEB12DDAC0FC009DABDC /* ASGeneratorView.swift */; };
+		A800FEB42DDAC73E009DABDC /* ASGeneratorLoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A800FEB32DDAC738009DABDC /* ASGeneratorLoadingView.swift */; };
+		A800FEB62DDAC764009DABDC /* ASGeneratorErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A800FEB52DDAC75D009DABDC /* ASGeneratorErrorView.swift */; };
+		A800FEB82DDAC826009DABDC /* TSNetWork+Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = A800FEB72DDAC81D009DABDC /* TSNetWork+Error.swift */; };
+		A800FEBB2DDACAF3009DABDC /* ASRingGeneratorVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A800FEBA2DDACAF2009DABDC /* ASRingGeneratorVC.swift */; };
+		A800FEBD2DDACCD4009DABDC /* ASRingGeneratorBaseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A800FEBC2DDACCCF009DABDC /* ASRingGeneratorBaseVC.swift */; };
+		A848F8822DD6D1AF00B746EC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A848F8792DD6D1AF00B746EC /* Assets.xcassets */; };
+		A848F8842DD6D1AF00B746EC /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A848F87C2DD6D1AF00B746EC /* LaunchScreen.storyboard */; };
+		A848F8862DD6D1AF00B746EC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8782DD6D1AF00B746EC /* AppDelegate.swift */; };
+		A848F88E2DD6D38600B746EC /* APLaunchVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F88D2DD6D38300B746EC /* APLaunchVC.swift */; };
+		A848F8912DD6D50000B746EC /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8902DD6D4FD00B746EC /* Common.swift */; };
+		A848F8932DD6D52100B746EC /* AIEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8922DD6D51900B746EC /* AIEnums.swift */; };
+		A848F89E2DD6D59C00B746EC /* TSNetWork+Business.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F89A2DD6D59C00B746EC /* TSNetWork+Business.swift */; };
+		A848F89F2DD6D59C00B746EC /* TSNetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8992DD6D59C00B746EC /* TSNetworkManager.swift */; };
+		A848F8A12DD6D59C00B746EC /* TSNetworkManager+Loading.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F89B2DD6D59C00B746EC /* TSNetworkManager+Loading.swift */; };
+		A848F8A42DD6D67000B746EC /* APRingTonesVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8A32DD6D66D00B746EC /* APRingTonesVC.swift */; };
+		A848F8A92DD6D74A00B746EC /* APAudioToRingVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8A82DD6D74900B746EC /* APAudioToRingVC.swift */; };
+		A848F8AB2DD6D75300B746EC /* APMyRingVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8AA2DD6D75200B746EC /* APMyRingVC.swift */; };
+		A848F8AD2DD6D75900B746EC /* APSettingVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8AC2DD6D75800B746EC /* APSettingVC.swift */; };
+		A848F8B02DD6D77C00B746EC /* ASTabBarVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8AF2DD6D77B00B746EC /* ASTabBarVC.swift */; };
+		A848F8B32DD6D82300B746EC /* APConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8B22DD6D82300B746EC /* APConfig.swift */; };
+		A848F8B52DD6D83E00B746EC /* APConfig+Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8B42DD6D82E00B746EC /* APConfig+Color.swift */; };
+		A848F8B92DD6DF7900B746EC /* ASAppBtnView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8B82DD6DF7700B746EC /* ASAppBtnView.swift */; };
+		A848F8BB2DD6E30600B746EC /* APRingTonesVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8BA2DD6E30000B746EC /* APRingTonesVM.swift */; };
+		A848F8BD2DD6E38900B746EC /* ASLeftHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8BC2DD6E36800B746EC /* ASLeftHeaderView.swift */; };
+		A848F8C02DD6E6FA00B746EC /* APRingTonesVC+TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8BF2DD6E6F600B746EC /* APRingTonesVC+TextView.swift */; };
+		A848F8C22DD6E70000B746EC /* APRingTonesVC+Duration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8C12DD6E6FD00B746EC /* APRingTonesVC+Duration.swift */; };
+		A848F8C42DD6E70500B746EC /* APRingTonesVC+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8C32DD6E70400B746EC /* APRingTonesVC+Style.swift */; };
+		A848F8C62DD6E72D00B746EC /* APRingTonesVC+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8C52DD6E72C00B746EC /* APRingTonesVC+View.swift */; };
+		A848F8CA2DD6E82B00B746EC /* APRingTonesVC+StackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8C92DD6E82A00B746EC /* APRingTonesVC+StackView.swift */; };
+		A848F8CD2DD6EAD300B746EC /* ASPromptTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8CC2DD6EACB00B746EC /* ASPromptTextView.swift */; };
+		A848F8D22DD7149D00B746EC /* ASDurationColView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8D12DD7148F00B746EC /* ASDurationColView.swift */; };
+		A848F8D52DD719B600B746EC /* ring_duration.json in Resources */ = {isa = PBXBuildFile; fileRef = A848F8D42DD719AB00B746EC /* ring_duration.json */; };
+		A848F8D82DD71A3A00B746EC /* ASRingGenerateSecModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8D72DD71A3100B746EC /* ASRingGenerateSecModel.swift */; };
+		A848F8DB2DD7231E00B746EC /* APRingStyleVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8DA2DD7231C00B746EC /* APRingStyleVC.swift */; };
+		A848F8E12DD7271900B746EC /* ring_style.json in Resources */ = {isa = PBXBuildFile; fileRef = A848F8E02DD7271400B746EC /* ring_style.json */; };
+		A848F8E32DD7286A00B746EC /* ASGenerateStyleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8E22DD7286600B746EC /* ASGenerateStyleModel.swift */; };
+		A848F8E82DD74DFD00B746EC /* ASDBHistoryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8E72DD74DF900B746EC /* ASDBHistoryManager.swift */; };
+		A848F8EA2DD74E3A00B746EC /* ASDBActionInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8E92DD74E3600B746EC /* ASDBActionInfoModel.swift */; };
+		A848F8EC2DD74EF800B746EC /* ASActionInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8EB2DD74EF400B746EC /* ASActionInfoModel.swift */; };
+		A848F8EE2DD7508300B746EC /* ASRealmManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8ED2DD7508000B746EC /* ASRealmManager.swift */; };
+		A848F8F12DD7528800B746EC /* ASBaseOperationQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8F02DD7528200B746EC /* ASBaseOperationQueue.swift */; };
+		A848F8F32DD7528D00B746EC /* ASBaseOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8F22DD7528C00B746EC /* ASBaseOperation.swift */; };
+		A848F8F62DD752D700B746EC /* ASGenerateBaseOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8F52DD752C400B746EC /* ASGenerateBaseOperation.swift */; };
+		A848F8F82DD752E700B746EC /* ASGeneratePosterOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8F72DD752D900B746EC /* ASGeneratePosterOperation.swift */; };
+		A848F8FA2DD7536700B746EC /*  Notification+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8F92DD7536300B746EC /*  Notification+Ex.swift */; };
+		A848F8FC2DD753A000B746EC /* ASProgressState.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8FB2DD7539E00B746EC /* ASProgressState.swift */; };
+		C6F204E3DD79A0F96C8DB3FF /* Pods_AIPlayRingtones.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6EFB792FA59CD8536D0BD11F /* Pods_AIPlayRingtones.framework */; };
+/* End PBXBuildFile section */
+
 /* Begin PBXFileReference section */
+		6EFB792FA59CD8536D0BD11F /* Pods_AIPlayRingtones.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AIPlayRingtones.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		A800FEB12DDAC0FC009DABDC /* ASGeneratorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASGeneratorView.swift; sourceTree = "<group>"; };
+		A800FEB32DDAC738009DABDC /* ASGeneratorLoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASGeneratorLoadingView.swift; sourceTree = "<group>"; };
+		A800FEB52DDAC75D009DABDC /* ASGeneratorErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASGeneratorErrorView.swift; sourceTree = "<group>"; };
+		A800FEB72DDAC81D009DABDC /* TSNetWork+Error.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSNetWork+Error.swift"; sourceTree = "<group>"; };
+		A800FEBA2DDACAF2009DABDC /* ASRingGeneratorVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASRingGeneratorVC.swift; sourceTree = "<group>"; };
+		A800FEBC2DDACCCF009DABDC /* ASRingGeneratorBaseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASRingGeneratorBaseVC.swift; sourceTree = "<group>"; };
 		A848F8602DD6D19100B746EC /* AIPlayRingtones.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AIPlayRingtones.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		A848F8782DD6D1AF00B746EC /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
+		A848F8792DD6D1AF00B746EC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+		A848F87A2DD6D1AF00B746EC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		A848F87B2DD6D1AF00B746EC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
+		A848F88D2DD6D38300B746EC /* APLaunchVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APLaunchVC.swift; sourceTree = "<group>"; };
+		A848F8902DD6D4FD00B746EC /* Common.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Common.swift; sourceTree = "<group>"; };
+		A848F8922DD6D51900B746EC /* AIEnums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AIEnums.swift; sourceTree = "<group>"; };
+		A848F8992DD6D59C00B746EC /* TSNetworkManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSNetworkManager.swift; sourceTree = "<group>"; };
+		A848F89A2DD6D59C00B746EC /* TSNetWork+Business.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSNetWork+Business.swift"; sourceTree = "<group>"; };
+		A848F89B2DD6D59C00B746EC /* TSNetworkManager+Loading.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSNetworkManager+Loading.swift"; sourceTree = "<group>"; };
+		A848F8A32DD6D66D00B746EC /* APRingTonesVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APRingTonesVC.swift; sourceTree = "<group>"; };
+		A848F8A82DD6D74900B746EC /* APAudioToRingVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APAudioToRingVC.swift; sourceTree = "<group>"; };
+		A848F8AA2DD6D75200B746EC /* APMyRingVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APMyRingVC.swift; sourceTree = "<group>"; };
+		A848F8AC2DD6D75800B746EC /* APSettingVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APSettingVC.swift; sourceTree = "<group>"; };
+		A848F8AF2DD6D77B00B746EC /* ASTabBarVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASTabBarVC.swift; sourceTree = "<group>"; };
+		A848F8B22DD6D82300B746EC /* APConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APConfig.swift; sourceTree = "<group>"; };
+		A848F8B42DD6D82E00B746EC /* APConfig+Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APConfig+Color.swift"; sourceTree = "<group>"; };
+		A848F8B82DD6DF7700B746EC /* ASAppBtnView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASAppBtnView.swift; sourceTree = "<group>"; };
+		A848F8BA2DD6E30000B746EC /* APRingTonesVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APRingTonesVM.swift; sourceTree = "<group>"; };
+		A848F8BC2DD6E36800B746EC /* ASLeftHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASLeftHeaderView.swift; sourceTree = "<group>"; };
+		A848F8BF2DD6E6F600B746EC /* APRingTonesVC+TextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APRingTonesVC+TextView.swift"; sourceTree = "<group>"; };
+		A848F8C12DD6E6FD00B746EC /* APRingTonesVC+Duration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APRingTonesVC+Duration.swift"; sourceTree = "<group>"; };
+		A848F8C32DD6E70400B746EC /* APRingTonesVC+Style.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APRingTonesVC+Style.swift"; sourceTree = "<group>"; };
+		A848F8C52DD6E72C00B746EC /* APRingTonesVC+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APRingTonesVC+View.swift"; sourceTree = "<group>"; };
+		A848F8C92DD6E82A00B746EC /* APRingTonesVC+StackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APRingTonesVC+StackView.swift"; sourceTree = "<group>"; };
+		A848F8CC2DD6EACB00B746EC /* ASPromptTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASPromptTextView.swift; sourceTree = "<group>"; };
+		A848F8D12DD7148F00B746EC /* ASDurationColView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASDurationColView.swift; sourceTree = "<group>"; };
+		A848F8D42DD719AB00B746EC /* ring_duration.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = ring_duration.json; sourceTree = "<group>"; };
+		A848F8D72DD71A3100B746EC /* ASRingGenerateSecModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASRingGenerateSecModel.swift; sourceTree = "<group>"; };
+		A848F8DA2DD7231C00B746EC /* APRingStyleVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APRingStyleVC.swift; sourceTree = "<group>"; };
+		A848F8E02DD7271400B746EC /* ring_style.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = ring_style.json; sourceTree = "<group>"; };
+		A848F8E22DD7286600B746EC /* ASGenerateStyleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASGenerateStyleModel.swift; sourceTree = "<group>"; };
+		A848F8E72DD74DF900B746EC /* ASDBHistoryManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASDBHistoryManager.swift; sourceTree = "<group>"; };
+		A848F8E92DD74E3600B746EC /* ASDBActionInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASDBActionInfoModel.swift; sourceTree = "<group>"; };
+		A848F8EB2DD74EF400B746EC /* ASActionInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASActionInfoModel.swift; sourceTree = "<group>"; };
+		A848F8ED2DD7508000B746EC /* ASRealmManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASRealmManager.swift; sourceTree = "<group>"; };
+		A848F8F02DD7528200B746EC /* ASBaseOperationQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASBaseOperationQueue.swift; sourceTree = "<group>"; };
+		A848F8F22DD7528C00B746EC /* ASBaseOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASBaseOperation.swift; sourceTree = "<group>"; };
+		A848F8F52DD752C400B746EC /* ASGenerateBaseOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASGenerateBaseOperation.swift; sourceTree = "<group>"; };
+		A848F8F72DD752D900B746EC /* ASGeneratePosterOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASGeneratePosterOperation.swift; sourceTree = "<group>"; };
+		A848F8F92DD7536300B746EC /*  Notification+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = " Notification+Ex.swift"; sourceTree = "<group>"; };
+		A848F8FB2DD7539E00B746EC /* ASProgressState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASProgressState.swift; sourceTree = "<group>"; };
+		B4EF561F1D6A688DA6595B7A /* Pods-AIPlayRingtones.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AIPlayRingtones.debug.xcconfig"; path = "Target Support Files/Pods-AIPlayRingtones/Pods-AIPlayRingtones.debug.xcconfig"; sourceTree = "<group>"; };
+		B6A4769786320594B791AFDE /* Pods-AIPlayRingtones.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AIPlayRingtones.release.xcconfig"; path = "Target Support Files/Pods-AIPlayRingtones/Pods-AIPlayRingtones.release.xcconfig"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
-/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
-		A848F8722DD6D19300B746EC /* Exceptions for "AIPlayRingtones" folder in "AIPlayRingtones" target */ = {
-			isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
-			membershipExceptions = (
-				Info.plist,
-			);
-			target = A848F85F2DD6D19100B746EC /* AIPlayRingtones */;
-		};
-/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
-
-/* Begin PBXFileSystemSynchronizedRootGroup section */
-		A848F8622DD6D19100B746EC /* AIPlayRingtones */ = {
-			isa = PBXFileSystemSynchronizedRootGroup;
-			exceptions = (
-				A848F8722DD6D19300B746EC /* Exceptions for "AIPlayRingtones" folder in "AIPlayRingtones" target */,
-			);
-			path = AIPlayRingtones;
-			sourceTree = "<group>";
-		};
-/* End PBXFileSystemSynchronizedRootGroup section */
-
 /* Begin PBXFrameworksBuildPhase section */
 		A848F85D2DD6D19100B746EC /* Frameworks */ = {
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				C6F204E3DD79A0F96C8DB3FF /* Pods_AIPlayRingtones.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+		6B369F15FA74FED594C60569 /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				6EFB792FA59CD8536D0BD11F /* Pods_AIPlayRingtones.framework */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		A800FEAF2DDAC0E9009DABDC /* CommonView */ = {
+			isa = PBXGroup;
+			children = (
+				A800FEB02DDAC0F0009DABDC /* ASGeneratorView */,
+			);
+			path = CommonView;
+			sourceTree = "<group>";
+		};
+		A800FEB02DDAC0F0009DABDC /* ASGeneratorView */ = {
+			isa = PBXGroup;
+			children = (
+				A800FEB12DDAC0FC009DABDC /* ASGeneratorView.swift */,
+				A800FEB32DDAC738009DABDC /* ASGeneratorLoadingView.swift */,
+				A800FEB52DDAC75D009DABDC /* ASGeneratorErrorView.swift */,
+			);
+			path = ASGeneratorView;
+			sourceTree = "<group>";
+		};
+		A800FEB92DDACAE7009DABDC /* ASRingGeneratorVC */ = {
+			isa = PBXGroup;
+			children = (
+				A800FEBC2DDACCCF009DABDC /* ASRingGeneratorBaseVC.swift */,
+				A800FEBA2DDACAF2009DABDC /* ASRingGeneratorVC.swift */,
+			);
+			path = ASRingGeneratorVC;
+			sourceTree = "<group>";
+		};
 		A848F8572DD6D19100B746EC = {
 			isa = PBXGroup;
 			children = (
-				A848F8622DD6D19100B746EC /* AIPlayRingtones */,
+				A848F8812DD6D1AF00B746EC /* AIPlayRingtones */,
 				A848F8612DD6D19100B746EC /* Products */,
+				E2F3D1383EB360A9148D55CA /* Pods */,
+				6B369F15FA74FED594C60569 /* Frameworks */,
 			);
 			sourceTree = "<group>";
 		};
@@ -58,6 +177,235 @@
 			name = Products;
 			sourceTree = "<group>";
 		};
+		A848F8812DD6D1AF00B746EC /* AIPlayRingtones */ = {
+			isa = PBXGroup;
+			children = (
+				A800FEAF2DDAC0E9009DABDC /* CommonView */,
+				A848F8EF2DD7526600B746EC /* OperationQueue */,
+				A848F8E62DD74DF300B746EC /* Data */,
+				A848F8D32DD7198100B746EC /* Resources */,
+				A848F8B12DD6D80900B746EC /* APConfig */,
+				A848F88B2DD6D2C600B746EC /* AppPage */,
+				A848F88F2DD6D4E800B746EC /* Common */,
+				A848F8782DD6D1AF00B746EC /* AppDelegate.swift */,
+				A848F8792DD6D1AF00B746EC /* Assets.xcassets */,
+				A848F87A2DD6D1AF00B746EC /* Info.plist */,
+				A848F87C2DD6D1AF00B746EC /* LaunchScreen.storyboard */,
+			);
+			path = AIPlayRingtones;
+			sourceTree = "<group>";
+		};
+		A848F88B2DD6D2C600B746EC /* AppPage */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8B62DD6DF5500B746EC /* ASCommonView */,
+				A848F8AE2DD6D76F00B746EC /* ASTabBarVC */,
+				A848F8A72DD6D74300B746EC /* APSettingVC */,
+				A848F8A62DD6D73E00B746EC /* APMyRingVC */,
+				A848F8A52DD6D73500B746EC /* APAudioToRingVC */,
+				A848F8A22DD6D65900B746EC /* APRingTonesVC */,
+				A848F88C2DD6D2F700B746EC /* APLaunchVC */,
+				A800FEB92DDACAE7009DABDC /* ASRingGeneratorVC */,
+			);
+			path = AppPage;
+			sourceTree = "<group>";
+		};
+		A848F88C2DD6D2F700B746EC /* APLaunchVC */ = {
+			isa = PBXGroup;
+			children = (
+				A848F88D2DD6D38300B746EC /* APLaunchVC.swift */,
+			);
+			path = APLaunchVC;
+			sourceTree = "<group>";
+		};
+		A848F88F2DD6D4E800B746EC /* Common */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8F92DD7536300B746EC /*  Notification+Ex.swift */,
+				A848F89D2DD6D59C00B746EC /* TSNetWork */,
+				A848F8922DD6D51900B746EC /* AIEnums.swift */,
+				A848F8902DD6D4FD00B746EC /* Common.swift */,
+			);
+			path = Common;
+			sourceTree = "<group>";
+		};
+		A848F89D2DD6D59C00B746EC /* TSNetWork */ = {
+			isa = PBXGroup;
+			children = (
+				A800FEB72DDAC81D009DABDC /* TSNetWork+Error.swift */,
+				A848F8992DD6D59C00B746EC /* TSNetworkManager.swift */,
+				A848F89A2DD6D59C00B746EC /* TSNetWork+Business.swift */,
+				A848F89B2DD6D59C00B746EC /* TSNetworkManager+Loading.swift */,
+			);
+			path = TSNetWork;
+			sourceTree = "<group>";
+		};
+		A848F8A22DD6D65900B746EC /* APRingTonesVC */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8D92DD7230B00B746EC /* APRingStyleVC */,
+				A848F8D02DD6ECC800B746EC /* APRingTonesVC */,
+			);
+			path = APRingTonesVC;
+			sourceTree = "<group>";
+		};
+		A848F8A52DD6D73500B746EC /* APAudioToRingVC */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8A82DD6D74900B746EC /* APAudioToRingVC.swift */,
+			);
+			path = APAudioToRingVC;
+			sourceTree = "<group>";
+		};
+		A848F8A62DD6D73E00B746EC /* APMyRingVC */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8AA2DD6D75200B746EC /* APMyRingVC.swift */,
+			);
+			path = APMyRingVC;
+			sourceTree = "<group>";
+		};
+		A848F8A72DD6D74300B746EC /* APSettingVC */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8AC2DD6D75800B746EC /* APSettingVC.swift */,
+			);
+			path = APSettingVC;
+			sourceTree = "<group>";
+		};
+		A848F8AE2DD6D76F00B746EC /* ASTabBarVC */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8AF2DD6D77B00B746EC /* ASTabBarVC.swift */,
+			);
+			path = ASTabBarVC;
+			sourceTree = "<group>";
+		};
+		A848F8B12DD6D80900B746EC /* APConfig */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8B22DD6D82300B746EC /* APConfig.swift */,
+				A848F8B42DD6D82E00B746EC /* APConfig+Color.swift */,
+			);
+			path = APConfig;
+			sourceTree = "<group>";
+		};
+		A848F8B62DD6DF5500B746EC /* ASCommonView */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8B72DD6DF6800B746EC /* ASBtnView */,
+			);
+			path = ASCommonView;
+			sourceTree = "<group>";
+		};
+		A848F8B72DD6DF6800B746EC /* ASBtnView */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8BC2DD6E36800B746EC /* ASLeftHeaderView.swift */,
+				A848F8B82DD6DF7700B746EC /* ASAppBtnView.swift */,
+			);
+			path = ASBtnView;
+			sourceTree = "<group>";
+		};
+		A848F8BE2DD6E6E800B746EC /* VM */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8BA2DD6E30000B746EC /* APRingTonesVM.swift */,
+			);
+			path = VM;
+			sourceTree = "<group>";
+		};
+		A848F8CB2DD6EABD00B746EC /* View */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8CC2DD6EACB00B746EC /* ASPromptTextView.swift */,
+				A848F8D12DD7148F00B746EC /* ASDurationColView.swift */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
+		A848F8D02DD6ECC800B746EC /* APRingTonesVC */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8D62DD71A2600B746EC /* Model */,
+				A848F8CB2DD6EABD00B746EC /* View */,
+				A848F8BE2DD6E6E800B746EC /* VM */,
+				A848F8A32DD6D66D00B746EC /* APRingTonesVC.swift */,
+				A848F8C52DD6E72C00B746EC /* APRingTonesVC+View.swift */,
+				A848F8C92DD6E82A00B746EC /* APRingTonesVC+StackView.swift */,
+				A848F8BF2DD6E6F600B746EC /* APRingTonesVC+TextView.swift */,
+				A848F8C12DD6E6FD00B746EC /* APRingTonesVC+Duration.swift */,
+				A848F8C32DD6E70400B746EC /* APRingTonesVC+Style.swift */,
+			);
+			path = APRingTonesVC;
+			sourceTree = "<group>";
+		};
+		A848F8D32DD7198100B746EC /* Resources */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8E02DD7271400B746EC /* ring_style.json */,
+				A848F8D42DD719AB00B746EC /* ring_duration.json */,
+			);
+			path = Resources;
+			sourceTree = "<group>";
+		};
+		A848F8D62DD71A2600B746EC /* Model */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8E22DD7286600B746EC /* ASGenerateStyleModel.swift */,
+				A848F8D72DD71A3100B746EC /* ASRingGenerateSecModel.swift */,
+			);
+			path = Model;
+			sourceTree = "<group>";
+		};
+		A848F8D92DD7230B00B746EC /* APRingStyleVC */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8DA2DD7231C00B746EC /* APRingStyleVC.swift */,
+			);
+			path = APRingStyleVC;
+			sourceTree = "<group>";
+		};
+		A848F8E62DD74DF300B746EC /* Data */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8ED2DD7508000B746EC /* ASRealmManager.swift */,
+				A848F8EB2DD74EF400B746EC /* ASActionInfoModel.swift */,
+				A848F8E72DD74DF900B746EC /* ASDBHistoryManager.swift */,
+				A848F8E92DD74E3600B746EC /* ASDBActionInfoModel.swift */,
+			);
+			path = Data;
+			sourceTree = "<group>";
+		};
+		A848F8EF2DD7526600B746EC /* OperationQueue */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8F42DD752BC00B746EC /* Generate */,
+				A848F8F02DD7528200B746EC /* ASBaseOperationQueue.swift */,
+				A848F8F22DD7528C00B746EC /* ASBaseOperation.swift */,
+				A848F8FB2DD7539E00B746EC /* ASProgressState.swift */,
+			);
+			path = OperationQueue;
+			sourceTree = "<group>";
+		};
+		A848F8F42DD752BC00B746EC /* Generate */ = {
+			isa = PBXGroup;
+			children = (
+				A848F8F52DD752C400B746EC /* ASGenerateBaseOperation.swift */,
+				A848F8F72DD752D900B746EC /* ASGeneratePosterOperation.swift */,
+			);
+			path = Generate;
+			sourceTree = "<group>";
+		};
+		E2F3D1383EB360A9148D55CA /* Pods */ = {
+			isa = PBXGroup;
+			children = (
+				B4EF561F1D6A688DA6595B7A /* Pods-AIPlayRingtones.debug.xcconfig */,
+				B6A4769786320594B791AFDE /* Pods-AIPlayRingtones.release.xcconfig */,
+			);
+			path = Pods;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
@@ -65,20 +413,17 @@
 			isa = PBXNativeTarget;
 			buildConfigurationList = A848F8732DD6D19300B746EC /* Build configuration list for PBXNativeTarget "AIPlayRingtones" */;
 			buildPhases = (
+				D0205DF6DCB58A873C2BAAC6 /* [CP] Check Pods Manifest.lock */,
 				A848F85C2DD6D19100B746EC /* Sources */,
 				A848F85D2DD6D19100B746EC /* Frameworks */,
 				A848F85E2DD6D19100B746EC /* Resources */,
+				F1EA8B9CDF6FB52C878D5307 /* [CP] Embed Pods Frameworks */,
 			);
 			buildRules = (
 			);
 			dependencies = (
 			);
-			fileSystemSynchronizedGroups = (
-				A848F8622DD6D19100B746EC /* AIPlayRingtones */,
-			);
 			name = AIPlayRingtones;
-			packageProductDependencies = (
-			);
 			productName = AIPlayRingtones;
 			productReference = A848F8602DD6D19100B746EC /* AIPlayRingtones.app */;
 			productType = "com.apple.product-type.application";
@@ -90,6 +435,7 @@
 			isa = PBXProject;
 			attributes = {
 				BuildIndependentTargetsInParallel = 1;
+				CLASSPREFIX = AI;
 				LastSwiftUpdateCheck = 1620;
 				LastUpgradeCheck = 1620;
 				TargetAttributes = {
@@ -122,24 +468,125 @@
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				A848F8822DD6D1AF00B746EC /* Assets.xcassets in Resources */,
+				A848F8D52DD719B600B746EC /* ring_duration.json in Resources */,
+				A848F8842DD6D1AF00B746EC /* LaunchScreen.storyboard in Resources */,
+				A848F8E12DD7271900B746EC /* ring_style.json in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 /* End PBXResourcesBuildPhase section */
 
+/* Begin PBXShellScriptBuildPhase section */
+		D0205DF6DCB58A873C2BAAC6 /* [CP] Check Pods Manifest.lock */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			inputPaths = (
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
+			);
+			name = "[CP] Check Pods Manifest.lock";
+			outputFileListPaths = (
+			);
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/Pods-AIPlayRingtones-checkManifestLockResult.txt",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+			showEnvVarsInLog = 0;
+		};
+		F1EA8B9CDF6FB52C878D5307 /* [CP] Embed Pods Frameworks */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-AIPlayRingtones/Pods-AIPlayRingtones-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+			);
+			name = "[CP] Embed Pods Frameworks";
+			outputFileListPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-AIPlayRingtones/Pods-AIPlayRingtones-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AIPlayRingtones/Pods-AIPlayRingtones-frameworks.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+/* End PBXShellScriptBuildPhase section */
+
 /* Begin PBXSourcesBuildPhase section */
 		A848F85C2DD6D19100B746EC /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				A800FEB22DDAC100009DABDC /* ASGeneratorView.swift in Sources */,
+				A848F88E2DD6D38600B746EC /* APLaunchVC.swift in Sources */,
+				A848F8CA2DD6E82B00B746EC /* APRingTonesVC+StackView.swift in Sources */,
+				A848F8C22DD6E70000B746EC /* APRingTonesVC+Duration.swift in Sources */,
+				A848F8A42DD6D67000B746EC /* APRingTonesVC.swift in Sources */,
+				A848F8BD2DD6E38900B746EC /* ASLeftHeaderView.swift in Sources */,
+				A848F8D82DD71A3A00B746EC /* ASRingGenerateSecModel.swift in Sources */,
+				A848F8E82DD74DFD00B746EC /* ASDBHistoryManager.swift in Sources */,
+				A848F89E2DD6D59C00B746EC /* TSNetWork+Business.swift in Sources */,
+				A848F8AB2DD6D75300B746EC /* APMyRingVC.swift in Sources */,
+				A848F89F2DD6D59C00B746EC /* TSNetworkManager.swift in Sources */,
+				A848F8E32DD7286A00B746EC /* ASGenerateStyleModel.swift in Sources */,
+				A848F8A12DD6D59C00B746EC /* TSNetworkManager+Loading.swift in Sources */,
+				A800FEBD2DDACCD4009DABDC /* ASRingGeneratorBaseVC.swift in Sources */,
+				A800FEB62DDAC764009DABDC /* ASGeneratorErrorView.swift in Sources */,
+				A800FEB82DDAC826009DABDC /* TSNetWork+Error.swift in Sources */,
+				A848F8FA2DD7536700B746EC /*  Notification+Ex.swift in Sources */,
+				A848F8C02DD6E6FA00B746EC /* APRingTonesVC+TextView.swift in Sources */,
+				A848F8EA2DD74E3A00B746EC /* ASDBActionInfoModel.swift in Sources */,
+				A848F8B02DD6D77C00B746EC /* ASTabBarVC.swift in Sources */,
+				A848F8B32DD6D82300B746EC /* APConfig.swift in Sources */,
+				A848F8FC2DD753A000B746EC /* ASProgressState.swift in Sources */,
+				A848F8A92DD6D74A00B746EC /* APAudioToRingVC.swift in Sources */,
+				A848F8AD2DD6D75900B746EC /* APSettingVC.swift in Sources */,
+				A848F8912DD6D50000B746EC /* Common.swift in Sources */,
+				A800FEBB2DDACAF3009DABDC /* ASRingGeneratorVC.swift in Sources */,
+				A848F8F32DD7528D00B746EC /* ASBaseOperation.swift in Sources */,
+				A848F8BB2DD6E30600B746EC /* APRingTonesVM.swift in Sources */,
+				A848F8C42DD6E70500B746EC /* APRingTonesVC+Style.swift in Sources */,
+				A848F8F82DD752E700B746EC /* ASGeneratePosterOperation.swift in Sources */,
+				A800FEB42DDAC73E009DABDC /* ASGeneratorLoadingView.swift in Sources */,
+				A848F8EC2DD74EF800B746EC /* ASActionInfoModel.swift in Sources */,
+				A848F8F62DD752D700B746EC /* ASGenerateBaseOperation.swift in Sources */,
+				A848F8932DD6D52100B746EC /* AIEnums.swift in Sources */,
+				A848F8EE2DD7508300B746EC /* ASRealmManager.swift in Sources */,
+				A848F8B52DD6D83E00B746EC /* APConfig+Color.swift in Sources */,
+				A848F8B92DD6DF7900B746EC /* ASAppBtnView.swift in Sources */,
+				A848F8F12DD7528800B746EC /* ASBaseOperationQueue.swift in Sources */,
+				A848F8CD2DD6EAD300B746EC /* ASPromptTextView.swift in Sources */,
+				A848F8DB2DD7231E00B746EC /* APRingStyleVC.swift in Sources */,
+				A848F8D22DD7149D00B746EC /* ASDurationColView.swift in Sources */,
+				A848F8C62DD6E72D00B746EC /* APRingTonesVC+View.swift in Sources */,
+				A848F8862DD6D1AF00B746EC /* AppDelegate.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 /* End PBXSourcesBuildPhase section */
 
+/* Begin PBXVariantGroup section */
+		A848F87C2DD6D1AF00B746EC /* LaunchScreen.storyboard */ = {
+			isa = PBXVariantGroup;
+			children = (
+				A848F87B2DD6D1AF00B746EC /* Base */,
+			);
+			name = LaunchScreen.storyboard;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
 /* Begin XCBuildConfiguration section */
 		A848F8742DD6D19300B746EC /* Debug */ = {
 			isa = XCBuildConfiguration;
+			baseConfigurationReference = B4EF561F1D6A688DA6595B7A /* Pods-AIPlayRingtones.debug.xcconfig */;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
@@ -149,7 +596,6 @@
 				INFOPLIST_FILE = AIPlayRingtones/Info.plist;
 				INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
 				INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
-				INFOPLIST_KEY_UIMainStoryboardFile = Main;
 				INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
 				INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
 				LD_RUNPATH_SEARCH_PATHS = (
@@ -167,6 +613,7 @@
 		};
 		A848F8752DD6D19300B746EC /* Release */ = {
 			isa = XCBuildConfiguration;
+			baseConfigurationReference = B6A4769786320594B791AFDE /* Pods-AIPlayRingtones.release.xcconfig */;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
@@ -176,7 +623,6 @@
 				INFOPLIST_FILE = AIPlayRingtones/Info.plist;
 				INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
 				INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
-				INFOPLIST_KEY_UIMainStoryboardFile = Main;
 				INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
 				INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
 				LD_RUNPATH_SEARCH_PATHS = (

+ 1 - 1
AIPlayRingtones.xcodeproj/xcuserdata/100years.xcuserdatad/xcschemes/xcschememanagement.plist

@@ -7,7 +7,7 @@
 		<key>AIPlayRingtones.xcscheme_^#shared#^_</key>
 		<dict>
 			<key>orderHint</key>
-			<integer>0</integer>
+			<integer>32</integer>
 		</dict>
 	</dict>
 </dict>

+ 10 - 0
AIPlayRingtones.xcworkspace/contents.xcworkspacedata

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "group:AIPlayRingtones.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:Pods/Pods.xcodeproj">
+   </FileRef>
+</Workspace>

+ 27 - 0
AIPlayRingtones/APConfig/APConfig+Color.swift

@@ -0,0 +1,27 @@
+//
+//  APConfig+Color.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+
+extension UIColor {
+    /// 背景色
+    static let mainBg = "#07080C".uiColor
+    
+    /// 主色调
+    static let themeColor = "#FECB34".uiColor
+    
+    /// 弹窗色
+    static let popupColor = "#222222".uiColor
+    
+    /// 主要文字
+    static let mainText = UIColor.white
+    
+    /// 辅助文字
+    static let textAssist = UIColor.fromHex("#FFFFFF", alpha: 0.4)
+    
+    /// 卡片色
+    static let cardColor = "#202030".uiColor
+
+}

+ 7 - 0
AIPlayRingtones/APConfig/APConfig.swift

@@ -0,0 +1,7 @@
+//
+//  APConfig.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+

+ 72 - 13
AIPlayRingtones/AppDelegate.swift

@@ -9,28 +9,87 @@ import UIKit
 
 @main
 class AppDelegate: UIResponder, UIApplicationDelegate {
-
-
-
+    
+    var window: UIWindow?
+    var backgroundTaskIdentifier: UIBackgroundTaskIdentifier = .invalid
     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
-        // Override point for customization after application launch.
+        
+        window = UIWindow(frame: UIScreen.main.bounds)
+        window?.backgroundColor = UIColor.black
+        window?.makeKeyAndVisible()
+        initPlatform()
+        goToLoadVC()
         return true
     }
+    
+    func goToLoadVC() {
+        let launchVC = ASLaunchVC()
+        launchVC.dismissHandler = { [weak self] in
+            guard let self = self else { return }
+            JudgmentSkipPage()
+        }
+        window?.rootViewController = launchVC
+    }
+    
+    func goToTab() {
+        window?.rootViewController = ASTabBarVC()
+    }
+
+    func JudgmentSkipPage() {
+//        if AppDelegate.isFirstInstallApp() {
+//            let bootPageVC = TSBootPageVC { [weak self] in
+//                guard let self = self else { return }
+//                UserDefaults.standard.set("1", forKey: "isFirstInstallApp")
+//                UserDefaults.standard.synchronize()
+//                goToTab()
+//            }
+//            let navi = TSBaseNavigationC(rootViewController: bootPageVC)
+//            window?.rootViewController = navi
+//        } else {
+            goToTab()
+//        }
+    }
+
+    func initPlatform() {
+        TSColorConfigShared.naviMianTextColor = .white
+    }
+}
 
-    // MARK: UISceneSession Lifecycle
 
-    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
-        // Called when a new scene session is being created.
-        // Use this method to select a configuration to create the new scene with.
-        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
+extension AppDelegate {
+
+    func applicationDidEnterBackground(_ application: UIApplication) {
+        beginBackgroundTask()
+    }
+
+    func beginBackgroundTask() {
+        backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask { [weak self] in
+            self?.endBackgroundTask()
+        }
     }
 
-    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
-        // Called when the user discards a scene session.
-        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
-        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
+    func endBackgroundTask() {
+        if backgroundTaskIdentifier != .invalid {
+            UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier)
+            backgroundTaskIdentifier = .invalid
+        }
     }
 
+    func applicationWillEnterForeground(_ application: UIApplication) {
+
+    }
+    
+    func applicationWillTerminate(_ application: UIApplication) {
+        // 当应用即将被终止时,这里也可以添加数据保存逻辑,但系统留给的时间很有限
+    }
 
 }
 
+
+extension AppDelegate {
+    
+    static func isFirstInstallApp() -> Bool {
+        return UserDefaults.standard.string(forKey: "isFirstInstallApp") == nil
+    }
+
+}

+ 10 - 0
AIPlayRingtones/AppPage/APAudioToRingVC/APAudioToRingVC.swift

@@ -0,0 +1,10 @@
+//
+//  APAudioToRingVC.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+
+class APAudioToRingVC: TSBaseVC {
+    
+}

+ 125 - 0
AIPlayRingtones/AppPage/APLaunchVC/APLaunchVC.swift

@@ -0,0 +1,125 @@
+//
+//  APLaunchVC.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+
+import Alamofire
+import UIKit
+
+class ASLaunchVC: UIViewController {
+    var dismissHandler: (() -> Void)?
+
+    // 定时器
+    private var timer: DispatchSourceTimer?
+    // 闪屏页剩余显示时长
+    #if DEBUG
+    private var remindTimeInterval: TimeInterval = 2.0
+    #else
+        private var remindTimeInterval: TimeInterval = 2.0
+    #endif
+
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        setupLaunchScreenView()
+        addNotifiy()
+        
+        if AppDelegate.isFirstInstallApp() {//首次安装需要等待网络权限弹窗
+            startTimer()
+        }else {
+            self.enterApp()
+        }
+
+        
+        startTimer()
+        addNotifiy()
+    }
+
+    func addNotifiy() {
+//        TSNetworkTool.shared.startListenNetStatus { status, manager in
+//            switch status {
+//            case .reachable:
+//                PurchaseManager.default.requestProducts()
+//                manager?.stopListening()
+//                break
+//            default:
+//                PurchaseManager.default.requestProducts()
+//                break
+//            }
+//        }
+    }
+
+    func enterApp() {
+        dismissHandler?()
+    }
+
+
+    
+    private func startTimer() {
+        if timer == nil {
+            
+            var maxTime:Int = 0 //200*10=2s 200 *10*3 =6s
+            timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global())
+            timer?.schedule(deadline: .now(), repeating: .milliseconds(200))
+            timer?.setEventHandler(handler: { [weak self] in
+                // App活跃时,计时有效;如网络授权弹窗唤起时,计时失效
+                DispatchQueue.main.async {
+                    guard let self = self  else {
+                        return
+                    }
+                    
+                    guard UIApplication.shared.applicationState == .active
+                    else {
+                        dePrint("倒计时:!= active")
+                        maxTime += 1
+                        if maxTime > 30 {
+                            dePrint("超过最大倒计时进入 app")
+                            self.timer?.cancel()
+                            self.timer = nil
+                            self.enterApp()
+                        }
+                        
+                        return
+                    }
+                    
+                    self.remindTimeInterval -= 0.2
+                    dePrint("倒计时:\(self.remindTimeInterval)")
+                    if self.remindTimeInterval <= 0 {
+                        self.timer?.cancel()
+                        self.timer = nil
+                        self.enterApp()
+                    }
+                }
+
+            })
+            timer?.resume()
+        }else{
+            self.enterApp()
+        }
+    }
+    
+    
+
+    private func setupLaunchScreenView() {
+        // 获取 LaunchScreen.storyboard 的视图控制器
+        let storyboard = UIStoryboard(name: "LaunchScreen", bundle: nil)
+        guard let launchVC = storyboard.instantiateInitialViewController() else {
+            debugPrint("无法加载 LaunchScreen 的初始视图控制器")
+            return
+        }
+
+        // 获取 LaunchScreen 的视图
+        guard let launchView = launchVC.view else {
+            debugPrint("无法获取 LaunchScreen 的视图")
+            return
+        }
+
+        // 设置 launchView 的 frame 为当前视图的 bounds
+        launchView.frame = UIScreen.main.bounds
+
+        // 将 launchView 添加到 ASLaunchVC 的视图中
+        view.addSubview(launchView)
+    }
+}
+

+ 10 - 0
AIPlayRingtones/AppPage/APMyRingVC/APMyRingVC.swift

@@ -0,0 +1,10 @@
+//
+//  APMyRingVC.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+
+class APMyRingVC: TSBaseVC {
+    
+}

+ 192 - 0
AIPlayRingtones/AppPage/APRingTonesVC/APRingStyleVC/APRingStyleVC.swift

@@ -0,0 +1,192 @@
+//
+//  APRingStyleVC.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/16.
+//
+
+import ObjectMapper
+class APRingStyleVC: TSBaseVC {
+    
+    var selectedCompleted:((ASGenerateStyleModel,Int)->Void)?
+
+    //选择生成类类型组
+    var generateStyleIndex:Int = 0{
+        didSet{
+            if generateStyleModels.count <= 0 { return }
+            DispatchQueue.main.async {
+                self.colView.collectionView.selectItem(at: IndexPath(item: self.generateStyleIndex, section: 0), animated: true, scrollPosition: .centeredVertically)
+            }
+        }
+    }
+    var generateStyleModel:ASGenerateStyleModel?{
+        didSet{
+            if let generateStyleModel = generateStyleModel {
+                selectedCompleted?(generateStyleModel,generateStyleIndex)
+            }
+        }
+    }
+    lazy var generateStyleModels: [ASGenerateStyleModel] = {
+        var ptpStyleModels = [ASGenerateStyleModel]()
+        if let dataArray = Mapper<ASGenerateStyleModel>().mapArray(JSONfile: "ring_style.json"){
+            ptpStyleModels = dataArray
+            
+            if let model = dataArray.safeObj(At: generateStyleIndex) {
+                generateStyleModel = model //加上默认的选择
+            }
+        }
+        
+        return ptpStyleModels
+    }()
+    
+    private var collectionViewObserver: TSCollectionViewObserver!
+    lazy var colView: TSSimpleCollectionView = {
+        let identifier = "APRingStyleCell"
+
+        let layout = UICollectionViewFlowLayout()
+        let cp = TSSimpleCollectionView()
+        cp.layout.minimumLineSpacing = 16
+        cp.layout.minimumInteritemSpacing = 16
+        cp.layout.scrollDirection = .vertical
+        cp.delegate = self
+        let contentInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
+        cp.collectionView.contentInset = contentInset
+        cp.layout.itemSize = kGetCollectionViewCellSize(sectionInset: contentInset, itemSpacing: 16, originalSize: CGSize(width: 104, height: 104), cellRowNum: 3)
+        cp.registerCell(APRingStyleCell.self,identifier:identifier)
+        cp.cellIdentifierForItem = { data in
+            return identifier
+        }
+
+        return cp
+    }()
+    
+    override func createView() {
+        setNavBarViewHidden(true)
+        contentView.addSubview(colView)
+        colView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+            make.height.equalTo(k_ScreenHeight)
+        }
+    }
+
+    override func dealThings() {
+
+        // 监听collectionView 的 contentSize
+        collectionViewObserver = TSCollectionViewObserver(collectionView: colView.collectionView)
+        collectionViewObserver.onContentSizeChange = { [weak self] size in
+            guard let self = self else { return }
+            print("collectionViewObserver 内容大小变化: \(size)")
+            self.colView.snp.updateConstraints { make in
+                make.height.equalTo(size.height)
+            }
+        }
+        
+        colView.reload(with: [TSSimpleSectionData(items: generateStyleModels)])
+        self.generateStyleIndex = abs(generateStyleIndex)
+    }
+}
+extension APRingStyleVC: TSSimpleCollectionViewDelegate {
+    
+    func collectionView(didTrigger event: TSSmalCoacopods.TSSimpleCellEvent) {
+        switch event.action {
+        case .tap:
+            generateStyleIndex = event.indexPath.row
+            if let model = generateStyleModels.safeObj(At: generateStyleIndex) {
+                generateStyleModel = model
+            }
+        default:
+            break
+        }
+    }
+    
+}
+
+
+
+class APRingStyleCell: TSBaseCollectionCell ,TSSimpleConfigurableView {
+    
+    weak var delegate: (any TSSmalCoacopods.TSSimpleCollectionViewDelegate)?
+    var indexPath: IndexPath = IndexPath(item: 0, section: 0)
+    var data: Any? {
+        didSet {
+            if let model = data as? ASGenerateStyleModel {
+                proImageView.isHidden = !model.vip
+                textLab.text = model.imageText.localized
+                imageView.image = UIImage(named: model.imageName)
+            }
+        }
+    }
+    
+    override var isSelected: Bool{
+        didSet{
+            textLab.textColor = .white.withAlphaComponent( isSelected ? 1.0 : 0.7)
+            bgImageView.image = isSelected ? .ringTextSelectedBg : .ringTextUnSelectBg
+            boardImageView.isHidden = !isSelected
+        }
+    }
+    
+    lazy var bgImageView: UIImageView = {
+        let bgImageView = UIImageView.createImageView(image: .ringTextUnSelectBg)
+        return bgImageView
+    }()
+    
+    lazy var boardImageView: UIImageView = {
+        let boardImageView = UIImageView.createImageView(image: .ringTextSelectedBoard)
+        boardImageView.isHidden = true
+        return boardImageView
+    }()
+
+    lazy var imageView: UIImageView = {
+        let imageView = UIImageView()
+        imageView.cornerRadius = 12
+        return imageView
+    }()
+    
+    lazy var proImageView:UIImageView = {
+        let proImageView = UIImageView.createImageView(image: .PRO)
+        return proImageView
+    }()
+    
+
+    lazy var textLab: UILabel = {
+        let textLab = UILabel.createLabel(font: .font(size:14,weight: .regular),textColor: .white.withAlphaComponent(0.6),textAlignment: .center)
+        return textLab
+    }()
+    
+    
+    override func creatUI() {
+        
+        contentView.addSubview(bgImageView)
+        bgImageView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        
+        contentView.addSubview(imageView)
+        imageView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        
+
+        contentView.addSubview(textLab)
+        textLab.snp.makeConstraints { make in
+            make.leading.equalTo(0)
+            make.trailing.equalTo(0)
+            make.bottom.equalTo(0)
+            make.height.equalTo(36)
+        }
+        
+        contentView.addSubview(proImageView)
+        proImageView.snp.makeConstraints { make in
+            make.top.equalTo(6)
+            make.trailing.equalTo(-8)
+            make.width.equalTo(21)
+            make.height.equalTo(10)
+        }
+ 
+        contentView.addSubview(boardImageView)
+        boardImageView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+    
+    }
+}

+ 28 - 0
AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/APRingTonesVC+Duration.swift

@@ -0,0 +1,28 @@
+//
+//  APRingTonesVC+Duration.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+
+extension APRingTonesVC {
+    
+    func creatDurationCollectionView() -> ASGenerateDurationColView {
+        let durationColView = ASGenerateDurationColView()
+        durationColView.currentSelectedIndex = viewModel.generateSecIndex
+        durationColView.secModelArray = viewModel.generateSecModels
+        durationColView.selectedCompleted = { [weak self] model,index in
+            guard let self = self else { return }
+            viewModel.generateSecModel = model
+            viewModel.generateSecIndex = index
+        }
+        return durationColView
+    }
+    
+    
+    
+    
+    
+}
+
+

+ 29 - 0
AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/APRingTonesVC+StackView.swift

@@ -0,0 +1,29 @@
+//
+//  APRingTonesVC+StackView.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+
+extension APRingTonesVC {
+    
+    
+    func creatCusStackView() -> TSCustomStackView {
+        let cusStackView = TSCustomStackView(axis: .vertical, spacing: 0)
+        cusStackView.scrollView.isScrollEnabled = true
+        return cusStackView
+    }
+    
+    
+    
+    func setUpCusStackView() {
+
+        cusStackView.addSpacing(length: 10)
+        cusStackView.addSubviewToStack(customTextView)
+        cusStackView.addSubviewToStack(ASLeftHeaderView.creatTitleView(title: "Duration".localized),length: kSectionTitleViewH)
+        cusStackView.addSubviewToStack(secStyleView, length: 36.0)
+        cusStackView.addSubviewToStack(ASLeftHeaderView.creatTitleView(title: "Ringtone Genre".localized),length: kSectionTitleViewH)
+        cusStackView.addSubviewToStack(ringStyleVC.view)
+    }
+
+}

+ 11 - 0
AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/APRingTonesVC+Style.swift

@@ -0,0 +1,11 @@
+//
+//  APRingTonesVC+Style.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+
+extension APRingTonesVC {
+    
+}
+ 

+ 21 - 0
AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/APRingTonesVC+TextView.swift

@@ -0,0 +1,21 @@
+//
+//  APRingTonesVC+TextView.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+
+extension APRingTonesVC {
+ 
+    func creatCustomTextView() -> ASPromptTextView {
+        
+        let promptTextView = ASPromptTextView(randomTextArray: kRandomTextToRintone) { [weak self] text in
+            guard let self = self else { return }
+            viewModel.promptText = text
+        }
+        return promptTextView
+    }
+    
+}
+
+

+ 78 - 0
AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/APRingTonesVC+View.swift

@@ -0,0 +1,78 @@
+//
+//  APRingTonesVC+Nav.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+
+
+extension APRingTonesVC {
+    
+//    func creatVipBtn()->UIButton{
+//        let vipBtn = UIButton.createButton(image: UIImage(named: "nav_vip")) { [weak self] in
+//            guard let self = self else { return }
+//            TSPurchaseVC.show(target: self) {}
+//        }
+//        return vipBtn
+//    }
+    
+    
+    func creatNavBarView()->TSBaseNavContentBarView{
+        let navBarView = TSBaseNavContentBarView()
+
+        let titleImageView = UIImageView.createImageView(imageName: "nav_title_aiRingtone", contentMode: .scaleToFill)
+        navBarView.barView.addSubview(titleImageView)
+        titleImageView.snp.makeConstraints { make in
+            make.center.equalToSuperview()
+        }
+
+//        navBarView.barView.addSubview(vipBtn)
+//        vipBtn.snp.makeConstraints { make in
+//            make.centerY.equalToSuperview()
+//            make.trailing.equalTo(-16) // (-60)
+//            make.width.height.equalTo(24)
+//        }
+
+        return navBarView
+    }
+    
+}
+
+extension APRingTonesVC {
+    
+    func creatRingStyleVC() -> APRingStyleVC{
+        let ringStyleVC = APRingStyleVC()
+        ringStyleVC.selectedCompleted = { [weak self] model,index in
+            guard let self = self else { return }
+            viewModel.generateStyleModel = model
+        }
+        return ringStyleVC
+    }
+    
+    func creatCreatBtnView() -> ASAppBtnView{
+        let creatBtnView = ASAppBtnView()
+        creatBtnView.setUpButton(style: .generate) { [weak self] in
+            guard let self = self else { return }
+            generateAI()
+        }
+        creatBtnView.setBtnEnabled(isEnabled: false)
+//        creatBtnView.isIconVipBlock = { [weak self] in
+//            guard let self = self else { return false }
+//            var showVip = kPurchaseDefault.generateVipShow(type: .picToPic)
+//            if showVip == false {
+//                showVip = self.viewModel.selectedPTPStyleModel.isVip
+//            }
+//            return showVip
+//        }
+//        creatBtnView.isClickVipBlock = { [weak self] in
+//            guard let self = self else { return false }
+//            var isVip = kPurchaseDefault.freeNumAvailable(type: .picToPic) == false
+//            if viewModel.selectedPTPStyleModel.isVip == true {
+//                isVip = true
+//            }
+//            return isVip
+//        }
+        return creatBtnView
+    }
+    
+}

+ 78 - 0
AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/APRingTonesVC.swift

@@ -0,0 +1,78 @@
+//
+//  APRingTonesVC.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+
+import Combine
+class APRingTonesVC: TSBaseVC {
+    lazy var viewModel: APRingTonesVM = {
+        let viewModel = APRingTonesVM()
+//        viewModel.isCanGennerateBlock = { [weak self] _ in
+//            guard let self = self else { return }
+//            setCreatBtnEnabled()
+//        }
+        return viewModel
+    }()
+
+//    lazy var vipBtn: UIButton = creatVipBtn()
+    lazy var navBarView: TSBaseNavContentBarView = creatNavBarView()
+    lazy var cusStackView: TSCustomStackView = creatCusStackView()
+    lazy var customTextView: ASPromptTextView = creatCustomTextView()
+    lazy var secStyleView: ASGenerateDurationColView = creatDurationCollectionView()
+    lazy var ringStyleVC: APRingStyleVC = creatRingStyleVC()
+    lazy var creatBtnView: ASAppBtnView = creatCreatBtnView()
+    
+    
+    override func createView() {
+        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(clickView))
+        tapGesture.cancelsTouchesInView = false
+        view.addGestureRecognizer(tapGesture)
+
+        navBarContentView.addSubview(navBarView)
+        navBarView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+
+        contentView.addSubview(cusStackView)
+        cusStackView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+
+        contentView.addSubview(creatBtnView)
+        creatBtnView.snp.makeConstraints { make in
+            make.centerX.equalToSuperview()
+            make.bottom.equalTo(-16)
+            make.size.equalTo(creatBtnView.btnSize)
+        }
+
+        
+        self.addChild(ringStyleVC)
+        setUpCusStackView()
+    }
+    
+    override func dealThings() {
+        viewModel.$isCanGennerate.receive(on: DispatchQueue.main).sink { [weak self] enble in
+            guard let self = self else { return }
+            creatBtnView.setBtnEnabled(isEnabled: enble)
+        }.store(in: &cancellable)
+    }
+}
+
+
+extension APRingTonesVC {
+    @objc func clickView() {
+        view.endEditing(true)
+    }
+    
+    
+    func generateAI() {
+        view.endEditing(true)
+        
+        
+        
+        TSToastShared.showToast(text: "nihao")
+    }
+    
+}

+ 32 - 0
AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/Model/ASGenerateStyleModel.swift

@@ -0,0 +1,32 @@
+//
+//  ASGenerateStyleModel.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/16.
+//
+import ObjectMapper
+
+
+// 1. 定义历史记录类型枚举
+enum ASGenerateType: String {
+    case textToRing      //图生图
+    case ringToRing     //文生图
+}
+
+class ASGenerateStyleModel: TSBaseModel {
+    var imageName:String = ""
+    var imageText:String = ""
+    var prompt:String = ""
+    var vip:Bool = false
+    
+    override func mapping(map: ObjectMapper.Map) {
+        imageName               <- map["imageName"]
+        imageText               <- map["imageText"]
+        prompt                  <- map["prompt"]
+        vip                     <- map["vip"]
+    }
+
+    var upLoadData:Data?
+    var upLoadRingUrl:String?
+    var generateType:ASGenerateType = .textToRing
+}

+ 16 - 0
AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/Model/ASRingGenerateSecModel.swift

@@ -0,0 +1,16 @@
+//
+//  ASRingGenerateSecModel.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/16.
+//
+import ObjectMapper
+class ASRingGenerateSecModel: TSBaseModel {
+    var sec:Int = 5
+    var vip:Bool = false
+    
+    override func mapping(map: Map) {
+        sec <- map["sec"]
+        vip <- map["vip"]
+    }
+}

+ 62 - 0
AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/VM/APRingTonesVM.swift

@@ -0,0 +1,62 @@
+//
+//  APRingTonesVM.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+
+
+let kRandomTextToRintone:[String] = [
+    "Create a upbeat Pop ringtone with a catchy melody, bright synths, and a cheerful vibe. Use a BPM of 120-130 and keep it energetic and memorable.",
+    "Generate a cinematic ringtone with orchestral strings, powerful brass, and a dramatic build-up. Use a BPM of 60-80 for a grand, inspiring feel.",
+    "Produce a Lo-Fi ringtone with a relaxed piano melody, soft beats, and warm vinyl crackle. Use a BPM of 70-90 for a cozy, laid-back vibe.",
+    "Create a EDM ringtone with a pulsating bassline, uplifting synths, and a quick build-up. Use a BPM of 128-132 for a high-energy, festival-ready sound.",
+    "Generate a Jazz ringtone with a smooth saxophone melody, soft piano chords, and a gentle swing rhythm. Use a BPM of 90-100 for a classy, sophisticated tone.",
+    "Produce a Funk ringtone with a groovy bassline, rhythmic guitar chops, and punchy brass hits. Use a BPM of 100-110 for a lively, danceable vibe.",
+    "Create a Dubstep ringtone with heavy bass wobbles, aggressive synths, and a quick drop. Use a BPM of 140-150 for an intense, edgy sound.",
+    "Generate a Folk ringtone with a fingerpicked acoustic guitar melody and light percussion. Use a BPM of 80-90 for a warm, earthy feel.",
+    "Produce a Synthwave ringtone with retro arpeggiated synths, a driving beat, and an 80s-inspired vibe. Use a BPM of 100-110 for a nostalgic, futuristic tone.",
+    "Create a Techno ringtone with a repetitive bassline, crisp hi-hats, and subtle synth textures. Use a BPM of 125-130 for a sleek, modern sound.",
+]
+import Combine
+import ObjectMapper
+class APRingTonesVM {
+    private var cancellables = Set<AnyCancellable>()
+    //输入框内容
+    @Published var promptText:String = ""
+    
+
+    //选择生成时长类型组
+    var generateSecIndex:Int = 0
+    @Published var generateSecModel:ASRingGenerateSecModel?
+    lazy var generateSecModels: [ASRingGenerateSecModel] = {
+        var ptpStyleModels = [ASRingGenerateSecModel]()
+        if let dataArray = Mapper<ASRingGenerateSecModel>().mapArray(JSONfile: "ring_duration.json"){
+            ptpStyleModels = dataArray
+            
+            if let model = dataArray.safeObj(At: generateSecIndex) {
+                generateSecModel = model //加上默认的选择
+            }
+        }
+        
+        return ptpStyleModels
+    }()
+    
+    
+    //选择生成类类型
+    @Published var generateStyleModel:ASGenerateStyleModel?
+    
+    @Published private(set) var isCanGennerate: Bool = false
+    init(){
+        
+       
+        Publishers.CombineLatest3($promptText, $generateSecModel,$generateStyleModel)
+              .map { promptText, generateSecModel,generateStyleModel in
+                  // 当两者长度都 > 0 时返回 true
+                  return !promptText.isEmpty && generateSecModel != nil && generateStyleModel != nil
+              }
+              .assign(to: \.isCanGennerate, on: self)
+              .store(in: &cancellables)
+    }
+
+}

+ 132 - 0
AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/View/ASDurationColView.swift

@@ -0,0 +1,132 @@
+//
+//  ASDurationColView.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+
+class ASGenerateDurationColView: TSBaseView {
+    
+    var selectedCompleted:((ASRingGenerateSecModel,Int)->Void)?
+    
+    var currentSelectedIndex:Int = 0 {
+        didSet{
+            if self.secModelArray.count <= 0 { return }
+            collectionView.collectionView.selectItem(at: IndexPath(item: currentSelectedIndex, section: 0), animated: true, scrollPosition: .centeredHorizontally)
+        }
+    }
+    var secModelArray:[ASRingGenerateSecModel] = [] {
+        didSet{
+            collectionView.reload(with: [TSSimpleSectionData(items: secModelArray)])
+            let index = currentSelectedIndex
+            kExecuteOnMainThread {
+                self.currentSelectedIndex = index
+            }
+        }
+    }
+    lazy var collectionView: TSSimpleCollectionView = {
+        let identifier = "ASDurationColViewCell"
+
+        let layout = UICollectionViewFlowLayout()
+        let cp = TSSimpleCollectionView()
+        cp.layout.itemSize = CGSize(width: 88, height: 36)
+        cp.layout.minimumLineSpacing = 8
+        cp.layout.minimumInteritemSpacing = 0
+        cp.layout.scrollDirection = .horizontal
+        cp.delegate = self
+        cp.collectionView.contentInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
+        cp.registerCell(ASDurationColViewCell.self,identifier:identifier)
+        cp.cellIdentifierForItem = { data in
+            return identifier
+        }
+
+        return cp
+    }()
+    
+    
+    override func creatUI(){
+        contentView.addSubview(collectionView)
+        collectionView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+    }
+}
+extension ASGenerateDurationColView: TSSimpleCollectionViewDelegate {
+    
+    func collectionView(didTrigger event: TSSmalCoacopods.TSSimpleCellEvent) {
+        switch event.action {
+        case .tap:
+            currentSelectedIndex = event.indexPath.row
+            if let model = secModelArray.safeObj(At: currentSelectedIndex) {
+                selectedCompleted?(model,currentSelectedIndex)
+            }
+        default:
+            break
+        }
+    }
+    
+}
+
+
+
+class ASDurationColViewCell: TSBaseCollectionCell ,TSSimpleConfigurableView {
+    
+    weak var delegate: (any TSSmalCoacopods.TSSimpleCollectionViewDelegate)?
+    var indexPath: IndexPath = IndexPath(item: 0, section: 0)
+    var data: Any? {
+        didSet {
+            if let model = data as? ASRingGenerateSecModel {
+                textLab.text = "\(model.sec) Sec"
+                proImageView.isHidden = !model.vip
+            }
+        }
+    }
+    
+    override var isSelected: Bool{
+        didSet{
+            bgImageView.image = isSelected ? .secSelectedBg : .secUnSelectedBg
+            textLab.font = .font(size:14,weight: isSelected ? .medium : .regular)
+            textLab.textColor = .white.withAlphaComponent( isSelected ? 1.0 : 0.6)
+        }
+    }
+    
+    lazy var proImageView:UIImageView = {
+        let proImageView = UIImageView.createImageView(image: .PRO)
+        return proImageView
+    }()
+    
+    lazy var bgImageView: UIImageView = {
+        let bgImageView = UIImageView.createImageView(image: .secUnSelectedBg)
+        return bgImageView
+    }()
+    
+    lazy var textLab: UILabel = {
+        let textLab = UILabel.createLabel(font: .font(size:14,weight: .regular),textColor: .white.withAlphaComponent(0.6),textAlignment: .center)
+        return textLab
+    }()
+    
+    
+    override func creatUI() {
+        
+        contentView.addSubview(bgImageView)
+        bgImageView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        
+        contentView.addSubview(textLab)
+        textLab.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.leading.equalTo(8)
+            make.trailing.equalTo(-8)
+            make.height.equalTo(20)
+        }
+        
+        contentView.addSubview(proImageView)
+        proImageView.snp.makeConstraints { make in
+            make.top.equalTo(4)
+            make.trailing.equalTo(-4)
+            make.width.equalTo(21)
+            make.height.equalTo(10)
+        }
+    }
+}

+ 206 - 0
AIPlayRingtones/AppPage/APRingTonesVC/APRingTonesVC/View/ASPromptTextView.swift

@@ -0,0 +1,206 @@
+//
+//  ASPromptTextView.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+
+
+class ASPromptTextView : TSBaseView{
+    
+    var randomTextArray:[String]
+    var textChangedBlock:((String)->Void)
+    
+    init(randomTextArray: [String], textChangedBlock: @escaping (String) -> Void) {
+        self.randomTextArray = randomTextArray
+        self.textChangedBlock = textChangedBlock
+        super.init(frame: .zero)
+    }
+    
+    @MainActor required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+
+    lazy var randomTextPicker: TSRandomTextTool = {
+        let textPicker = TSRandomTextTool(texts: randomTextArray)
+        return textPicker
+    }()
+    
+    lazy var boardImageView: UIImageView = {
+        let boardImageView = UIImageView.createImageView(imageName: "textView_board",contentMode: .scaleToFill)
+        boardImageView.isHidden = true
+        return boardImageView
+    }()
+    
+    lazy var textBgView: UIView = {
+        let textBgView = UIView()
+        
+        let bgImageView = UIImageView.createImageView(imageName: "textView_bg",contentMode: .scaleToFill)
+        textBgView.addSubview(bgImageView)
+        bgImageView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        
+        textBgView.addSubview(boardImageView)
+        boardImageView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        
+        return textBgView
+    }()
+    
+    lazy var customTextView: TSPlaceholderTextView = {
+        let customTextView = TSPlaceholderTextView(
+            placeholder: "Type your idea here.",
+            text: "",
+            font: .font(size: 14),
+            textColor: .white,
+            backgroundColor: .clear
+        )
+        customTextView.delegate = self
+        customTextView.returnKeyType = .done
+        customTextView.textViewTextChanged = { [weak self]  in
+            guard let self = self else { return }
+            textViewTextChanged(textView: customTextView)
+        }
+        return customTextView
+    }()
+    
+ 
+    lazy var inspirationBtn: UIButton = {
+        let inspirationBtn = UIButton.createButton(
+            title: "💡Get Inspired?".localized,
+            font: .font(size: 12),
+            titleColor: "#F3F0EA".toColor()
+        )
+        { [weak self]  in
+            guard let self = self else { return }
+            customTextView.text = randomTextPicker.getRandomText()
+            textViewTextChanged(textView: customTextView)
+        }
+//        inspirationBtn.contentEdgeInsets = UIEdgeInsets(top: 4, left: 40, bottom: 4, right: 50)
+//        inspirationBtn.imageEdgeInsets = UIEdgeInsets(top: 0, left: -10, bottom: 0, right: 0)
+        return inspirationBtn
+    }()
+    
+    
+    lazy var clearBtn: TSUIExpandedTouchButton = {
+        let clearBtn = TSUIExpandedTouchButton()
+        clearBtn.setUpButton(image: UIImage(named: "clear_text"))
+        { [weak self]  in
+            guard let self = self else { return }
+            customTextView.text = ""
+            textViewTextChanged(textView: customTextView)
+        }
+        clearBtn.setImage(UIImage(named: "clear_gary_text"), for: .disabled)
+        clearBtn.isEnabled = false
+        return clearBtn
+    }()
+    
+    let maxNum:Int = 1000
+    var currenMun:Int = 0 {
+        didSet{
+            currenMunLab.text = "\(currenMun)"
+        }
+    }
+    lazy var currenMunLab: UILabel = {
+        let numLab = UILabel.createLabel(text: "\(currenMun)",font: .font(name: .PingFangSC,size: 12),textColor: .white)
+        return numLab
+    }()
+    
+    lazy var numView: UIView = {
+        let numView = UIView()
+        
+        numView.addSubview(currenMunLab)
+        
+        let numLab = UILabel.createLabel(text: "/\(maxNum)",font: .font(name: .PingFangSC,size: 12),textColor: .white.withAlphaComponent(0.4))
+        numView.addSubview(numLab)
+        
+        let lineView = UIView()
+        lineView.cornerRadius = 0.5
+        lineView.backgroundColor = .white
+        numView.addSubview(lineView)
+        
+        currenMunLab.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.leading.equalTo(0)
+        }
+        
+        numLab.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.leading.equalTo(currenMunLab.snp.trailing)
+        }
+        
+        lineView.snp.makeConstraints { make in
+            make.top.trailing.bottom.equalToSuperview()
+            make.leading.equalTo(numLab.snp.trailing).offset(8)
+            make.width.equalTo(1)
+            make.height.equalTo(12)
+        }
+        
+        return numView
+    }()
+    
+    override func creatUI() {
+        contentView.addSubview(textBgView)
+        textBgView.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.leading.equalTo(16)
+            make.trailing.equalTo(-16)
+            make.height.equalTo(114.0*kDesignScale)
+            make.bottom.equalTo(0)
+        }
+   
+        textBgView.addSubview(customTextView)
+        customTextView.snp.makeConstraints { make in
+            make.top.equalTo(16)
+            make.leading.equalTo(12)
+            make.trailing.equalTo(-12)
+            make.bottom.equalTo(-42)
+        }
+        
+        textBgView.addSubview(inspirationBtn)
+        inspirationBtn.snp.makeConstraints { make in
+            make.height.equalTo(12)
+            make.bottom.equalTo(-12)
+            make.leading.equalTo(12)
+        }
+        
+        textBgView.addSubview(clearBtn)
+        clearBtn.snp.makeConstraints { make in
+            make.width.height.equalTo(16)
+            make.bottom.equalTo(-10)
+            make.trailing.equalTo(-12)
+        }
+        
+        textBgView.addSubview(numView)
+        numView.snp.makeConstraints { make in
+            make.centerY.equalTo(clearBtn)
+            make.trailing.equalTo(clearBtn.snp.leading).offset(-8)
+        }
+    
+    }
+
+    func getVipText()->String{
+        return "Generate"
+    }
+    
+    func textViewTextChanged(textView: UITextView) {
+        currenMun = textView.text.count
+        clearBtn.isEnabled = currenMun > 0
+        boardImageView.isHidden = !clearBtn.isEnabled
+        textChangedBlock(textView.text)
+    }
+}
+
+extension ASPromptTextView: UITextViewDelegate{
+     func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
+         if text == "\n" {
+             textView.resignFirstResponder()
+             return false
+         }
+         return true
+     }
+    
+}

+ 10 - 0
AIPlayRingtones/AppPage/APSettingVC/APSettingVC.swift

@@ -0,0 +1,10 @@
+//
+//  APSettingVC.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+
+class APSettingVC: TSBaseVC {
+    
+}

+ 192 - 0
AIPlayRingtones/AppPage/ASCommonView/ASBtnView/ASAppBtnView.swift

@@ -0,0 +1,192 @@
+//
+//  ASBtnView.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+
+class ASAppBtnView: TSBaseView {
+    enum ViewStyle {
+        case generate   //创造类的按钮
+    }
+    
+    var viewH:CGFloat = 64
+    var style:ViewStyle = .generate
+//    var vipFreeNumType:VipFreeNumType = .none{
+//        didSet{
+//            updateVipView()
+//        }
+//    }
+    var clickBlock:(()->Void)?
+    var btnSize:CGSize = .zero
+    var isIconVipBlock:(()->Bool)? //vip 图片显示
+    var isClickVipBlock:(()->Bool)?  //点击是,是否需要弹出 vip
+    
+//    var loading:Bool = false{
+//        willSet {
+//            if loading != newValue {
+//                loadingAnimation(loading: newValue)
+//                
+//                if loading == false {
+//                    self.resetBtnText()
+//                }
+//            }
+//        }
+//    }
+    
+    //###################################### Button ######################################
+    var button:UIButton = UIButton()
+    var title:String = ""
+    override func creatUI() {
+
+    }
+    
+    override func dealThings(){
+        
+    }
+
+    func setUpButton(style:ViewStyle,btnSize:CGSize = .zero,clickBlock: @escaping () -> Void) {
+        self.btnSize = btnSize
+        self.style = style
+//        self.vipFreeNumType = vipFreeNumType
+        self.clickBlock = clickBlock
+        
+        contentView.removeAllSubViews()
+        
+        switch style {
+        case .generate:
+            title = "Generate".localized
+            setUpGenerate()
+            launchVipLogic()
+        }
+        
+    }
+    
+    
+//    func setLoadingText(text:String?){
+//        if loading {
+//            button.setTitle(text, for: .normal)
+//        }else{
+//            resetBtnText()
+//        }
+//    }
+    
+    func resetBtnText(){
+        button.setTitle(title, for:.normal)
+    }
+}
+
+extension ASAppBtnView{
+    
+    func launchVipLogic(){
+//        //监听 Vip 变化
+//        NotificationCenter.default.addObserver(forName: .kPurchaseDidChanged, object: nil, queue: OperationQueue.main) { [weak self] notification in
+//            guard let self = self else { return }
+//            updateVipView()
+//        }
+//        
+//        NotificationCenter.default.addObserver(forName: .kVipFreeNumChanged, object: nil, queue: OperationQueue.main) { [weak self] notification in
+//            guard let self = self else { return }
+//            if let userInfo = notification.userInfo as? [String: VipFreeNumType], let myEnum = userInfo["VipFreeNumType"] {
+//                if myEnum == self.vipFreeNumType {
+//                    self.updateVipView()
+//                }
+//            }
+//        }
+        
+        updateVipView()
+    }
+
+    func updateVipView() {
+//        switch style {
+//        case .generate:
+//            setVip(vip: isIconVipBlock?() ?? false)
+//        }
+    }
+    
+    func setBtnEnabled(isEnabled:Bool) {
+        button.isEnabled = isEnabled
+        button.setTitleColor(.white.withAlphaComponent(isEnabled ? 1.0 : 0.4), for: .normal)
+    }
+    
+    var isEnabled:Bool{
+        return button.isEnabled
+    }
+    
+//    func setVip(vip:Bool) {
+//        
+//        if loading { //loading,正在显示转圈动画
+//            return
+//        }
+//        
+//        if vip {
+//            button.setImage(UIImage(named: "btnImage_vip"), for: .normal)
+//        }else{
+//            button.setImage(nil, for: .normal)
+//        }
+//    }
+    
+}
+//创造按钮
+extension ASAppBtnView{
+
+    func setUpGenerate() {
+        
+        if btnSize == .zero{
+            btnSize = CGSizeMake(291, 52)
+        }
+        
+        button = kCreateNormalSubmitBtn(
+            title: title,
+            frame: CGRect(origin: .zero, size: btnSize),
+            action: { [weak self]  in
+            guard let self = self else { return }
+//            if let vc = WindowHelper.getCurrentViewController() {
+//                if kJudgeVip(externalBool: isClickVipBlock?() ?? false, vc: vc) { return }  //判断 vip
+//            }
+
+            clickBlock?()
+        })
+        contentView.addSubview(button)
+        button.snp.makeConstraints { make in
+            make.center.equalToSuperview()
+            make.width.equalTo(button.width)
+            make.height.equalTo(button.height)
+        }
+   
+        
+        viewH = 52
+    }
+}
+//创造按钮
+extension ASAppBtnView{
+    
+//    private func loadingAnimation(loading:Bool) {
+//        if loading {
+//            button.setImage(UIImage(named: "generated_loading"), for: .normal)
+//            self.button.imageView?.startRotating()
+//        }else {
+//            button.imageView?.stopRotating()
+//            updateVipView()
+//        }
+//    }
+    
+}
+//常用提交按钮
+func kCreateNormalSubmitBtn(title:String,frame:CGRect,action: (() -> Void)? = nil) -> UIButton {
+    let btn = UIButton()
+    btn.frame = frame
+    btn.setUpButton(title:title,font: UIFont.font(size: 16,weight: .medium),titleColor:.black,corner: frame.height/2,action: action)
+    btn.setTitleImageSpace(spacing: 8)
+
+    var buttonBgImage = UIImage(named: "submit_btn_bg")!
+    buttonBgImage = buttonBgImage.resizableImage(withCapInsets: UIEdgeInsets(top:24, left: 24, bottom: 24, right: 24), resizingMode: .stretch)
+    btn.setBackgroundImage(buttonBgImage, for: .normal)
+    
+    var buttonDisBgImage = UIImage(named: "submit_btn_dis_bg")!
+    buttonDisBgImage = buttonDisBgImage.resizableImage(withCapInsets: UIEdgeInsets(top:24, left: 24, bottom: 24, right: 24), resizingMode: .stretch)
+    btn.setBackgroundImage(buttonDisBgImage, for: .disabled)
+    
+    return btn
+}
+

+ 84 - 0
AIPlayRingtones/AppPage/ASCommonView/ASBtnView/ASLeftHeaderView.swift

@@ -0,0 +1,84 @@
+//
+//  ASLeftHeaderView.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+
+
+let kSectionTitleViewH:CGFloat = 56.0
+let kSectionTitleViewCenterYOffset:CGFloat = 6.0
+class ASLeftHeaderView: TSBaseView {
+    
+    static let viewH:CGFloat = kSectionTitleViewH
+    let viewH:CGFloat = ASLeftHeaderView.viewH
+    
+    lazy var titleLab: UILabel = {
+        let titleLab = UILabel.createLabel(font: .font(size: 16,weight: .medium),textColor: .fromHex("FFFFFF"))
+        return titleLab
+    }()
+    override func creatUI() {
+
+        contentView.addSubview(titleLab)
+        titleLab.snp.makeConstraints { make in
+            make.leading.equalTo(16)
+            make.centerY.equalToSuperview().offset(kSectionTitleViewCenterYOffset)
+        }
+    
+    }
+}
+
+extension ASLeftHeaderView {
+    
+    static func creatTitleView(title:String) -> ASLeftHeaderView {
+        let titleView = ASLeftHeaderView()
+        titleView.titleLab.text = title
+        return titleView
+    }
+}
+//class ASLeftHeaderMoreView: ASLeftHeaderView {
+//    
+//    lazy var moreView: UIView = {
+//        let moreView = UIView()
+//        moreView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(clickMoreView)))
+//        
+//        let label = UILabel.createLabel(text: "See all".localized,font: .font(size: 12),textColor: .white.withAlphaComponent(0.4))
+//        moreView.addSubview(label)
+//        label.snp.makeConstraints { make in
+//            make.leading.top.bottom.equalTo(0)
+//        }
+//        
+//        let imageView = UIImageView.createImageView(imageName: "gray_right_arrow")
+//        
+//        moreView.addSubview(imageView)
+//        imageView.snp.makeConstraints { make in
+//            make.trailing.top.bottom.equalTo(0)
+//            make.leading.equalTo(label.snp.trailing)
+//        }
+//        
+//        return moreView
+//    }()
+//
+//    override func creatUI() {
+//        super.creatUI()
+//
+//        contentView.addSubview(moreView)
+//        moreView.snp.makeConstraints { make in
+//            make.trailing.equalTo(-6)//16
+//            make.centerY.equalTo(titleLab)
+//        }
+//        
+//    }
+//    
+//    @objc private func clickMoreView() {
+//        clickMoreBlock?()
+//    }
+//    
+//    var clickMoreBlock:(()->Void)?
+//    func setTitle(title:String,clickMoreBlock:(()->Void)?) {
+//        titleLab.text = title
+//        self.clickMoreBlock = clickMoreBlock
+//    }
+//    
+//    
+//}

+ 299 - 0
AIPlayRingtones/AppPage/ASRingGeneratorVC/ASRingGeneratorBaseVC.swift

@@ -0,0 +1,299 @@
+//
+//  ASRingGeneratorBaseVC.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/18.
+//
+
+
+class ASRingGeneratorBaseVC: TSBaseVC {
+    
+    lazy var topBgView: UIView = {
+        let topBgView = UIView(frame: CGRectMake(0, 0, k_ScreenWidth, k_ScreenHeight))
+        topBgView.backgroundColor = .black.withAlphaComponent(0.5)
+        topBgView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard)))
+        return topBgView
+    }()
+    
+    var bottomViewH:CGFloat = 340{
+        didSet{
+            bottomView.frame = CGRectMake(0, k_ScreenHeight-bottomViewH, k_ScreenWidth, bottomViewH)
+        }
+    }
+    
+    lazy var bgImageView: UIImageView = {
+        let bgImageView = UIImageView()
+        bgImageView.image = UIImage(named: "bottom_alert_bg")?.resizableImage(capInsets:UIEdgeInsets(top:40, left: 30, bottom: 30, right: 170))
+        bgImageView.contentMode = .scaleToFill
+        return bgImageView
+    }()
+    
+    lazy var bottomView: UIView = {
+        let bottomView = UIView(frame: CGRectMake(0, k_ScreenHeight-bottomViewH, k_ScreenWidth, bottomViewH))
+        bottomView.addSubview(bgImageView)
+        bgImageView.snp.makeConstraints { make in
+            make.bottom.top.leading.right.equalTo(0)
+        }
+        return bottomView
+    }()
+    
+
+    lazy var xBtn: UIButton = {
+        let xBtn = TSUIExpandedTouchButton()
+        xBtn.setUpButton(image: UIImage(named: "x")) { [weak self]  in
+//        let xBtn = UIButton.createButton(image: UIImage(named: "x")) { [weak self]  in
+            guard let self = self else { return }
+            clickXBtn()
+        }
+        return xBtn
+    }()
+    
+    lazy var againBtn: UIButton = {
+        let againBtn = UIButton.createButton(title:"Try Again".localized,backgroundColor:.themeColor,font: UIFont.font(size: 14,weight: .medium),titleColor:.white,corner: 24)
+        { [weak self]  in
+            guard let self = self else { return }
+            clickAgainBtn()
+        }
+        return againBtn
+    }()
+    
+    lazy var saveBtn: UIButton = {
+        let saveBtn = UIButton.createButton(title:"Save".localized,backgroundColor:.themeColor,font: UIFont.font(size: 14,weight: .medium),titleColor:.white,corner: 24)
+        { [weak self]  in
+            guard let self = self else { return }
+            clickSubmitBtn()
+        }
+        kDelayMainShort {
+            saveBtn.addGradientBg(colors: ["#E961F6".uiColor.cgColor,"#7E57F4".uiColor.cgColor])
+        }
+        return saveBtn
+    }()
+    
+    
+    lazy var leftBtn: UIButton = {
+        let leftBtn = UIButton.createButton(title:"Copy".localized,backgroundColor: .fromHex("#FFFFFF", alpha: 0.4),font: UIFont.font(size: 14,weight: .medium),titleColor:.white,corner: 24)
+        { [weak self]  in
+            guard let self = self else { return }
+            clickLeftBtn()
+        }
+        leftBtn.isHidden = true
+        return leftBtn
+    }()
+    
+    lazy var rightBtn: UIButton = {
+        
+        let rightBtn = UIButton.createButton(title:"Save".localized,backgroundColor:.themeColor,font: UIFont.font(size: 14,weight: .medium),titleColor:.white,corner: 24)
+        { [weak self]  in
+            guard let self = self else { return }
+            clickRightBtn()
+        }
+        
+        kDelayMainShort {
+            rightBtn.addGradientBg(colors: ["#E961F6".uiColor.cgColor,"#7E57F4".uiColor.cgColor])
+        }
+        rightBtn.isHidden = true
+        return rightBtn
+    }()
+    
+
+    lazy var regenerateBtn: UIButton = {
+        let regenerateBtn = UIButton.createButton(
+            title: "regenerate",
+            image: UIImage(named: "refresh_gary"),
+            backgroundColor:.white.withAlphaComponent(0.1),
+            font: .font(size: 12),
+            titleColor: .white.withAlphaComponent(0.6),
+            corner: 8.0)
+        { [weak self]  in
+            guard let self = self else { return }
+            clickAgainBtn()
+        }
+        regenerateBtn.contentEdgeInsets = UIEdgeInsets(top: 4, left: 7, bottom: 4, right: 7)
+        regenerateBtn.imageEdgeInsets = UIEdgeInsets(top: 0, left: -4, bottom: 0, right: 0)
+        regenerateBtn.isHidden = true
+        return regenerateBtn
+    }()
+    
+    //############################## 失败 View ##############################
+    
+    lazy var failLabel: UILabel = {
+        let failLabel = UILabel.createLabel(text: "Generation Failed".localized,font: .font(size: 14.0),textColor: .white.withAlphaComponent(0.6),textAlignment: .center)
+        return failLabel
+    }()
+    
+    lazy var failView: UIView = {
+        let failView = UIView()
+        let failImageView = UIImageView.createImageView(imageName: "generation_failed")
+    
+        failView.addSubview(failImageView)
+        failImageView.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.centerX.equalToSuperview()
+            make.width.equalTo(88)
+            make.height.equalTo(88)
+        }
+        
+        failView.addSubview(failLabel)
+        failLabel.snp.makeConstraints { make in
+            make.top.equalTo(failImageView.snp.bottom).offset(16)
+            make.leading.equalTo(10)
+            make.trailing.equalTo(-10)
+            make.width.greaterThanOrEqualTo(88)
+            make.height.equalTo(14)
+            make.bottom.equalTo(0)
+        }
+        failView.isHidden = true
+        return failView
+    }()
+    
+    //############################## 结果 View ##############################
+    lazy var resultIconImageView: UIImageView = {
+        let resultIconImageView = UIImageView.createImageView(imageName: "")
+        return resultIconImageView
+    }()
+    
+    lazy var successTopView: UIView = {
+        let resultView = UIView()
+
+        resultView.addSubview(resultIconImageView)
+        resultIconImageView.snp.makeConstraints { make in
+            make.top.equalTo(-15)
+            make.trailing.equalTo(-28)
+            make.width.equalTo(88)
+            make.height.equalTo(88)
+        }
+        
+        let successLabel = UILabel.createLabel(text: "Successfully Generated".localized,font: .font(size: 18.0),textColor: .themeColor,textAlignment: .left)
+        resultView.addSubview(successLabel)
+        successLabel.snp.makeConstraints { make in
+            make.top.equalTo(30)
+            make.leading.equalTo(20)
+            make.trailing.equalTo(resultIconImageView.snp.leading).offset(-20)
+            make.height.equalTo(18)
+        }
+        kDelayMainShort {
+            successLabel.applyGradient(colors: [UIColor.white,"#D999FF".uiColor])
+        }
+        resultView.isHidden = true
+        return resultView
+    }()
+    
+    //############################## 自定义 View ##############################
+    lazy var diyView: UIView = {
+        let diyView = UIView()
+ 
+        diyView.addSubview(failView)
+        failView.snp.makeConstraints { make in
+            make.centerY.equalToSuperview().offset(-40)
+            make.centerX.equalToSuperview()
+        }
+        
+        diyView.addSubview(successTopView)
+        successTopView.snp.makeConstraints { make in
+            make.leading.top.trailing.equalTo(0)
+            make.height.equalTo(73)
+        }
+        
+
+        return diyView
+    }()
+    
+    //点击空白,关闭页面
+    var isClickTheBlankClosePage = true
+    
+    override func createView() {
+        view.backgroundColor = .clear
+        setNavBarViewHidden(true)
+
+        contentView.addSubview(topBgView)
+        contentView.addSubview(bottomView)
+    
+        let safeBottom = k_Height_safeAreaInsetsBottom()
+        //重试
+        bottomView.addSubview(againBtn)
+        againBtn.snp.makeConstraints { make in
+            make.bottom.equalTo(-16-safeBottom)
+            make.centerX.equalToSuperview()
+            make.width.equalTo(228)
+            make.height.equalTo(48)
+        }
+        
+        //保存
+        bottomView.addSubview(saveBtn)
+        saveBtn.snp.makeConstraints { make in
+            make.bottom.equalTo(-16-safeBottom)
+            make.centerX.equalToSuperview()
+            make.width.equalTo(228)
+            make.height.equalTo(48)
+        }
+        
+        
+        //中心点
+        let centerView = UIView()
+        bottomView.addSubview(centerView)
+        centerView.snp.makeConstraints { make in
+            make.center.equalToSuperview()
+        }
+        bottomView.addSubview(leftBtn)
+        leftBtn.snp.makeConstraints { make in
+            make.bottom.equalTo(-16-safeBottom)
+            make.trailing.equalTo(centerView.snp.leading).offset(-8)
+            make.width.equalTo(163)
+            make.height.equalTo(48)
+        }
+        
+        bottomView.addSubview(rightBtn)
+        rightBtn.snp.makeConstraints { make in
+            make.bottom.equalTo(-16-safeBottom)
+            make.leading.equalTo(centerView.snp.trailing).offset(8)
+            make.width.equalTo(163)
+            make.height.equalTo(48)
+        }
+        
+        bottomView.addSubview(diyView)
+        diyView.snp.makeConstraints { make in
+            make.bottom.equalTo(saveBtn.snp.top).offset(-10)
+            make.top.left.right.equalTo(0)
+        }
+        
+        bottomView.addSubview(xBtn)
+        xBtn.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.trailing.equalTo(-6)
+            make.width.equalTo(24)
+            make.height.equalTo(24)
+        }
+        
+
+    }
+    
+    func closePage() {
+        self.dismiss(animated: true, completion: nil)
+    }
+
+    @objc func clickAgainBtn(){
+        
+    }
+    
+    @objc func clickSubmitBtn(){
+        
+    }
+    
+    @objc func clickLeftBtn(){
+        
+    }
+    
+    @objc func clickRightBtn(){
+        
+    }
+    
+    @objc func clickXBtn(){
+        closePage()
+    }
+    
+    @objc private func dismissKeyboard() {
+        if isClickTheBlankClosePage {
+            closePage()
+        }
+    }
+}

+ 306 - 0
AIPlayRingtones/AppPage/ASRingGeneratorVC/ASRingGeneratorVC.swift

@@ -0,0 +1,306 @@
+//
+//  ASRingGeneratorVC.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/18.
+//
+
+class ASRingGeneratorVC: ASRingGeneratorBaseVC {
+    var infoModel:ASActionInfoModel?
+    var complete:((ASActionInfoModel)->Void)
+    var reloadViewBlock:(()->Void)?
+    var changeImageBlock:((UIImage)->Void)?
+    var progressState = ASProgressState.none
+
+    
+    // 1. 定义历史记录类型枚举
+    enum generateType: String,CaseIterable {
+        case texToRing = "texToRingHistoryListString"  //图生图
+        case ringToRing = "ringToRingHistoryListString"       //文生图
+    }
+    
+    var generateStyleModel:ASGenerateStyleModel
+    init(generateStyleModel:ASGenerateStyleModel,infoModel:ASActionInfoModel? = nil,complete:@escaping ((ASActionInfoModel)->Void)) {
+        self.generateStyleModel = generateStyleModel
+        self.infoModel = infoModel
+        self.complete = complete
+        super.init()
+    }
+    
+    @MainActor required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    lazy var generateInView : ASGeneratorView = {
+        let generateInView = ASGeneratorView()
+        generateInView.animationView.setText(time: String(format: "~ %d min".localized, 2), info: "Lots of people are creating images right now, so this might take a bit.".localized)
+
+        
+        generateInView.clickBackstageBlock = { [weak self]  in
+            guard let self = self else { return }
+            clickBackstageBtn()
+        }
+        
+        generateInView.clickErrorBlock = { [weak self] style in
+            guard let self = self else { return }
+            
+            switch style {
+            case .netWorkError:
+//                clickTryAgainBtn()
+                self.dismiss(animated: true, completion: nil)
+            case .sensitiveError:
+//                pickSinglePhoto()
+                self.dismiss(animated: true, completion: nil)
+            case .generalError:
+                self.dismiss(animated: true, completion: nil)
+            default:
+                break
+            }
+        }
+        return generateInView
+    }()
+    
+
+    override func createView() {
+
+        contentView.addSubview(generateInView)
+        generateInView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        
+        super.createView()
+        
+//        xBtn.isHidden = true
+    }
+    
+    override func closePage() {
+        if progressState.isResult {
+            self.dismiss(animated: true, completion: nil)
+        }else{
+            TSCustomAlertController.show(in: self, config: TSCustomAlertController.AlertConfig(
+                message: "As you leave, your generation will be interrupted and no result.".localized,
+                messageColor: .white,
+                messageFont: .systemFont(ofSize: 16),
+                
+                cancelTitle: "Leave".localized,
+                cancelColor: .white,
+                
+                confirmTitle: "Wait".localized,
+                confirmColor: .themeColor,
+                
+                cancelAction: { [weak self]  in
+                    guard let self = self else { return }
+                    print("用户点击了Leave")
+//                    operation.cancel()
+                    if let model = infoModel{
+                        ASRMShared.texToRingDBHistory.deleteListModel(id: model.id)
+                    }
+                    self.dismiss(animated: true, completion: nil)
+                },
+                confirmAction: {
+                    print("用户点击了Stay")
+                }
+            ))
+        }
+    }
+    
+//    override func closePage() {
+//        self.dismiss(animated: true, completion: nil)
+//    }
+    
+//    //重试
+//    @objc override func clickTryAgainBtn(){
+//        clickRegenerateBtn()
+//    }
+    
+    //后台生成
+    @objc func clickBackstageBtn() {
+//        self.operation.isSaveDB = true //后台生成,让数据库保存数据
+        if let model = infoModel {
+            dbHistory.updateData(model)
+            debugPrint("图生图进入后台,保存数据listModels.first=\(dbHistory.listModels.first)")
+            NotificationCenter.default.post(name: dataChangedNotification, object: nil)
+        }else{
+            debugPrint("进入后台,但是没有新数据")
+        }
+
+        self.dismiss(animated: true, completion: nil)
+    }
+    
+//    //重新生成
+//    @objc override func clickRegenerateBtn(){
+//        //判断 vip
+//        if kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: .picToPic) == false, vc: self) { return }
+//        
+//        if let model = self.infoModel {
+//            if model.actionStatus == .success  {
+//                model.id = Date.timestampInt //如果是成功,且再生成一个,则更换一个 id ,作为新数据保存
+//            }
+//            creatOperation(infoModel: model)
+//        }else {
+//            uploadImageCreatOperation()
+//        }
+//        
+//    }
+    
+//    //保存功能
+//    @objc override func clickSaveBtn(){
+//        if let image = getSuccessImage() {
+//            PhotoManagerShared.saveImageToAlbum(image) { success, error in
+//                if success {
+//                    kSaveSuccesswShared.show(atView:self.view)
+//                    kFirstSaveRateAction()
+//                }else{
+//                    debugPrint(error)
+//                }
+//            }
+//        }
+//    }
+    
+    override func dealThings() {
+//        creatImage()
+    }
+    
+    
+//    func creatImage() {
+//        if let model = self.infoModel{
+//            if model.actionStatus == .failed{
+//                creatOperation(infoModel: model)
+//            }else if model.response.resultUrl.count > 0 {
+//                upDateView(state: .success(model), model: model)
+//            }
+//        }else{
+//            uploadImageCreatOperation()
+//        }
+//    }
+//    var operation:ASGeneratePTPOperation = TSGeneratePTPOperation(uuid: UUID().uuidString)
+//    func creatOperation(infoModel: ASActionInfoModel) {
+//        operation = TSGeneratePTPOperationQueue.shared.creatOperation(uuid: UUID().uuidString)
+//        operation.$stateDatauPblished.receive(on: DispatchQueue.main).sink {[weak self]  (state,model) in
+//            guard let self = self else { return }
+//            self.upDateView(state: state, model: model)
+//        }.store(in: &cancellable)
+//        operation.creatImage(oldModel: infoModel)
+//        generateInView.setBackgroundGenerateBtnHidden(false)
+//        xBtn.isHidden = false
+//    }
+//    
+//    func uploadImageCreatOperation() {
+//        operation = TSGeneratePTPOperationQueue.shared.creatOperation(uuid: UUID().uuidString)
+//        operation.$stateDatauPblished.receive(on: DispatchQueue.main).sink {[weak self]  (state,model) in
+//            guard let self = self else { return }
+//            self.upDateView(state: state, model: model)
+//        }.store(in: &cancellable)
+//        operation.uploadImage(generateStyleModel: viewModel.generateStyleModel) {[weak self] actionInfoModel in
+//            guard let self = self else { return }
+//            if let actionInfoModel = actionInfoModel{
+//                operation.creatImage(oldModel: actionInfoModel)
+//                generateInView.setBackgroundGenerateBtnHidden(false)
+//                xBtn.isHidden = false
+//            }
+//        }
+//    }
+    
+    
+    deinit {
+//        operation.isShowSuccessView = true
+    }
+}
+
+extension ASRingGeneratorVC {
+
+    var dbHistory:ASDBHistory{
+        switch generateStyleModel.generateType {
+        case .textToRing:
+            return ASRMShared.texToRingDBHistory
+        case .ringToRing:
+            return ASRMShared.ringToRingDBHistory
+        }
+    }
+    
+    var dataChangedNotification:Notification.Name{
+        switch generateStyleModel.generateType {
+        case .textToRing:
+            return .kTextToRingDataChanged
+        case .ringToRing:
+            return .kRingToRingDataChanged
+        }
+    }
+    
+}
+extension ASRingGeneratorVC {
+    
+    func upDateView(state:ASProgressState,model:ASActionInfoModel?){
+        infoModel = model
+        progressState = state
+        switch state {
+            case .failed(let errorStr,let code):
+                showError(text: errorStr,code:code)
+            case .success:
+                if let model = model {
+                    showSuccess(model: model)
+                }else{
+                    showError(text: "")
+                }
+            case .progressString(let string):
+                showProgress(text: string)
+            case .none:
+                break
+            default:
+                showLoading()
+        }
+    }
+    
+    func showProgress(text:String) {
+        generateInView.updateShowProgress(text: text)
+        
+        isClickTheBlankClosePage = false
+        bottomView.isHidden = true
+//        netWorkImageView.isHidden = true
+//        rotatingPictureBtn.isHidden = true
+    }
+    
+    func showLoading(){
+        generateInView.updateShowLoading(text: "Generating".localized + " ...")
+
+        isClickTheBlankClosePage = false
+        bottomView.isHidden = true
+//        netWorkImageView.isHidden = true
+//        rotatingPictureBtn.isHidden = true
+    }
+    
+    func showError(text:String,code:Int = 0){
+        generateInView.updateShowError(text: text,code: code)
+
+        isClickTheBlankClosePage = true
+        
+        xBtn.isHidden = false
+//        tryAgainBtn.isHidden = true
+//        bigSaveBtn.isHidden = true
+        bottomView.isHidden = true
+//        netWorkImageView.isHidden = true
+//        rotatingPictureBtn.isHidden = true
+    }
+    
+    func showSuccess(model:ASActionInfoModel){
+        generateInView.updateShowSuccess()
+
+        isClickTheBlankClosePage = true
+        
+        xBtn.isHidden = false
+//        tryAgainBtn.isHidden = false
+//        bigSaveBtn.isHidden = false
+        bottomView.isHidden = false
+//        netWorkImageView.isHidden = false
+//        rotatingPictureBtn.isHidden = false
+        
+        
+        dbHistory.updateData(model)
+//        self.netWorkImageView.setAsyncImage(urlString: model.response.resultUrl,placeholder:kPlaceholderImage,backgroundColor:netWorkImageView.backgroundColor!)
+        
+        if let model = infoModel {
+            complete(model)
+        }
+    }
+    
+}

+ 88 - 0
AIPlayRingtones/AppPage/ASTabBarVC/ASTabBarVC.swift

@@ -0,0 +1,88 @@
+//
+//  ASTabBarVC.swift
+//  AIPlayRingtones
+//
+//  Created by 100Years on 2025/5/15.
+//
+
+
+import UIKit
+class ASTabBarVC: UITabBarController {
+  
+    private var viewControllerArray: [String] = []
+    private var titleArray: [String] = []
+    private var selectedImageArray: [String] = []
+    private var unselectedImageArray: [String] = []
+    
+    private var interceptVC: UINavigationController = UINavigationController()
+    
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        createUI()
+        setUpData()
+    }
+
+    @objc private func setUpData() {
+        viewControllerArray = ["APRingTonesVC","APAudioToRingVC","APMyRingVC","APSettingVC"]
+
+        titleArray = ["Audio","Create","Mine","Setting"]
+        selectedImageArray = [
+            "tabbar_selected_create",
+            "tabbar_selected_audio",
+            "tabbar_selected_mine",
+            "tabbar_selected_setting"
+        ]
+        unselectedImageArray = [
+            "tabbar_unSelect_create",
+            "tabbar_unSelect_audio",
+            "tabbar_unSelect_mine",
+            "tabbar_unSelect_setting"
+        ]
+
+        var tabArray: [UINavigationController] = []
+
+        for i in 0..<viewControllerArray.count {
+            if let rootViewController = viewControllerArray[i].toInstance(of: UIViewController.self) {
+                let title = titleArray[i]
+                let nav = TSBaseNavigationC(rootViewController: rootViewController)
+                nav.view.backgroundColor = UIColor.black
+                nav.tabBarItem = tabBarItem(
+                    title: title.localized,
+                    image: UIImage(named: unselectedImageArray[i]),
+                    selectedImage: UIImage(named: selectedImageArray[i]),
+                    tag: i
+                )
+                tabArray.append(nav)
+            }
+        }
+
+        self.viewControllers = tabArray
+        interceptVC = tabArray.last!
+    }
+
+    private func createUI() {
+        tabBar.barStyle = .black
+        tabBar.isTranslucent = false
+        tabBar.backgroundColor = "#1E1D29".uiColor
+        tabBar.backgroundImage = UIImage.colorFrom(color: tabBar.backgroundColor!, size: CGSize(width: k_ScreenWidth, height: k_TabBar_Height))
+        
+        UITabBar.appearance().unselectedItemTintColor = .white.withAlphaComponent(0.4)
+        UITabBar.appearance().tintColor = UIColor.white
+
+    }
+
+    private func tabBarItem(title: String, image: UIImage?, selectedImage: UIImage?, tag: Int) -> UITabBarItem {
+        let tabBarItem = UITabBarItem()
+        tabBarItem.image = image?.withRenderingMode(.alwaysOriginal)
+        tabBarItem.title = title
+        tabBarItem.selectedImage = selectedImage?.withRenderingMode(.alwaysOriginal)
+        return tabBarItem
+    }
+
+    deinit {
+        debugPrint("ASTabBarVC deinit")
+        NotificationCenter.default.removeObserver(self)
+    }
+    
+
+}

+ 6 - 0
AIPlayRingtones/Assets.xcassets/AIRingtone/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 22 - 0
AIPlayRingtones/Assets.xcassets/AIRingtone/nav_title_aiRingtone.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "nav_title_aiRingtone@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "nav_title_aiRingtone@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/nav_title_aiRingtone.imageset/nav_title_aiRingtone@2x.png


BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/nav_title_aiRingtone.imageset/nav_title_aiRingtone@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/AIRingtone/sec_selected_bg.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "sec_selected_bg@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "sec_selected_bg@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/sec_selected_bg.imageset/sec_selected_bg@2x.png


BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/sec_selected_bg.imageset/sec_selected_bg@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/AIRingtone/sec_unSelected_bg.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "sec_unSelected_bg@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "sec_unSelected_bg@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/sec_unSelected_bg.imageset/sec_unSelected_bg@2x.png


BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/sec_unSelected_bg.imageset/sec_unSelected_bg@3x.png


+ 6 - 0
AIPlayRingtones/Assets.xcassets/AIRingtone/style/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 22 - 0
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Disco.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "ring_style_Disco@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "ring_style_Disco@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Disco.imageset/ring_style_Disco@2x.png


BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Disco.imageset/ring_style_Disco@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Dubstep.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "ring_style_Dubstep@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "ring_style_Dubstep@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Dubstep.imageset/ring_style_Dubstep@2x.png


BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Dubstep.imageset/ring_style_Dubstep@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Electro.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "ring_style_Electro@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "ring_style_Electro@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Electro.imageset/ring_style_Electro@2x.png


BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Electro.imageset/ring_style_Electro@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Funk.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "ring_style_Funk@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "ring_style_Funk@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Funk.imageset/ring_style_Funk@2x.png


BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Funk.imageset/ring_style_Funk@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_HipHop.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "ring_style_HipHop@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "ring_style_HipHop@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_HipHop.imageset/ring_style_HipHop@2x.png


BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_HipHop.imageset/ring_style_HipHop@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Jazz.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "ring_style_Jazz@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "ring_style_Jazz@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Jazz.imageset/ring_style_Jazz@2x.png


BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Jazz.imageset/ring_style_Jazz@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Normal.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "ring_style_Normal@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "ring_style_Normal@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Normal.imageset/ring_style_Normal@2x.png


BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Normal.imageset/ring_style_Normal@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Pop.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "ring_style_Pop@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "ring_style_Pop@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Pop.imageset/ring_style_Pop@2x.png


BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Pop.imageset/ring_style_Pop@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Rock.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "ring_style_Rock@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "ring_style_Rock@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Rock.imageset/ring_style_Rock@2x.png


BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_style_Rock.imageset/ring_style_Rock@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_selected_bg.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "ring_text_selected_bg@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "ring_text_selected_bg@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_selected_bg.imageset/ring_text_selected_bg@2x.png


BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_selected_bg.imageset/ring_text_selected_bg@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_selected_board.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "ring_text_selected_board@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "ring_text_selected_board@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_selected_board.imageset/ring_text_selected_board@2x.png


BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_selected_board.imageset/ring_text_selected_board@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_unSelect_bg.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "ring_text_unSelect_bg@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "ring_text_unSelect_bg@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_unSelect_bg.imageset/ring_text_unSelect_bg@2x.png


BIN
AIPlayRingtones/Assets.xcassets/AIRingtone/style/ring_text_unSelect_bg.imageset/ring_text_unSelect_bg@3x.png


+ 6 - 0
AIPlayRingtones/Assets.xcassets/AudioToRingtone/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 22 - 0
AIPlayRingtones/Assets.xcassets/AudioToRingtone/nav_titile_audioRingtone.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "nav_titile_audioRingtone@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "nav_titile_audioRingtone@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/AudioToRingtone/nav_titile_audioRingtone.imageset/nav_titile_audioRingtone@2x.png


BIN
AIPlayRingtones/Assets.xcassets/AudioToRingtone/nav_titile_audioRingtone.imageset/nav_titile_audioRingtone@3x.png


+ 6 - 0
AIPlayRingtones/Assets.xcassets/Common/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 22 - 0
AIPlayRingtones/Assets.xcassets/Common/PRO.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "PRO@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "PRO@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/Common/PRO.imageset/PRO@2x.png


BIN
AIPlayRingtones/Assets.xcassets/Common/PRO.imageset/PRO@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/Common/clear_gary_text.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "clear_gary_text@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "clear_gary_text@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/Common/clear_gary_text.imageset/clear_gary_text@2x.png


BIN
AIPlayRingtones/Assets.xcassets/Common/clear_gary_text.imageset/clear_gary_text@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/Common/clear_text.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "clear_text@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "clear_text@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/Common/clear_text.imageset/clear_text@2x.png


BIN
AIPlayRingtones/Assets.xcassets/Common/clear_text.imageset/clear_text@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/Common/submit_btn_bg.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "submit_btn_bg@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "submit_btn_bg@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/Common/submit_btn_bg.imageset/submit_btn_bg@2x.png


BIN
AIPlayRingtones/Assets.xcassets/Common/submit_btn_bg.imageset/submit_btn_bg@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/Common/submit_btn_dis_bg.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "submit_btn_dis_bg@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "submit_btn_dis_bg@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/Common/submit_btn_dis_bg.imageset/submit_btn_dis_bg@2x.png


BIN
AIPlayRingtones/Assets.xcassets/Common/submit_btn_dis_bg.imageset/submit_btn_dis_bg@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/Common/textView_bg.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "textView_bg@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "textView_bg@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/Common/textView_bg.imageset/textView_bg@2x.png


BIN
AIPlayRingtones/Assets.xcassets/Common/textView_bg.imageset/textView_bg@3x.png


+ 22 - 0
AIPlayRingtones/Assets.xcassets/Common/textView_board.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "textView_board@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "textView_board@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIPlayRingtones/Assets.xcassets/Common/textView_board.imageset/textView_board@2x.png


Деякі файли не було показано, через те що забагато файлів було змінено