Ver Fonte

Merge branch 'developer' into configuration

# Conflicts:
#	KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj
#	KulexiuForStudent/KulexiuForStudent/AppDelegate.m
#	KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSMediaMergeView.m
#	KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/MusicPlayer/kSNewPlayer.m
#	KulexiuForStudent/KulexiuForStudent/Common/Tools/Category/UrlDecode.m
#	KulexiuForStudent/KulexiuForStudent/Common/Tools/Extension/NSString+Extension.m
Steven há 1 ano atrás
pai
commit
2bc3ed698d
33 ficheiros alterados com 1225 adições e 45 exclusões
  1. 17 15
      KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj
  2. 6 3
      KulexiuForStudent/KulexiuForStudent/AppDelegate.m
  3. 6 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/Contents.json
  4. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/save_linkIcon.imageset/Contents.json
  5. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/save_linkIcon.imageset/save_linkIcon@2x.png
  6. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/save_linkIcon.imageset/save_linkIcon@3x.png
  7. 21 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/shareImage.imageset/Contents.json
  8. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/shareImage.imageset/shareImage@2x.png
  9. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/share_friendCircle.imageset/Contents.json
  10. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/share_friendCircle.imageset/share_friendCircle@2x.png
  11. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/share_friendCircle.imageset/share_friendCircle@3x.png
  12. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/share_friendIcon.imageset/Contents.json
  13. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/share_friendIcon.imageset/share_friendIcon@2x.png
  14. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/share_friendIcon.imageset/share_friendIcon@3x.png
  15. 28 6
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSBaseWKWebViewController.m
  16. 64 1
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSMediaMergeView.m
  17. 31 0
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/ShareFunctionView.h
  18. 108 0
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/ShareFunctionView.m
  19. 254 0
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/ShareFunctionView.xib
  20. 456 0
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/MusicPlayer/kSNewPlayer.m
  21. 3 2
      KulexiuForStudent/KulexiuForStudent/Common/Tools/UMShare/KSUMShareManager.h
  22. 17 8
      KulexiuForStudent/KulexiuForStudent/Common/Tools/UMShare/KSUMShareManager.m
  23. 2 2
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Home/Controller/TenantMoreViewController.m
  24. 1 1
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/Controller/TenantNotiferCenterController.m
  25. 5 5
      KulexiuForStudent/KulexiuForStudent/Module/Home/Controller/HomeViewController.m
  26. 1 1
      KulexiuForStudent/KulexiuForStudent/Module/Home/NoticeCenter/Controller/NotiferMessageViewController.m
  27. 1 1
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomePageView/HomeInformationBodyView.m
  28. 4 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Scan/Controller/KSScanViewController.m
  29. 47 0
      KulexiuForStudent/KulexiuForStudent/PrivacyInfo.xcprivacy
  30. BIN
      KulexiuForStudent/KulexiuForStudent/SoundFontFile/shareImage@2x.png
  31. BIN
      KulexiuForStudent/KulexiuForStudent/SoundFontFile/synthgms.sf2
  32. 2 0
      KulexiuForStudent/KulexiuForStudent/ToolKit/KSToolLibrary.framework/Headers/NSString+Extension.h
  33. 85 0
      KulexiuForStudent/Pods/Pods.xcodeproj/xcuserdata/wangzhi.xcuserdatad/xcschemes/xcschememanagement.plist

+ 17 - 15
KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj

@@ -411,6 +411,8 @@
 		BC3BF62C2B9EAF8800831494 /* KSTunerLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC3BF6282B9EAF6F00831494 /* KSTunerLibrary.framework */; };
 		BC3BF62D2B9EAF8800831494 /* KSTunerLibrary.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BC3BF6282B9EAF6F00831494 /* KSTunerLibrary.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 		BC3BF63C2B9EFA7200831494 /* KSToolLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC3BF63B2B9EFA7200831494 /* KSToolLibrary.framework */; };
+		BC3BF6402B9FE92600831494 /* ShareFunctionView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC3BF63E2B9FE92600831494 /* ShareFunctionView.m */; };
+		BC3BF6412B9FE92600831494 /* ShareFunctionView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC3BF63F2B9FE92600831494 /* ShareFunctionView.xib */; };
 		BC40B9F82811767A00DEC0D1 /* HotInformationHeadView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC40B9F72811767A00DEC0D1 /* HotInformationHeadView.m */; };
 		BC40B9FA2811768400DEC0D1 /* HotInformationHeadView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC40B9F92811768400DEC0D1 /* HotInformationHeadView.xib */; };
 		BC40B9FE281177BD00DEC0D1 /* HomeInformationCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BC40B9FC281177BD00DEC0D1 /* HomeInformationCell.m */; };
@@ -453,6 +455,7 @@
 		BC60E3CE287D552800B05441 /* DeleteAccountBodyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC60E3CB287D552800B05441 /* DeleteAccountBodyView.xib */; };
 		BC60E3D2287D592800B05441 /* KSPublicAlertView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC60E3CF287D592800B05441 /* KSPublicAlertView.xib */; };
 		BC60E3D3287D592800B05441 /* KSPublicAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC60E3D1287D592800B05441 /* KSPublicAlertView.m */; };
+		BC66739D2BA841B500FC01A5 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = BC66739C2BA841B500FC01A5 /* PrivacyInfo.xcprivacy */; };
 		BC71D0F32881A2420010F14B /* UMCommonLog.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC71D0C82881A2420010F14B /* UMCommonLog.framework */; };
 		BC71D0F42881A2420010F14B /* UMCommonLog.bundle in Resources */ = {isa = PBXBuildFile; fileRef = BC71D0C92881A2420010F14B /* UMCommonLog.bundle */; };
 		BC71D0F52881A2420010F14B /* UMAPM.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC71D0CC2881A2420010F14B /* UMAPM.framework */; };
@@ -873,7 +876,6 @@
 		BCD9294F28F8FCA4006793E4 /* AudioKit in Frameworks */ = {isa = PBXBuildFile; productRef = BCD9294E28F8FCA4006793E4 /* AudioKit */; };
 		BCD959C928DB071B00B70314 /* MusicTagView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD959C828DB071B00B70314 /* MusicTagView.m */; };
 		BCD959CC28DB0BAB00B70314 /* KSImageShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD959CB28DB0BAB00B70314 /* KSImageShareViewController.m */; };
-		BCDE35882897B40000A9A560 /* shareImage@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BCDE35872897B40000A9A560 /* shareImage@2x.png */; };
 		BCDE358E289A7D8700A9A560 /* KSGroupTagImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCDE358D289A7D8700A9A560 /* KSGroupTagImageView.m */; };
 		BCECE2452B3D670500C0D555 /* FeedbackListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCECE2292B3D670500C0D555 /* FeedbackListViewController.m */; };
 		BCECE2462B3D670500C0D555 /* FeedbackViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCECE22A2B3D670500C0D555 /* FeedbackViewController.m */; };
@@ -1703,6 +1705,9 @@
 		BC3BF62A2B9EAF8100831494 /* CloudAccompanyLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = CloudAccompanyLibrary.framework; sourceTree = "<group>"; };
 		BC3BF62F2B9EAFC800831494 /* client.p12 */ = {isa = PBXFileReference; lastKnownFileType = file; path = client.p12; sourceTree = "<group>"; };
 		BC3BF63B2B9EFA7200831494 /* KSToolLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = KSToolLibrary.framework; sourceTree = "<group>"; };
+		BC3BF63D2B9FE92500831494 /* ShareFunctionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShareFunctionView.h; sourceTree = "<group>"; };
+		BC3BF63E2B9FE92600831494 /* ShareFunctionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShareFunctionView.m; sourceTree = "<group>"; };
+		BC3BF63F2B9FE92600831494 /* ShareFunctionView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ShareFunctionView.xib; sourceTree = "<group>"; };
 		BC40B9F62811767A00DEC0D1 /* HotInformationHeadView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HotInformationHeadView.h; sourceTree = "<group>"; };
 		BC40B9F72811767A00DEC0D1 /* HotInformationHeadView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HotInformationHeadView.m; sourceTree = "<group>"; };
 		BC40B9F92811768400DEC0D1 /* HotInformationHeadView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HotInformationHeadView.xib; sourceTree = "<group>"; };
@@ -1773,6 +1778,7 @@
 		BC60E3CF287D592800B05441 /* KSPublicAlertView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KSPublicAlertView.xib; sourceTree = "<group>"; };
 		BC60E3D0287D592800B05441 /* KSPublicAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSPublicAlertView.h; sourceTree = "<group>"; };
 		BC60E3D1287D592800B05441 /* KSPublicAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSPublicAlertView.m; sourceTree = "<group>"; };
+		BC66739C2BA841B500FC01A5 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
 		BC71D0C82881A2420010F14B /* UMCommonLog.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = UMCommonLog.framework; sourceTree = "<group>"; };
 		BC71D0C92881A2420010F14B /* UMCommonLog.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = UMCommonLog.bundle; sourceTree = "<group>"; };
 		BC71D0CC2881A2420010F14B /* UMAPM.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = UMAPM.framework; sourceTree = "<group>"; };
@@ -2400,7 +2406,6 @@
 		BCD959C828DB071B00B70314 /* MusicTagView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MusicTagView.m; sourceTree = "<group>"; };
 		BCD959CA28DB0BAB00B70314 /* KSImageShareViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSImageShareViewController.h; sourceTree = "<group>"; };
 		BCD959CB28DB0BAB00B70314 /* KSImageShareViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSImageShareViewController.m; sourceTree = "<group>"; };
-		BCDE35872897B40000A9A560 /* shareImage@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shareImage@2x.png"; sourceTree = "<group>"; };
 		BCDE358C289A7D8700A9A560 /* KSGroupTagImageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSGroupTagImageView.h; sourceTree = "<group>"; };
 		BCDE358D289A7D8700A9A560 /* KSGroupTagImageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSGroupTagImageView.m; sourceTree = "<group>"; };
 		BCECE2282B3D670500C0D555 /* FeedbackViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FeedbackViewController.h; sourceTree = "<group>"; };
@@ -2762,6 +2767,7 @@
 		275E8AA727E18F8800DD3F6E /* KulexiuForStudent */ = {
 			isa = PBXGroup;
 			children = (
+				BC66739C2BA841B500FC01A5 /* PrivacyInfo.xcprivacy */,
 				BC255E822B29425F00A1FC27 /* SwiftImportHeader.h */,
 				BC255E832B29425F00A1FC27 /* WebViewBaseConfig.h */,
 				BC3BF6252B9EAF4B00831494 /* ToolKit */,
@@ -4402,18 +4408,10 @@
 			isa = PBXGroup;
 			children = (
 				BC38C3D42AF893B300ABFCC2 /* AudioMerge */,
-				BC38C3D02AF8936300ABFCC2 /* MediaEditor */,
 			);
 			path = MediaMerge;
 			sourceTree = "<group>";
 		};
-		BC38C3D02AF8936300ABFCC2 /* MediaEditor */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			path = MediaEditor;
-			sourceTree = "<group>";
-		};
 		BC38C3D42AF893B300ABFCC2 /* AudioMerge */ = {
 			isa = PBXGroup;
 			children = (
@@ -4426,6 +4424,9 @@
 				BC38C3F72AF8B3E000ABFCC2 /* KSNewAlertView.xib */,
 				BC38C3E62AF893B300ABFCC2 /* KSMediaMergeView.h */,
 				BC38C3D72AF893B300ABFCC2 /* KSMediaMergeView.m */,
+				BC3BF63D2B9FE92500831494 /* ShareFunctionView.h */,
+				BC3BF63E2B9FE92600831494 /* ShareFunctionView.m */,
+				BC3BF63F2B9FE92600831494 /* ShareFunctionView.xib */,
 				BC38C3F22AF8B3B900ABFCC2 /* UIView+KSCovertImage.h */,
 				BC38C3F32AF8B3BA00ABFCC2 /* UIView+KSCovertImage.m */,
 				BC38C3D82AF893B300ABFCC2 /* KSMergeAudioControlView.h */,
@@ -4543,7 +4544,6 @@
 		BC3BF6252B9EAF4B00831494 /* ToolKit */ = {
 			isa = PBXGroup;
 			children = (
-				BC8A45C0283DDD7100094BBB /* synthgms.sf2 */,
 				BC3BF62F2B9EAFC800831494 /* client.p12 */,
 				BC3BF63B2B9EFA7200831494 /* KSToolLibrary.framework */,
 				BC3BF6282B9EAF6F00831494 /* KSTunerLibrary.framework */,
@@ -5225,7 +5225,7 @@
 			children = (
 				BCFCE44D28DD5C000051FED8 /* High.wav */,
 				BCFCE44C28DD5C000051FED8 /* Low.wav */,
-				BCDE35872897B40000A9A560 /* shareImage@2x.png */,
+				BC8A45C0283DDD7100094BBB /* synthgms.sf2 */,
 			);
 			path = SoundFontFile;
 			sourceTree = "<group>";
@@ -6374,6 +6374,7 @@
 				BC119270280FAF7D00A716F7 /* AccompanyCourseInfoCell.xib in Resources */,
 				BC2DFF5828BE143A0056105A /* HomeTempLiveCell.xib in Resources */,
 				BCFDA65528BCA2000022B497 /* accomapny_animation_0.png in Resources */,
+				BC3BF6412B9FE92600831494 /* ShareFunctionView.xib in Resources */,
 				BCC583C828A9EC6400BAB4CF /* cloud_animation_10.png in Resources */,
 				BCC583C328A9EC6400BAB4CF /* cloud_animation_14.png in Resources */,
 				BC8C2C5B2823F57100FBA5D5 /* AddressBottomView.xib in Resources */,
@@ -6527,6 +6528,7 @@
 				BC31BF232B21925700F7D538 /* ToneTuningBodyView.xib in Resources */,
 				BCC583CA28A9EC6400BAB4CF /* cloud_animation_6.png in Resources */,
 				2723B5C527F157B100E0B90B /* ContractListCell.xib in Resources */,
+				BC66739D2BA841B500FC01A5 /* PrivacyInfo.xcprivacy in Resources */,
 				BCBFDF48281159A40052AFE5 /* HomeHotAlbumView.xib in Resources */,
 				BC802D8F28B8964C0079E350 /* LiveApplyView.xib in Resources */,
 				BCECE24C2B3D670500C0D555 /* CourseFileDisplayView.xib in Resources */,
@@ -6578,7 +6580,6 @@
 				BC31BF2E2B21925700F7D538 /* WidgetDotView.xib in Resources */,
 				BC8A45B3283DC33400094BBB /* CloudFeedbackView.xib in Resources */,
 				BCFDA65228BCA2000022B497 /* musicRoom_animation_0.png in Resources */,
-				BCDE35882897B40000A9A560 /* shareImage@2x.png in Resources */,
 				BCC0F66B2A8CD8F500C4EFA4 /* ClassRoomTitleButton.xib in Resources */,
 				BC31BF1B2B21925700F7D538 /* TuningNavView.xib in Resources */,
 				BCFDA66828BDF06E0022B497 /* HomeHotStyleCell.xib in Resources */,
@@ -6789,6 +6790,7 @@
 				BC31BF2A2B21925700F7D538 /* WidgetBottomButtonView.m in Sources */,
 				BC106C392A9338A7000759A9 /* TXLiveVideoView.m in Sources */,
 				2779356527E324A70010E277 /* KSMediaManager.m in Sources */,
+				BC3BF6402B9FE92600831494 /* ShareFunctionView.m in Sources */,
 				BCC0F6AD2A8CDD4000C4EFA4 /* KSNormalAlertView.m in Sources */,
 				BCBFDF5028115D9A0052AFE5 /* HomeIntroduceView.m in Sources */,
 				BCF472EA2AB01AEB0032BE16 /* TenantMoreViewController.m in Sources */,
@@ -7534,7 +7536,7 @@
 					"$(PROJECT_DIR)/KulexiuForStudent/Common/ThirdPart/UMSocialSDK/share/share_ios_6.10.5/SocialLibraries/Sina/SinaSDK",
 					"$(PROJECT_DIR)/KulexiuForStudent/Common/ThirdPart/UMSocialSDK/share/share_ios_6.10.5/UMSocialSDKPlugin",
 				);
-				MARKETING_VERSION = 1.6.0;
+				MARKETING_VERSION = 1.6.1;
 				MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
 				MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
 				OTHER_LDFLAGS = (
@@ -7721,7 +7723,7 @@
 					"$(PROJECT_DIR)/KulexiuForStudent/Common/ThirdPart/UMSocialSDK/share/share_ios_6.10.5/SocialLibraries/Sina/SinaSDK",
 					"$(PROJECT_DIR)/KulexiuForStudent/Common/ThirdPart/UMSocialSDK/share/share_ios_6.10.5/UMSocialSDKPlugin",
 				);
-				MARKETING_VERSION = 1.6.0;
+				MARKETING_VERSION = 1.6.1;
 				MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
 				MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
 				OTHER_LDFLAGS = (

+ 6 - 3
KulexiuForStudent/KulexiuForStudent/AppDelegate.m

@@ -26,6 +26,7 @@
 #endif
 
 #import <KSToolLibrary/UrlDecode.h>
+
 #import "KSBaseWKWebViewController.h"
 #import "UserInfoManager.h"
 
@@ -216,7 +217,9 @@
 
     [UMConfigure initWithAppkey:@"62a2a806eae04539a8e253ed" channel:@"App Store"];
 
+#ifdef DEBUG
     [UMConfigure setLogEnabled:YES];
+#endif
     // 配置友盟分享
     // 微信、QQ、微博完整版会校验合法的universalLink,不设置会在初始化平台失败
        //配置微信Universal Link需注意 universalLinkDic的key是rawInt类型,不是枚举类型 ,即为 UMSocialPlatformType.wechatSession.rawInt
@@ -669,7 +672,7 @@ didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
     if ([detailUrl containsString:@"linkUrl="]) {
         NSString *linkUrl = [[detailUrl componentsSeparatedByString:@"linkUrl="] lastObject];
         if (![NSString isEmptyString:linkUrl]) {
-            linkUrl = [UrlDecode decodeStringWithString:linkUrl];
+            linkUrl = [linkUrl removeUrlEndcodeString];
             // 转成 dic
             NSData *jsonData = [linkUrl mj_JSONData];
             NSError *error;
@@ -731,7 +734,7 @@ didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
         NSString *webUrl = [dict ks_stringValueForKey:@"url"];
         if (![NSString isEmptyString:webUrl]) {
             KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
-            webCtrl.url = webUrl;
+            webCtrl.url = [webUrl getUrlEndcodeString];
             CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
             [navCtrl pushViewController:webCtrl animated:YES];
         }
@@ -873,7 +876,7 @@ didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
             NSString *webUrl = [dict ks_stringValueForKey:@"url"];
             if (![NSString isEmptyString:webUrl]) {
                 KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
-                webCtrl.url = webUrl;
+                webCtrl.url = [webUrl getUrlEndcodeString];
                 CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
                 [navCtrl pushViewController:webCtrl animated:YES];
             }

+ 6 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/Contents.json

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

+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/save_linkIcon.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/save_linkIcon.imageset/save_linkIcon@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/save_linkIcon.imageset/save_linkIcon@3x.png


+ 21 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/shareImage.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/shareImage.imageset/shareImage@2x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/share_friendCircle.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/share_friendCircle.imageset/share_friendCircle@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/share_friendCircle.imageset/share_friendCircle@3x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/share_friendIcon.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/share_friendIcon.imageset/share_friendIcon@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/ShareIcon/share_friendIcon.imageset/share_friendIcon@3x.png


+ 28 - 6
KulexiuForStudent/KulexiuForStudent/Common/Base/KSBaseWKWebViewController.m

@@ -850,19 +850,36 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
     }];
 }
 
+- (KSSHARETYPE)getTypeWithTypeString:(NSString *)typeString {
+    if ([typeString isEqualToString:@"image"]) { // 图片
+        return KSSHARETYPE_IMAGE;
+    }
+    else if ([typeString isEqualToString:@"link"]) { // 链接
+        return KSSHARETYPE_URL;
+    }
+    else {
+        return KSSHARETYPE_VODEO;
+    }
+}
+
 - (void)shareToWeChat:(NSDictionary *)parm {
     
     NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
     if ([[content ks_stringValueForKey:@"shareType"] isEqualToString:@"wechat"]) {
         NSString *typeString = [content ks_stringValueForKey:@"type"];
-        KSSHARETYPE shareType = [typeString isEqualToString:@"image"] ? KSSHARETYPE_IMAGE : KSSHARETYPE_VODEO;
+        KSSHARETYPE shareType = [self getTypeWithTypeString:typeString];
         NSString *shareTitle = [content ks_stringValueForKey:@"title"];
         NSString *descMessage = [content ks_stringValueForKey:@"desc"];
-        NSString *videoUrl = [content ks_stringValueForKey:@"video"];
+        NSString *url = [content ks_stringValueForKey:@"video"];
+        if (shareType == KSSHARETYPE_URL) {
+            url = [content ks_stringValueForKey:@"url"];
+        }
         NSString *imgStr = [content ks_stringValueForKey:@"image"];
         UIImage *shareImage = [self imageWithBase64String:imgStr];
+        NSString *thumImage = [content ks_stringValueForKey:@"thumb"];
+        
         MJWeakSelf;
-        self.shareManager = [KSUMShareManager shareInstanceToWechatWithImage:shareImage url:videoUrl shareTitle:shareTitle descMessage:descMessage shareType:shareType callback:^(BOOL isSuccess, NSString * _Nonnull descMessage) {
+        self.shareManager = [KSUMShareManager shareInstanceToWechatWithImage:shareImage url:url shareTitle:shareTitle descMessage:descMessage shareType:shareType thumImage:thumImage callback:^(BOOL isSuccess, NSString * _Nonnull descMessage) {
             NSMutableDictionary *responParm = [NSMutableDictionary dictionary];
             [responParm setValue:[parm ks_stringValueForKey:@"api"] forKey:@"api"];
             NSMutableDictionary *content = [NSMutableDictionary dictionary];
@@ -876,14 +893,19 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
     }
     else if ([[content ks_stringValueForKey:@"shareType"] isEqualToString:@"wechat_circle"]) { // 微信朋友圈
         NSString *typeString = [content ks_stringValueForKey:@"type"];
-        KSSHARETYPE shareType = [typeString isEqualToString:@"image"] ? KSSHARETYPE_IMAGE : KSSHARETYPE_VODEO;
+        KSSHARETYPE shareType = [self getTypeWithTypeString:typeString];
         NSString *shareTitle = [content ks_stringValueForKey:@"title"];
         NSString *descMessage = [content ks_stringValueForKey:@"desc"];
-        NSString *videoUrl = [content ks_stringValueForKey:@"video"];
+        NSString *url = [content ks_stringValueForKey:@"video"];
+        if (shareType == KSSHARETYPE_URL) {
+            url = [content ks_stringValueForKey:@"url"];
+        }
         NSString *imgStr = [content ks_stringValueForKey:@"image"];
         UIImage *shareImage = [self imageWithBase64String:imgStr];
+        NSString *thumImage = [content ks_stringValueForKey:@"thumb"];
+
         MJWeakSelf;
-        self.shareManager = [KSUMShareManager shareInstanceToWechatCircleWithImage:shareImage url:videoUrl shareTitle:shareTitle descMessage:descMessage shareType:shareType callback:^(BOOL isSuccess, NSString * _Nonnull descMessage) {
+        self.shareManager = [KSUMShareManager shareInstanceToWechatCircleWithImage:shareImage url:url shareTitle:shareTitle descMessage:descMessage shareType:shareType thumImage:thumImage callback:^(BOOL isSuccess, NSString * _Nonnull descMessage) {
             NSMutableDictionary *responParm = [NSMutableDictionary dictionary];
             [responParm setValue:[parm ks_stringValueForKey:@"api"] forKey:@"api"];
             NSMutableDictionary *content = [NSMutableDictionary dictionary];

+ 64 - 1
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSMediaMergeView.m

@@ -21,6 +21,8 @@
 #import "KSVideoCropViewController.h"
 #import <KSToolLibrary/KSAudioSessionManager.h>
 
+#import "ShareFunctionView.h"
+#import "KSUMShareManager.h"
 
 @interface KSMediaMergeView ()<kSNewPlayerManagerDelegate,KSVideoPlayerViewDelegate,RSKImageCropViewControllerDelegate,RSKImageCropViewControllerDataSource>
 
@@ -117,6 +119,8 @@
 
 @property (nonatomic, assign) BOOL fromDraftPage; // 是否从草稿页面进入
 
+@property (nonatomic, strong) KSUMShareManager *shareManager;
+
 @end
 
 @implementation KSMediaMergeView
@@ -1109,8 +1113,12 @@
     [KSNetworkingManager saveMusicMessage:KS_POST jsonConfig:self.jsonConfig img:self.coverImage videoUrl:fileUrl accompanyUrl:self.remoteBgAudioUrl desc:self.desc type:type musicPracticeRecordId:self.recordId videoImg:self.videoCoverUrl success:^(NSDictionary * _Nonnull dic) {
         if ([dic ks_integerValueForKey:@"code"] == 200) {
             if (isFormal) {
+                NSString *productId = @"";
+                if ([[dic objectForKey:@"data"] isKindOfClass:[NSString class]]) {
+                    productId = [dic ks_stringValueForKey:@"data"];
+                }
                 [LOADING_MANAGER KSShowProgressMsg:@"发布成功" promptCompletion:^{
-                    [self removeView];
+                    [self showShareView:self.desc productId:productId];
                 }];
             }
             else {
@@ -1136,6 +1144,61 @@
     }];
 }
 
+- (void)showShareView:(NSString *)desc productId:(NSString *)productId {
+    if ([NSString isEmptyString:productId]) {
+        [self removeView];
+        return;
+    }
+    ShareFunctionView *shareView = [ShareFunctionView shareInstance];
+    [shareView showShareView:self];
+    [shareView shareOutCallback:^(MINESHARETYPE type) {
+        [self shareAction:type desc:desc productId:productId];
+    }];
+    
+}
+
+- (void)shareAction:(MINESHARETYPE)type desc:(NSString *)desc productId:(NSString *)productId {
+    
+    NSString *shareTitle = @"我在酷乐秀发布了演奏作品";
+    NSString *url = [NSString stringWithFormat:@"%@%@?id=%@",WEBHOST, @"/#/shareCreation", productId];
+    UIImage *image = [UIImage new];
+    NSString *descMessage = desc;
+    id thumImage = [NSString isEmptyString:self.coverImage] ? [UIImage imageNamed:@"pub_music_placeholder"] : [self.coverImage getUrlEndcodeString];
+    switch (type) {
+        case MINESHARETYPE_FRIEND:
+        {
+            self.shareManager = [KSUMShareManager shareInstanceToWechatWithImage:image url:url shareTitle:shareTitle descMessage:descMessage shareType:KSSHARETYPE_URL thumImage:thumImage callback:^(BOOL isSuccess, NSString * _Nonnull descMessage) {
+
+            }];
+        }
+            break;
+        case MINESHARETYPE_CIRCLE:
+        {
+            self.shareManager = [KSUMShareManager shareInstanceToWechatCircleWithImage:image url:url shareTitle:shareTitle descMessage:descMessage shareType:KSSHARETYPE_URL thumImage:thumImage callback:^(BOOL isSuccess, NSString * _Nonnull descMessage) {
+
+            }];
+            
+        }
+            break;
+        case MINESHARETYPE_SAVE:
+        {
+            // 复制
+            UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
+            pasteboard.string = url;
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"复制成功"];
+        }
+            break;
+        case MINESHARETYPE_CANCEL:
+        {
+            [self removeView];
+        }
+        default:
+            break;
+    }
+
+}
+
+
 - (void)showSaveDraftTipsAlert {
     MJWeakSelf;
     [self.alertView configTitle:@"提示" descMessage:@"已成功保存到草稿,草稿7天未发布将自动删除。" leftButtonTitle:@"确认" rightButtonTitle:@"查看草稿" leftButtonAction:^{

+ 31 - 0
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/ShareFunctionView.h

@@ -0,0 +1,31 @@
+//
+//  ShareFunctionView.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2024/3/8.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef NS_ENUM(NSInteger, MINESHARETYPE) {
+    MINESHARETYPE_FRIEND,  // 微信好友
+    MINESHARETYPE_CIRCLE,  // 朋友圈
+    MINESHARETYPE_SAVE,    // 保存链接
+    MINESHARETYPE_CANCEL,  // 取消下载
+};
+
+typedef void(^ShareChooseCallback)(MINESHARETYPE type);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface ShareFunctionView : UIView
+
++ (instancetype)shareInstance;
+
+- (void)showShareView:(UIView *)displayView;
+
+- (void)shareOutCallback:(ShareChooseCallback)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 108 - 0
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/ShareFunctionView.m

@@ -0,0 +1,108 @@
+//
+//  ShareFunctionView.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2024/3/8.
+//
+
+#import "ShareFunctionView.h"
+
+@interface ShareFunctionView ()<UIGestureRecognizerDelegate>
+
+@property (weak, nonatomic) IBOutlet UIView *containerView;
+
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomSpace;
+
+@property (nonatomic, copy) ShareChooseCallback callback;
+
+@end
+
+@implementation ShareFunctionView
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+//    [self addGesture];
+}
+
++ (instancetype)shareInstance {
+    ShareFunctionView *view = [[[NSBundle mainBundle] loadNibNamed:@"ShareFunctionView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)showShareView:(UIView *)displayView {
+    if (displayView) {
+        [displayView addSubview:self];
+        [self mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.top.bottom.mas_equalTo(displayView);
+        }];
+    }
+    else {
+        UIView *showView = [NSObject getKeyWindow];
+        [showView addSubview:self];
+        [self mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.top.bottom.mas_equalTo(showView);
+        }];
+    }
+}
+
+- (void)shareOutCallback:(ShareChooseCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (IBAction)shareFriend:(id)sender {
+    if (self.callback) {
+        self.callback(MINESHARETYPE_FRIEND);
+    }
+}
+
+- (IBAction)shareCircle:(id)sender {
+    if (self.callback) {
+        self.callback(MINESHARETYPE_CIRCLE);
+    }
+}
+
+- (IBAction)saveLink:(id)sender {
+    if (self.callback) {
+        self.callback(MINESHARETYPE_SAVE);
+    }
+}
+
+
+- (IBAction)cancelAction:(id)sender {
+    [self cancelShareAction];
+}
+
+- (void)cancelShareAction {
+    if (self.callback) {
+        self.callback(MINESHARETYPE_CANCEL);
+    }
+}
+
+#pragma mark ---- gesture
+- (void)addGesture {
+    UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
+    gesture.delegate = self;
+    [self addGestureRecognizer:gesture];
+}
+
+- (void)tapAction:(UITapGestureRecognizer *)gesture {
+    [self cancelShareAction];
+}
+
+- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
+    if ([touch.view isDescendantOfView:self.containerView]) {
+        return NO;
+    }
+    return YES;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 254 - 0
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/ShareFunctionView.xib

@@ -0,0 +1,254 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22504"/>
+        <capability name="System colors in document resources" minToolsVersion="11.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="ShareFunctionView">
+            <rect key="frame" x="0.0" y="0.0" width="393" height="662"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xxd-Rj-n4H">
+                    <rect key="frame" x="46.666666666666657" y="229" width="300" height="204.33333333333337"/>
+                    <subviews>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="作品发布成功!快来分享吧!" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="whi-jN-odv">
+                            <rect key="frame" x="22.000000000000014" y="15" width="204.33333333333337" height="22"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="22" id="mcC-RU-mid"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                            <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cancle_button" translatesAutoresizingMaskIntoConstraints="NO" id="d68-wP-nqr">
+                            <rect key="frame" x="278" y="11" width="12" height="12"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="12" id="2dO-Ib-kPr"/>
+                                <constraint firstAttribute="height" constant="12" id="UWh-M8-xRo"/>
+                            </constraints>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1X7-2b-H7z">
+                            <rect key="frame" x="260" y="0.0" width="40" height="40"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="40" id="mfV-tg-6hm"/>
+                                <constraint firstAttribute="width" constant="40" id="twM-LS-3el"/>
+                            </constraints>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="cancelAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="c7H-59-kBo"/>
+                            </connections>
+                        </button>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3o6-xF-kdP">
+                            <rect key="frame" x="52" y="60.999999999999993" width="52" height="68.333333333333314"/>
+                            <subviews>
+                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="share_friendIcon" translatesAutoresizingMaskIntoConstraints="NO" id="hP0-qM-Y11">
+                                    <rect key="frame" x="4" y="0.0" width="44" height="44"/>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="44" id="dFC-Nr-TLC"/>
+                                        <constraint firstAttribute="height" constant="44" id="r6X-iY-jcE"/>
+                                    </constraints>
+                                </imageView>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="微信好友" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vjl-Z1-6Mv">
+                                    <rect key="frame" x="0.0" y="54" width="52" height="14.333333333333329"/>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="52" id="5M4-h2-Hz5"/>
+                                    </constraints>
+                                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                    <color key="textColor" red="0.39215686274509803" green="0.396078431372549" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Iho-8X-SD1">
+                                    <rect key="frame" x="0.0" y="0.0" width="52" height="68.333333333333329"/>
+                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                                    <connections>
+                                        <action selector="shareFriend:" destination="iN0-l3-epB" eventType="touchUpInside" id="eSM-hz-qsf"/>
+                                    </connections>
+                                </button>
+                            </subviews>
+                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                            <constraints>
+                                <constraint firstItem="Iho-8X-SD1" firstAttribute="top" secondItem="3o6-xF-kdP" secondAttribute="top" id="E9B-P3-Ipy"/>
+                                <constraint firstItem="hP0-qM-Y11" firstAttribute="top" secondItem="3o6-xF-kdP" secondAttribute="top" id="Hxy-Co-Vhl"/>
+                                <constraint firstItem="vjl-Z1-6Mv" firstAttribute="top" secondItem="hP0-qM-Y11" secondAttribute="bottom" constant="10" id="N6s-Ve-z05"/>
+                                <constraint firstItem="Iho-8X-SD1" firstAttribute="leading" secondItem="3o6-xF-kdP" secondAttribute="leading" id="Qh1-Gg-sJL"/>
+                                <constraint firstItem="hP0-qM-Y11" firstAttribute="centerX" secondItem="3o6-xF-kdP" secondAttribute="centerX" id="Uif-5u-jbS"/>
+                                <constraint firstAttribute="trailing" secondItem="Iho-8X-SD1" secondAttribute="trailing" id="dJE-5d-b5Y"/>
+                                <constraint firstItem="hP0-qM-Y11" firstAttribute="centerX" secondItem="3o6-xF-kdP" secondAttribute="centerX" id="dL8-Et-tDy"/>
+                                <constraint firstAttribute="trailing" secondItem="vjl-Z1-6Mv" secondAttribute="trailing" id="fS1-aW-f6t"/>
+                                <constraint firstItem="vjl-Z1-6Mv" firstAttribute="leading" secondItem="3o6-xF-kdP" secondAttribute="leading" id="i3i-iB-r6u"/>
+                                <constraint firstAttribute="bottom" secondItem="Iho-8X-SD1" secondAttribute="bottom" id="jvV-NO-JXW"/>
+                                <constraint firstAttribute="bottom" secondItem="vjl-Z1-6Mv" secondAttribute="bottom" id="s7r-eh-W7i"/>
+                            </constraints>
+                        </view>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cJu-Gs-vEw">
+                            <rect key="frame" x="13" y="146.33333333333331" width="274" height="1"/>
+                            <color key="backgroundColor" red="0.94901960784313721" green="0.94901960784313721" blue="0.94901960784313721" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="1" id="h5e-T1-Xll"/>
+                            </constraints>
+                        </view>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="取消" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="KgM-5w-lll">
+                            <rect key="frame" x="133.33333333333334" y="162.33333333333331" width="33.333333333333343" height="22"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="22" id="233-tf-otD"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                            <color key="textColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Hbd-Au-HVO">
+                            <rect key="frame" x="0.0" y="147.33333333333331" width="300" height="57"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="cancelAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="RDg-wT-LHI"/>
+                            </connections>
+                        </button>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pii-x4-YtS">
+                            <rect key="frame" x="124" y="60.999999999999993" width="52" height="68.333333333333314"/>
+                            <subviews>
+                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="share_friendCircle" translatesAutoresizingMaskIntoConstraints="NO" id="5ej-dh-tsG">
+                                    <rect key="frame" x="4" y="0.0" width="44" height="44"/>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="44" id="GeQ-L3-drg"/>
+                                        <constraint firstAttribute="height" constant="44" id="cdb-cb-4rs"/>
+                                    </constraints>
+                                </imageView>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="朋友圈" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="12Q-cw-qeX">
+                                    <rect key="frame" x="0.0" y="54" width="52" height="14.333333333333329"/>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="52" id="6pb-Kd-q83"/>
+                                    </constraints>
+                                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                    <color key="textColor" red="0.3921568627" green="0.39607843139999999" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="pJm-Pm-dKW">
+                                    <rect key="frame" x="0.0" y="0.0" width="52" height="68.333333333333329"/>
+                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                                    <connections>
+                                        <action selector="shareCircle:" destination="iN0-l3-epB" eventType="touchUpInside" id="rGy-7k-Iyh"/>
+                                    </connections>
+                                </button>
+                            </subviews>
+                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                            <constraints>
+                                <constraint firstItem="5ej-dh-tsG" firstAttribute="centerX" secondItem="pii-x4-YtS" secondAttribute="centerX" id="45O-ma-CiK"/>
+                                <constraint firstAttribute="bottom" secondItem="pJm-Pm-dKW" secondAttribute="bottom" id="7CI-AM-1OX"/>
+                                <constraint firstItem="5ej-dh-tsG" firstAttribute="top" secondItem="pii-x4-YtS" secondAttribute="top" id="8Ff-be-1ov"/>
+                                <constraint firstAttribute="trailing" secondItem="12Q-cw-qeX" secondAttribute="trailing" id="QhJ-iA-bhb"/>
+                                <constraint firstAttribute="trailing" secondItem="pJm-Pm-dKW" secondAttribute="trailing" id="TDv-0N-obo"/>
+                                <constraint firstAttribute="bottom" secondItem="12Q-cw-qeX" secondAttribute="bottom" id="WPN-UM-Kah"/>
+                                <constraint firstItem="12Q-cw-qeX" firstAttribute="top" secondItem="5ej-dh-tsG" secondAttribute="bottom" constant="10" id="hZ0-PK-ZlL"/>
+                                <constraint firstItem="pJm-Pm-dKW" firstAttribute="leading" secondItem="pii-x4-YtS" secondAttribute="leading" id="iD2-2P-i69"/>
+                                <constraint firstItem="5ej-dh-tsG" firstAttribute="centerX" secondItem="pii-x4-YtS" secondAttribute="centerX" id="mFK-Da-0mO"/>
+                                <constraint firstItem="pJm-Pm-dKW" firstAttribute="top" secondItem="pii-x4-YtS" secondAttribute="top" id="qTJ-SH-oRz"/>
+                                <constraint firstItem="12Q-cw-qeX" firstAttribute="leading" secondItem="pii-x4-YtS" secondAttribute="leading" id="rSX-aV-7am"/>
+                            </constraints>
+                        </view>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="972-C6-GND">
+                            <rect key="frame" x="196" y="60.999999999999993" width="52" height="68.333333333333314"/>
+                            <subviews>
+                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="save_linkIcon" translatesAutoresizingMaskIntoConstraints="NO" id="HFC-kg-Cnl">
+                                    <rect key="frame" x="4" y="0.0" width="44" height="44"/>
+                                    <constraints>
+                                        <constraint firstAttribute="height" constant="44" id="Pun-mH-KQi"/>
+                                        <constraint firstAttribute="width" constant="44" id="bAc-gW-UQ6"/>
+                                    </constraints>
+                                </imageView>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="复制链接" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NrI-8j-lth">
+                                    <rect key="frame" x="0.0" y="54" width="52" height="14.333333333333329"/>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="52" id="z0T-Iz-msj"/>
+                                    </constraints>
+                                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                    <color key="textColor" red="0.3921568627" green="0.39607843139999999" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mlB-f7-6X8">
+                                    <rect key="frame" x="0.0" y="0.0" width="52" height="68.333333333333329"/>
+                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                                    <connections>
+                                        <action selector="saveLink:" destination="iN0-l3-epB" eventType="touchUpInside" id="rSH-Ut-2gO"/>
+                                    </connections>
+                                </button>
+                            </subviews>
+                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                            <constraints>
+                                <constraint firstItem="mlB-f7-6X8" firstAttribute="leading" secondItem="972-C6-GND" secondAttribute="leading" id="33I-aM-kwu"/>
+                                <constraint firstItem="NrI-8j-lth" firstAttribute="top" secondItem="HFC-kg-Cnl" secondAttribute="bottom" constant="10" id="7Pn-OD-jM1"/>
+                                <constraint firstItem="HFC-kg-Cnl" firstAttribute="centerX" secondItem="972-C6-GND" secondAttribute="centerX" id="BKc-lH-1f1"/>
+                                <constraint firstItem="NrI-8j-lth" firstAttribute="leading" secondItem="972-C6-GND" secondAttribute="leading" id="GCP-e1-0HQ"/>
+                                <constraint firstAttribute="bottom" secondItem="mlB-f7-6X8" secondAttribute="bottom" id="GwM-Fx-IV6"/>
+                                <constraint firstAttribute="bottom" secondItem="NrI-8j-lth" secondAttribute="bottom" id="KEg-Ts-4em"/>
+                                <constraint firstAttribute="trailing" secondItem="mlB-f7-6X8" secondAttribute="trailing" id="Ktg-ph-Fod"/>
+                                <constraint firstItem="HFC-kg-Cnl" firstAttribute="top" secondItem="972-C6-GND" secondAttribute="top" id="aXq-Jg-dZT"/>
+                                <constraint firstAttribute="trailing" secondItem="NrI-8j-lth" secondAttribute="trailing" id="k9k-fX-vxJ"/>
+                                <constraint firstItem="mlB-f7-6X8" firstAttribute="top" secondItem="972-C6-GND" secondAttribute="top" id="nnB-0i-WJM"/>
+                                <constraint firstItem="HFC-kg-Cnl" firstAttribute="centerX" secondItem="972-C6-GND" secondAttribute="centerX" id="y5F-za-Lsz"/>
+                            </constraints>
+                        </view>
+                    </subviews>
+                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                    <constraints>
+                        <constraint firstItem="1X7-2b-H7z" firstAttribute="top" secondItem="xxd-Rj-n4H" secondAttribute="top" id="0eY-1Q-fY5"/>
+                        <constraint firstItem="whi-jN-odv" firstAttribute="leading" secondItem="xxd-Rj-n4H" secondAttribute="leading" constant="22" id="77b-d3-fXo"/>
+                        <constraint firstItem="pii-x4-YtS" firstAttribute="leading" secondItem="3o6-xF-kdP" secondAttribute="trailing" constant="20" id="8oP-dH-jon"/>
+                        <constraint firstItem="Hbd-Au-HVO" firstAttribute="top" secondItem="cJu-Gs-vEw" secondAttribute="bottom" id="AXs-66-0Hc"/>
+                        <constraint firstItem="cJu-Gs-vEw" firstAttribute="top" secondItem="3o6-xF-kdP" secondAttribute="bottom" constant="17" id="DJm-3W-Ppo"/>
+                        <constraint firstAttribute="trailing" secondItem="1X7-2b-H7z" secondAttribute="trailing" id="Fg7-FP-q51"/>
+                        <constraint firstItem="pii-x4-YtS" firstAttribute="centerX" secondItem="xxd-Rj-n4H" secondAttribute="centerX" id="HkN-nL-ZkK"/>
+                        <constraint firstAttribute="trailing" secondItem="d68-wP-nqr" secondAttribute="trailing" constant="10" id="I0M-Uk-GhE"/>
+                        <constraint firstAttribute="trailing" secondItem="cJu-Gs-vEw" secondAttribute="trailing" constant="13" id="Idm-7d-lED"/>
+                        <constraint firstAttribute="bottom" secondItem="KgM-5w-lll" secondAttribute="bottom" constant="20" id="KaZ-ue-dRl"/>
+                        <constraint firstItem="3o6-xF-kdP" firstAttribute="top" secondItem="whi-jN-odv" secondAttribute="bottom" constant="24" id="QqV-SP-EIG"/>
+                        <constraint firstAttribute="trailing" secondItem="Hbd-Au-HVO" secondAttribute="trailing" id="Rgn-1H-6vP"/>
+                        <constraint firstItem="972-C6-GND" firstAttribute="leading" secondItem="pii-x4-YtS" secondAttribute="trailing" constant="20" id="Rlx-5Z-6Ld"/>
+                        <constraint firstItem="pii-x4-YtS" firstAttribute="centerY" secondItem="3o6-xF-kdP" secondAttribute="centerY" id="YaR-Tg-ZcD"/>
+                        <constraint firstItem="whi-jN-odv" firstAttribute="top" secondItem="xxd-Rj-n4H" secondAttribute="top" constant="15" id="ZWU-fk-uQU"/>
+                        <constraint firstItem="cJu-Gs-vEw" firstAttribute="leading" secondItem="xxd-Rj-n4H" secondAttribute="leading" constant="13" id="bD5-oG-A0K"/>
+                        <constraint firstAttribute="bottom" secondItem="Hbd-Au-HVO" secondAttribute="bottom" id="bw7-c0-8jw"/>
+                        <constraint firstItem="KgM-5w-lll" firstAttribute="centerX" secondItem="xxd-Rj-n4H" secondAttribute="centerX" id="iF6-pQ-QO3"/>
+                        <constraint firstItem="Hbd-Au-HVO" firstAttribute="leading" secondItem="xxd-Rj-n4H" secondAttribute="leading" id="mdL-48-aTV"/>
+                        <constraint firstItem="KgM-5w-lll" firstAttribute="top" secondItem="cJu-Gs-vEw" secondAttribute="bottom" constant="15" id="oKd-gp-JKZ"/>
+                        <constraint firstItem="972-C6-GND" firstAttribute="centerY" secondItem="3o6-xF-kdP" secondAttribute="centerY" id="q9s-ei-XU2"/>
+                        <constraint firstItem="d68-wP-nqr" firstAttribute="top" secondItem="xxd-Rj-n4H" secondAttribute="top" constant="11" id="qKv-jP-uao"/>
+                        <constraint firstAttribute="width" constant="300" id="tqA-Z0-lUX"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="10"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+            </subviews>
+            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
+            <constraints>
+                <constraint firstItem="xxd-Rj-n4H" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="ERe-kV-nbc"/>
+                <constraint firstItem="xxd-Rj-n4H" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="PTm-7m-F6B"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="bottomSpace" destination="KaZ-ue-dRl" id="xJR-P0-MOI"/>
+                <outlet property="containerView" destination="xxd-Rj-n4H" id="xuA-Pw-lve"/>
+            </connections>
+            <point key="canvasLocation" x="104.58015267175573" y="-166.90140845070422"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="cancle_button" width="20" height="20"/>
+        <image name="save_linkIcon" width="44" height="44"/>
+        <image name="share_friendCircle" width="44" height="44"/>
+        <image name="share_friendIcon" width="44" height="44"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 456 - 0
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/MusicPlayer/kSNewPlayer.m

@@ -0,0 +1,456 @@
+//
+//  kSNewPlayer.m
+//  StudentDaya
+//
+//  Created by 王智 on 2023/5/17.
+//  Copyright © 2023 DayaMusic. All rights reserved.
+//
+
+#import "kSNewPlayer.h"
+#import "AVPlayer+KSSeekSmoothly.h"
+
+@interface kSNewPlayer ()
+
+@property(nonatomic,strong) AVPlayer *player;
+
+@property(nonatomic,strong) AVPlayerItem *songItem;
+
+@property(nonatomic,retain)id timeObserver;//时间观察
+
+@property (nonatomic, assign) BOOL cacheFinish;
+
+@property (nonatomic, assign) BOOL hasFreeObserver;
+
+@end
+
+@implementation kSNewPlayer
+
++ (instancetype)shareInstance {
+    kSNewPlayer * manager = [[kSNewPlayer alloc] init];
+    return manager;
+}
+
+- (instancetype)init {
+    self = [super init];
+    if (self) {
+        
+    }
+    return self;
+}
+
+- (void)resetPlayer {
+    self.player = nil;
+}
+
+- (void)preparePlaySongWithUrl:(NSString *)urlStr {
+    self.cacheFinish = NO;
+    urlStr = [urlStr getUrlEndcodeString];
+    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL URLWithString:urlStr] options:nil];
+    if (_songItem) {
+        [self removeAllNoticeAndObserver];
+        [self resetPlayer];
+    }
+    _songItem = [[AVPlayerItem alloc] initWithAsset:asset];
+    _player = [AVPlayer playerWithPlayerItem:_songItem];
+    if ([_player respondsToSelector:@selector(automaticallyWaitsToMinimizeStalling)]) {
+        _player.automaticallyWaitsToMinimizeStalling = NO;
+    }
+
+    //添加监听
+    [self addNotificationAndObserver];
+    self.volume = 1.0;
+    self.isMute = NO;
+    //    AVAudioPlayer *player = [[AVAudioPlayer alloc] init];
+}
+
+
+// 播放本地文件
+- (void)preparePlayNativeSongWithUrl:(NSString *)urlStr {
+    self.cacheFinish = NO;
+    NSURL *url = [NSURL fileURLWithPath:urlStr];
+    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
+    if (_songItem) {
+        [self removeAllNoticeAndObserver];
+        [self resetPlayer];
+    }
+    _songItem = [AVPlayerItem playerItemWithAsset:asset];
+    _player = [AVPlayer playerWithPlayerItem:_songItem];
+    if ([_player respondsToSelector:@selector(automaticallyWaitsToMinimizeStalling)]) {
+        _player.automaticallyWaitsToMinimizeStalling = NO;
+    }
+    //添加监听
+    [self addNotificationAndObserver];
+    self.volume = 1.0;
+    self.isMute = NO;
+}
+
+- (void)preparePlayNativeSongWithPath:(NSURL *)urlStr {
+    self.cacheFinish = NO;
+    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:urlStr options:nil];
+    if (_songItem) {
+        [self removeAllNoticeAndObserver];
+        [self resetPlayer];
+    }
+    _songItem = [AVPlayerItem playerItemWithAsset:asset];
+    _player = [AVPlayer playerWithPlayerItem:_songItem];
+    if ([_player respondsToSelector:@selector(automaticallyWaitsToMinimizeStalling)]) {
+        _player.automaticallyWaitsToMinimizeStalling = NO;
+    }
+    //添加监听
+    [self addNotificationAndObserver];
+    self.volume = 1.0;
+    self.isMute = NO;
+}
+
+- (void)addNotificationAndObserver {
+    if (self.songItem) {
+        self.hasFreeObserver = NO;
+        //添加播放器状态的监听
+        [self addAVPlayerStatusObserver];
+        //添加数据缓存的监听
+        [self addNetDataStatusObserver];
+        
+        //添加时间的监听
+        [self addTimeObserve];
+        //添加播放完成的通知
+        [self addPlayToEndObserver];
+        // 添加异常通知
+        [self addExceptionObserver];
+    }
+}
+- (void)configPlayerRate:(CGFloat)rate {
+    if (_isPlaying) {
+        if (rate >= 0) {
+            self.player.rate = rate;
+        }
+    }
+}
+
+- (void)startPlay {
+    if (_isPlaying) {
+        [_player pause];
+    }
+    _isPlaying = YES;
+    @weakObj(self);
+    CMTime toleranceTime = CMTimeMake(1, 1000);
+    [self.player ss_seekToTime:kCMTimeZero toleranceBefore:toleranceTime toleranceAfter:toleranceTime completionHandler:^(BOOL finished) {
+        @strongObj(self);
+        [self.player play];
+    }];
+}
+
+- (void)startPlayNoSeek {
+    if (_isPlaying) {
+        [_player pause];
+    }
+    _isPlaying = YES;
+    [self.player play];
+}
+
+- (void)resumePlay {
+    if (_isPlaying) {
+        [_player pause];
+    }
+    _isPlaying = YES;
+    [self.player play];
+}
+
+- (void)puasePlay {
+    if (_isPlaying) {
+        _isPlaying = NO;
+        [_player pause];
+    }
+}
+
+- (void)freePlayer {
+    if (_isPlaying) {
+        _isPlaying = NO;
+        [_player pause];
+    }
+    [self removeAllNoticeAndObserver];
+    [self resetPlayer];
+}
+
+- (void)seekToStart {
+    CMTime toleranceTime = CMTimeMake(1, 1000);
+    [self.player ss_seekToTime:kCMTimeZero toleranceBefore:toleranceTime toleranceAfter:toleranceTime completionHandler:^(BOOL finished) {
+        
+    }];
+}
+
+// 从某个位置开始播放 ms
+- (void)seekToTimePlay:(NSInteger)time {
+    _isPlaying = YES;
+    CMTime offsetCTTime = CMTimeMake(labs(time), 1000);
+    @weakObj(self);
+    CMTime toleranceTime = CMTimeMake(1, 1000);
+    [self.player ss_seekToTime:offsetCTTime toleranceBefore:toleranceTime toleranceAfter:toleranceTime completionHandler:^(BOOL finished) {
+        @strongObj(self);
+        [self.player play];
+    }];
+}
+
+// 调整进度到某个位置
+- (void)seekToTime:(NSInteger)time callback:(void(^)(void))callback {
+    [self.player pause];
+    CMTime offsetCTTime = CMTimeMake(labs(time), 1000);
+    CMTime toleranceTime = CMTimeMake(1, 1000);
+    [self.player ss_seekToTime:offsetCTTime toleranceBefore:toleranceTime toleranceAfter:toleranceTime completionHandler:^(BOOL finished) {
+        callback();
+    }];
+}
+
+- (void)seekOffsetTime:(NSInteger)offsetTime {
+    CMTime newTime = CMTimeMake(offsetTime, 1000);
+    CMTime toleranceTime = CMTimeMake(1, 1000);
+    
+    [self.player pause];
+    @weakObj(self);
+    [self.player ss_seekToTime:newTime toleranceBefore:toleranceTime toleranceAfter:toleranceTime completionHandler:^(BOOL finished) {
+        @strongObj(self);
+        if (self.isPlaying) {
+            [self.player play];
+        }
+    }];
+}
+
+// 调整进度
+- (void)seekOffsetTimeNoPuase:(NSInteger)offsetTime {
+    CMTime newTime = CMTimeMake(offsetTime, 1000);
+    CMTime toleranceTime = CMTimeMake(1, 1000);
+
+    [self.player ss_seekToTime:newTime toleranceBefore:toleranceTime toleranceAfter:toleranceTime completionHandler:^(BOOL finished) {
+
+    }];
+}
+
+- (CMTime)getCurrentPlayTime {
+    return [self.player currentTime];
+}
+
+- (void)setIsMute:(BOOL)isMute {
+    _isMute = isMute;
+    [self.player setMuted:isMute];
+}
+
+- (float)getTotalDuration {
+    float total = CMTimeGetSeconds(self.player.currentItem.asset.duration);
+    return total;
+}
+
+#pragma mark----设置player的volume
+- (void)setVolume:(CGFloat)volume {
+    _volume = volume;
+    _player.volume=_volume;
+}
+
+-(void)addTimeObserve
+{
+//    __block typeof(self) bself = self;
+    @weakObj(self);
+    _timeObserver = [_player addPeriodicTimeObserverForInterval:CMTimeMake(1, 100) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
+        @strongObj(self);
+        //设置player的声音
+        //        [self setPlayerVolume];
+        //当前时间
+        float current = CMTimeGetSeconds(time);
+        //总共时间
+        float total = CMTimeGetSeconds(self.player.currentItem.asset.duration);
+        //进度
+        float progress = current/total;
+        //将值传入知道delegate方法中
+        //        NSLog(@"--current %f -- total %f -----%f", current, total, progress);
+        if (self.delegate && [self.delegate respondsToSelector:@selector(getSongCurrentTime:andTotalTime:andProgress:currentInterval:playTime:inPlayer:)]) {
+            NSDate *date = [NSDate date];
+            NSTimeInterval inteveral = [date timeIntervalSince1970];
+            //            NSLog(@"----- start play %f", inteveral * 1000);
+            [self.delegate getSongCurrentTime:current*1000  andTotalTime:total*1000 andProgress:progress currentInterval:inteveral playTime:current*1000 inPlayer:self];
+        }
+    }];
+}
+
+#pragma mark---移除时间观察者
+-(void)removeTimeObserver
+{
+    if (_timeObserver) {
+        [_player removeTimeObserver:_timeObserver];
+        _timeObserver = nil;
+    }
+}
+#pragma mark---float转00:00类型
+- (NSString *)formatTime:(float)num{
+    
+    int sec =(int)num%60;
+    int min =(int)num/60;
+    if (num < 60) {
+        return [NSString stringWithFormat:@"00:%02d",(int)num];
+    }
+    return [NSString stringWithFormat:@"%02d:%02d",min,sec];
+}
+#pragma mark----监听播放器的加载状态
+-(void)addAVPlayerStatusObserver
+{
+    [_songItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
+}
+#pragma mark----数据缓冲状态的监听
+-(void)addNetDataStatusObserver
+{
+    [_songItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
+}
+
+
+#pragma mark----KVO方法
+-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
+{
+    //播放器缓冲状态
+    if ([keyPath isEqualToString:@"status"]) {
+        switch (_player.status) {
+            case AVPlayerStatusUnknown:{
+                _isPlaying = NO;
+                NSLog(@"未知状态,此时不能播放");
+            }
+                break;
+            case AVPlayerStatusReadyToPlay: {
+                _isReady = YES;
+                NSLog(@"准备完毕,可以播放");
+                dispatch_main_sync_safe(^{
+                    if (self.delegate && [self.delegate respondsToSelector:@selector(playerIsReadyPlay:)]) {
+                        [self.delegate playerIsReadyPlay:self];
+                    }
+                });
+            }
+                break;
+            case AVPlayerStatusFailed:{
+                _isPlaying = NO;
+                NSLog(@"加载失败,网络或者服务器出现问题");
+            }
+                break;
+            default:
+                break;
+        }
+    }
+    //数据缓冲状态
+    if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
+        // 计算缓冲进度
+        NSTimeInterval timeInterval = [self availableDuration];
+        CGFloat totalDuration = CMTimeGetSeconds(self.player.currentItem.asset.duration);
+        if (timeInterval == totalDuration && self.cacheFinish == NO) {
+            self.cacheFinish = YES;
+            dispatch_main_sync_safe(^{
+                if (self.delegate && [self.delegate respondsToSelector:@selector(preparePlay:)]) {
+                    [self.delegate preparePlay:self];
+                }
+            });
+        }
+    }
+}
+
+#pragma mark - 计算缓冲进度
+
+/**
+ *  计算缓冲进度
+ *
+ *  @return 缓冲进度
+ */
+- (NSTimeInterval)availableDuration {
+    NSArray *loadedTimeRanges = [[_player currentItem] loadedTimeRanges];
+    CMTimeRange timeRange     = [loadedTimeRanges.firstObject CMTimeRangeValue];// 获取缓冲区域
+    CGFloat startSeconds        = CMTimeGetSeconds(timeRange.start);
+    CGFloat durationSeconds     = CMTimeGetSeconds(timeRange.duration);
+    CGFloat result = startSeconds + durationSeconds;// 计算缓冲总进度
+    return result;
+}
+#pragma mark---移除媒体加载状态的监听
+-(void)removeAVPlayerObserver
+{
+    [_songItem removeObserver:self forKeyPath:@"status"];
+}
+#pragma mark---移除数据加载状态的监听
+-(void)removeNetDataObserver
+{
+    [_songItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
+}
+#pragma mark----播放完成后发送通知
+-(void)addPlayToEndObserver
+{
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:_songItem];
+}
+#pragma mark ---- 异常通知
+- (void)addExceptionObserver {
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerError:) name:AVPlayerItemFailedToPlayToEndTimeNotification object:_songItem];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerError:) name:AVPlayerItemPlaybackStalledNotification object:_songItem];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerError:) name:AVPlayerItemPlaybackStalledNotification object:_songItem];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerError:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerError:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]];
+}
+
+-(void)playerError:(NSNotification *)notice {
+    //移除所有监听
+    dispatch_main_sync_safe(^{
+        if ([notice.name isEqualToString:AVAudioSessionRouteChangeNotification]) {
+            NSDictionary *info = notice.userInfo;
+            AVAudioSessionRouteChangeReason routeChangeReason = [[info valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
+            if (routeChangeReason == AVAudioSessionRouteChangeReasonCategoryChange) {
+                return;
+            }
+        }
+        if ([self.delegate respondsToSelector:@selector(playerDidError:)]) {
+            [self.delegate playerDidError:self];
+        }
+    });
+}
+
+#pragma mark---通知的方法
+-(void)playFinished:(NSNotification *)notice
+{
+    //移除所有监听
+    _isPlaying = NO;
+    dispatch_main_sync_safe(^{
+        if ([notice.name isEqualToString:AVAudioSessionRouteChangeNotification]) {
+            NSDictionary *info = notice.userInfo;
+            AVAudioSessionRouteChangeReason routeChangeReason = [[info valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
+            if (routeChangeReason == AVAudioSessionRouteChangeReasonCategoryChange) {
+                return;
+            }
+        }
+        if ([self.delegate respondsToSelector:@selector(playFinished:)]) {
+            [self.delegate playFinished:self];
+        }
+    });
+}
+
+#pragma mark----移除通知
+- (void)removePlayToEndNotice
+{
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+#pragma mark-----移除所有监听
+-(void)removeAllNoticeAndObserver
+{
+    if (self.hasFreeObserver) {
+        return;
+    }
+    self.hasFreeObserver = YES;
+    //移除时间进度的监听
+    [self removeTimeObserver];
+    //移除播放完成的通知
+    [self removePlayToEndNotice];
+    //移除播放器状态的监听
+    [self removeAVPlayerObserver];
+    //移除数据缓存的监听
+    [self removeNetDataObserver];
+}
+
+- (void)dealloc {
+    NSLog(@" -------- player dealloc ");
+}
+
+/*
+ // Only override drawRect: if you perform custom drawing.
+ // An empty implementation adversely affects performance during animation.
+ - (void)drawRect:(CGRect)rect {
+ // Drawing code
+ }
+ */
+
+@end

+ 3 - 2
KulexiuForStudent/KulexiuForStudent/Common/Tools/UMShare/KSUMShareManager.h

@@ -10,6 +10,7 @@
 typedef NS_ENUM(NSInteger, KSSHARETYPE) {
     KSSHARETYPE_IMAGE,  // 图片
     KSSHARETYPE_VODEO,  // 视频
+    KSSHARETYPE_URL,    // 链接
 };
 
 typedef void(^KSShareActionCallback)(BOOL isSuccess, NSString * _Nonnull descMessage);
@@ -24,9 +25,9 @@ NS_ASSUME_NONNULL_BEGIN
 
 + (instancetype)shareInstanceShowWithImage:(UIImage *)image showSaveLink:(BOOL)showSaveLink saveLinkUrl:(NSString *)saveLinkUrl url:(NSString *)url shareTitle:(NSString *)shareTitle descMessage:(NSString *)descMessage shareType:(KSSHARETYPE)type showInView:(UIViewController *)ctrl callback:(KSShareActionCallback)callback;
 
-+ (instancetype)shareInstanceToWechatWithImage:(UIImage *)image url:(NSString *)url shareTitle:(NSString *)shareTitle descMessage:(NSString *)descMessage shareType:(KSSHARETYPE)type  callback:(KSShareActionCallback)callback;
++ (instancetype)shareInstanceToWechatWithImage:(UIImage *)image url:(NSString *)url shareTitle:(NSString *)shareTitle descMessage:(NSString *)descMessage shareType:(KSSHARETYPE)type thumImage:(_Nullable id)thumImage  callback:(KSShareActionCallback)callback;
 
-+ (instancetype)shareInstanceToWechatCircleWithImage:(UIImage *)image url:(NSString *)url shareTitle:(NSString *)shareTitle descMessage:(NSString *)descMessage shareType:(KSSHARETYPE)type  callback:(KSShareActionCallback)callback;
++ (instancetype)shareInstanceToWechatCircleWithImage:(UIImage *)image url:(NSString *)url shareTitle:(NSString *)shareTitle descMessage:(NSString *)descMessage shareType:(KSSHARETYPE)type thumImage:(_Nullable id)thumImage callback:(KSShareActionCallback)callback;
 @end
 
 NS_ASSUME_NONNULL_END

+ 17 - 8
KulexiuForStudent/KulexiuForStudent/Common/Tools/UMShare/KSUMShareManager.m

@@ -29,6 +29,9 @@
 
 @property (nonatomic, strong) NSString *saveLinkUrl;
 
+@property (nonatomic, strong) id thumImage;
+
+
 @end
 
 @implementation KSUMShareManager
@@ -162,13 +165,15 @@
     return [NSObject getKeyWindow];
 }
 
-+ (instancetype)shareInstanceToWechatWithImage:(UIImage *)image url:(NSString *)url shareTitle:(NSString *)shareTitle descMessage:(NSString *)descMessage shareType:(KSSHARETYPE)type  callback:(KSShareActionCallback)callback {
++ (instancetype)shareInstanceToWechatWithImage:(UIImage *)image url:(NSString *)url shareTitle:(NSString *)shareTitle descMessage:(NSString *)descMessage shareType:(KSSHARETYPE)type thumImage:(_Nullable id)thumImage callback:(KSShareActionCallback)callback {
     KSUMShareManager *manager = [[self alloc] init];
     manager.shareType = type;
     manager.shareImage = image;
     manager.shareUrl = url;
     manager.shareTitle = shareTitle;
     manager.shareMessage = descMessage;
+    manager.thumImage = thumImage;
+
     if (callback) {
         manager.callback = callback;
     }
@@ -176,13 +181,15 @@
     return manager;
 }
 
-+ (instancetype)shareInstanceToWechatCircleWithImage:(UIImage *)image url:(NSString *)url shareTitle:(NSString *)shareTitle descMessage:(NSString *)descMessage shareType:(KSSHARETYPE)type  callback:(KSShareActionCallback)callback {
++ (instancetype)shareInstanceToWechatCircleWithImage:(UIImage *)image url:(NSString *)url shareTitle:(NSString *)shareTitle descMessage:(NSString *)descMessage shareType:(KSSHARETYPE)type thumImage:(_Nullable id)thumImage callback:(KSShareActionCallback)callback {
     KSUMShareManager *manager = [[self alloc] init];
     manager.shareType = type;
     manager.shareImage = image;
     manager.shareUrl = url;
     manager.shareTitle = shareTitle;
     manager.shareMessage = descMessage;
+    manager.thumImage = thumImage;
+    
     if (callback) {
         manager.callback = callback;
     }
@@ -217,9 +224,10 @@
         //分享消息对象设置分享内容对象
         messageObject.shareObject = shareObj;
     }
-    else if (self.shareType == KSSHARETYPE_VODEO) {
-        UMShareWebpageObject *shareObj = [UMShareWebpageObject shareObjectWithTitle:shareTitle descr:descMessage thumImage:[UIImage imageNamed:@"shareImage"]];
-        //            NSString *shareUrl = [self.shareUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
+    else if (self.shareType == KSSHARETYPE_VODEO || self.shareType == KSSHARETYPE_URL) {
+        id thumImage = self.thumImage == nil ? [UIImage imageNamed:@"shareImage"] : self.thumImage;
+
+        UMShareWebpageObject *shareObj = [UMShareWebpageObject shareObjectWithTitle:shareTitle descr:descMessage thumImage:thumImage];
         shareObj.webpageUrl = self.shareUrl;
         //分享消息对象设置分享内容对象
         messageObject.shareObject = shareObj;
@@ -275,9 +283,10 @@
         //分享消息对象设置分享内容对象
         messageObject.shareObject = shareObj;
     }
-    else if (self.shareType == KSSHARETYPE_VODEO) {
-        UMShareWebpageObject *shareObj = [UMShareWebpageObject shareObjectWithTitle:shareTitle descr:descMessage thumImage:[UIImage imageNamed:@"shareImage"]];
-        //            NSString *shareUrl = [self.shareUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
+    else if (self.shareType == KSSHARETYPE_VODEO || self.shareType == KSSHARETYPE_URL) {
+        id thumImage = self.thumImage == nil ? [UIImage imageNamed:@"shareImage"] : self.thumImage;
+
+        UMShareWebpageObject *shareObj = [UMShareWebpageObject shareObjectWithTitle:shareTitle descr:descMessage thumImage:thumImage];
         shareObj.webpageUrl = self.shareUrl;
         //分享消息对象设置分享内容对象
         messageObject.shareObject = shareObj;

+ 2 - 2
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Home/Controller/TenantMoreViewController.m

@@ -434,11 +434,11 @@
     if (![NSString isEmptyString:model.linkUrl]) {
         if ([model.linkType isEqualToString:@"OUT"]) {
             // 外部浏览器打开
-            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:model.linkUrl] options: @{} completionHandler: nil];
+            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[model.linkUrl getUrlEndcodeString]] options: @{} completionHandler: nil];
         }
         else {
             KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
-            webCtrl.url = model.linkUrl;
+            webCtrl.url = [model.linkUrl getUrlEndcodeString];
             [self.navigationController pushViewController:webCtrl animated:YES];
         }
     }

+ 1 - 1
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/Controller/TenantNotiferCenterController.m

@@ -202,7 +202,7 @@
             NSString *webUrl = [dict ks_stringValueForKey:@"url"];
             if (![NSString isEmptyString:webUrl]) {
                 KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
-                webCtrl.url = webUrl;
+                webCtrl.url = [webUrl getUrlEndcodeString];
                 CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
                 [navCtrl pushViewController:webCtrl animated:YES];
             }

+ 5 - 5
KulexiuForStudent/KulexiuForStudent/Module/Home/Controller/HomeViewController.m

@@ -905,7 +905,7 @@
         if (isSure) {
             if (![NSString isEmptyString:linkUrl]) {
                 KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
-                webCtrl.url = linkUrl;
+                webCtrl.url = [linkUrl getUrlEndcodeString];
                 [weakSelf.navigationController pushViewController:webCtrl animated:YES];
             }
         }
@@ -1081,7 +1081,7 @@
             }
             else {
                 KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
-                webCtrl.url = model.linkUrl;
+                webCtrl.url = [model.linkUrl getUrlEndcodeString];
                 [self.navigationController pushViewController:webCtrl animated:YES];
             }
             
@@ -1321,11 +1321,11 @@
     if (![NSString isEmptyString:model.linkUrl]) {
         if ([model.linkType isEqualToString:@"OUT"]) {
             // 外部浏览器打开
-            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:model.linkUrl] options: @{} completionHandler: nil];
+            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[model.linkUrl getUrlEndcodeString]] options: @{} completionHandler: nil];
         }
         else {
             KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
-            webCtrl.url = model.linkUrl;
+            webCtrl.url = [model.linkUrl getUrlEndcodeString];
             [self.navigationController pushViewController:webCtrl animated:YES];
         }
     }
@@ -2191,7 +2191,7 @@
     NSString *linkUrl = self.buttonModel.linkUrl;
     if ([self.buttonModel.linkType isEqualToString:@"OUT"]) {
         // 外部浏览器打开
-        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:linkUrl] options: @{} completionHandler: nil];
+        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[linkUrl getUrlEndcodeString]] options: @{} completionHandler: nil];
     }
     else {
         if (![NSString isEmptyString:linkUrl]) {

+ 1 - 1
KulexiuForStudent/KulexiuForStudent/Module/Home/NoticeCenter/Controller/NotiferMessageViewController.m

@@ -266,7 +266,7 @@
                 NSString *webUrl = [dict ks_stringValueForKey:@"url"];
                 if (![NSString isEmptyString:webUrl]) {
                     KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
-                    webCtrl.url = webUrl;
+                    webCtrl.url = [webUrl getUrlEndcodeString];
                     CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
                     [navCtrl pushViewController:webCtrl animated:YES];
                 }

+ 1 - 1
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomePageView/HomeInformationBodyView.m

@@ -142,7 +142,7 @@
     
     if ([model.linkType isEqualToString:@"OUT"]) {
         // 外部浏览器打开
-        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:model.linkUrl] options: @{} completionHandler: nil];
+        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[model.linkUrl getUrlEndcodeString]] options: @{} completionHandler: nil];
     }
     else {
         // 跳转

+ 4 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Scan/Controller/KSScanViewController.m

@@ -106,6 +106,7 @@
     if (result) {
         [self stopScan];
         if ([result containsString:hostURL]) {
+            result = [result getUrlEndcodeString];
             KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
             webCtrl.url = result;
             [self.navigationController pushViewController:webCtrl animated:YES];
@@ -114,6 +115,9 @@
             [self backPreView];
         }
     }
+    else {
+        [self backPreView];
+    }
 }
 
 - (void)backPreView {

+ 47 - 0
KulexiuForStudent/KulexiuForStudent/PrivacyInfo.xcprivacy

@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+    <key>NSPrivacyTracking</key>
+    <true/>
+    <key>NSPrivacyCollectedDataTypes</key>
+    <array/>
+    <key>NSPrivacyTrackingDomains</key>
+    <array/>
+    <key>NSPrivacyAccessedAPITypes</key>
+    <array>
+        <dict>
+            <key>NSPrivacyAccessedAPIType</key>
+            <string>NSPrivacyAccessedAPICategorySystemBootTime</string>
+            <key>NSPrivacyAccessedAPITypeReasons</key>
+            <array>
+                <string>35F9.1</string>
+            </array>
+        </dict>
+        <dict>
+            <key>NSPrivacyAccessedAPIType</key>
+            <string>NSPrivacyAccessedAPICategoryDiskSpace</string>
+            <key>NSPrivacyAccessedAPITypeReasons</key>
+            <array>
+                <string>E174.1</string>
+            </array>
+        </dict>
+        <dict>
+            <key>NSPrivacyAccessedAPIType</key>
+            <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
+            <key>NSPrivacyAccessedAPITypeReasons</key>
+            <array>
+                <string>C617.1</string>
+            </array>
+        </dict>
+        <dict>
+            <key>NSPrivacyAccessedAPIType</key>
+            <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
+            <key>NSPrivacyAccessedAPITypeReasons</key>
+            <array>
+                <string>CA92.1</string>
+            </array>
+        </dict>
+    </array>
+</dict>
+</plist>

BIN
KulexiuForStudent/KulexiuForStudent/SoundFontFile/shareImage@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/SoundFontFile/synthgms.sf2


+ 2 - 0
KulexiuForStudent/KulexiuForStudent/ToolKit/KSToolLibrary.framework/Headers/NSString+Extension.h

@@ -33,6 +33,8 @@ typedef NS_ENUM(NSInteger,CHECKTYPE){
 - (NSString *)dateFormatString; // 返回年月日 传入格式 YYYY-MM-dd hh:mm:ss
 // url encoding
 - (NSString *)getUrlEndcodeString;
+// 移除endcodeing
+- (NSString *)removeUrlEndcodeString;
 // 获取保存文件名
 - (NSString *)getUrlFileName;
 /**

+ 85 - 0
KulexiuForStudent/Pods/Pods.xcodeproj/xcuserdata/wangzhi.xcuserdatad/xcschemes/xcschememanagement.plist

@@ -8,171 +8,246 @@
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>1</integer>
 		</dict>
 		<key>AlipaySDK-iOS.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>2</integer>
 		</dict>
 		<key>Bugly.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>3</integer>
 		</dict>
 		<key>CHIPageControl.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>4</integer>
 		</dict>
 		<key>IQKeyboardManager.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>6</integer>
 		</dict>
 		<key>JCore.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>7</integer>
 		</dict>
 		<key>JPush.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>8</integer>
 		</dict>
 		<key>JXCategoryView.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>9</integer>
 		</dict>
 		<key>JXPagingView.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>10</integer>
 		</dict>
 		<key>MBProgressHUD.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>13</integer>
 		</dict>
 		<key>MJExtension.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>14</integer>
 		</dict>
 		<key>MJRefresh.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>15</integer>
 		</dict>
 		<key>Masonry.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>12</integer>
 		</dict>
 		<key>NTLBridge.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>16</integer>
 		</dict>
 		<key>Pods-KulexiuForStudent-KulexiuForStudentUITests.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>18</integer>
 		</dict>
 		<key>Pods-KulexiuForStudent.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>17</integer>
 		</dict>
 		<key>Pods-KulexiuForStudentTests.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>19</integer>
 		</dict>
 		<key>QCloudCOSXML.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>21</integer>
 		</dict>
 		<key>QCloudCore.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>20</integer>
 		</dict>
 		<key>RSKImageCropper.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>24</integer>
 		</dict>
 		<key>Reachability.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>22</integer>
 		</dict>
 		<key>ReactiveObjC.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>23</integer>
 		</dict>
 		<key>SDWebImage.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>25</integer>
 		</dict>
 		<key>SSZipArchive.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>27</integer>
 		</dict>
 		<key>SocketRocket.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>26</integer>
 		</dict>
 		<key>TIMCommon.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>28</integer>
 		</dict>
 		<key>TUIChat.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>29</integer>
 		</dict>
 		<key>TUIConversation.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>30</integer>
 		</dict>
 		<key>TUICore.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>31</integer>
 		</dict>
 		<key>TUIGroup.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>32</integer>
 		</dict>
 		<key>TUISearch.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>33</integer>
 		</dict>
 		<key>TXIMSDK_Plus_iOS.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>34</integer>
 		</dict>
 		<key>TXLiteAVSDK_Professional.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>35</integer>
 		</dict>
 		<key>TYCyclePagerView.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>36</integer>
+		</dict>
+		<key>TZImagePickerController.xcscheme</key>
+		<dict>
+			<key>isShown</key>
+			<false/>
+			<key>orderHint</key>
+			<integer>37</integer>
 		</dict>
 		<key>TZImagePickerController.xcscheme</key>
 		<dict>
@@ -183,26 +258,36 @@
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>39</integer>
 		</dict>
 		<key>Whiteboard.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>38</integer>
 		</dict>
 		<key>YYModel.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>40</integer>
 		</dict>
 		<key>iOS-KS3SDK.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>5</integer>
 		</dict>
 		<key>lottie-ios.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>11</integer>
 		</dict>
 	</dict>
 	<key>SuppressBuildableAutocreation</key>