From 475a5d56c4cc4420d869c3c8ef0ff3cff2c2e122 Mon Sep 17 00:00:00 2001 From: "Mr.zhou" <1422157428@qq.com> Date: Fri, 31 May 2024 21:50:46 +0800 Subject: [PATCH] =?UTF-8?q?b=E9=9D=A2=E6=AD=A3=E5=BC=8F=E7=89=88-1.0.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MusicPlayer.xcodeproj/project.pbxproj | 6 +- .../placeholder.imageset/Contents.json | 22 ++ ...9660da3e-8f28-4628-863b-00379a5887ag 1.png | Bin 0 -> 11405 bytes ...d_9660da3e-8f28-4628-863b-00379a5887ag.png | Bin 0 -> 11405 bytes MusicPlayer/Info.plist | 5 +- .../Controllers/MP_LunchViewController.swift | 2 - .../Common/Macro(宏定义与全局量)/Macro.swift | 9 +- .../Tool(工具封装)/MP_LocationManager.swift | 314 +++++++++--------- .../Tool(工具封装)/MP_NetWorkManager.swift | 191 ++++++----- .../Tool(工具封装)/MP_PlayerManager.swift | 16 +- .../MPPositive_JsonBrowse.swift | 40 +++ .../MPPositive_PlayerLoadViewModel.swift | 7 +- .../MPPositive_MoreSongOperationsViewController.swift | 8 +- .../MPPositive_LoveSongsViewController.swift | 6 + .../MPPositive_HomeViewController.swift | 1 + .../MPPositive_PlayerViewController.swift | 29 +- .../MPPositive_RecommendViewController.swift | 6 +- .../Player/MPPositive_PlayerCoverView.swift | 4 +- .../MPSideA_AboutViewController.xib | 4 +- 19 files changed, 390 insertions(+), 280 deletions(-) create mode 100644 MusicPlayer/Assets.xcassets/placeholder.imageset/Contents.json create mode 100644 MusicPlayer/Assets.xcassets/placeholder.imageset/img_v3_02bd_9660da3e-8f28-4628-863b-00379a5887ag 1.png create mode 100644 MusicPlayer/Assets.xcassets/placeholder.imageset/img_v3_02bd_9660da3e-8f28-4628-863b-00379a5887ag.png diff --git a/MusicPlayer.xcodeproj/project.pbxproj b/MusicPlayer.xcodeproj/project.pbxproj index cbea268..77ed83a 100644 --- a/MusicPlayer.xcodeproj/project.pbxproj +++ b/MusicPlayer.xcodeproj/project.pbxproj @@ -1554,11 +1554,10 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = MusicPlayer/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Musiclax; - INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "\"Musiclax\" needs to obtain your location information in order to refine the preview music information provided to you!"; - INFOPLIST_KEY_NSLocationAlwaysUsageDescription = "\"Musiclax\" needs to obtain your location information in order to refine the preview music information provided to you!"; INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "\"Musiclax\" needs to obtain your location information in order to refine the preview music information provided to you!"; INFOPLIST_KEY_NSMicrophoneUsageDescription = "\"Musiclax\" requires you to turn on the microphone to recognize surrounding decibels and automatically turn on white noise for you. Do you allow this application to obtain your microphone permissions?"; INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "\"Musiclax\" requires opening your album to obtain photos, which are used to add your custom white noise. Do you want to allow this application to obtain your album permissions?"; + INFOPLIST_KEY_NSUserTrackingUsageDescription = "\"Musiclax\" needs to request tracking permissions to provide a personalized advertising experience. We respect and protect your privacy and will not sell your data to third parties."; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UIMainStoryboardFile = Main; @@ -1598,11 +1597,10 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = MusicPlayer/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Musiclax; - INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "\"Musiclax\" needs to obtain your location information in order to refine the preview music information provided to you!"; - INFOPLIST_KEY_NSLocationAlwaysUsageDescription = "\"Musiclax\" needs to obtain your location information in order to refine the preview music information provided to you!"; INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "\"Musiclax\" needs to obtain your location information in order to refine the preview music information provided to you!"; INFOPLIST_KEY_NSMicrophoneUsageDescription = "\"Musiclax\" requires you to turn on the microphone to recognize surrounding decibels and automatically turn on white noise for you. Do you allow this application to obtain your microphone permissions?"; INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "\"Musiclax\" requires opening your album to obtain photos, which are used to add your custom white noise. Do you want to allow this application to obtain your album permissions?"; + INFOPLIST_KEY_NSUserTrackingUsageDescription = "\"Musiclax\" needs to request tracking permissions to provide a personalized advertising experience. We respect and protect your privacy and will not sell your data to third parties."; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UIMainStoryboardFile = Main; diff --git a/MusicPlayer/Assets.xcassets/placeholder.imageset/Contents.json b/MusicPlayer/Assets.xcassets/placeholder.imageset/Contents.json new file mode 100644 index 0000000..1617ccb --- /dev/null +++ b/MusicPlayer/Assets.xcassets/placeholder.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "img_v3_02bd_9660da3e-8f28-4628-863b-00379a5887ag 1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "img_v3_02bd_9660da3e-8f28-4628-863b-00379a5887ag.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MusicPlayer/Assets.xcassets/placeholder.imageset/img_v3_02bd_9660da3e-8f28-4628-863b-00379a5887ag 1.png b/MusicPlayer/Assets.xcassets/placeholder.imageset/img_v3_02bd_9660da3e-8f28-4628-863b-00379a5887ag 1.png new file mode 100644 index 0000000000000000000000000000000000000000..4f84b371554ebea68274727125e43d5bc89e23b4 GIT binary patch literal 11405 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 BmM;JR literal 0 HcmV?d00001 diff --git a/MusicPlayer/Assets.xcassets/placeholder.imageset/img_v3_02bd_9660da3e-8f28-4628-863b-00379a5887ag.png b/MusicPlayer/Assets.xcassets/placeholder.imageset/img_v3_02bd_9660da3e-8f28-4628-863b-00379a5887ag.png new file mode 100644 index 0000000000000000000000000000000000000000..4f84b371554ebea68274727125e43d5bc89e23b4 GIT binary patch literal 11405 zcmeIYZi7RD4ueCG5S$P^I0Oa>lHhJ31PK~^ z=d-`s+J9j8-S}>T0VH;?d%vpr8<{sVeHDpr8i+*Kp8~nwheK zkI07r7X<}fHw6_1FLy6r18-Y4<|S7WFvR?101wCY2xa5e_aQUk{>NzAZ|2>YVCe1RO{|DbvQ{9@-R>N; zo@=wM>KNKAZ@L5*W`br}Hf>9OnRV&-aH zC&5gs>kaXej%Dr?F!xOnnnA?l>mS8qaN5U>dAU>?%FXwQ*&fNb>+CN<&fMEIo85@f z=s94qL{YXw!M_~SSv*&0yBeTM;xZIFHwjYL8nd`w{KF)7nEtokge@5db&{@L6b9y2 z#KT;gOd6lBiH$BW9Stz9s76B8JaqBB)Rq+NgCqC*UAx~=I8ojGn1{zH1Hihp@o z9$l=kH1o&Gau5bJEsE!FO<_Zo-=)|4zJ2$&0x&e_DOZc_{s41eNCd&JkgW%Mf-?rR zH`x~rtW(Fdam7)*kJwb)uH6P$atP#q5QCViIcjO4@E~Oz6x4VZ6bz(% zzK_-0C)melZ(aN$B;4oCR0P#Yy2Q!$>g$x}kcf~#ncl*%o!*=DUN5K9hEvOngox3^ zfUt3#1c>(ME9NxBkp|A*_W8rkhWjTmI=7ku2-FRiT@3k4x#6+&IIvVfLkM{|8&>k)*$mUPkU zjn@|kTKNlA3l4ADof(ml>)u1?6Z3=bMVs4Gp;prh_WI}Gh%OG*2le@phRG$50BuX3 zrU{^g?C1m7lc;@vKRKU?Y$3&VX|2`N(MjtK3sRjO<%UCqh^J+3$#rX*ureR#yBL*W zacrVX6*cldD;*Nf-+qf@YnP``(*2cSKfMH2bD$z;v4_C|ld}jcdb45Hy7-^BSZ7y?MCWyPZDxF~C+Lj%Jtlo0y7f z)A9qqC?JYEhuHCQVq1jl$7+9q@DSYUXLq-x7=`4F<+`l+pAX9^K(DWsWYpmg)0rvo z#?t)G76_4Nja`VzNS;81lclF12Q$@nrPs8l*X7oD-8QM73GEgAuM>UdGkeS&6c!O26ved2bn?c$ z&QYI6Smw;*TpciH+#;|mU@PEYTr;dX!e`eS&bmu#JW3-*l;&9tpldLmDvVlrlsVZn zz<@#yr+kp9iJt0Nr^0KSeTxjV_~tVaj?rz%?cHy?&cMAWI*v_C*u(kuVY(jE9a-O< z4?S|1kM>Ie0(x>kON7(JM7mr&T;1Lt(O3=^gf-E{;VZ+;n72S*RC*~9^gXx*Xl*iU z^?4f0!o8ZbkzB$NZtYmm&ilRVzr8x`sbpJs!Q@DTDp8LrrJ5#w+j2fkm7L+XsN+j{ z2ehK^pDT6&_*9j*S0{%N)8A;4e_ZJy6DU3A^=aH)n`d6&re(_d&DExY92v2eoI6Z_ z@bdBDN}l&7ZE09$9Qpk^+@HDxg4_U7mp4z&3YyFYnxw{eS(t9HU1b`QNhqH_lRCfv zWf{vXiF^OPTB50Z7YiG&eoV<)F*A8_|8N+buK=es)dW@94=BoAz94_UX31!vNH%<7 zBRUMmj=2kwgOK~dIW!kVHqXxP?fb8RBw9H8{U-^K7g(*l)hTu`RThzc6p8BkI!a}s zq=3MZ_aWragnd&jo}5?o=MeIk+{?@ODN&dRS>qXVmF20LqTujfre4uSst{tSKSbLt+b7@Gp6u89tUix zOUlXm9Hq>zf5!jZ7M!)j_S+ca1v8c}n*;Z4p^z z;O7i{C|OR+5Vi81zJxmKx|g}$%lN(Kw8Dx9F|WkeXF%=pc>2K7$6K%(a`fItNsN1T zm+n|uV#8%tgzkGl+26D}G$C8;#ouYBj=XF#W42G*bEm_MCx&g}918u3e$LVNXHUPs z@^!e$pq0Jql@xrbd9kHxwd27jlJ%031vyy^PiDHW8B*2#v+JurKH)17rAu$ahin{U zx)jubs|)a#*0%#}pYOxA`(gu$?I}e(TX7BNcen(Qhe?edG%f=7{+ zaP$&rB~N}+fdlkv(v`b^iua&)Y5_l6_>xf<5~nST(t=ms@{%X1Gz!E9y^?vj{-%1w z-JHMT{$1SAZ7fd8*9WmOYd#3@u;IiPS|i+mkB_%)-EVDZ1=wvzB1T2JKxp9zPt-6ZCKAKkJyK zRwo%nHoaA-+=$=twP5v}1|PmxR)D5`%{G&(4NSB1CVXHHsrtjBv?4s{HU7+|@mX;V z1NDf`)P|4Arl2>{+E*tapV!}3JW)8D4#>e#|L19EBb{#<|AHS7-gSTP;g7reg=f;% zuH*EP15xRbCrBxo>M{gYE^*AfJrTPPx{Pe^Q&*P z)2hwKM{aYrzfaHpuR^Szpi0(iq){mWKi+0iFGXjplh<~vOOV~^XIsZt8`zylX$vQq@CG}-IS86NFVEW#`PsgGw zePgt^VjS!w;v&&B!9$&Dpdki63S-v+>1CFt*mWOJq<*MHgAnD({drorJVNC_yT0;h z!&c?_&6UHAo%`feXnqI3;ZCpC?l$2Dg&N9&2wo!IR5jLmo-9u0ed^-n!?apDd2iLF zzkTQ+YL1#u4c6qbeH**DuTLPUq#E7JWgB-MFVQ_M5mJG^rrQ;VABeK}B3;(1dS;7J zN&I9hd(kCvq@BNtx3-okg}Bg=1qP=$fe3PntAy1jLTlUQ+GP+)!M~>d4V(OQok|aY*8Y(P7(~-mMzNpZQ`OS9`F$nbg$TW0O=`cr@--}KB#|!EGsiXc zIEb>y1Sk-aqg&0T*yWL40v<^_jtKL9p-Beyw|5g#ar5*q&|oPJW=oo)S!)DWOUqR| z)Z$eg-cILSu4e<`_B<}Yy8?DP+ZP(m9YWrUVySU6wgjB~x&%8(u(TDRH|^itSFs)G z3oc8RP(7E>RzOxjbNUc?Nh`f8i=dpv{}JPj{|m$~UO62b=W0?Pp~gLfH`L@`e*_iPdHqg7^Y}K zVZj3ar*10-ZTlR?D*uu)tm4ar5USTdv|sp8o>mgXZa*#12KS@iZzIx4`3)UNk}?k&l!tMyMgT)eQ^X?34MOJgH_g5H^frd<5D}x zeh<*s7<7^DD#1^HfMr{{M}rvaamQmf`dTqK%Kh{m=4ZQ7eg+7}xQL{G#cEc6)jwpO zojdc3GN-AV=pbq6HJ(IMTuT{r0$Q9)NB*XA^_FG}_gmKD9Qk`v4)6;S`}otKW?3NiCsPlKQ!yQ zrO+F7alNaLZ%zdu@^@h^i70QMdx_`^(}{_&|Cyhv89XMWLA5(Ck8EnP+y znNYc3ahFn3+toV`0e9X+nLkzqqD)8d9NRbfCd@QJ2}$Ql`ZlWA)COw!T=T0N{TiLm zd%&78%bckbi|wV-u_YRue3Po=>b3pqAq?}8b=pAgETUlme#*4klC}o!C$1#aOh{jE zOimFx&WzNdgdL6Bg&$HS$xp}R~DodRYXfdD@0xE?Q4 zu74klku_Kz~_>|~Dm zu*?`mPK#o>ktuLdkuy$6j#}!skRnU!>@RMd`Z{-2rjCexe#bnnIQESkW>9wBPg}v8 z94>c0-r$<#{J`f!sL~jEitNqR1`#BwUAds13#P74D=|k<^=RQk<946F4Tfs<%$%1E z9La6h$lJcuF;yY;W631RK9N30QzjiOlM=Q+SO`C8Ip~wngF&hHsi}(kd za+E1&Kn5fcW&@Y2E|c$Y6TyeQiotS<#2zQ*tKnia#p7TZXt&t z_=IrIW`o5FBQYuDb7e6Pse)ADQD(wSy4PWe#-dgELuUcfqw`q6H!HJlgCt;1zAzaP z-;s`iG%HyUnTkE&*>pjVAXloy&Nuz%3=1EI43D~~6tYO-cq>mm+Io3)Rl}dYesxa7 z%B-%*56BGzAK9 zEM_^Ir(II57zL2)5MK=Aq_6RBe7Hz$Pi5~Xk7HBLciMnCXI4&JUI!XiQbw-}qlY(r z{iH@>hJ0+}Y!py4;`|8;$~uW`OGpct8t}_ILZc6qT*@Zw@2xAmiq?W=((RKB(^uby6Zs?@<)QLnqAz zt7d21mJ~EeKE@Uo3Hoya$cixkax0w0_>$;1SSdv15Y^lcZJ`bCDqrB@d~50^#aiQ_ zVs_FZt<7RoKYB`&E z>u^r#sD%|&W7t6&Uk2Y~Q%JA1>RHMu$6bBOIpXPJI4kSo^9kz%Oo*PP_%STt!hb}b zbF8dDSS{1gCBsT)82nROcC@v72(UJ9{(<@Ryi4cpN-OhG72CJqJA3;wRG_qs4gJ}s z$SXto$L~BY*|9!czF{>MQ|SWl==Xsy?qbWdchgKc%1e7`q+{(s9fC=k>=1(ZjZcux zID3BfLxSEh&p@^cIS^5=496?GcQNHuP?On{*@K<%p3l1zH@eP2wl303U}jH5;1C$` zFZ8YJ;n$qpEzZ(U5wWE-ij*+H-M3G7-MBNdz%;vw{4i;PJf@TT>z8%Q)Q!J7ehq&i zASVN_wTne~R80w-x~!8R96ondgiuhE(9jNLfU5_5j2x$!UX}$voMu*3f?lsmW%cVd z8xWX@ZAo4VWkLyP21^Jk=)#1mjt-vX8Kh+bdka=9X)kdr3coS@m)_!$*-2AJ${U56 zp$zNW@rKv9P=9nJ2aFEStt~VjRn?mlp(oFj5XXTllxz77I}_S%vsKw)9$P?BIbk;~ zaQ}aXBq5a&l{N7_;ng5c_pNW{ya+r}ZmO0n|7FU>_cQ*7?O7QIzqvL3w$c|E`5D*q zKi1~QX7$pAVrnez9B(I=n%gbQ{&L4WAY@KB6Z7as z1e#zrnJG_I2ekEt&jB%8n^O%me^}|UNgENU<*Z{kdbg{)_p7B+(L(fX9e}6sd9JqF58q5uCfp5FPN%{&AV)$DbWPrH%4eK_x}>@+zT}k9bVt-z1&ZY-IVrY@PiYV*EW=OVPw6A^Z-&A6n~E>v2E{Ud z{Q+3oP-=ZS*20qY$K~I-eah{sOu)*fzbVwwc|@~9RB~=A4Pf*L`&cWQ0lo{%6(@e- zyz*N%srU+ZIVj(3(EjunziwNb-QkB1TjFDPo3)V({G zk6j3IDE*8adCr)pn}$iUcC%xyVHRpH_jpW^bD4ctb-{opJ~_IKvT$)0IUzOO!2m}Y zv^eLLdnFa$Z$fYY2#KK3lr&mVZ{%Tyl-JRIn4RSN6ytnmkftgGBe;2PPv+UY7X7fF zT`d}1j%uG=+=`MvJShC-UY?utUKNnJb_u(r{IpK0H33}7L2a9=`rSlu->TJ zA9KfqRCGQbUY{JO09vJQ~8fhREA>Y0&RqvLEM-gbcrOSiWA;pN`Ov4wf}ewkLsMI z#~~@-{s%exGq6g?yz*;4gez4-SJOFEuRj~E^14wMHTjBmf0iLV(zLRXv$2?c3``)P zynIodID8&QyVwkRvGnyDF<}@Xzs-cODdmSY+#)SZz|e=XgW;45S&tm=hUsWIa^bEs zyiu@ULn?IQEf8T;+j41_H-H7vW)oimk&Ge=vQ&hezQ@mkXukIFF^KPUK!+Bc0bcf& z{bHG&fah4t#x+x}EH>-PSX=B67&nfO1S(lB!4xq4TaNgxv3HdrL2?xd{x zi0L=7Ks<B~hiF~0LiMW7YCDN`p2 z>eZjh@48)MNYKOiaxN}rHoWYYJu3FsYX8N$EewW10+!3GJ)m7i?ZWiGbI-m znR}QR)~&JvR{6);yK!Mph%#$TVpxQq#e9s#`jzcvs~8mo1(4k=`a-n(eQe z@|>KB`|6{<{c#R1xVsjzK&wA!!%U%>w$tZm>Up1ry*HTc&l2J>qdzz({#6O^KB11))bPXLq&lDc_O&)X8O`)B!8k~;9M=TBEFI_py_F>$-GpAxkquHNW6J`i})FlX5 zynZ2UXAUWI`ga~k-f|cLqjqmhO7bTcYO3}~3j_Z2Anp|`T&qaX)YgE{PJLC@?8tVG z?Te4|6?VE!C%v<0_bPfaZ7mK0cv~+J{M%Dfo=6zvr^B*7{z|F}&TQqETv;#%v_R-U zA~+yZwr$bBQ$y3uY$vRQ*U5rh`Ylfr3DboZme3e{zEKecrHZZcQrXM*o|OLw{>}Ky z>gp^`5@e_fHlGI2ObjX0}8FWh#m1=;zE4KZ5G}6<*-U3L((0KBFKRDpY3; zvjpR9(Y5EdZCSq>oVx9$W*!3UZ=Q8hSGD8v@drBnc%huxml8Z~V(GtZmL9gQ`c0Mv zNQFM`BtDZP+&55zm|Hr={^9M#O>-)~VZe11P~a`HPMO%2i?=@0rCzttVoO~i4J#Y9 zPMsrIIM2r7a;yo2zsZRZOt`IlenM2 zf4Ij>sAaH&1c%U#0_TBb?6ugSuPZ&a8_P4q%FfMz_sb8_Q$=?F7OG{Y;GyiS#*ncg zFr>Z0uj95-#(MwDbKLEXhR{fYOU1tvj4{h3pUKOs*q>yYo8l8XO`1vt!D_RIsi?G< zkTI zY^s&&)Go-}bcc)HTv4lt(|JgPS(Ka6lKP8{#75H2;91R(pCwM?h?QBT=!jP3Xp&Be zvR5aXp{T>{YwOlG;vb!Uzu{wV{%T_}8ywNODQ8pQbVxWuY}XeuJ{}OAXy!d+S+r(| z!2(BD*vDuRH_k>fF!C>VB-@-?mI?8>+#cww!IR{J*9ZVB$#9QLa8PkQ%|u#Bg6Y0@ ziGA4tY3dDT&}&9*L}6BJ_UNqDy*#Qlp9+Yskg=Pr0Iq8Q@cZt_#Y$_n@aImVy3B(L z>o!{LB-&nYqRHH7Wgv zNeIKq1h=aspObKrl-;IGl3m(&go;uUL>XC$H>WsT!uAhVa!2vMfCYVDRG-<5cH@ z?mZ~Fib3nWu#*zmrsh6-VdM*;9NB%5k`H3BmPtiAO^WOf^^tW|EQO!8TroTh61r!} zdtB$JNoNCfCu=7b+NGguP5(C%YQ)PP67e!TWMcV9$QTnlNe0V^u^)c*fF^d99H=@f zdw6GxG?y0lP~{u;FY?d>4OsjV7C~S+IHKf?C}=2+%|F9`$#wC#jJ2fO<*M^WB6TZa zzgI`p`s*IBg2trZj}V~X9;CvWiau6qvdzD^3~!?V`{%iT(%@7) zt0{&2L`D10TCT0r$H}nMj}TG39ZV_a+-PAR(s_of@DF8QB%OlV z@savhSqLhv+$2%l~ z1L0*;Ue#xZL{zK|tXBGMDoFNTs#2H@yqp&v?J444LU|c0G1UN?>!dU( zLTE*ZWVjoBc-Mak6^A5Iq64#6*RA^l*u;~w^^dVu)5H^;vOf6VHsnXb(AZRCMq$0W5b4qvZ&V5Y|e5`nw+%v^AZr#JQ0E?>&As|Imoz<@t2nR zz=nCThPa*f*fn0!NJyL*m~&V{vSy}Lt69zwF8W=2jVmR0LFJ1zgVT%+(PPOE@dSvu zM;=QLEOwhHdBo#IO(Su=>PJP6Z*gNT9O;|tn1N(A#}`eej>X4cs#^s;p1dnlEe=C& zw$xrTID-&nR>d#H5pe;s)1GrN-}cCa)*guw{tF+<@oq8QSNl4ne8l?a`1&N~&pY0; z$N;yOR>&lsU*q;KjmV?~`3E8qK55;?QH5?u1xWeOx5+kChh@%b_gnYj%;a_Wd%( zMf}z=BOVp6owM3G$NYNOWnQ{)R zK}HnJ-`V~H)AE(nasM~W|E=c#_U8Y0E)?~Q-N7ZNtr~Yg`rj2*H6?AudU>1Z{|h$C BmM;JR literal 0 HcmV?d00001 diff --git a/MusicPlayer/Info.plist b/MusicPlayer/Info.plist index 5452127..ad9c38c 100644 --- a/MusicPlayer/Info.plist +++ b/MusicPlayer/Info.plist @@ -4,12 +4,11 @@ UIBackgroundModes - fetch + audio backgroundFetch + fetch UIViewControllerBasedStatusBarAppearance - NSUserTrackingUsageDescription - "Musiclax" needs to request tracking permissions to provide a personalized advertising experience. We respect and protect your privacy and will not sell your data to third parties. diff --git a/MusicPlayer/MP/Common/Base(公用基类)/Controllers/MP_LunchViewController.swift b/MusicPlayer/MP/Common/Base(公用基类)/Controllers/MP_LunchViewController.swift index c668fbf..9dce3b6 100644 --- a/MusicPlayer/MP/Common/Base(公用基类)/Controllers/MP_LunchViewController.swift +++ b/MusicPlayer/MP/Common/Base(公用基类)/Controllers/MP_LunchViewController.swift @@ -31,8 +31,6 @@ class MP_LunchViewController: UIViewController { timer.add(to: RunLoop.current, forMode: .common) //获取idfa _ = requestTrackingAuthorization(self) - //获取定位权限 - MP_LocationManager.shared.setLocationPermission(self, complete: nil) MP_AnalyticsManager.shared.getOpenStatus { [weak self] open in guard let self = self else {return} if open { diff --git a/MusicPlayer/MP/Common/Macro(宏定义与全局量)/Macro.swift b/MusicPlayer/MP/Common/Macro(宏定义与全局量)/Macro.swift index 49ac272..4095611 100644 --- a/MusicPlayer/MP/Common/Macro(宏定义与全局量)/Macro.swift +++ b/MusicPlayer/MP/Common/Macro(宏定义与全局量)/Macro.swift @@ -51,7 +51,7 @@ var app_Version:String{ ///底部安全区域 let bottomPadding = UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0 ///全局占位图 -let placeholderImage:UIImage = UIImage(named: "Home First'placeholder")! +let placeholderImage:UIImage = UIImage(named: "placeholder")! ///隐私政策网址 let privacyUrl:URL = .init(string: "https://musiclax.mystrikingly.com/privacy")! ///用户协议网址 @@ -167,7 +167,7 @@ func switchPlayTypeBtnIcon(_ btn:UIButton) { } } ///请求广告授权 -func requestTrackingAuthorization(_ observe:UIViewController) -> Bool { +func requestTrackingAuthorization(_ observe:UIViewController,max:Int = 0) -> Bool { if #available(iOS 14, *) { // 检查当前的跟踪管理器状态 let status = ATTrackingManager.trackingAuthorizationStatus @@ -178,7 +178,10 @@ func requestTrackingAuthorization(_ observe:UIViewController) -> Bool { ATTrackingManager.requestTrackingAuthorization { status in let isAuthorized = status == .authorized DispatchQueue.main.async { - _ = requestTrackingAuthorization(observe) + let new = max + 1 + if new < 3 { + _ = requestTrackingAuthorization(observe, max: new) + } } } case .authorized: diff --git a/MusicPlayer/MP/Common/Tool(工具封装)/MP_LocationManager.swift b/MusicPlayer/MP/Common/Tool(工具封装)/MP_LocationManager.swift index 1404e33..e090de1 100644 --- a/MusicPlayer/MP/Common/Tool(工具封装)/MP_LocationManager.swift +++ b/MusicPlayer/MP/Common/Tool(工具封装)/MP_LocationManager.swift @@ -8,160 +8,160 @@ import Foundation import CoreLocation -class MP_LocationManager: NSObject { - static let shared = MP_LocationManager() - var getAuthHandle: ((_ success: Bool) -> Void)? - //位置管理 - private var locationManager: CLLocationManager! - //定位信息(字符串) - private var location:String = "US" - override init() { - super.init() - locationManager = CLLocationManager() - //设置了精度最差的 3公里内 kCLLocationAccuracyThreeKilometers - locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers - locationManager.delegate = self - - } - - /// 获取定位权限并处理新事件 - /// - Parameter complete: 尾随事件 - func setLocationPermission(_ viewController:UIViewController ,complete:(() -> Void)?) { - if MP_LocationManager().hasLocationPermission() == true { - //成功获取权限 - if complete != nil { - complete!() - } - }else { - //未获取权限 - switch MP_LocationManager().locationPermission() { - case .notDetermined: - MP_LocationManager().requestLocationAuthorizaiton() - case .restricted, .denied: - DispatchQueue.main.async { - let alertController = UIAlertController(title: "Location permission request", message: "“Musiclax” needs to obtain your location information in order to refine the preview music information provided to you!", preferredStyle: .alert) - let CancelAction = UIAlertAction(title:"Cancel", style: .cancel) - let OKAction = UIAlertAction(title: "Settings", style: .default) { (action) in - let url = URL(string: UIApplication.openSettingsURLString) - if let url = url,UIApplication.shared.canOpenURL(url){ - if #available(iOS 10, *) { - UIApplication.shared.open(url, options:[:], completionHandler: nil) - }else{ - UIApplication.shared.canOpenURL(url) - } - } - } - alertController.addAction(CancelAction) - alertController.addAction(OKAction) - viewController.present(alertController, animated: true, completion: nil) - } - default: - if complete != nil { - complete!() - } - } - } - } - - /// 设备是否开启了定位服务 - fileprivate func hasLocationService() -> Bool { - - return CLLocationManager.locationServicesEnabled() - - } - /// APP是否有定位权限 - fileprivate func hasLocationPermission() -> Bool { - - switch locationPermission() { - case .notDetermined, .restricted, .denied: - return false - case .authorizedWhenInUse, .authorizedAlways: - return true - default: - break - } - return false - } - - /// 定位的权限 - fileprivate func locationPermission() -> CLAuthorizationStatus { - if #available(iOS 14.0, *) { - let status: CLAuthorizationStatus = locationManager.authorizationStatus - print("location authorizationStatus is \(status.rawValue)") - return status - } else { - let status = CLLocationManager.authorizationStatus() - print("location authorizationStatus is \(status.rawValue)") - return status - } - } - - - //MARK: - 获取权限,在代理‘didChangeAuthorization’中拿到结果 - func requestLocationAuthorizaiton() { - locationManager.requestWhenInUseAuthorization() - - } - //MARK: - 获取位置 - func requestLocation() -> String { - //请求地理位置 - locationManager.requestLocation() - return location - } -} -extension MP_LocationManager: CLLocationManagerDelegate { - //MARK: - ios 14.0 之前,获取权限结果的方法 - func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { - handleChangedAuthorization() - } - - //MARK: - ios 14.0,获取权限结果的方法 - func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { - handleChangedAuthorization() - } - - private func handleChangedAuthorization() { - if let block = getAuthHandle, locationPermission() != .notDetermined { - if hasLocationPermission() { - block(true) - } else { - block(false) - } - } - } - //MARK: - 获取定位后的位置 - func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { - if let loction = locations.last { - //成功获取定位 - print("latitude: \(loction.coordinate.latitude) longitude:\(loction.coordinate.longitude)") - let geocoder = CLGeocoder() - geocoder.reverseGeocodeLocation(loction) { (placemarks, error) in - if let placemark = placemarks?.first { - //编码成功 - if let area = placemark.administrativeArea, !area.isEmpty { - print("Area code: \(area)") - self.location = area - } else if let locality = placemark.locality, !locality.isEmpty { - print("Area code: \(locality)") - self.location = locality - } else if let country = placemark.country, !country.isEmpty { - print("Country code: \(country)") - self.location = country - } - } - if let error = error { - print("Reverse geocoding failure: \(error.localizedDescription)") - //编码失败,默认设置位置是US - self.location = "US" - return - } - } - } - } - - func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { - print("Reverse geocoding failure: \(error.localizedDescription)") - //编码失败,默认设置位置是US - self.location = "US" - } -} +//class MP_LocationManager: NSObject { +// static let shared = MP_LocationManager() +// var getAuthHandle: ((_ success: Bool) -> Void)? +// //位置管理 +// private var locationManager: CLLocationManager! +// //定位信息(字符串) +// private var location:String = "US" +// override init() { +// super.init() +// locationManager = CLLocationManager() +// //设置了精度最差的 3公里内 kCLLocationAccuracyThreeKilometers +// locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers +// locationManager.delegate = self +// +// } +// +// /// 获取定位权限并处理新事件 +// /// - Parameter complete: 尾随事件 +// func setLocationPermission(_ viewController:UIViewController ,complete:(() -> Void)?) { +// if MP_LocationManager().hasLocationPermission() == true { +// //成功获取权限 +// if complete != nil { +// complete!() +// } +// }else { +// //未获取权限 +// switch MP_LocationManager().locationPermission() { +// case .notDetermined: +// MP_LocationManager().requestLocationAuthorizaiton() +// case .restricted, .denied: +// DispatchQueue.main.async { +// let alertController = UIAlertController(title: "Location permission request", message: "“Musiclax” needs to obtain your location information in order to refine the preview music information provided to you!", preferredStyle: .alert) +// let CancelAction = UIAlertAction(title:"Cancel", style: .cancel) +// let OKAction = UIAlertAction(title: "Settings", style: .default) { (action) in +// let url = URL(string: UIApplication.openSettingsURLString) +// if let url = url,UIApplication.shared.canOpenURL(url){ +// if #available(iOS 10, *) { +// UIApplication.shared.open(url, options:[:], completionHandler: nil) +// }else{ +// UIApplication.shared.canOpenURL(url) +// } +// } +// } +// alertController.addAction(CancelAction) +// alertController.addAction(OKAction) +// viewController.present(alertController, animated: true, completion: nil) +// } +// default: +// if complete != nil { +// complete!() +// } +// } +// } +// } +// +// /// 设备是否开启了定位服务 +// fileprivate func hasLocationService() -> Bool { +// +// return CLLocationManager.locationServicesEnabled() +// +// } +// /// APP是否有定位权限 +// fileprivate func hasLocationPermission() -> Bool { +// +// switch locationPermission() { +// case .notDetermined, .restricted, .denied: +// return false +// case .authorizedWhenInUse, .authorizedAlways: +// return true +// default: +// break +// } +// return false +// } +// +// /// 定位的权限 +// fileprivate func locationPermission() -> CLAuthorizationStatus { +// if #available(iOS 14.0, *) { +// let status: CLAuthorizationStatus = locationManager.authorizationStatus +// print("location authorizationStatus is \(status.rawValue)") +// return status +// } else { +// let status = CLLocationManager.authorizationStatus() +// print("location authorizationStatus is \(status.rawValue)") +// return status +// } +// } +// +// +// //MARK: - 获取权限,在代理‘didChangeAuthorization’中拿到结果 +// func requestLocationAuthorizaiton() { +// locationManager.requestWhenInUseAuthorization() +// +// } +// //MARK: - 获取位置 +// func requestLocation() -> String { +// //请求地理位置 +// locationManager.requestLocation() +// return location +// } +//} +//extension MP_LocationManager: CLLocationManagerDelegate { +// //MARK: - ios 14.0 之前,获取权限结果的方法 +// func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { +// handleChangedAuthorization() +// } +// +// //MARK: - ios 14.0,获取权限结果的方法 +// func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { +// handleChangedAuthorization() +// } +// +// private func handleChangedAuthorization() { +// if let block = getAuthHandle, locationPermission() != .notDetermined { +// if hasLocationPermission() { +// block(true) +// } else { +// block(false) +// } +// } +// } +// //MARK: - 获取定位后的位置 +// func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { +// if let loction = locations.last { +// //成功获取定位 +// print("latitude: \(loction.coordinate.latitude) longitude:\(loction.coordinate.longitude)") +// let geocoder = CLGeocoder() +// geocoder.reverseGeocodeLocation(loction) { (placemarks, error) in +// if let placemark = placemarks?.first { +// //编码成功 +// if let area = placemark.administrativeArea, !area.isEmpty { +// print("Area code: \(area)") +// self.location = area +// } else if let locality = placemark.locality, !locality.isEmpty { +// print("Area code: \(locality)") +// self.location = locality +// } else if let country = placemark.country, !country.isEmpty { +// print("Country code: \(country)") +// self.location = country +// } +// } +// if let error = error { +// print("Reverse geocoding failure: \(error.localizedDescription)") +// //编码失败,默认设置位置是US +// self.location = "US" +// return +// } +// } +// } +// } +// +// func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { +// print("Reverse geocoding failure: \(error.localizedDescription)") +// //编码失败,默认设置位置是US +// self.location = "US" +// } +//} diff --git a/MusicPlayer/MP/Common/Tool(工具封装)/MP_NetWorkManager.swift b/MusicPlayer/MP/Common/Tool(工具封装)/MP_NetWorkManager.swift index c38ef1f..6e847cb 100644 --- a/MusicPlayer/MP/Common/Tool(工具封装)/MP_NetWorkManager.swift +++ b/MusicPlayer/MP/Common/Tool(工具封装)/MP_NetWorkManager.swift @@ -40,7 +40,8 @@ class MP_NetWorkManager: NSObject { ///YouTuBe资源键值 private let youTubeKeys:[String] = ["MUSIC_VIDEO_TYPE_ATV","MUSIC_VIDEO_TYPE_OMV","MUSIC_PAGE_TYPE_ALBUM","MUSIC_PAGE_TYPE_ARTIST","MUSIC_PAGE_TYPE_PLAYLIST","MUSIC_PAGE_TYPE_TRACK_LYRICS","MUSIC_PAGE_TYPE_TRACK_RELATED"] ///禁止接入IP信息组 - private let banIPs:[String] = ["CN", + private let banIPs:[String] = [ + "CN", "HK", "TW", "JP", @@ -49,7 +50,8 @@ class MP_NetWorkManager: NSObject { "CH", "BE", "MO", - "SG"] + "SG" + ] //网络状态 enum NetWorkStatus: String { case notReachable = "网络不可用" @@ -80,7 +82,7 @@ class MP_NetWorkManager: NSObject { //固定时间点(同一天的上一周) private lazy var currTimeDate:String = (Date().timeZone() - 7.days).toString(.custom("YYYYMMdd")) ///地址 - private lazy var locaton:String = MP_LocationManager.shared.requestLocation() + private var locaton:String? //预览下一阶段参数(网络请求获取) private var continuationAndItct:(String?,String?){ willSet{ @@ -108,7 +110,7 @@ class MP_NetWorkManager: NSObject { //语言 "hl":Language_first_local, //地址 - "gl":locaton + "gl":locaton ?? "" ] ] ] @@ -214,10 +216,12 @@ extension MP_NetWorkManager { return } if banIPs.contains(code) == true { + locaton = "" //包含,是禁止区域 completion(false) }else { //不包含,是通行区域 + locaton = code completion(true) } case .failure(let error): @@ -260,7 +264,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":locaton + "gl":locaton ?? "" ] ] ] @@ -324,7 +328,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":locaton + "gl":locaton ?? "" ] ] ] @@ -381,7 +385,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":locaton + "gl":locaton ?? "" ] ] ] @@ -437,7 +441,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":locaton + "gl":locaton ?? "" ] ] ] @@ -490,7 +494,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":locaton + "gl":locaton ?? "" ] ] ] @@ -544,7 +548,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":locaton + "gl":locaton ?? "" ] ] ] @@ -595,7 +599,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":locaton + "gl":locaton ?? "" ] ] ] @@ -697,7 +701,7 @@ extension MP_NetWorkManager { // //语言 // "hl":Language_first_local, // //地址 -// "gl":locaton +// "gl":locaton ?? "" // ] // ], // "playbackContext": [ @@ -754,7 +758,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":locaton + "gl":locaton ?? "" ] ] ] @@ -801,7 +805,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":locaton + "gl":locaton ?? "" ] ] ] @@ -854,7 +858,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":locaton + "gl":locaton ?? "" ] ] ] @@ -905,7 +909,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":locaton + "gl":locaton ?? "" ] ] ] @@ -962,7 +966,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":locaton + "gl":locaton ?? "" ] ] ] @@ -1019,7 +1023,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":locaton + "gl":locaton ?? "" ] ] ] @@ -1591,7 +1595,7 @@ extension MP_NetWorkManager { contents.forEach { content in //生成更多内容块 let item = MPPositive_BrowseItemModel() - if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer { + if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer, (musicResponsiveListItemRenderer.playlistItemData != nil || musicResponsiveListItemRenderer.navigationEndpoint != nil) && (musicResponsiveListItemRenderer.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE"){ //设置预览图 item.coverUrls = musicResponsiveListItemRenderer.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""}) //设置一级标题与二级标题 @@ -1614,7 +1618,7 @@ extension MP_NetWorkManager { //是专辑列表/艺术家 item.browseId = musicResponsiveListItemRenderer.navigationEndpoint?.browseEndpoint?.browseId let pageType = musicResponsiveListItemRenderer.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType - if youTubeKeys.contains(pageType ?? "") == true { + if youTubeKeys.contains(pageType ?? "") == true && pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" { //判断细分 if pageType == "MUSIC_PAGE_TYPE_ARTIST" { item.artistId = musicResponsiveListItemRenderer.navigationEndpoint?.browseEndpoint?.browseId @@ -1627,7 +1631,7 @@ extension MP_NetWorkManager { } } } - if item.title != nil && item.itemType != nil { + if item.title != nil && item.itemType != nil, item.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" { resultList.previewItemViews.append(.init(item)) } } @@ -1643,6 +1647,72 @@ extension MP_NetWorkManager { musicShelfRenderer.contents?.forEach({ content in //专辑/列表/单曲视频/艺术家 let item = MPPositive_BrowseItemModel() + if (content.musicResponsiveListItemRenderer?.playlistItemData != nil || content.musicResponsiveListItemRenderer?.navigationEndpoint != nil) && (content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE") { + //设置内容块的封面 + item.coverUrls = content.musicResponsiveListItemRenderer?.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""}) + //设置一级标题与二级标题 + for (index, flexColumn) in (content.musicResponsiveListItemRenderer?.flexColumns ?? []).enumerated() { + if index == 0 { + //一级标题 + item.title = flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")}) + item.pageType = flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.first?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType + }else { + //二级标题 + item.subtitle = (item.subtitle ?? "") + (flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")}) ?? "") + } + } + item.playListId = content.musicResponsiveListItemRenderer?.menu?.menuRenderer?.items?.first?.menuNavigationItemRenderer?.navigationEndpoint?.watchEndpoint?.playlistId + //设置id和类型 + if content.musicResponsiveListItemRenderer?.playlistItemData != nil { + //是单曲 + item.itemType = .single + item.videoId = content.musicResponsiveListItemRenderer?.playlistItemData?.videoId + }else { + //是专辑列表/艺术家 + item.browseId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId + let pageType = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType + if youTubeKeys.contains(pageType ?? "") == true && pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" { + //判断细分 + if pageType == "MUSIC_PAGE_TYPE_ARTIST" { + item.artistId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId + //是艺术家 + item.itemType = .artist + }else { + //是列表/专辑 + item.itemType = .list + } + } + } + } + if item.itemType != nil, item.title != nil, item.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" { + resultList.previewItemViews.append(.init(item)) + } + }) + //设置query和params值 + if let searchEndpoint = musicShelfRenderer.bottomEndpoint?.searchEndpoint { + resultList.query = searchEndpoint.query + resultList.params = searchEndpoint.params + } + } + resultListSections.append(resultList) + } + resultListSections.forEach { list in + list.previewItemViews = list.previewItemViews.filter({ item in + return item.item.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" + }) + } + resultListSections = resultListSections.filter({$0.previewItemViews.count != 0}) + return resultListSections + } + ///解析搜索分页结果 + private func parsingSearchTypeResults(_ musicShelfRenderer:JsonSearchTypeResults.Contents.TabbedSearchResultsRenderer.Tab.TabRenderer.Content.SectionListRenderer.Content.MusicShelfRenderer) -> ([MPPositive_SearchResultItemViewModel], String?, String?) { + var array:[MPPositive_SearchResultItemViewModel] = [] + if let contents = musicShelfRenderer.contents { + ///解析内容块 + contents.forEach({ content in + //专辑/列表/单曲视频/艺术家 + let item = MPPositive_BrowseItemModel() + if (content.musicResponsiveListItemRenderer?.playlistItemData != nil || content.musicResponsiveListItemRenderer?.navigationEndpoint != nil) && (content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE") { //设置内容块的封面 item.coverUrls = content.musicResponsiveListItemRenderer?.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""}) //设置一级标题与二级标题 @@ -1665,7 +1735,7 @@ extension MP_NetWorkManager { //是专辑列表/艺术家 item.browseId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId let pageType = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType - if youTubeKeys.contains(pageType ?? "") == true { + if youTubeKeys.contains(pageType ?? "") == true && pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" { //判断细分 if pageType == "MUSIC_PAGE_TYPE_ARTIST" { item.artistId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId @@ -1677,67 +1747,12 @@ extension MP_NetWorkManager { } } } + //添加内容块 if item.itemType != nil { - resultList.previewItemViews.append(.init(item)) - } - }) - //设置query和params值 - if let searchEndpoint = musicShelfRenderer.bottomEndpoint?.searchEndpoint { - resultList.query = searchEndpoint.query - resultList.params = searchEndpoint.params - } - } - resultListSections.append(resultList) - } - resultListSections = resultListSections.filter({$0.previewItemViews.count != 0}) - return resultListSections - } - ///解析搜索分页结果 - private func parsingSearchTypeResults(_ musicShelfRenderer:JsonSearchTypeResults.Contents.TabbedSearchResultsRenderer.Tab.TabRenderer.Content.SectionListRenderer.Content.MusicShelfRenderer) -> ([MPPositive_SearchResultItemViewModel], String?, String?) { - var array:[MPPositive_SearchResultItemViewModel] = [] - if let contents = musicShelfRenderer.contents { - ///解析内容块 - contents.forEach({ content in - //专辑/列表/单曲视频/艺术家 - let item = MPPositive_BrowseItemModel() - //设置内容块的封面 - item.coverUrls = content.musicResponsiveListItemRenderer?.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""}) - //设置一级标题与二级标题 - for (index, flexColumn) in (content.musicResponsiveListItemRenderer?.flexColumns ?? []).enumerated() { - if index == 0 { - //一级标题 - item.title = flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")}) - }else { - //二级标题 - item.subtitle = (item.subtitle ?? "") + (flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")}) ?? "") + array.append(.init(item)) } } - item.playListId = content.musicResponsiveListItemRenderer?.menu?.menuRenderer?.items?.first?.menuNavigationItemRenderer?.navigationEndpoint?.watchEndpoint?.playlistId - //设置id和类型 - if content.musicResponsiveListItemRenderer?.playlistItemData != nil { - //是单曲 - item.itemType = .single - item.videoId = content.musicResponsiveListItemRenderer?.playlistItemData?.videoId - }else { - //是专辑列表/艺术家 - item.browseId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId - let pageType = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType - if youTubeKeys.contains(pageType ?? "") == true { - //判断细分 - if pageType == "MUSIC_PAGE_TYPE_ARTIST" { - item.artistId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId - //是艺术家 - item.itemType = .artist - }else { - //是列表/专辑 - item.itemType = .list - } - } - } - //添加内容块 - if item.itemType != nil { - array.append(.init(item)) - } + }) } var continuation:String? @@ -1780,7 +1795,7 @@ extension MP_NetWorkManager { //是专辑列表/艺术家 item.browseId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId let pageType = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType - if youTubeKeys.contains(pageType ?? "") == true { + if youTubeKeys.contains(pageType ?? "") == true && pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" { //判断细分 if pageType == "MUSIC_PAGE_TYPE_ARTIST" { item.artistId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId @@ -1840,17 +1855,19 @@ extension MP_NetWorkManager { } if let navigationEndpoint = musicResponsiveListItemRenderer.navigationEndpoint { //是专辑列表艺术家 - if navigationEndpoint.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType == "MUSIC_PAGE_TYPE_ARTIST" { + if navigationEndpoint.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType == "MUSIC_PAGE_TYPE_ARTIST" && navigationEndpoint.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" { //是艺术家 item.itemType = .artist item.artistId = navigationEndpoint.browseEndpoint?.browseId item.pageType = "MUSIC_PAGE_TYPE_ARTIST" }else { - //是专辑列表 - item.itemType = .list - item.pageType = navigationEndpoint.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType - item.browseId = navigationEndpoint.browseEndpoint?.browseId - item.params = navigationEndpoint.browseEndpoint?.params + if navigationEndpoint.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" { + //是专辑列表 + item.itemType = .list + item.pageType = navigationEndpoint.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType + item.browseId = navigationEndpoint.browseEndpoint?.browseId + item.params = navigationEndpoint.browseEndpoint?.params + } } } return item diff --git a/MusicPlayer/MP/Common/Tool(工具封装)/MP_PlayerManager.swift b/MusicPlayer/MP/Common/Tool(工具封装)/MP_PlayerManager.swift index 371c056..55a6adf 100644 --- a/MusicPlayer/MP/Common/Tool(工具封装)/MP_PlayerManager.swift +++ b/MusicPlayer/MP/Common/Tool(工具封装)/MP_PlayerManager.swift @@ -258,6 +258,20 @@ class MP_PlayerManager:NSObject{ if playState != .Playing { //当statuVlaue值等于playerItem准备播放的值,说明已经准备好播放 print("当前音乐-\(loadPlayer.currentVideo?.title ?? "") 已经准备好播放") +// if playState != .Playing { +// player.play() +// playState = .Playing +// //暂停计时器,并获取延时值 +// suspendTimer() +// let times = Int(self.times) +// let msTimes = times*1000 +// MP_AnalyticsManager.shared.player_b_delay_actionAction(loadPlayer.currentVideo?.song.videoId ?? "", videoname: loadPlayer.currentVideo?.title ?? "", artistname: loadPlayer.currentVideo?.song.shortBylineText ?? "", delay: "\(msTimes)ms") +// MP_AnalyticsManager.shared.player_b_success_actionAction(loadPlayer.currentVideo?.song.videoId ?? "", videoname: loadPlayer.currentVideo?.title ?? "", artistname: loadPlayer.currentVideo?.song.shortBylineText ?? "") +// //执行开始播放闭包 +// if startActionBlock != nil { +// startActionBlock!() +// } +// } } }else { print("当前音乐-\(loadPlayer.currentVideo?.title ?? "") 未做好准备播放,失败原因是\(loadPlayer.currentVideo?.resourcePlayerItem.error?.localizedDescription ?? "")") @@ -295,7 +309,7 @@ class MP_PlayerManager:NSObject{ //获取缓冲值 private func cacheLoadTimes() { //获取当前播放Item的缓冲值组 - if let timeRanges = loadPlayer.currentVideo?.resourcePlayerItem.loadedTimeRanges.map({$0.timeRangeValue}), let first = timeRanges.first { + if let timeRanges = loadPlayer?.currentVideo?.resourcePlayerItem.loadedTimeRanges.map({$0.timeRangeValue}), let first = timeRanges.first { //获取开始时间的秒数 let startSeconds = first.start.seconds //获取缓冲区的持续时间 diff --git a/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonBrowse.swift b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonBrowse.swift index 687c41b..9faff48 100644 --- a/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonBrowse.swift +++ b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonBrowse.swift @@ -642,12 +642,15 @@ struct RootMusicResponsiveListItemRenderer: Codable { } struct NavigationEndpoint: Codable { let watchEndpoint:WatchEndpoint? + let browseEndpoint:BrowseEndpoint? enum CodingKeys: String, CodingKey { case watchEndpoint = "watchEndpoint" + case browseEndpoint = "browseEndpoint" } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint) + browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint) } struct WatchEndpoint: Codable { let playlistId:String? @@ -659,6 +662,42 @@ struct RootMusicResponsiveListItemRenderer: Codable { playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId) } } + struct BrowseEndpoint: Codable { + let browseId:String? + let params:String? + let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs? + enum CodingKeys: String, CodingKey { + case browseId = "browseId" + case params = "params" + case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + browseId = try values.decodeIfPresent(String.self, forKey: .browseId) + params = try values.decodeIfPresent(String.self, forKey: .params) + browseEndpointContextSupportedConfigs = try values.decodeIfPresent(BrowseEndpointContextSupportedConfigs.self, forKey: .browseEndpointContextSupportedConfigs) + } + struct BrowseEndpointContextSupportedConfigs: Codable { + let browseEndpointContextMusicConfig:BrowseEndpointContextMusicConfig? + enum CodingKeys: String, CodingKey { + case browseEndpointContextMusicConfig = "browseEndpointContextMusicConfig" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + browseEndpointContextMusicConfig = try values.decodeIfPresent(BrowseEndpointContextMusicConfig.self, forKey: .browseEndpointContextMusicConfig) + } + struct BrowseEndpointContextMusicConfig: Codable { + let pageType:String? + enum CodingKeys: String, CodingKey { + case pageType = "pageType" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + pageType = try values.decodeIfPresent(String.self, forKey: .pageType) + } + } + } + } } } } @@ -781,6 +820,7 @@ struct RootMusicResponsiveListItemRenderer: Codable { } } } + } } diff --git a/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_PlayerLoadViewModel.swift b/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_PlayerLoadViewModel.swift index 06b5e10..a1a172b 100644 --- a/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_PlayerLoadViewModel.swift +++ b/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_PlayerLoadViewModel.swift @@ -15,7 +15,7 @@ class MPPositive_PlayerLoadViewModel: NSObject { ///当前播放音乐ViewModel var currentVideo:MPPositive_SongViewModel!{ willSet{ - DispatchQueue.main.asyncAfter(deadline: .now()) { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in guard let self = self else {return} if newValue != nil { @@ -97,6 +97,7 @@ class MPPositive_PlayerLoadViewModel: NSObject { array = array.filter({!videoIDs.contains($0.videoId)}) group = DispatchGroup() + //去重完毕,对剩下内容补完 for item in array { group?.enter() @@ -108,7 +109,7 @@ class MPPositive_PlayerLoadViewModel: NSObject { self?.group?.leave() } }else { - group?.leave() + self.group?.leave() } group?.enter() //判断当前videoID是否进行过下载 @@ -117,7 +118,7 @@ class MPPositive_PlayerLoadViewModel: NSObject { item.resourceUrls = [resource] //补全完成,转化为ViewModel,并添加进listViewVideos listViewVideos.append(.init(item)) - group?.leave() + self.group?.leave() }else { //没有下载过 //补全资源路径组和封面路径组 diff --git a/MusicPlayer/MP/MPPositive/ViewControllers/Base(基类,导航栏,标签栏)/MPPositive_MoreSongOperationsViewController.swift b/MusicPlayer/MP/MPPositive/ViewControllers/Base(基类,导航栏,标签栏)/MPPositive_MoreSongOperationsViewController.swift index 6f0c56c..59335b4 100644 --- a/MusicPlayer/MP/MPPositive/ViewControllers/Base(基类,导航栏,标签栏)/MPPositive_MoreSongOperationsViewController.swift +++ b/MusicPlayer/MP/MPPositive/ViewControllers/Base(基类,导航栏,标签栏)/MPPositive_MoreSongOperationsViewController.swift @@ -74,6 +74,7 @@ class MPPositive_MoreSongOperationsViewController: UIViewController { } } var removeBlock:(() -> Void)? + var disMissBlock:(() -> Void)? init(_ song:MPPositive_SongItemModel) { super.init(nibName: nil, bundle: nil) DispatchQueue.main.async { @@ -94,7 +95,12 @@ class MPPositive_MoreSongOperationsViewController: UIViewController { view.layer.cornerRadius = 18*width configure() } - + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + if disMissBlock != nil { + disMissBlock!() + } + } private func configure() { view.addSubview(indictorImageView) indictorImageView.snp.makeConstraints { make in diff --git a/MusicPlayer/MP/MPPositive/ViewControllers/Center(个人曲库页)/MPPositive_LoveSongsViewController.swift b/MusicPlayer/MP/MPPositive/ViewControllers/Center(个人曲库页)/MPPositive_LoveSongsViewController.swift index a73ad2e..e507bc1 100644 --- a/MusicPlayer/MP/MPPositive/ViewControllers/Center(个人曲库页)/MPPositive_LoveSongsViewController.swift +++ b/MusicPlayer/MP/MPPositive/ViewControllers/Center(个人曲库页)/MPPositive_LoveSongsViewController.swift @@ -93,6 +93,12 @@ extension MPPositive_LoveSongsViewController: UITableViewDataSource, UITableView [weak self] in MPPositive_ModalType = .MoreOperations let moreVC = MPPositive_MoreSongOperationsViewController(first) + moreVC.removeBlock = { + self?.reload() + } + moreVC.disMissBlock = { + self?.reload() + } moreVC.transitioningDelegate = self moreVC.modalPresentationStyle = .custom self?.present(moreVC, animated: true) diff --git a/MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,艺术家页)/MPPositive_HomeViewController.swift b/MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,艺术家页)/MPPositive_HomeViewController.swift index a76a689..7d445ee 100644 --- a/MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,艺术家页)/MPPositive_HomeViewController.swift +++ b/MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,艺术家页)/MPPositive_HomeViewController.swift @@ -115,6 +115,7 @@ class MPPositive_HomeViewController: MPPositive_BaseViewController{ } removeErrorView() MP_HUD.hideNow() + tableView.showMessage(MPPositive_BrowseLoadViewModel.shared.browseModuleLists.count) tableView.reloadData() } } diff --git a/MusicPlayer/MP/MPPositive/ViewControllers/Player(播放器)/MPPositive_PlayerViewController.swift b/MusicPlayer/MP/MPPositive/ViewControllers/Player(播放器)/MPPositive_PlayerViewController.swift index 23b2dfc..65ef8bc 100644 --- a/MusicPlayer/MP/MPPositive/ViewControllers/Player(播放器)/MPPositive_PlayerViewController.swift +++ b/MusicPlayer/MP/MPPositive/ViewControllers/Player(播放器)/MPPositive_PlayerViewController.swift @@ -304,18 +304,23 @@ class MPPositive_PlayerViewController: MPPositive_BaseViewController, UIViewCont } //MARK: - 页面渲染 private func uploadUI() { - //填充数据 - backImageView.kf.setImage(with: MP_PlayerManager.shared.loadPlayer.currentVideo?.coverUrl) - coverView.coverImageView.kf.setImage(with: MP_PlayerManager.shared.loadPlayer.currentVideo?.coverUrl) - coverView.titleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.title - coverView.subtitleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.subtitle - lyricsView.titleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.title - lyricsView.subtitleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.subtitle - lyricsView.lyricsLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.lyrics?.isEmpty == true ? "No Lyrics":MP_PlayerManager.shared.loadPlayer.currentVideo?.lyrics - coverView.downloadButton.state = (MP_PlayerManager.shared.loadPlayer.currentVideo?.isDlownd ?? false) ? .downloaded:.startDownload - coverView.downloadButton.isUserInteractionEnabled = !(MP_PlayerManager.shared.loadPlayer.currentVideo?.isDlownd ?? false) - coverView.collectionSongBtn.isSelected = MP_PlayerManager.shared.loadPlayer.currentVideo?.isCollection ?? false - coverView.restoreDownloadProgress() + DispatchQueue.main.async { + [weak self] in + guard let self = self else {return} + print("\(MP_PlayerManager.shared.loadPlayer.currentVideo.title ?? "")刷新了页面") + //填充数据 + backImageView.kf.setImage(with: MP_PlayerManager.shared.loadPlayer.currentVideo?.coverUrl) + coverView.coverImageView.kf.setImage(with: MP_PlayerManager.shared.loadPlayer.currentVideo?.coverUrl) + coverView.titleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.title + coverView.subtitleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.subtitle + lyricsView.titleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.title + lyricsView.subtitleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.subtitle + lyricsView.lyricsLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.lyrics?.isEmpty == true ? "No Lyrics":MP_PlayerManager.shared.loadPlayer.currentVideo?.lyrics + coverView.downloadButton.state = (MPPositive_DownloadItemModel.fetch(.init(format: "videoId == %@", MP_PlayerManager.shared.loadPlayer.currentVideo?.song.videoId ?? "")).count != 0) ? .downloaded:.startDownload + coverView.downloadButton.isUserInteractionEnabled = !(MP_PlayerManager.shared.loadPlayer.currentVideo?.isDlownd ?? false) + coverView.collectionSongBtn.isSelected = MP_PlayerManager.shared.loadPlayer.currentVideo?.isCollection ?? false + coverView.restoreDownloadProgress() + } } //MARK: - 通知 //播放器音乐刷新 diff --git a/MusicPlayer/MP/MPPositive/ViewControllers/Player(播放器)/MPPositive_RecommendViewController.swift b/MusicPlayer/MP/MPPositive/ViewControllers/Player(播放器)/MPPositive_RecommendViewController.swift index 1698bf4..c3829eb 100644 --- a/MusicPlayer/MP/MPPositive/ViewControllers/Player(播放器)/MPPositive_RecommendViewController.swift +++ b/MusicPlayer/MP/MPPositive/ViewControllers/Player(播放器)/MPPositive_RecommendViewController.swift @@ -22,9 +22,9 @@ class MPPositive_RecommendViewController: MPPositive_BaseViewController,UIViewCo [weak self] in //刷新分页控制器 guard let self = self else {return} - sectionLabel.text = loadRecommend.members.title + sectionLabel.text = loadRecommend?.members?.title collectionView.reloadData() - dataSource.titles = loadRecommend?.sectionLists.compactMap({$0.title}) ?? [] + dataSource.titles = loadRecommend?.sectionLists?.compactMap({$0.title}) ?? [] dataSource.reloadData(selectedIndex: 0) segmentView.reloadData() } @@ -43,7 +43,7 @@ class MPPositive_RecommendViewController: MPPositive_BaseViewController,UIViewCo ///音乐人View private lazy var membersView:UIView = createMusicMembersView() //模块标题 - private lazy var sectionLabel:UILabel = createLabel(font: .systemFont(ofSize: 18*width, weight: .regular), textColor: .white, textAlignment: .left) + private lazy var sectionLabel:UILabel = createLabel("Loading",font: .systemFont(ofSize: 18*width, weight: .regular), textColor: .white, textAlignment: .left) //音乐人CollectionView private lazy var collectionView:UICollectionView = { let layout = UICollectionViewFlowLayout() diff --git a/MusicPlayer/MP/MPPositive/Views/Player/MPPositive_PlayerCoverView.swift b/MusicPlayer/MP/MPPositive/Views/Player/MPPositive_PlayerCoverView.swift index c4e74c0..f6abcde 100644 --- a/MusicPlayer/MP/MPPositive/Views/Player/MPPositive_PlayerCoverView.swift +++ b/MusicPlayer/MP/MPPositive/Views/Player/MPPositive_PlayerCoverView.swift @@ -131,8 +131,8 @@ class MPPositive_PlayerCoverView: UIView, PKDownloadButtonDelegate { downloadButton.stopDownloadButton.progress = progress } }else { - //不是正在下载的内容 - downloadButton.state = .startDownload + //不是正在下载的内容,判断是否下载了 + downloadButton.state = (MPPositive_DownloadItemModel.fetch(.init(format: "videoId == %@", currentVideo.song.videoId ?? "")).count != 0) ? .downloaded:.startDownload downloadButton.isUserInteractionEnabled = true } } diff --git a/MusicPlayer/MP/MPSideA/ViewControllers/Center(个人资源)/MPSideA_AboutViewController.xib b/MusicPlayer/MP/MPSideA/ViewControllers/Center(个人资源)/MPSideA_AboutViewController.xib index ef21b6c..e80a6d2 100644 --- a/MusicPlayer/MP/MPSideA/ViewControllers/Center(个人资源)/MPSideA_AboutViewController.xib +++ b/MusicPlayer/MP/MPSideA/ViewControllers/Center(个人资源)/MPSideA_AboutViewController.xib @@ -90,8 +90,8 @@ -