diff --git a/MusicPlayer.xcodeproj/project.pbxproj b/MusicPlayer.xcodeproj/project.pbxproj index 7062309..af3d2ad 100644 --- a/MusicPlayer.xcodeproj/project.pbxproj +++ b/MusicPlayer.xcodeproj/project.pbxproj @@ -23,6 +23,12 @@ CB0918A12BD26B0A006D2B39 /* MPPositive_SearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB0918A02BD26B0A006D2B39 /* MPPositive_SearchViewController.swift */; }; CB0918A32BD26B2F006D2B39 /* MPPositive_LibraryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB0918A22BD26B2F006D2B39 /* MPPositive_LibraryViewController.swift */; }; CB0918A52BD26E16006D2B39 /* MPPositive_BottomShowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB0918A42BD26E16006D2B39 /* MPPositive_BottomShowView.swift */; }; + CB102F502BFAE64C00E967D8 /* MPPositive_RecommendViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB102F4F2BFAE64C00E967D8 /* MPPositive_RecommendViewController.swift */; }; + CB102F522BFAE73800E967D8 /* MPPositive_JsonRecommend.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB102F512BFAE73800E967D8 /* MPPositive_JsonRecommend.swift */; }; + CB102F552BFAFA7200E967D8 /* MP_CircularProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB102F532BFAFA7200E967D8 /* MP_CircularProgressView.swift */; }; + CB102F562BFAFA7200E967D8 /* MP_DownloadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB102F542BFAFA7200E967D8 /* MP_DownloadManager.swift */; }; + CB102F582BFAFFCC00E967D8 /* MPPositive_RecommendListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB102F572BFAFFCC00E967D8 /* MPPositive_RecommendListViewModel.swift */; }; + CB102F5A2BFB002C00E967D8 /* MPPositive_RecommendLoadViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB102F592BFB002C00E967D8 /* MPPositive_RecommendLoadViewModel.swift */; }; CB1C16522BC80BF100B96AB3 /* MPSideA_MediaCenterManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB1C16512BC80BF100B96AB3 /* MPSideA_MediaCenterManager.swift */; }; CB5661292BE09D0500CFD014 /* MPPositive_JsonPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB5661282BE09D0500CFD014 /* MPPositive_JsonPlayer.swift */; }; CB56612D2BE0DF8C00CFD014 /* MP_WebWork.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB56612C2BE0DF8C00CFD014 /* MP_WebWork.swift */; }; @@ -132,6 +138,16 @@ CBD313612BD6453A0015D227 /* MPPositive_HomeListFifthCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD313602BD6453A0015D227 /* MPPositive_HomeListFifthCollectionViewCell.swift */; }; CBD5AEE12BBBE45300BF5A43 /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD5AEE02BBBE45300BF5A43 /* ImagePicker.swift */; }; CBD5E80C2BF33D0200A3EBED /* MPPositive_SearchResultTypeShowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD5E80B2BF33D0200A3EBED /* MPPositive_SearchResultTypeShowView.swift */; }; + CBD5E80E2BF3501200A3EBED /* MPPositive_JsonSearchTypeResults.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD5E80D2BF3501200A3EBED /* MPPositive_JsonSearchTypeResults.swift */; }; + CBD5E8102BF361B900A3EBED /* MPPositive_JsonSearchTypeContinuation.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD5E80F2BF361B900A3EBED /* MPPositive_JsonSearchTypeContinuation.swift */; }; + CBD6F2122BF4499800343A4A /* MPPositive_ArtistShowViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD6F2112BF4499800343A4A /* MPPositive_ArtistShowViewController.swift */; }; + CBD6F2142BF44D8A00343A4A /* MPPositive_JsonArtist.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD6F2132BF44D8A00343A4A /* MPPositive_JsonArtist.swift */; }; + CBD6F2162BF48DDD00343A4A /* MPPositive_ArtistHeaderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD6F2152BF48DDD00343A4A /* MPPositive_ArtistHeaderModel.swift */; }; + CBD6F2182BF4A29B00343A4A /* MPPositive_ArtistViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD6F2172BF4A29B00343A4A /* MPPositive_ArtistViewModel.swift */; }; + CBD6F21A2BF4A38C00343A4A /* MPPositive_ArtistContentListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD6F2192BF4A38C00343A4A /* MPPositive_ArtistContentListViewModel.swift */; }; + CBD6F21C2BF4AEE600343A4A /* MPPositive_ArtistShowHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD6F21B2BF4AEE600343A4A /* MPPositive_ArtistShowHeaderView.swift */; }; + CBD6F21E2BF4B61F00343A4A /* MPPositive_ArtistShowTypeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD6F21D2BF4B61F00343A4A /* MPPositive_ArtistShowTypeView.swift */; }; + CBD6F2202BF4CE8E00343A4A /* MPPositive_JsonArtistMore.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD6F21F2BF4CE8E00343A4A /* MPPositive_JsonArtistMore.swift */; }; CBD958D22BB6600500666B0D /* MP_PlayerSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD958D12BB6600500666B0D /* MP_PlayerSlider.swift */; }; CBD958D42BB6942F00666B0D /* MPSideA_VolumeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD958D32BB6942F00666B0D /* MPSideA_VolumeManager.swift */; }; CBDD516D2BEC6AFE000F12C5 /* MPPositive_JsonNext.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBDD516C2BEC6AFE000F12C5 /* MPPositive_JsonNext.swift */; }; @@ -148,6 +164,11 @@ CBE2C4C92BC7B25800F283A7 /* TableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE2C4C82BC7B25800F283A7 /* TableView.swift */; }; CBE2C4CB2BC7BE5D00F283A7 /* MP_NetWorkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE2C4CA2BC7BE5D00F283A7 /* MP_NetWorkManager.swift */; }; CBE477B12BB16CCC0031C14B /* Macro.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE477B02BB16CCC0031C14B /* Macro.swift */; }; + CBEB017D2BF5D35700D45006 /* MPPositive_ArtistShowSongTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBEB017C2BF5D35700D45006 /* MPPositive_ArtistShowSongTableViewCell.swift */; }; + CBEB017F2BF5D49400D45006 /* MPPositive_ArtistShowListableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBEB017E2BF5D49400D45006 /* MPPositive_ArtistShowListableViewCell.swift */; }; + CBEB01812BF5D69200D45006 /* MPPositive_ArtistShowListCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBEB01802BF5D69200D45006 /* MPPositive_ArtistShowListCollectionViewCell.swift */; }; + CBEB01832BF5D88400D45006 /* MPPositive_ArtistShowCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBEB01822BF5D88400D45006 /* MPPositive_ArtistShowCollectionViewCell.swift */; }; + CBEB01852BF5DB3400D45006 /* MPPositive_ArtistDescriptionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBEB01842BF5DB3400D45006 /* MPPositive_ArtistDescriptionTableViewCell.swift */; }; CBEE8E322BEB0FC0007DA798 /* MPPositive_PlayerCoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBEE8E312BEB0FC0007DA798 /* MPPositive_PlayerCoverView.swift */; }; CBEE8E342BEB16BB007DA798 /* MPPositive_PlayerSilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBEE8E332BEB16BB007DA798 /* MPPositive_PlayerSilder.swift */; }; CBEE8E362BEB2604007DA798 /* MPPositive_PlayerLyricView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBEE8E352BEB2604007DA798 /* MPPositive_PlayerLyricView.swift */; }; @@ -155,7 +176,7 @@ CBF456DD2BF1E72F00ABF761 /* MPPositive_SearchResultListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF456DC2BF1E72F00ABF761 /* MPPositive_SearchResultListViewModel.swift */; }; CBF456DF2BF1E8A500ABF761 /* MPPositive_SearchResultItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF456DE2BF1E8A500ABF761 /* MPPositive_SearchResultItemModel.swift */; }; CBF456E12BF1EB4300ABF761 /* MPPositive_SearchResultItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF456E02BF1EB4300ABF761 /* MPPositive_SearchResultItemViewModel.swift */; }; - CBF456E32BF2086600ABF761 /* MPPositive_LoadSearchResultsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF456E22BF2086600ABF761 /* MPPositive_LoadSearchResultsViewModel.swift */; }; + CBF456E32BF2086600ABF761 /* MPPositive_SearchResultsLoadViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF456E22BF2086600ABF761 /* MPPositive_SearchResultsLoadViewModel.swift */; }; CBF456E72BF20BBD00ABF761 /* MPPositive_SearchResultShowTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF456E62BF20BBD00ABF761 /* MPPositive_SearchResultShowTableViewCell.swift */; }; CBF456E92BF21E0E00ABF761 /* MPPositive_SearchResultPreviewShowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF456E82BF21E0E00ABF761 /* MPPositive_SearchResultPreviewShowView.swift */; }; CBF456EB2BF222EC00ABF761 /* MPPositive_SearchSuggestionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF456EA2BF222EC00ABF761 /* MPPositive_SearchSuggestionsView.swift */; }; @@ -187,6 +208,12 @@ CB0918A02BD26B0A006D2B39 /* MPPositive_SearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_SearchViewController.swift; sourceTree = ""; }; CB0918A22BD26B2F006D2B39 /* MPPositive_LibraryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_LibraryViewController.swift; sourceTree = ""; }; CB0918A42BD26E16006D2B39 /* MPPositive_BottomShowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_BottomShowView.swift; sourceTree = ""; }; + CB102F4F2BFAE64C00E967D8 /* MPPositive_RecommendViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_RecommendViewController.swift; sourceTree = ""; }; + CB102F512BFAE73800E967D8 /* MPPositive_JsonRecommend.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_JsonRecommend.swift; sourceTree = ""; }; + CB102F532BFAFA7200E967D8 /* MP_CircularProgressView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MP_CircularProgressView.swift; sourceTree = ""; }; + CB102F542BFAFA7200E967D8 /* MP_DownloadManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MP_DownloadManager.swift; sourceTree = ""; }; + CB102F572BFAFFCC00E967D8 /* MPPositive_RecommendListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_RecommendListViewModel.swift; sourceTree = ""; }; + CB102F592BFB002C00E967D8 /* MPPositive_RecommendLoadViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_RecommendLoadViewModel.swift; sourceTree = ""; }; CB1C16512BC80BF100B96AB3 /* MPSideA_MediaCenterManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPSideA_MediaCenterManager.swift; sourceTree = ""; }; CB5661282BE09D0500CFD014 /* MPPositive_JsonPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_JsonPlayer.swift; sourceTree = ""; }; CB56612C2BE0DF8C00CFD014 /* MP_WebWork.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MP_WebWork.swift; sourceTree = ""; }; @@ -296,6 +323,16 @@ CBD313602BD6453A0015D227 /* MPPositive_HomeListFifthCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_HomeListFifthCollectionViewCell.swift; sourceTree = ""; }; CBD5AEE02BBBE45300BF5A43 /* ImagePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePicker.swift; sourceTree = ""; }; CBD5E80B2BF33D0200A3EBED /* MPPositive_SearchResultTypeShowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_SearchResultTypeShowView.swift; sourceTree = ""; }; + CBD5E80D2BF3501200A3EBED /* MPPositive_JsonSearchTypeResults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_JsonSearchTypeResults.swift; sourceTree = ""; }; + CBD5E80F2BF361B900A3EBED /* MPPositive_JsonSearchTypeContinuation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_JsonSearchTypeContinuation.swift; sourceTree = ""; }; + CBD6F2112BF4499800343A4A /* MPPositive_ArtistShowViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_ArtistShowViewController.swift; sourceTree = ""; }; + CBD6F2132BF44D8A00343A4A /* MPPositive_JsonArtist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_JsonArtist.swift; sourceTree = ""; }; + CBD6F2152BF48DDD00343A4A /* MPPositive_ArtistHeaderModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_ArtistHeaderModel.swift; sourceTree = ""; }; + CBD6F2172BF4A29B00343A4A /* MPPositive_ArtistViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_ArtistViewModel.swift; sourceTree = ""; }; + CBD6F2192BF4A38C00343A4A /* MPPositive_ArtistContentListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_ArtistContentListViewModel.swift; sourceTree = ""; }; + CBD6F21B2BF4AEE600343A4A /* MPPositive_ArtistShowHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_ArtistShowHeaderView.swift; sourceTree = ""; }; + CBD6F21D2BF4B61F00343A4A /* MPPositive_ArtistShowTypeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_ArtistShowTypeView.swift; sourceTree = ""; }; + CBD6F21F2BF4CE8E00343A4A /* MPPositive_JsonArtistMore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_JsonArtistMore.swift; sourceTree = ""; }; CBD958D12BB6600500666B0D /* MP_PlayerSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MP_PlayerSlider.swift; sourceTree = ""; }; CBD958D32BB6942F00666B0D /* MPSideA_VolumeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPSideA_VolumeManager.swift; sourceTree = ""; }; CBDD516C2BEC6AFE000F12C5 /* MPPositive_JsonNext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_JsonNext.swift; sourceTree = ""; }; @@ -312,6 +349,11 @@ CBE2C4C82BC7B25800F283A7 /* TableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableView.swift; sourceTree = ""; }; CBE2C4CA2BC7BE5D00F283A7 /* MP_NetWorkManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MP_NetWorkManager.swift; sourceTree = ""; }; CBE477B02BB16CCC0031C14B /* Macro.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Macro.swift; sourceTree = ""; }; + CBEB017C2BF5D35700D45006 /* MPPositive_ArtistShowSongTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_ArtistShowSongTableViewCell.swift; sourceTree = ""; }; + CBEB017E2BF5D49400D45006 /* MPPositive_ArtistShowListableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_ArtistShowListableViewCell.swift; sourceTree = ""; }; + CBEB01802BF5D69200D45006 /* MPPositive_ArtistShowListCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_ArtistShowListCollectionViewCell.swift; sourceTree = ""; }; + CBEB01822BF5D88400D45006 /* MPPositive_ArtistShowCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_ArtistShowCollectionViewCell.swift; sourceTree = ""; }; + CBEB01842BF5DB3400D45006 /* MPPositive_ArtistDescriptionTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_ArtistDescriptionTableViewCell.swift; sourceTree = ""; }; CBEE8E312BEB0FC0007DA798 /* MPPositive_PlayerCoverView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_PlayerCoverView.swift; sourceTree = ""; }; CBEE8E332BEB16BB007DA798 /* MPPositive_PlayerSilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_PlayerSilder.swift; sourceTree = ""; }; CBEE8E352BEB2604007DA798 /* MPPositive_PlayerLyricView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_PlayerLyricView.swift; sourceTree = ""; }; @@ -319,7 +361,7 @@ CBF456DC2BF1E72F00ABF761 /* MPPositive_SearchResultListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_SearchResultListViewModel.swift; sourceTree = ""; }; CBF456DE2BF1E8A500ABF761 /* MPPositive_SearchResultItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_SearchResultItemModel.swift; sourceTree = ""; }; CBF456E02BF1EB4300ABF761 /* MPPositive_SearchResultItemViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_SearchResultItemViewModel.swift; sourceTree = ""; }; - CBF456E22BF2086600ABF761 /* MPPositive_LoadSearchResultsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_LoadSearchResultsViewModel.swift; sourceTree = ""; }; + CBF456E22BF2086600ABF761 /* MPPositive_SearchResultsLoadViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_SearchResultsLoadViewModel.swift; sourceTree = ""; }; CBF456E62BF20BBD00ABF761 /* MPPositive_SearchResultShowTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_SearchResultShowTableViewCell.swift; sourceTree = ""; }; CBF456E82BF21E0E00ABF761 /* MPPositive_SearchResultPreviewShowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_SearchResultPreviewShowView.swift; sourceTree = ""; }; CBF456EA2BF222EC00ABF761 /* MPPositive_SearchSuggestionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_SearchSuggestionsView.swift; sourceTree = ""; }; @@ -398,6 +440,7 @@ children = ( CBB5D3212BDF80C800CC333D /* MPPositive_PlayerViewController.swift */, CBCC23502BEE58C1004D7A57 /* MPPositive_PlayerListShowViewController.swift */, + CB102F4F2BFAE64C00E967D8 /* MPPositive_RecommendViewController.swift */, ); name = "Player(播放器)"; path = "MusicPlayer/MP/MPPositive/ViewControllers/Player(播放器)"; @@ -674,6 +717,7 @@ children = ( CBC32A522BD8D9F300687171 /* MPPositive_BrowseItemModel.swift */, CBE1CB4B2BDE440E00701D57 /* MPPositive_ListHeaderModel.swift */, + CBD6F2152BF48DDD00343A4A /* MPPositive_ArtistHeaderModel.swift */, CBB5D31E2BDF711600CC333D /* MPPositive_SongItemModel.swift */, CBB75B0A2BEF0BC400B3FF9A /* MPPositive_DownloadItemModel.swift */, CBFECE382BF0CFF900E07DC4 /* MPPositive_SearchSuggestionItemModel.swift */, @@ -689,7 +733,10 @@ CBD0CC5D2BDA260500C4B64D /* MPPositive_BrowseItemViewModel.swift */, CBE1CB4D2BDE4BD800701D57 /* MPPositive_ListAlbumListViewModel.swift */, CBE1CB4F2BDE4CC500701D57 /* MPPositive_ListHeaderViewModel.swift */, + CBD6F2172BF4A29B00343A4A /* MPPositive_ArtistViewModel.swift */, + CBD6F2192BF4A38C00343A4A /* MPPositive_ArtistContentListViewModel.swift */, CBEE8E372BEB92CC007DA798 /* MPPositive_SongViewModel.swift */, + CB102F572BFAFFCC00E967D8 /* MPPositive_RecommendListViewModel.swift */, CBE16B942BF251FF005B7EE6 /* MPPositive_SearchSuggestionItemListModel.swift */, CBF456DC2BF1E72F00ABF761 /* MPPositive_SearchResultListViewModel.swift */, CBF456E02BF1EB4300ABF761 /* MPPositive_SearchResultItemViewModel.swift */, @@ -702,7 +749,8 @@ children = ( CBD0CC582BDA238100C4B64D /* MPPositive_BrowseLoadViewModel.swift */, CBDD516E2BECBA6E000F12C5 /* MPPositive_PlayerLoadViewModel.swift */, - CBF456E22BF2086600ABF761 /* MPPositive_LoadSearchResultsViewModel.swift */, + CBF456E22BF2086600ABF761 /* MPPositive_SearchResultsLoadViewModel.swift */, + CB102F592BFB002C00E967D8 /* MPPositive_RecommendLoadViewModel.swift */, ); path = LoadViewModels; sourceTree = ""; @@ -719,7 +767,7 @@ CBCB4FE52BD11402009760B3 /* Models */ = { isa = PBXGroup; children = ( - CBD0CC5C2BDA253800C4B64D /* JsonStructs */, + CBD0CC5C2BDA253800C4B64D /* JsonStructs(js文件结构) */, CBCB4FE42BD11402009760B3 /* ViewModels */, CBCB4FE12BD11402009760B3 /* Models */, ); @@ -730,7 +778,7 @@ isa = PBXGroup; children = ( CBCB501D2BD118AA009760B3 /* Base(基类,导航栏,标签栏) */, - CBCB501C2BD118AA009760B3 /* Home(首页,各项列表页,播放器页) */, + CBCB501C2BD118AA009760B3 /* Home(首页,各项列表页,艺术家页) */, CBB5D3202BDF7DF100CC333D /* Player(播放器) */, CBCB501F2BD118AA009760B3 /* Search(搜索页) */, CBCB501E2BD118AA009760B3 /* Center(个人曲库页) */, @@ -760,14 +808,15 @@ path = MPPositive; sourceTree = ""; }; - CBCB501C2BD118AA009760B3 /* Home(首页,各项列表页,播放器页) */ = { + CBCB501C2BD118AA009760B3 /* Home(首页,各项列表页,艺术家页) */ = { isa = PBXGroup; children = ( CB09189E2BD26AFC006D2B39 /* MPPositive_HomeViewController.swift */, CBE1CB432BDDEAAD00701D57 /* MPPositive_MoreContentViewController.swift */, CBE1CB572BDE550800701D57 /* MPPositive_ListShowViewController.swift */, + CBD6F2112BF4499800343A4A /* MPPositive_ArtistShowViewController.swift */, ); - path = "Home(首页,各项列表页,播放器页)"; + path = "Home(首页,各项列表页,艺术家页)"; sourceTree = ""; }; CBCB501D2BD118AA009760B3 /* Base(基类,导航栏,标签栏) */ = { @@ -840,22 +889,34 @@ CBD313602BD6453A0015D227 /* MPPositive_HomeListFifthCollectionViewCell.swift */, CBE1CB492BDDEBF000701D57 /* MPPositive_MoreListContentCollectionViewCell.swift */, CBB5D31C2BDF4E9600CC333D /* MPPositive_MusicItemShowTableViewCell.swift */, + CBD6F21B2BF4AEE600343A4A /* MPPositive_ArtistShowHeaderView.swift */, + CBD6F21D2BF4B61F00343A4A /* MPPositive_ArtistShowTypeView.swift */, + CBEB017C2BF5D35700D45006 /* MPPositive_ArtistShowSongTableViewCell.swift */, + CBEB01842BF5DB3400D45006 /* MPPositive_ArtistDescriptionTableViewCell.swift */, + CBEB017E2BF5D49400D45006 /* MPPositive_ArtistShowListableViewCell.swift */, + CBEB01802BF5D69200D45006 /* MPPositive_ArtistShowListCollectionViewCell.swift */, + CBEB01822BF5D88400D45006 /* MPPositive_ArtistShowCollectionViewCell.swift */, ); path = Home; sourceTree = ""; }; - CBD0CC5C2BDA253800C4B64D /* JsonStructs */ = { + CBD0CC5C2BDA253800C4B64D /* JsonStructs(js文件结构) */ = { isa = PBXGroup; children = ( CBCB34DA2BD7ACE900802900 /* MPPositive_JsonBrowse.swift */, CBE1CB512BDE4F6C00701D57 /* MPPositive_JsonListAlbum.swift */, + CBD6F2132BF44D8A00343A4A /* MPPositive_JsonArtist.swift */, + CBD6F21F2BF4CE8E00343A4A /* MPPositive_JsonArtistMore.swift */, CBDD516C2BEC6AFE000F12C5 /* MPPositive_JsonNext.swift */, CB5661282BE09D0500CFD014 /* MPPositive_JsonPlayer.swift */, CBB9F9DC2BEDCFEE008338DE /* MPPositive_JsonLyrics.swift */, + CB102F512BFAE73800E967D8 /* MPPositive_JsonRecommend.swift */, CBFECE362BF0C11000E07DC4 /* MPPositive_JsonSearchSuggestions.swift */, CBFECE3E2BF1176B00E07DC4 /* MPPositive_JsonSearchResults.swift */, + CBD5E80D2BF3501200A3EBED /* MPPositive_JsonSearchTypeResults.swift */, + CBD5E80F2BF361B900A3EBED /* MPPositive_JsonSearchTypeContinuation.swift */, ); - path = JsonStructs; + path = "JsonStructs(js文件结构)"; sourceTree = ""; }; CBE4779F2BB16ABD0031C14B /* MP */ = { @@ -895,6 +956,8 @@ CBE2C4C62BC783F700F283A7 /* MP_HUD.swift */, CBC687482BC2882B0023ECA6 /* MPTableManager.swift */, CBD958D12BB6600500666B0D /* MP_PlayerSlider.swift */, + CB102F532BFAFA7200E967D8 /* MP_CircularProgressView.swift */, + CB102F542BFAFA7200E967D8 /* MP_DownloadManager.swift */, ); path = "Tool(工具封装)"; sourceTree = ""; @@ -1094,8 +1157,10 @@ CB0918A52BD26E16006D2B39 /* MPPositive_BottomShowView.swift in Sources */, CBB5D31F2BDF711600CC333D /* MPPositive_SongItemModel.swift in Sources */, CBCAFB5A2BB3C2A000BC6520 /* LayoutConstraint.swift in Sources */, + CB102F522BFAE73800E967D8 /* MPPositive_JsonRecommend.swift in Sources */, CBCB4FEF2BD11402009760B3 /* MPSideA_NavigationController.swift in Sources */, CBF456DD2BF1E72F00ABF761 /* MPPositive_SearchResultListViewModel.swift in Sources */, + CBEB01832BF5D88400D45006 /* MPPositive_ArtistShowCollectionViewCell.swift in Sources */, CBD5E80C2BF33D0200A3EBED /* MPPositive_SearchResultTypeShowView.swift in Sources */, CBCB35212BD7ACE900802900 /* MPPositive_JsonBrowse.swift in Sources */, CBCB4FF62BD11402009760B3 /* MPSideA_DeleteViewController.swift in Sources */, @@ -1103,6 +1168,7 @@ CBF456DF2BF1E8A500ABF761 /* MPPositive_SearchResultItemModel.swift in Sources */, CBF456E72BF20BBD00ABF761 /* MPPositive_SearchResultShowTableViewCell.swift in Sources */, CBDD516F2BECBA6E000F12C5 /* MPPositive_PlayerLoadViewModel.swift in Sources */, + CBD6F2122BF4499800343A4A /* MPPositive_ArtistShowViewController.swift in Sources */, CBEE8E382BEB92CC007DA798 /* MPPositive_SongViewModel.swift in Sources */, CBCB50122BD11402009760B3 /* MPSideA_Home_FirstListCollectionViewCell.swift in Sources */, CB1C16522BC80BF100B96AB3 /* MPSideA_MediaCenterManager.swift in Sources */, @@ -1112,24 +1178,30 @@ CBD313592BD63DDB0015D227 /* MPPositive_HomeListThirdCollectionViewCell.swift in Sources */, CBD958D42BB6942F00666B0D /* MPSideA_VolumeManager.swift in Sources */, CBBFA9182BBA83BA00057FD5 /* MP_CoreDataHandlerManager.swift in Sources */, + CBEB01812BF5D69200D45006 /* MPPositive_ArtistShowListCollectionViewCell.swift in Sources */, CBE1CB442BDDEAAD00701D57 /* MPPositive_MoreContentViewController.swift in Sources */, CBE1CB522BDE4F6C00701D57 /* MPPositive_JsonListAlbum.swift in Sources */, CB0918992BD25DCC006D2B39 /* MPPositive_CustomTabBar.swift in Sources */, CBCB50192BD11402009760B3 /* MPSideA_Home_SecondListCollectionViewCell.swift in Sources */, CBCB50022BD11402009760B3 /* MPSideA_CountTimerViewController.swift in Sources */, CBCAFB662BB3C82C00BC6520 /* MP_LunchViewController.swift in Sources */, + CBD6F21E2BF4B61F00343A4A /* MPPositive_ArtistShowTypeView.swift in Sources */, CBCB4FEA2BD11402009760B3 /* MPSideA_MusicModel.swift in Sources */, CBBFA91A2BBA846600057FD5 /* CoreDataDelegete.swift in Sources */, - CBF456E32BF2086600ABF761 /* MPPositive_LoadSearchResultsViewModel.swift in Sources */, + CBF456E32BF2086600ABF761 /* MPPositive_SearchResultsLoadViewModel.swift in Sources */, CB56612D2BE0DF8C00CFD014 /* MP_WebWork.swift in Sources */, CBFECE352BF0847F00E07DC4 /* MPPositive_SearchSuggestionItemTableViewCell.swift in Sources */, + CB102F562BFAFA7200E967D8 /* MP_DownloadManager.swift in Sources */, CBCB50042BD11402009760B3 /* MPSideA_HomeViewController.swift in Sources */, + CBD5E80E2BF3501200A3EBED /* MPPositive_JsonSearchTypeResults.swift in Sources */, CB09189D2BD25F63006D2B39 /* MPPositive_CustomTabBarItem.swift in Sources */, CBCB4FFC2BD11402009760B3 /* MPSideA_RenameViewController.swift in Sources */, CBCB50162BD11402009760B3 /* MPSideA_Home_HeadBannerView.swift in Sources */, CBCC234F2BEE57AC004D7A57 /* MPPositive_PresentationController.swift in Sources */, + CB102F5A2BFB002C00E967D8 /* MPPositive_RecommendLoadViewModel.swift in Sources */, CBCB500A2BD11402009760B3 /* MPSideA_CustomTabBar.swift in Sources */, CBCAFB692BB3CAC400BC6520 /* MP_Lunch_ProgressView.swift in Sources */, + CBD6F2182BF4A29B00343A4A /* MPPositive_ArtistViewModel.swift in Sources */, CBCB50102BD11402009760B3 /* MPSideA_SettingTableViewCell.swift in Sources */, CBCAFB5D2BB3C52100BC6520 /* HexColor.swift in Sources */, CB0918A12BD26B0A006D2B39 /* MPPositive_SearchViewController.swift in Sources */, @@ -1138,12 +1210,15 @@ CBD0CC592BDA238100C4B64D /* MPPositive_BrowseLoadViewModel.swift in Sources */, CBCB50082BD11402009760B3 /* MPSideA_BottomShowView.swift in Sources */, CBEE8E342BEB16BB007DA798 /* MPPositive_PlayerSilder.swift in Sources */, + CBEB017F2BF5D49400D45006 /* MPPositive_ArtistShowListableViewCell.swift in Sources */, CB09189F2BD26AFC006D2B39 /* MPPositive_HomeViewController.swift in Sources */, CBF456ED2BF2253D00ABF761 /* MPPositive_SearchResultsShowView.swift in Sources */, CBCAFB612BB3C59500BC6520 /* InstanceFromNib.swift in Sources */, CBCB4FFA2BD11402009760B3 /* MPSideA_PrivacyViewController.swift in Sources */, + CBD6F21C2BF4AEE600343A4A /* MPPositive_ArtistShowHeaderView.swift in Sources */, CBCB500E2BD11402009760B3 /* MPSideA_CenterTableViewCell.swift in Sources */, 009662312BB14A5A00FCA65F /* ViewController.swift in Sources */, + CBEB01852BF5DB3400D45006 /* MPPositive_ArtistDescriptionTableViewCell.swift in Sources */, CBE2C4C72BC783F700F283A7 /* MP_HUD.swift in Sources */, CBE2C4C92BC7B25800F283A7 /* TableView.swift in Sources */, CBCB4F9A2BD11089009760B3 /* MP_NavigationController.swift in Sources */, @@ -1157,6 +1232,7 @@ 0096622D2BB14A5A00FCA65F /* AppDelegate.swift in Sources */, CBC32A532BD8D9F300687171 /* MPPositive_BrowseItemModel.swift in Sources */, CBE16B952BF251FF005B7EE6 /* MPPositive_SearchSuggestionItemListModel.swift in Sources */, + CB102F552BFAFA7200E967D8 /* MP_CircularProgressView.swift in Sources */, CBCB4FEC2BD11402009760B3 /* MPSideA_AddViewController.swift in Sources */, CBB75B0B2BEF0BC400B3FF9A /* MPPositive_DownloadItemModel.swift in Sources */, CBCB50172BD11402009760B3 /* MPSideA_Home_RowListsTableViewCell.swift in Sources */, @@ -1164,18 +1240,24 @@ CBD0CC5E2BDA260500C4B64D /* MPPositive_BrowseItemViewModel.swift in Sources */, CBD313612BD6453A0015D227 /* MPPositive_HomeListFifthCollectionViewCell.swift in Sources */, CBE1CB4A2BDDEBF000701D57 /* MPPositive_MoreListContentCollectionViewCell.swift in Sources */, + CB102F502BFAE64C00E967D8 /* MPPositive_RecommendViewController.swift in Sources */, CBCB4FF82BD11402009760B3 /* MPSideA_MoreViewController.swift in Sources */, CBCB50142BD11402009760B3 /* MPSideA_Home_FourthListCollectionViewCell.swift in Sources */, CB5661292BE09D0500CFD014 /* MPPositive_JsonPlayer.swift in Sources */, + CBD5E8102BF361B900A3EBED /* MPPositive_JsonSearchTypeContinuation.swift in Sources */, CBCB50062BD11402009760B3 /* MPSideA_PlayerViewController.swift in Sources */, CBCB4FE92BD11402009760B3 /* MPSideA_LoadDataMusic.swift in Sources */, CBCB4FEE2BD11402009760B3 /* MPSideA_BaseViewController.swift in Sources */, CBE1CB582BDE550800701D57 /* MPPositive_ListShowViewController.swift in Sources */, CBCB500B2BD11402009760B3 /* MPSideA_CustomTabBarItem.swift in Sources */, CBB5D31D2BDF4E9600CC333D /* MPPositive_MusicItemShowTableViewCell.swift in Sources */, + CBEB017D2BF5D35700D45006 /* MPPositive_ArtistShowSongTableViewCell.swift in Sources */, CBCC23512BEE58C1004D7A57 /* MPPositive_PlayerListShowViewController.swift in Sources */, CBDD516D2BEC6AFE000F12C5 /* MPPositive_JsonNext.swift in Sources */, + CBD6F2202BF4CE8E00343A4A /* MPPositive_JsonArtistMore.swift in Sources */, + CBD6F21A2BF4A38C00343A4A /* MPPositive_ArtistContentListViewModel.swift in Sources */, CB0918912BD255EA006D2B39 /* MPPositive_NavigationController.swift in Sources */, + CB102F582BFAFFCC00E967D8 /* MPPositive_RecommendListViewModel.swift in Sources */, CBCB4FF42BD11402009760B3 /* MPSideA_CenterViewController.swift in Sources */, 009662372BB14A5A00FCA65F /* MusicPlayer.xcdatamodeld in Sources */, CB09189B2BD25F50006D2B39 /* MPPositive_CustomTabBarView.swift in Sources */, @@ -1185,7 +1267,9 @@ CBD958D22BB6600500666B0D /* MP_PlayerSlider.swift in Sources */, CBCC23532BEE596E004D7A57 /* MPPositive_PlayerListShowTableViewCell.swift in Sources */, CBC687492BC2882B0023ECA6 /* MPTableManager.swift in Sources */, + CBD6F2142BF44D8A00343A4A /* MPPositive_JsonArtist.swift in Sources */, CBD313532BD60CD80015D227 /* MPPositive_HomeShowTableViewCell.swift in Sources */, + CBD6F2162BF48DDD00343A4A /* MPPositive_ArtistHeaderModel.swift in Sources */, CB0918972BD25D8C006D2B39 /* MPPositive_TabBarController.swift in Sources */, CBCB500C2BD11402009760B3 /* MPSideA_CustomTabBarView.swift in Sources */, CBB9F9DD2BEDCFEE008338DE /* MPPositive_JsonLyrics.swift in Sources */, diff --git a/MusicPlayer.xcodeproj/xcshareddata/xcschemes/MusicPlayer.xcscheme b/MusicPlayer.xcodeproj/xcshareddata/xcschemes/MusicPlayer.xcscheme index fc613e4..36878cd 100644 --- a/MusicPlayer.xcodeproj/xcshareddata/xcschemes/MusicPlayer.xcscheme +++ b/MusicPlayer.xcodeproj/xcshareddata/xcschemes/MusicPlayer.xcscheme @@ -49,13 +49,6 @@ ReferencedContainer = "container:MusicPlayer.xcodeproj"> - - - - ) -> Void) { + let destination: DownloadRequest.Destination = { _, _ in + let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] + let downloadsURL = documentsURL.appendingPathComponent("Downloads") + + // 检查并创建 Downloads 文件夹 + if !FileManager.default.fileExists(atPath: downloadsURL.path) { + do { + try FileManager.default.createDirectory(at: downloadsURL, withIntermediateDirectories: true, attributes: nil) + } catch { + completion(.failure(error)) + return (downloadsURL, [.removePreviousFile, .createIntermediateDirectories]) + } + } + + let fileURL = downloadsURL.appendingPathComponent("\(videoId).mp4") + return (fileURL, [.removePreviousFile, .createIntermediateDirectories]) + } + + AF.download(url, to: destination).downloadProgress { progress in + progressView.setProgress(to: CGFloat(progress.fractionCompleted)) + }.response { response in + if let error = response.error { + completion(.failure(error)) + } else if let filePath = response.fileURL { + completion(.success(filePath)) + } + } + } +} diff --git a/MusicPlayer/MP/Common/Tool(工具封装)/MP_NetWorkManager.swift b/MusicPlayer/MP/Common/Tool(工具封装)/MP_NetWorkManager.swift index b2a9084..1abf7bc 100644 --- a/MusicPlayer/MP/Common/Tool(工具封装)/MP_NetWorkManager.swift +++ b/MusicPlayer/MP/Common/Tool(工具封装)/MP_NetWorkManager.swift @@ -32,10 +32,13 @@ class MP_NetWorkManager: NSObject { private let suggestions:String = "/music/get_search_suggestions" ///搜索接口 private let search = "/search" + ///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"] //MARK: - 固定参数 //访问数据(首次首页预览时获得) private var visitorData:String? - + ///地址 + private lazy var locaton:String = MP_LocationManager.shared.requestLocation() //预览下一阶段参数(网络请求获取) private var continuationAndItct:(String?,String?){ willSet{ @@ -63,7 +66,7 @@ class MP_NetWorkManager: NSObject { //语言 "hl":Language_first_local, //地址 - "gl":Location_First + "gl":locaton ] ] ] @@ -81,8 +84,6 @@ class MP_NetWorkManager: NSObject { //MARK: - 闭包 ///预览闭包(传递一个预览模块数据和完成状态) var browseRequestStateBlock:BrowseRequestStateBlock? - ///列表专辑闭包(传递一个请求完成的列表数据) - var listRequestResultBlock:ListRequestResultBlock? //私有初始化 private override init() { super.init() @@ -162,7 +163,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":Location_First + "gl":locaton ] ] ] @@ -175,9 +176,7 @@ extension MP_NetWorkManager { //发送post请求,并将结果转为RootBrowses AF.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseDecodable(of: JsonBrowses.self) { [weak self] (response) in guard let self = self else {return} - if let task = response.request { - print("URL: \(task.url!)") - } + switch response.result { case .success(let value): if value.responseContext?.visitorData != nil { @@ -201,8 +200,9 @@ extension MP_NetWorkManager { //MARK: - 请求列表专辑预览 /// 向YouTubemusic请求列表/专辑数据,该接口调用的同样是browse预览接口 /// - Parameters: - /// - item: 需要查看的模块 - func requestAlbumOrListDatas(_ item: MPPositive_BrowseItemViewModel) { + /// - browseId: 专辑列表的Id + /// - params: 专辑列表的访问编码 + func requestAlbumOrListDatas(_ browseId: String, params: String, comletion:@escaping (MPPositive_ListAlbumListViewModel) -> Void) { //拼接出browse路径 let path = header+point+browse //设置url @@ -212,8 +212,8 @@ extension MP_NetWorkManager { } //设置参数,browseId与params参数是必定携带内容 let parameters:[String:Any] = [ - "browseId":(item.browseItem.browseContent.browseId ?? ""), - "params":(item.browseItem.browseContent.params ?? ""), + "browseId":browseId, + "params":params, "prettyPrint":"false", "context":[ "client":[ @@ -226,20 +226,19 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":Location_First + "gl":locaton ] ] ] - requestPostAlbumOrList(url, parameters: parameters) + requestPostAlbumOrList(url, parameters: parameters) { results in + comletion(results) + } } //请求列表/专辑数据 - private func requestPostAlbumOrList(_ url:URL, parameters:Parameters) { + private func requestPostAlbumOrList(_ url:URL, parameters:Parameters, comletion:@escaping (MPPositive_ListAlbumListViewModel) -> Void) { //发送post请求,并将结果转为RootBrowses AF.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseDecodable(of: JsonListOrAlbum.self) { [weak self] (response) in guard let self = self else {return} - if let task = response.request { - print("URL: \(task.url!)") - } switch response.result { case .success(let value): let contents = value.contents @@ -251,33 +250,26 @@ extension MP_NetWorkManager { if let header = value.header { list.header = .init(parsingListHeaders(header)) } - //传递列表值 - guard listRequestResultBlock != nil else { - return - } - listRequestResultBlock!(list) + //列表数据完善,回调 + comletion(list) case .failure(let error): // 请求失败,处理错误 print("Request failed: \(error)") } } } - - //MARK: - 请求列表专辑下一部分 - ///请求Next列表(优先于Player) - /// - Parameter item: 请求的预览实体 - func requestNextList(_ item: MPPositive_BrowseItemViewModel, completion:@escaping(([MPPositive_SongItemModel]) -> Void)) { - //拼接出next路径 - let path = header+point+next + ///请求艺术家 + func requestArtist(_ browseId:String, comletion:@escaping (MPPositive_ArtistViewModel) -> Void) { + //拼接出browse路径 + let path = header+point+browse //设置url guard let url = URL(string: path) else { print("Url is Incorrect") return } - //设置参数,videoId与params参数是必定携带内容 + //设置参数,browseId与params参数是必定携带内容 let parameters:[String:Any] = [ - "playlistId":(item.browseItem.musicVideo.playListId ?? ""), - "videoId":(item.browseItem.musicVideo.videoId ?? ""), + "browseId":browseId, "prettyPrint":"false", "context":[ "client":[ @@ -290,7 +282,167 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":Location_First + "gl":locaton + ] + ] + ] + requestPostArtist(url, parameters: parameters) { result in + comletion(result) + } + } + //请求艺术家信息 + private func requestPostArtist(_ url:URL, parameters:Parameters, comletion:@escaping (MPPositive_ArtistViewModel) -> Void) { + //发送post请求,并将结果转为RootBrowses + AF.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseDecodable(of: JsonArtist.self) { [weak self] (response) in + guard let self = self else {return} + switch response.result { + case .success(let value): + //解析value + let artist = MPPositive_ArtistViewModel() + if let header = value.header { + artist.header = parsingArtistHeaders(header) + } + if let contents = value.contents?.singleColumnBrowseResultsRenderer?.tabs?.first?.tabRenderer?.content?.sectionListRenderer?.contents { + artist.lists = parsingArtistContents(contents) + } + comletion(artist) + case .failure(let error): + // 请求失败,处理错误 + print("Request failed: \(error)") + } + } + } + ///请求艺术家更多数据 + func requestArtistMore(_ browseId:String, params: String, comletion:@escaping (([MPPositive_BrowseItemViewModel], String?, String?)) -> Void) { + //拼接出browse路径 + let path = header+point+browse + //设置url + guard let url = URL(string: path) else { + print("Url is Incorrect") + return + } + //设置参数,browseId与params参数是必定携带内容 + let parameters:[String:Any] = [ + "browseId":browseId, + "params":params, + "prettyPrint":"false", + "context":[ + "client":[ + //web端 + "clientName": "WEB_REMIX", + "visitorData":visitorData, + //当前访问版本(日期值) + "clientVersion": "1.\(Date().timeZone().toString(.custom("YYYYMMdd"))).01.00", + "platform":"DESKTOP", + //语言 + "hl":Language_first_local, + //地址 + "gl":locaton + ] + ] + ] + requestPostArtistMore(url, parameters: parameters) { result in + comletion(result) + } + } + ///请求艺术家更多数据 + private func requestPostArtistMore(_ url:URL, parameters:Parameters, comletion:@escaping (([MPPositive_BrowseItemViewModel], String?, String?)) -> Void) { + //发送post请求,并将结果转为RootBrowses + AF.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseDecodable(of: JsonArtistMore.self) { [weak self] (response) in + guard let self = self else {return} + switch response.result { + case .success(let value): + if let content = value.contents?.singleColumnBrowseResultsRenderer?.tabs?.first?.tabRenderer?.content?.sectionListRenderer?.contents?.first { + let result = parsingArtistMore(content) + comletion(result) + } + case .failure(let error): + // 请求失败,处理错误 + print("Request failed: \(error)") + } + } + } + ///请求艺术家更多数据继续 + func requestArtistMoreContinuation(_ continuation:String, itct:String, comletion:@escaping (([MPPositive_BrowseItemViewModel], String?, String?)) -> Void) { + //拼接出browse路径 + let path = header+point+browse + //设置url + guard let url = URL(string: path) else { + print("Url is Incorrect") + return + } + //设置参数,browseId与params参数是必定携带内容 + let parameters:[String:Any] = [ + "continuation":continuation, + "ctoken":continuation, + "type":"next", + "itct":itct, + "prettyPrint":"false", + "context":[ + "client":[ + //web端 + "clientName": "WEB_REMIX", + "visitorData":visitorData, + //当前访问版本(日期值) + "clientVersion": "1.\(Date().timeZone().toString(.custom("YYYYMMdd"))).01.00", + "platform":"DESKTOP", + //语言 + "hl":Language_first_local, + //地址 + "gl":locaton + ] + ] + ] + requestPostArtistMoreContinuation(url, parameters: parameters) { result in + comletion(result) + } + } + ///请求艺术家更多数据继续 + private func requestPostArtistMoreContinuation(_ url:URL, parameters:Parameters, comletion:@escaping (([MPPositive_BrowseItemViewModel], String?, String?)) -> Void) { + //发送post请求,并将结果转为RootBrowses + AF.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseDecodable(of: JsonArtistMore.self) { [weak self] (response) in + guard let self = self else {return} + switch response.result { + case .success(let value): + if let musicPlaylistShelfContinuation = value.continuationContents?.musicPlaylistShelfContinuation { + let result = parsingArtistMoreContinuation(musicPlaylistShelfContinuation) + comletion(result) + } + case .failure(let error): + // 请求失败,处理错误 + print("Request failed: \(error)") + } + } + } + + //MARK: - 请求列表专辑下一部分 + ///请求Next列表(优先于Player) + /// - Parameter item: 请求的预览实体 + func requestNextList(_ browseId:String, videoId:String, completion:@escaping(([MPPositive_SongItemModel]) -> Void)) { + //拼接出next路径 + let path = header+point+next + //设置url + guard let url = URL(string: path) else { + print("Url is Incorrect") + return + } + //设置参数,videoId与params参数是必定携带内容 + let parameters:[String:Any] = [ + "playlistId":browseId, + "videoId":videoId, + "prettyPrint":"false", + "context":[ + "client":[ + //web端 + "clientName": "WEB_REMIX", + "visitorData":visitorData, + //当前访问版本(日期值) + "clientVersion": "1.\(Date().timeZone().toString(.custom("YYYYMMdd"))).01.00", + "platform":"DESKTOP", + //语言 + "hl":Language_first_local, + //地址 + "gl":locaton ] ] ] @@ -341,7 +493,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":Location_First + "gl":locaton ] ] ] @@ -370,7 +522,7 @@ extension MP_NetWorkManager { //MARK: - 请求player播放资源 /// 请求Player(单曲/视频)播放资源 /// - Parameter item: 请求的预览实体 - func requestPlayer(_ item: MPPositive_SongItemModel, completion:@escaping (([String]?, [String]?) -> Void)){ + func requestPlayer(_ item: MPPositive_SongItemModel, completion:@escaping ((([String],[String]), [String]?) -> Void)){ //拼接出player路径 let path = header+point+player //设置url @@ -380,7 +532,6 @@ extension MP_NetWorkManager { } //设置参数,videoId与params参数是必定携带内容 let parameters:[String:Any] = [ -// "playlistId":(item.browseItem.musicVideo.playListId ?? ""), "videoId":(item.videoId ?? ""), "prettyPrint":"false", "context":[ @@ -401,13 +552,11 @@ extension MP_NetWorkManager { } } //请求单曲/视频 - private func requestPostPlayer(_ url:URL, parameters:Parameters, completion:@escaping(([String]?, [String]?) -> Void)) { + private func requestPostPlayer(_ url:URL, parameters:Parameters, completion:@escaping((([String],[String]), [String]?) -> Void)) { //发送post请求 AF.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseDecodable(of: JsonPlayer.self) { [weak self] (response) in guard let self = self else {return} - if let task = response.request { - print("URL: \(task.url!)") - } + switch response.result { case .success(let value): parsingPlayer(value) { resourceUlrs, coverUrls in @@ -445,7 +594,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":Location_First + "gl":locaton ] ] ] @@ -467,6 +616,55 @@ extension MP_NetWorkManager { } } } + ///请求相关内容 + func requestRecommend(_ browseId:String, completion: @escaping ([MPPositive_RecommendListViewModel]) -> Void) { + //拼接出browse路径 + let path = header+point+browse + //设置url + guard let url = URL(string: path) else { + print("Url is Incorrect") + return + } + //设置参数,browseId与params参数是必定携带内容 + let parameters:[String:Any] = [ + "browseId":browseId, + "prettyPrint":"false", + "context":[ + "client":[ + //web端 + "clientName": "WEB_REMIX", + "visitorData":visitorData, + //当前访问版本(日期值) + "clientVersion": "1.\(Date().timeZone().toString(.custom("YYYYMMdd"))).01.00", + "platform":"DESKTOP", + //语言 + "hl":Language_first_local, + //地址 + "gl":locaton + ] + ] + ] + requestPostRecommend(url, parameters: parameters) { results in + completion(results) + } + } + ///请求相关内容 + private func requestPostRecommend(_ url:URL, parameters:Parameters, completion: @escaping ([MPPositive_RecommendListViewModel]) -> Void) { + //发送post请求 + AF.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseDecodable(of: JsonRecommend.self) { [weak self] (response) in + guard let self = self else {return} + switch response.result { + case .success(let value): + if let contents = value.contents?.sectionListRenderer?.contents { + let section = parsingRecommend(contents) + completion(section) + } + case .failure(let error): + // 请求失败,处理错误 + print("Request failed: \(error)") + } + } + } //MARK: - 请求搜索建议 /// 请求搜索建议 @@ -494,7 +692,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":Location_First + "gl":locaton ] ] ] @@ -544,7 +742,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":Location_First + "gl":locaton ] ] ] @@ -600,7 +798,7 @@ extension MP_NetWorkManager { //语言 "hl":Language_first_local, //地址 - "gl":Location_First + "gl":locaton ] ] ] @@ -608,7 +806,7 @@ extension MP_NetWorkManager { completion(result) } } - //请求搜索分页结果 + //请求搜索分类结果 private func requestPostSearchTypeResults(_ url:URL, parameters:Parameters, completion:@escaping (([MPPositive_SearchResultItemViewModel], String?, String?))->Void) { //发送post请求 AF.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseDecodable(of: JsonSearchTypeResults.self) { [weak self] (response) in @@ -618,12 +816,70 @@ extension MP_NetWorkManager { if let musicShelfRenderer = value.contents?.tabbedSearchResultsRenderer?.tabs?.first?.tabRenderer?.content?.sectionListRenderer?.contents?.first?.musicShelfRenderer { completion(parsingSearchTypeResults(musicShelfRenderer)) } + case .failure(let error): // 请求失败,处理错误 print("Request failed: \(error)") } } } + + /// 请求搜索分类继续结果 + /// - Parameters: + /// - continuation: 继续编码 + /// - itct: 继续事件码 + func requestSearchTypeContinuation(_ continuation:String, itct:String, completion:@escaping (([MPPositive_SearchResultItemViewModel], String?, String?))->Void) { + //拼接路径 + let path = header+point+search + //设置url + guard let url = URL(string: path) else { + print("Url is Incorrect") + return + } + //设置参数 + let parameters:[String:Any] = [ + "ctoken":continuation, + "continuation":continuation, + "type":"next", + "itct":itct, + "prettyPrint":false, + "context":[ + "client":[ + //web端 + "clientName": "WEB_REMIX", + "visitorData":visitorData, + //当前访问版本(日期值) + "clientVersion": "1.\(Date().timeZone().toString(.custom("YYYYMMdd"))).01.00", + "platform":"DESKTOP", + //语言 + "hl":Language_first_local, + //地址 + "gl":locaton + ] + ] + ] + requestPostSearchTypeContinuation(url, parameters: parameters) { result in + completion(result) + } + } + //请求搜索分类继续结果 + private func requestPostSearchTypeContinuation(_ url:URL, parameters:Parameters, completion:@escaping (([MPPositive_SearchResultItemViewModel], String?, String?))->Void) { + //发送post请求 + AF.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseDecodable(of: JsonSearchTypeContinuation.self) { [weak self] (response) in + guard let self = self else {return} + switch response.result { + case .success(let value): + if let musicShelfContinuation = value.continuationContents?.musicShelfContinuation { + completion(parsingSearchTypeContinuation(musicShelfContinuation)) + } + + case .failure(let error): + // 请求失败,处理错误 + print("Request failed: \(error)") + } + } + } + } //MARK: - 数据解析 extension MP_NetWorkManager { @@ -745,6 +1001,103 @@ extension MP_NetWorkManager { } return listHeader } + ///解析艺术家_Header + private func parsingArtistHeaders(_ header:JsonArtist.Header) -> MPPositive_ArtistHeaderModel { + let model = MPPositive_ArtistHeaderModel() + model.title = header.musicImmersiveHeaderRenderer?.title?.runs?.reduce("", { $0 + ($1.text ?? "")}) + model.subscriptions = header.musicImmersiveHeaderRenderer?.subscriptionButton?.subscribeButtonRenderer?.subscriberCountText?.runs?.reduce("", { $0 + ($1.text ?? "")}) + model.subscriptionedText = header.musicImmersiveHeaderRenderer?.subscriptionButton?.subscribeButtonRenderer?.subscribedButtonText?.runs?.reduce("", { $0 + ($1.text ?? "")}) + model.fordescription = header.musicImmersiveHeaderRenderer?.description?.runs?.reduce("", { $0 + ($1.text ?? "")}) + model.thumbnails = header.musicImmersiveHeaderRenderer?.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.compactMap({$0.url}) + return model + } + ///解析艺术家_Contents + private func parsingArtistContents(_ contents:[JsonArtist.Contents.SingleColumnBrowseResultsRenderer.Tab.TabRenderer.Content.SectionListRenderer.Content]) -> [MPPositive_ArtistContentListViewModel] { + var listArray:[MPPositive_ArtistContentListViewModel] = [] + ///遍历解析模块内容 + contents.forEach { content in + var title:String? + var itemViews:[MPPositive_BrowseItemViewModel] = [] + var id:String? + var params:String? + if let musicShelfRenderer = content.musicShelfRenderer { + //这是首选模块 + title = musicShelfRenderer.title?.runs?.reduce("", { $0 + ($1.text ?? "")}) + //获取模块的事件值 + id = musicShelfRenderer.title?.runs?.first?.navigationEndpoint?.browseEndpoint?.browseId + params = musicShelfRenderer.title?.runs?.first?.navigationEndpoint?.browseEndpoint?.params + //解析模块内容 + musicShelfRenderer.contents?.forEach({ item in + if item.musicResponsiveListItemRenderer != nil { + itemViews.append(.init(parsingMusicResponsiveListItemRenderer(item.musicResponsiveListItemRenderer!))) + } + }) + } + if let musicCarouselShelfRenderer = content.musicCarouselShelfRenderer { + //这是次选模块 + title = musicCarouselShelfRenderer.header?.musicCarouselShelfBasicHeaderRenderer?.title?.runs?.reduce("", { $0 + ($1.text ?? "")}) + id = musicCarouselShelfRenderer.header?.musicCarouselShelfBasicHeaderRenderer?.title?.runs?.first?.navigationEndpoint?.browseEndpoint?.browseId + params = musicCarouselShelfRenderer.header?.musicCarouselShelfBasicHeaderRenderer?.title?.runs?.first?.navigationEndpoint?.browseEndpoint?.params + //解析模块内容 + musicCarouselShelfRenderer.contents?.forEach({ item in + if item.musicTwoRowItemRenderer != nil { + itemViews.append(.init(parsingMusicTwoRowItemRenderer(item.musicTwoRowItemRenderer!))) + } + }) + } + let list = MPPositive_ArtistContentListViewModel(title, itemViews: itemViews, browseId: id, params: params) + listArray.append(list) + } + return listArray + } + ///解析艺术家更多_More + private func parsingArtistMore(_ content:JsonArtistMore.Contents.SingleColumnBrowseResultsRenderer.Tab.TabRenderer.Content.SectionListRenderer.Content) -> ([MPPositive_BrowseItemViewModel], String?, String?) { + //返回一组预览实体和一对继续编码 + var continuation:String? + var clickTrackingParams:String? + var array:[MPPositive_BrowseItemViewModel] = [] + //判断返回内容是音视频还是专辑列表 + if let musicPlaylistShelfRenderer = content.musicPlaylistShelfRenderer { + //是音视频 + musicPlaylistShelfRenderer.contents?.forEach({ item in + if let musicResponsiveListItemRenderer = item.musicResponsiveListItemRenderer { + array.append(.init(parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer))) + } + }) + continuation = musicPlaylistShelfRenderer.continuations?.first?.nextContinuationData?.continuation + clickTrackingParams = musicPlaylistShelfRenderer.continuations?.first?.nextContinuationData?.clickTrackingParams + } + if let gridRenderer = content.gridRenderer { + //是专辑列表 + gridRenderer.items?.forEach({ item in + if let musicTwoRowItemRenderer = item.musicTwoRowItemRenderer { + array.append(.init(parsingMusicTwoRowItemRenderer(musicTwoRowItemRenderer))) + } + continuation = gridRenderer.continuations?.first?.nextContinuationData?.continuation + clickTrackingParams = gridRenderer.continuations?.first?.nextContinuationData?.clickTrackingParams + }) + } + return (array, continuation, clickTrackingParams) + } + ///解析艺术家更多继续_Continuation + private func parsingArtistMoreContinuation(_ musicPlaylistShelfContinuation: JsonArtistMore.ContinuationContents.MusicPlaylistShelfContinuation) -> ([MPPositive_BrowseItemViewModel], String?, String?) { + //返回一组预览实体和一对继续编码 + var continuation:String? + var clickTrackingParams:String? + var array:[MPPositive_BrowseItemViewModel] = [] + //判断返回内容是音视频还是专辑列表 + if let contents = musicPlaylistShelfContinuation.contents { + contents.forEach { item in + if let musicResponsiveListItemRenderer = item.musicResponsiveListItemRenderer { + array.append(.init(parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer))) + } + } + } + continuation = musicPlaylistShelfContinuation.continuations?.first?.nextContinuationData?.continuation + clickTrackingParams = musicPlaylistShelfContinuation.continuations?.first?.nextContinuationData?.clickTrackingParams + return (array,continuation,clickTrackingParams) + } + ///解析相关内容_Next_中的接下来播放列表 private func parsingNextList(_ next:JsonNext) -> [MPPositive_SongItemModel] { var array:[MPPositive_SongItemModel] = [] @@ -797,24 +1150,28 @@ extension MP_NetWorkManager { /// - Parameters: /// - player: player库 /// - completion: 传递两个字符串数组,第一个资源路径组,第二个是封面路径组 - private func parsingPlayer(_ player:JsonPlayer, completion:@escaping(([String]?, [String]?) -> Void)){ + private func parsingPlayer(_ player:JsonPlayer, completion:@escaping((([String],[String]), [String]?) -> Void)){ var infos:[String]? //解析player,获取资源库和信息库 if let videoDetails = player.videoDetails { infos = parsingPlayerVideoDetails(videoDetails) } if let streamingData = player.streamingData { - parsingPlayerStreamingData(streamingData){ urls in - completion(urls,infos) + parsingPlayerStreamingData(streamingData){ audios,videos in + completion((audios,videos),infos) } } } + /// 解析播放器_StreamingData - /// - Parameter streamingData: 资源库 - private func parsingPlayerStreamingData(_ streamingData:JsonPlayer.StreamingData, completion:@escaping(([String]) -> Void)) { + /// - Parameters: + /// - streamingData: 资源库 + /// - completion: 第一位是音频资源,第二位是视频资源 + private func parsingPlayerStreamingData(_ streamingData:JsonPlayer.StreamingData, completion:@escaping(([String],[String]) -> Void)) { var group:DispatchGroup? = DispatchGroup() - var array:[String] = [] + var videos:[String] = [] + var audios:[String] = [] let allFormats = (streamingData.formats ?? []) + (streamingData.adaptiveFormats ?? []) for format in allFormats { if let signatureCipher = format.signatureCipher { @@ -822,14 +1179,21 @@ extension MP_NetWorkManager { group?.enter() //获得资源签名,开始解密签名内容 parsingPlayerSignatureCipher(signatureCipher) { result in - array.append(result) + //对数据进行拆分,分为视频资源和音频资源 + if format.mimeType?.contains("video") == true { + //这是条视频资源 + videos.append(result) + } + if format.mimeType?.contains("audio") == true { + audios.append(result) + } // 离开DispatchGroup,表示异步任务完成 group?.leave() } } } group?.notify(queue: .main) { - completion(array) + completion(audios,videos) group = nil } } @@ -885,7 +1249,25 @@ extension MP_NetWorkManager { } return "" } - + ///解析相关内容 + private func parsingRecommend(_ contents:[JsonRecommend.Contents.SectionListRenderer.Content]) -> [MPPositive_RecommendListViewModel] { + var sectionLists:[MPPositive_RecommendListViewModel] = [] + contents.forEach { section in + let list = MPPositive_RecommendListViewModel() + list.title = section.musicCarouselShelfRenderer?.header?.musicCarouselShelfBasicHeaderRenderer?.title?.runs?.reduce("", { $0 + ($1.text ?? "")}) + section.musicCarouselShelfRenderer?.contents?.forEach({ content in + if content.musicResponsiveListItemRenderer != nil { + let item = parsingMusicResponsiveListItemRenderer(content.musicResponsiveListItemRenderer!) + list.items.append(.init(item)) + }else if content.musicTwoRowItemRenderer != nil { + let item = parsingMusicTwoRowItemRenderer(content.musicTwoRowItemRenderer!) + list.items.append(.init(item)) + } + }) + sectionLists.append(list) + } + return sectionLists + } /// 解析搜索建议_SearchSuggestions /// - Parameters: /// - searchSuggestions: 需要解析搜索建议 @@ -938,9 +1320,10 @@ extension MP_NetWorkManager { //设置模块标题 resultList.title = musicCardShelfRenderer.header?.musicCardShelfHeaderBasicRenderer?.title?.runs?.reduce("", { $0 + ($1.text ?? "")}) //生成第一个内容块(根据内容不同,可能是单曲/歌手/专辑) - let item = MPPositive_SearchResultItemModel() + let item = MPPositive_BrowseItemModel() //设置第一个内容块的预览图 - item.reviewUrls = musicCardShelfRenderer.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""}) + item.coverUrls = musicCardShelfRenderer.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""}) + item.playListId = musicCardShelfRenderer.menu?.menuRenderer?.items?.first?.menuNavigationItemRenderer?.navigationEndpoint?.watchEndpoint?.playlistId //设置第一个内容块的一级标题和类型和ID if let title = musicCardShelfRenderer.title { title.runs?.forEach({ run in @@ -950,14 +1333,19 @@ extension MP_NetWorkManager { item.videoId = run.navigationEndpoint?.watchEndpoint?.videoId item.itemType = .single }else { - //这个内容块是艺术家/列表 + //这个内容块是艺术家/列表/专辑 item.browseId = run.navigationEndpoint?.browseEndpoint?.browseId - if run.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType == "MUSIC_PAGE_TYPE_ARTIST" { - //是艺术家 - item.itemType = .artist - }else { - //是列表专辑 - item.itemType = .list + let pageType = run.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType + if youTubeKeys.contains(pageType ?? "") == true { + //判断细分 + if pageType == "MUSIC_PAGE_TYPE_ARTIST" { + item.artistId = run.navigationEndpoint?.browseEndpoint?.browseId + //是艺术家 + item.itemType = .artist + }else { + //是列表/专辑 + item.itemType = .list + } } } }) @@ -967,15 +1355,17 @@ extension MP_NetWorkManager { item.subtitle = subtitle.runs?.reduce("", { $0 + ($1.text ?? "")}) } //第一个内容块填充完毕 - resultList.previewItemViews.append(.init(item)) + if item.itemType != nil { + resultList.previewItemViews.append(.init(item)) + } //设置最佳结果的其他内容块 if let contents = musicCardShelfRenderer.contents { contents.forEach { content in //生成更多内容块 - let item = MPPositive_SearchResultItemModel() + let item = MPPositive_BrowseItemModel() if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer { //设置预览图 - item.reviewUrls = musicResponsiveListItemRenderer.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""}) + item.coverUrls = musicResponsiveListItemRenderer.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""}) //设置一级标题与二级标题 for (index, flexColumn) in (musicResponsiveListItemRenderer.flexColumns ?? []).enumerated() { if index == 0 { @@ -986,6 +1376,7 @@ extension MP_NetWorkManager { item.subtitle = (item.subtitle ?? "") + (flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")}) ?? "") } } + item.playListId = musicResponsiveListItemRenderer.menu?.menuRenderer?.items?.first?.menuNavigationItemRenderer?.navigationEndpoint?.watchEndpoint?.playlistId //设置id和类型 if musicResponsiveListItemRenderer.playlistItemData != nil { //是单曲 @@ -994,16 +1385,21 @@ extension MP_NetWorkManager { }else { //是专辑列表/艺术家 item.browseId = musicResponsiveListItemRenderer.navigationEndpoint?.browseEndpoint?.browseId - if musicResponsiveListItemRenderer.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType == "MUSIC_PAGE_TYPE_ARTIST" { - //是艺术家 - item.itemType = .artist - }else { - //是专辑/列表 - item.itemType = .list + let pageType = musicResponsiveListItemRenderer.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType + if youTubeKeys.contains(pageType ?? "") == true { + //判断细分 + if pageType == "MUSIC_PAGE_TYPE_ARTIST" { + item.artistId = musicResponsiveListItemRenderer.navigationEndpoint?.browseEndpoint?.browseId + //是艺术家 + item.itemType = .artist + }else { + //是列表/专辑 + item.itemType = .list + } } } } - if item.title != nil { + if item.title != nil && item.itemType != nil { resultList.previewItemViews.append(.init(item)) } } @@ -1018,9 +1414,9 @@ extension MP_NetWorkManager { //设置内容块 musicShelfRenderer.contents?.forEach({ content in //专辑/列表/单曲视频/艺术家 - let item = MPPositive_SearchResultItemModel() + let item = MPPositive_BrowseItemModel() //设置内容块的封面 - item.reviewUrls = content.musicResponsiveListItemRenderer?.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""}) + item.coverUrls = content.musicResponsiveListItemRenderer?.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""}) //设置一级标题与二级标题 for (index, flexColumn) in (content.musicResponsiveListItemRenderer?.flexColumns ?? []).enumerated() { if index == 0 { @@ -1031,6 +1427,7 @@ extension MP_NetWorkManager { 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 { //是单曲 @@ -1039,15 +1436,22 @@ extension MP_NetWorkManager { }else { //是专辑列表/艺术家 item.browseId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId - if content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType == "MUSIC_PAGE_TYPE_ARTIST" { - //是艺术家 - item.itemType = .artist - }else { - //是专辑/列表 - item.itemType = .list + 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 + } } } - resultList.previewItemViews.append(.init(item)) + if item.itemType != nil { + resultList.previewItemViews.append(.init(item)) + } }) //设置query和params值 if let searchEndpoint = musicShelfRenderer.bottomEndpoint?.searchEndpoint { @@ -1067,9 +1471,9 @@ extension MP_NetWorkManager { ///解析内容块 contents.forEach({ content in //专辑/列表/单曲视频/艺术家 - let item = MPPositive_SearchResultItemModel() + let item = MPPositive_BrowseItemModel() //设置内容块的封面 - item.reviewUrls = content.musicResponsiveListItemRenderer?.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""}) + item.coverUrls = content.musicResponsiveListItemRenderer?.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""}) //设置一级标题与二级标题 for (index, flexColumn) in (content.musicResponsiveListItemRenderer?.flexColumns ?? []).enumerated() { if index == 0 { @@ -1080,6 +1484,7 @@ extension MP_NetWorkManager { 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 { //是单曲 @@ -1088,120 +1493,172 @@ extension MP_NetWorkManager { }else { //是专辑列表/艺术家 item.browseId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId - if content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType == "MUSIC_PAGE_TYPE_ARTIST" { - //是艺术家 - item.itemType = .artist - }else { - //是专辑/列表 - item.itemType = .list + 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 + } } } //添加内容块 - array.append(.init(item)) + if item.itemType != nil { + array.append(.init(item)) + } }) } var continuation:String? var clickTrackingParams:String? - if let continuations = musicShelfRenderer.continuations { + if let continuations = musicShelfRenderer.continuations?.first { ///解析继续编码 continuation = continuations.nextContinuationData?.continuation clickTrackingParams = continuations.nextContinuationData?.clickTrackingParams } + array = array.filter({$0.item.itemType != nil}) + return (array, continuation, clickTrackingParams) + } + ///解析搜索分页继续 + private func parsingSearchTypeContinuation(_ musicShelfContinuation:JsonSearchTypeContinuation.ContinuationContents.MusicShelfContinuation) -> ([MPPositive_SearchResultItemViewModel], String?, String?) { + var array:[MPPositive_SearchResultItemViewModel] = [] + if let contents = musicShelfContinuation.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 ?? "")}) ?? "") + } + } + 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? + var clickTrackingParams:String? + if let continuations = musicShelfContinuation.continuations?.first { + ///解析继续编码 + continuation = continuations.nextContinuationData?.continuation + clickTrackingParams = continuations.nextContinuationData?.clickTrackingParams + } + array = array.filter({$0.item.itemType != nil}) return (array, continuation, clickTrackingParams) } - //MARK: - 解析具体内容形式 - //解析musicResponsiveListItemRenderer(单曲/视频) + //解析musicResponsiveListItemRenderer(通常是音视频内容) private func parsingMusicResponsiveListItemRenderer(_ musicResponsiveListItemRenderer: RootMusicResponsiveListItemRenderer) -> MPPositive_BrowseItemModel { //生成一个音乐模型接收数据 let item = MPPositive_BrowseItemModel() - item.itemType = .single - //封面路径 - item.coverUrl = musicResponsiveListItemRenderer.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.last?.url + //预览图片路径 + item.coverUrls = musicResponsiveListItemRenderer.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.compactMap({$0.url}) + //设置主副标题 if let flexColumns = musicResponsiveListItemRenderer.flexColumns { for (index,flexColumn) in flexColumns.enumerated() { if index == 0 { - item.maintitle = flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")}) - }else if index == 1 { - item.subtitle = flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")}) - }else { - item.thirdtitle = flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")}) + //添加主标题 + item.title = flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")}) + item.playListId = flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.first?.navigationEndpoint?.watchEndpoint?.playlistId + }else{ + item.subtitle = (item.subtitle ?? "") + (flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")}) ?? "") } - var browseContent = BrowseItemContent() - flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.forEach({ run in -// if run.navigationEndpoint?.browseEndpoint?.browseId != nil { -// //获取到艺术家的ID -// item.artistsId = run.navigationEndpoint?.browseEndpoint?.browseId -// } - if run.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != nil && run.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != "MUSIC_PAGE_TYPE_ARTIST" { - //专辑或则歌单 - browseContent.pageType = run.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType - browseContent.browseId = run.navigationEndpoint?.browseEndpoint?.browseId - browseContent.params = run.navigationEndpoint?.browseEndpoint?.params - } - }) - item.browseContent = browseContent } } - //设置音乐id和列表id - if let watch = musicResponsiveListItemRenderer.overlay?.musicItemThumbnailOverlayRenderer?.content?.musicPlayButtonRenderer?.playNavigationEndpoint?.watchEndpoint { - var musicVideo = BrowseItemMusicVideo() - musicVideo.videoId = watch.videoId - musicVideo.playListId = watch.playlistId - musicVideo.musicVideoType = watch.watchEndpointMusicSupportedConfigs?.watchEndpointMusicConfig?.musicVideoType - item.musicVideo = musicVideo + if item.playListId == nil { + //通过操作菜单获取playListId + item.playListId = musicResponsiveListItemRenderer.menu?.menuRenderer?.items?.first?.menuNavigationItemRenderer?.navigationEndpoint?.watchEndpoint?.playlistId + } + //判断这个内容是音视频还是专辑列表艺术家 + if let playlistItemData = musicResponsiveListItemRenderer.playlistItemData { + //是音视频 + item.itemType = .single + item.videoId = playlistItemData.videoId + item.pageType = "MUSIC_VIDEO_TYPE_ATV" + } + if let navigationEndpoint = musicResponsiveListItemRenderer.navigationEndpoint { + //是专辑列表艺术家 + if navigationEndpoint.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType == "MUSIC_PAGE_TYPE_ARTIST" { + //是艺术家 + 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 + } } return item } - //解析musicResponsiveListItemRenderer(list) + //解析musicResponsiveListItemRenderer(是列表专辑内容) private func parsingMusicTwoRowItemRenderer(_ musicTwoRowItemRenderer: RootMusicTwoRowItemRenderer) -> MPPositive_BrowseItemModel { //生成一个音乐模型接收数据 let item = MPPositive_BrowseItemModel() - item.itemType = .list //封面路径 - item.coverUrl = musicTwoRowItemRenderer.thumbnailRenderer?.musicThumbnailRenderer?.thumbnail?.thumbnails?.last?.url + item.coverUrls = musicTwoRowItemRenderer.thumbnailRenderer?.musicThumbnailRenderer?.thumbnail?.thumbnails?.compactMap({$0.url}) //标题 - item.maintitle = musicTwoRowItemRenderer.title?.runs?.reduce("", { $0 + ($1.text ?? "")}) + item.title = musicTwoRowItemRenderer.title?.runs?.reduce("", { $0 + ($1.text ?? "")}) //副标题 item.subtitle = musicTwoRowItemRenderer.subtitle?.runs?.reduce("", { $0 + ($1.text ?? "")}) - var browseContent = BrowseItemContent() - musicTwoRowItemRenderer.title?.runs?.forEach({ run in -// if run.navigationEndpoint?.browseEndpoint?.browseId != nil { -// //获取到艺术家的ID -// item.artistsId = run.navigationEndpoint?.browseEndpoint?.browseId -// } - if run.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != nil && run.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != "MUSIC_PAGE_TYPE_ARTIST" { - //专辑或则歌单 - browseContent.pageType = run.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType - browseContent.browseId = run.navigationEndpoint?.browseEndpoint?.browseId - browseContent.params = run.navigationEndpoint?.browseEndpoint?.params - } - }) - musicTwoRowItemRenderer.subtitle?.runs?.forEach({ run in -// if run.navigationEndpoint?.browseEndpoint?.browseId != nil { -// //获取到艺术家的ID -// item.artistsId = run.navigationEndpoint?.browseEndpoint?.browseId -// } - if run.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != nil && run.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != "MUSIC_PAGE_TYPE_ARTIST" { - //专辑或则歌单 - browseContent.pageType = run.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType - browseContent.browseId = run.navigationEndpoint?.browseEndpoint?.browseId - browseContent.params = run.navigationEndpoint?.browseEndpoint?.params - } - }) - item.browseContent = browseContent - if let playListId = musicTwoRowItemRenderer.thumbnailOverlay?.musicItemThumbnailOverlayRenderer?.content?.musicPlayButtonRenderer?.playNavigationEndpoint?.watchPlaylistEndpoint?.playlistId { - //设置列表ID - var musicVideo = BrowseItemMusicVideo() - musicVideo.playListId = playListId - item.musicVideo = musicVideo - } - if let videoId = musicTwoRowItemRenderer.navigationEndpoint?.watchEndpoint?.videoId { - //是视频 - var musicVideo = BrowseItemMusicVideo() - musicVideo.videoId = videoId - item.musicVideo = musicVideo + //判断这个内容是音视频还是专辑列表艺术家 + if let watchEndpoint = musicTwoRowItemRenderer.navigationEndpoint?.watchEndpoint { + //是音视频 item.itemType = .single + item.videoId = watchEndpoint.videoId + item.playListId = watchEndpoint.playlistId + item.pageType = watchEndpoint.watchEndpointMusicSupportedConfigs?.watchEndpointMusicConfig?.musicVideoType + } + if let browseEndpoint = musicTwoRowItemRenderer.navigationEndpoint?.browseEndpoint { + //是列表专辑艺术家 + if browseEndpoint.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType == "MUSIC_PAGE_TYPE_ARTIST" { + //是艺术家 + item.itemType = .artist + item.artistId = browseEndpoint.browseId + item.pageType = "MUSIC_PAGE_TYPE_ARTIST" + }else { + //是专辑列表 + item.itemType = .list + item.pageType = browseEndpoint.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType + item.browseId = browseEndpoint.browseId + item.params = browseEndpoint.params + } } return item } @@ -1217,3 +1674,4 @@ extension MP_NetWorkManager { return decodedString } } + diff --git a/MusicPlayer/MP/Common/Tool(工具封装)/MP_PlayerManager.swift b/MusicPlayer/MP/Common/Tool(工具封装)/MP_PlayerManager.swift index 6e2296d..68ec22f 100644 --- a/MusicPlayer/MP/Common/Tool(工具封装)/MP_PlayerManager.swift +++ b/MusicPlayer/MP/Common/Tool(工具封装)/MP_PlayerManager.swift @@ -42,6 +42,8 @@ typealias MP_PlayTimerResumeAction = () -> Void typealias MP_PlayTimerStopAction = () -> Void ///播放器调整进度时执行事件 typealias MP_PlayTimerEditEndAction = () -> Void +///播放器缓存值执行事件 +typealias MP_PlayCacheValueAction = (_ currentValue:TimeInterval, _ duration:TimeInterval) -> Void ///播放器 class MP_PlayerManager:NSObject{ ///控制器单例 @@ -57,6 +59,7 @@ class MP_PlayerManager:NSObject{ }else { //用户清空了load模块,隐藏播放器 NotificationCenter.notificationKey.post(notificationName: .player_delete_list) + playState = .Null } } } @@ -94,7 +97,8 @@ class MP_PlayerManager:NSObject{ private var startActionBlock:MP_PlayTimerStartAction! ///播放器运行时执行事件记录 var runActionBlock:MP_PlayTimerRunAction! - + ///播放器缓存值闭包 + var cacheValueBlock:MP_PlayCacheValueAction! private override init() { super.init() // 添加观察者,监听播放结束事件 @@ -151,26 +155,13 @@ class MP_PlayerManager:NSObject{ } } }) - //判断当前Video是否完成预加载 - if loadPlayer.currentVideo.isPreloading == true { - //已经完成了预加载 - print("开始播放音乐-\(loadPlayer.currentVideo.title ?? "")") - player.play() - playState = .Playing - //执行开始播放闭包 - if startActionBlock != nil { - startActionBlock!() - } - }else { - //未完成预加载,通过KVO来准确控制播放 - //为这个currentVideo的resourcePlayerItem创建KVO,分别监听这个item的status,playbackLikelyToKeepUp - loadPlayer.currentVideo.resourcePlayerItem.addObserver(self, forKeyPath: "status", options: .new, context: nil) - loadPlayer.currentVideo.resourcePlayerItem.addObserver(self, forKeyPath: "playbackLikelyToKeepUp", options: .new, context: nil) - } - //启动除了当前播放Video以外的Item的预加载内容 -// for item in loadPlayer.listViewVideos where item.song.videoId != loadPlayer.currentVideo.song.videoId { -// item.preloadPlayerItem() -// } + //对当前播放PlayerItem设置监听状态 + //准备状态 + loadPlayer.currentVideo?.resourcePlayerItem?.addObserver(self, forKeyPath: "status", options: [.old,.new], context: nil) + //当前缓冲值 + loadPlayer.currentVideo?.resourcePlayerItem.addObserver(self, forKeyPath: "loadedTimeRanges", options: [.old,.new], context: nil) + //对其他PlayerItem进行预加载 + } //实现KVO监听 override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { @@ -181,30 +172,48 @@ class MP_PlayerManager:NSObject{ switch keyPath { case "status"://playerItem状态 if let statuValue = change?[.newKey] as? Int, statuValue == AVPlayerItem.Status.readyToPlay.rawValue { - //当statuVlaue值等于playerItem准备播放的值,说明已经准备好播放 - print("当前音乐-\(loadPlayer.currentVideo.title ?? "") 已经准备好播放") - }else { - print("当前音乐-\(loadPlayer.currentVideo.title ?? "") 未做好准备播放") - //当不能播放时,调整内容,再次播放 - } - case "playbackLikelyToKeepUp"://是否存在足够的数据开始播放 - if let playbackLikelyToKeepUp = change?[.newKey] as? Bool, playbackLikelyToKeepUp == true { - //播放器已经加载足够的数据,能够支撑播放 - print("当前音乐-\(loadPlayer.currentVideo.title ?? "") 有足够的缓存来播放") //判断当前播放器是否在播放当前音乐中 if playState != .Playing { + //当statuVlaue值等于playerItem准备播放的值,说明已经准备好播放 + print("当前音乐-\(loadPlayer.currentVideo?.title ?? "") 已经准备好播放") //还未播放当前音乐,启动播放 - print("开始播放音乐-\(loadPlayer.currentVideo.title ?? "")") + print("开始播放音乐-\(loadPlayer.currentVideo?.title ?? "")") player.play() playState = .Playing //执行开始播放闭包 if startActionBlock != nil { startActionBlock!() } - }else { - //播放器已经在播放了,不需要操作 + } + }else { + print("当前音乐-\(loadPlayer.currentVideo?.title ?? "") 未做好准备播放,失败原因是\(loadPlayer.currentVideo?.resourcePlayerItem.error?.localizedDescription ?? "")") + //资源更新,重新配置一下相关内容 + loadPlayer.remakeImproveData { + [weak self] in + guard let self = self else {return} + //重新播放 + play() } } + case "loadedTimeRanges"://当前缓冲进度 + //获取当前播放Item的缓冲值组 + if let timeRanges = loadPlayer.currentVideo?.resourcePlayerItem.loadedTimeRanges.map({$0.timeRangeValue}), let first = timeRanges.first { + //获取开始时间的秒数 + let startSeconds = first.start.seconds + //获取缓冲区的持续时间 + let durationSeconds = first.duration.seconds + //计算当前缓冲总时间 + let bufferedSeconds = startSeconds + durationSeconds + //获取当前播放音乐资源的最大时间值 + let maxDuration = getMusicDuration() + //传递缓存值 + if cacheValueBlock != nil { + cacheValueBlock!(bufferedSeconds, maxDuration) + } + } + + case "playbackLikelyToKeepUp"://是否存在足够的数据开始播放 + break default: break } @@ -224,9 +233,9 @@ class MP_PlayerManager:NSObject{ } switch playType { case .single: - playState = .Null //重播 player.seek(to: CMTime.zero) + player.play() default: //当前音乐播放器正在播放中,下一首 nextEvent() @@ -399,8 +408,10 @@ class MP_PlayerManager:NSObject{ playState = .Null //优先获取传递的值 if let video = sender.object as? MPPositive_SongViewModel { + //切歌时移除KVO监听 video.resourcePlayerItem.removeObserver(self, forKeyPath: "status") - video.resourcePlayerItem.removeObserver(self, forKeyPath: "playbackLikelyToKeepUp") + video.resourcePlayerItem.removeObserver(self, forKeyPath: "loadedTimeRanges") +// video.resourcePlayerItem.removeObserver(self, forKeyPath: "playbackLikelyToKeepUp") } if loadPlayer.currentVideo != nil { //开始播放 diff --git a/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonArtist.swift b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonArtist.swift new file mode 100644 index 0000000..3a13cdd --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonArtist.swift @@ -0,0 +1,836 @@ +// +// MPPositive_JsonArtist.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/15. +// + +import UIKit +///艺术家结构 +struct JsonArtist: Codable { + ///头部结构(艺术家照片,订阅,解说) + let header:Header? + ///艺术家内容结构 + let contents:Contents? + enum CodingKeys: String, CodingKey { + case header = "header" + case contents = "contents" + + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + header = try values.decodeIfPresent(Header.self, forKey: .header) + contents = try values.decodeIfPresent(Contents.self, forKey: .contents) + } + struct Header: Codable { + let musicImmersiveHeaderRenderer:MusicImmersiveHeaderRenderer? + enum CodingKeys: String, CodingKey { + case musicImmersiveHeaderRenderer = "musicImmersiveHeaderRenderer" + + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicImmersiveHeaderRenderer = try values.decodeIfPresent(MusicImmersiveHeaderRenderer.self, forKey: .musicImmersiveHeaderRenderer) + } + struct MusicImmersiveHeaderRenderer: Codable { + ///艺术家名字 + let title:Title? + ///艺术家当前订阅总数 + let subscriptionButton:SubscriptionButton? + ///艺术家介绍 + let description:Description? + ///艺术家大头照 + let thumbnail:Thumbnail? + enum CodingKeys: String, CodingKey { + case title = "title" + case subscriptionButton = "subscriptionButton" + case description = "description" + case thumbnail = "thumbnail" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + title = try values.decodeIfPresent(Title.self, forKey: .title) + subscriptionButton = try values.decodeIfPresent(SubscriptionButton.self, forKey: .subscriptionButton) + description = try values.decodeIfPresent(Description.self, forKey: .description) + thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) + } + struct Title: Codable { + let runs:[Run]? + enum CodingKeys: String, CodingKey { + case runs = "runs" + + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + runs = try values.decodeIfPresent([Run].self, forKey: .runs) + } + struct Run: Codable { + let text:String? + enum CodingKeys: String, CodingKey { + case text = "text" + + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + text = try values.decodeIfPresent(String.self, forKey: .text) + } + } + } + struct SubscriptionButton: Codable { + let subscribeButtonRenderer:SubscribeButtonRenderer? + enum CodingKeys: String, CodingKey { + case subscribeButtonRenderer = "subscribeButtonRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + subscribeButtonRenderer = try values.decodeIfPresent(SubscribeButtonRenderer.self, forKey: .subscribeButtonRenderer) + } + struct SubscribeButtonRenderer: Codable { + ///订阅数文本 + let subscriberCountText:SubscriberCountText? + ///已订阅文本 + let subscribedButtonText:SubscribedButtonText? + enum CodingKeys: String, CodingKey { + case subscriberCountText = "subscriberCountText" + case subscribedButtonText = "subscribedButtonText" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + subscriberCountText = try values.decodeIfPresent(SubscriberCountText.self, forKey: .subscriberCountText) + subscribedButtonText = try values.decodeIfPresent(SubscribedButtonText.self, forKey: .subscribedButtonText) + } + struct SubscriberCountText: Codable { + let runs:[Run]? + enum CodingKeys: String, CodingKey { + case runs = "runs" + + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + runs = try values.decodeIfPresent([Run].self, forKey: .runs) + } + struct Run: Codable { + let text:String? + enum CodingKeys: String, CodingKey { + case text = "text" + + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + text = try values.decodeIfPresent(String.self, forKey: .text) + } + } + } + struct SubscribedButtonText: Codable { + let runs:[Run]? + enum CodingKeys: String, CodingKey { + case runs = "runs" + + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + runs = try values.decodeIfPresent([Run].self, forKey: .runs) + } + struct Run: Codable { + let text:String? + enum CodingKeys: String, CodingKey { + case text = "text" + + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + text = try values.decodeIfPresent(String.self, forKey: .text) + } + } + } + } + } + struct Description:Codable { + let runs:[Run]? + enum CodingKeys: String, CodingKey { + case runs = "runs" + + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + runs = try values.decodeIfPresent([Run].self, forKey: .runs) + } + struct Run: Codable { + let text:String? + enum CodingKeys: String, CodingKey { + case text = "text" + + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + text = try values.decodeIfPresent(String.self, forKey: .text) + } + } + } + struct Thumbnail: Codable { + let musicThumbnailRenderer:MusicThumbnailRenderer? + enum CodingKeys: String, CodingKey { + case musicThumbnailRenderer = "musicThumbnailRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicThumbnailRenderer = try values.decodeIfPresent(MusicThumbnailRenderer.self, forKey: .musicThumbnailRenderer) + } + struct MusicThumbnailRenderer: Codable { + let thumbnail:Thumbnail? + enum CodingKeys: String, CodingKey { + case thumbnail = "thumbnail" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) + } + struct Thumbnail: Codable { + let thumbnails:[Thumbnails]? + enum CodingKeys: String, CodingKey { + case thumbnails = "thumbnails" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + thumbnails = try values.decodeIfPresent([Thumbnails].self, forKey: .thumbnails) + } + struct Thumbnails: Codable { + let url:String? + enum CodingKeys: String, CodingKey { + case url = "url" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + url = try values.decodeIfPresent(String.self, forKey: .url) + } + } + } + } + } + } + } + struct Contents: Codable { + let singleColumnBrowseResultsRenderer:SingleColumnBrowseResultsRenderer? + enum CodingKeys: String, CodingKey { + case singleColumnBrowseResultsRenderer = "singleColumnBrowseResultsRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + singleColumnBrowseResultsRenderer = try values.decodeIfPresent(SingleColumnBrowseResultsRenderer.self, forKey: .singleColumnBrowseResultsRenderer) + } + struct SingleColumnBrowseResultsRenderer: Codable { + let tabs:[Tab]? + enum CodingKeys: String, CodingKey { + case tabs = "tabs" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + tabs = try values.decodeIfPresent([Tab].self, forKey: .tabs) + } + struct Tab: Codable { + let tabRenderer:TabRenderer? + enum CodingKeys: String, CodingKey { + case tabRenderer = "tabRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + tabRenderer = try values.decodeIfPresent(TabRenderer.self, forKey: .tabRenderer) + } + struct TabRenderer: Codable { + let content:Content? + enum CodingKeys: String, CodingKey { + case content = "content" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + content = try values.decodeIfPresent(Content.self, forKey: .content) + } + struct Content: Codable { + let sectionListRenderer:SectionListRenderer? + enum CodingKeys: String, CodingKey { + case sectionListRenderer = "sectionListRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + sectionListRenderer = try values.decodeIfPresent(SectionListRenderer.self, forKey: .sectionListRenderer) + } + struct SectionListRenderer: Codable { + ///各种模块组 + let contents:[Content]? + enum CodingKeys: String, CodingKey { + case contents = "contents" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + contents = try values.decodeIfPresent([Content].self, forKey: .contents) + } + struct Content: Codable { + ///首选模块组 + let musicShelfRenderer:MusicShelfRenderer? + ///其他模块组 + let musicCarouselShelfRenderer:MusicCarouselShelfRenderer? + enum CodingKeys: String, CodingKey { + case musicShelfRenderer = "musicShelfRenderer" + case musicCarouselShelfRenderer = "musicCarouselShelfRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicShelfRenderer = try values.decodeIfPresent(MusicShelfRenderer.self, forKey: .musicShelfRenderer) + musicCarouselShelfRenderer = try values.decodeIfPresent(MusicCarouselShelfRenderer.self, forKey: .musicCarouselShelfRenderer) + } + struct MusicShelfRenderer: Codable { + ///模块组标题信息 + let title:Title? + ///模块组内容组 + let contents:[Content]? + enum CodingKeys: String, CodingKey { + case title = "title" + case contents = "contents" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + title = try values.decodeIfPresent(Title.self, forKey: .title) + contents = try values.decodeIfPresent([Content].self, forKey: .contents) + } + struct Title: Codable { + let runs:[Run]? + enum CodingKeys: String, CodingKey { + case runs = "runs" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + runs = try values.decodeIfPresent([Run].self, forKey: .runs) + } + struct Run: Codable { + ///模块标题 + let text:String? + ///模块事件值 + let navigationEndpoint:NavigationEndpoint? + enum CodingKeys: String, CodingKey { + case text = "text" + case navigationEndpoint = "navigationEndpoint" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + text = try values.decodeIfPresent(String.self, forKey: .text) + navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) + } + struct NavigationEndpoint: Codable { + let browseEndpoint:BrowseEndpoint? + enum CodingKeys: String, CodingKey { + case browseEndpoint = "browseEndpoint" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint) + } + struct BrowseEndpoint: Codable { + ///事件Id + let browseId: String? + ///事件参数 + let params: String? + enum CodingKeys: String, CodingKey { + case browseId = "browseId" + case params = "params" + } + 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) + } + } + } + } + } + struct Content: Codable { + ///内容信息 + let musicResponsiveListItemRenderer:RootMusicResponsiveListItemRenderer? + enum CodingKeys: String, CodingKey { + case musicResponsiveListItemRenderer = "musicResponsiveListItemRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicResponsiveListItemRenderer = try values.decodeIfPresent(RootMusicResponsiveListItemRenderer.self, forKey: .musicResponsiveListItemRenderer) + } +// struct MusicResponsiveListItemRenderer: Codable { +// ///封面 +// let thumbnail:Thumbnail? +// ///文本内容(第0位是标题,其他拼成副标题) +// let flexColumns:[FlexColumn]? +// ///单曲/视频ID(playlistItemData存在说明这条数据单曲/视频) +// let playlistItemData:PlaylistItemData? +// ///专辑/歌单ID(navigationEndpoint存在说明这条数据是专辑/歌单) +// let navigationEndpoint:NavigationEndpoint? +// enum CodingKeys: String, CodingKey { +// case thumbnail = "thumbnail" +// case flexColumns = "flexColumns" +// case playlistItemData = "playlistItemData" +// case navigationEndpoint = "navigationEndpoint" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) +// flexColumns = try values.decodeIfPresent([FlexColumn].self, forKey: .flexColumns) +// playlistItemData = try values.decodeIfPresent(PlaylistItemData.self, forKey: .playlistItemData) +// navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) +// } +// struct Thumbnail: Codable { +// let musicThumbnailRenderer:MusicThumbnailRenderer? +// enum CodingKeys: String, CodingKey { +// case musicThumbnailRenderer = "musicThumbnailRenderer" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// musicThumbnailRenderer = try values.decodeIfPresent(MusicThumbnailRenderer.self, forKey: .musicThumbnailRenderer) +// } +// struct MusicThumbnailRenderer: Codable { +// let thumbnail:Thumbnail? +// enum CodingKeys: String, CodingKey { +// case thumbnail = "thumbnail" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) +// } +// struct Thumbnail: Codable { +// let thumbnails:[Thumbnails]? +// enum CodingKeys: String, CodingKey { +// case thumbnails = "thumbnails" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// thumbnails = try values.decodeIfPresent([Thumbnails].self, forKey: .thumbnails) +// } +// struct Thumbnails: Codable { +// let url:String? +// enum CodingKeys: String, CodingKey { +// case url = "url" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// url = try values.decodeIfPresent(String.self, forKey: .url) +// } +// } +// } +// } +// } +// struct FlexColumn: Codable { +// let musicResponsiveListItemFlexColumnRenderer:MusicResponsiveListItemFlexColumnRenderer? +// enum CodingKeys: String, CodingKey { +// case musicResponsiveListItemFlexColumnRenderer = "musicResponsiveListItemFlexColumnRenderer" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// musicResponsiveListItemFlexColumnRenderer = try values.decodeIfPresent(MusicResponsiveListItemFlexColumnRenderer.self, forKey: .musicResponsiveListItemFlexColumnRenderer) +// } +// struct MusicResponsiveListItemFlexColumnRenderer: Codable { +// let text:Text? +// enum CodingKeys: String, CodingKey { +// case text = "text" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// text = try values.decodeIfPresent(Text.self, forKey: .text) +// } +// struct Text: Codable { +// let runs:[Run]? +// enum CodingKeys: String, CodingKey { +// case runs = "runs" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// runs = try values.decodeIfPresent([Run].self, forKey: .runs) +// } +// struct Run: Codable { +// ///标题文本 +// let text:String? +// let navigationEndpoint:NavigationEndpoint? +// enum CodingKeys: String, CodingKey { +// case text = "text" +// case navigationEndpoint = "navigationEndpoint" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// text = try values.decodeIfPresent(String.self, forKey: .text) +// navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) +// } +// struct NavigationEndpoint: Codable { +// let watchEndpoint:WatchEndpoint? +// enum CodingKeys: String, CodingKey { +// case watchEndpoint = "watchEndpoint" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint) +// } +// struct WatchEndpoint: Codable { +// let playlistId:String? +// enum CodingKeys: String, CodingKey { +// case playlistId = "playlistId" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId) +// } +// } +// } +// } +// } +// } +// } +// struct PlaylistItemData: Codable { +// let videoId:String? +// enum CodingKeys: String, CodingKey { +// case videoId = "videoId" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// videoId = try values.decodeIfPresent(String.self, forKey: .videoId) +// } +// } +// struct NavigationEndpoint: Codable { +// let browseEndpoint:BrowseEndpoint? +// enum CodingKeys: String, CodingKey { +// case browseEndpoint = "browseEndpoint" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint) +// } +// struct BrowseEndpoint: Codable { +// let browseId:String? +// let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs? +// enum CodingKeys: String, CodingKey { +// case browseId = "browseId" +// case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// browseId = try values.decodeIfPresent(String.self, forKey: .browseId) +// 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) +// } +// } +// } +// } +// } +// } + } + } + struct MusicCarouselShelfRenderer: Codable { + ///模块标题信息 + let header:Header? + ///模块内容组 + let contents:[Content]? + enum CodingKeys: String, CodingKey { + case header = "header" + case contents = "contents" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + header = try values.decodeIfPresent(Header.self, forKey: .header) + contents = try values.decodeIfPresent([Content].self, forKey: .contents) + } + struct Header: Codable { + let musicCarouselShelfBasicHeaderRenderer:MusicCarouselShelfBasicHeaderRenderer? + enum CodingKeys: String, CodingKey { + case musicCarouselShelfBasicHeaderRenderer = "musicCarouselShelfBasicHeaderRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicCarouselShelfBasicHeaderRenderer = try values.decodeIfPresent(MusicCarouselShelfBasicHeaderRenderer.self, forKey: .musicCarouselShelfBasicHeaderRenderer) + } + struct MusicCarouselShelfBasicHeaderRenderer: Codable { + let title:Title? + enum CodingKeys: String, CodingKey { + case title = "title" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + title = try values.decodeIfPresent(Title.self, forKey: .title) + } + struct Title: Codable { + let runs:[Run]? + enum CodingKeys: String, CodingKey { + case runs = "runs" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + runs = try values.decodeIfPresent([Run].self, forKey: .runs) + } + struct Run: Codable { + ///模块标题 + let text:String? + ///模块事件值 + let navigationEndpoint:NavigationEndpoint? + enum CodingKeys: String, CodingKey { + case text = "text" + case navigationEndpoint = "navigationEndpoint" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + text = try values.decodeIfPresent(String.self, forKey: .text) + navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) + } + struct NavigationEndpoint: Codable { + let browseEndpoint:BrowseEndpoint? + enum CodingKeys: String, CodingKey { + case browseEndpoint = "browseEndpoint" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint) + } + struct BrowseEndpoint: Codable { + ///事件Id + let browseId: String? + ///事件参数 + let params: String? + enum CodingKeys: String, CodingKey { + case browseId = "browseId" + case params = "params" + } + 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) + } + } + } + } + } + } + } + struct Content: Codable { + let musicTwoRowItemRenderer:RootMusicTwoRowItemRenderer? + enum CodingKeys: String, CodingKey { + case musicTwoRowItemRenderer = "musicTwoRowItemRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicTwoRowItemRenderer = try values.decodeIfPresent(RootMusicTwoRowItemRenderer.self, forKey: .musicTwoRowItemRenderer) + } +// struct MusicTwoRowItemRenderer: Codable { +// ///内容预览图片 +// let thumbnailRenderer:ThumbnailRenderer? +// ///内容标题 +// let title:Title? +// ///内容副标题 +// let subtitle:Subtitle? +// ///内容iD和编码 +// let navigationEndpoint:NavigationEndpoint? +// enum CodingKeys: String, CodingKey { +// case thumbnailRenderer = "thumbnailRenderer" +// case title = "title" +// case subtitle = "subtitle" +// case navigationEndpoint = "navigationEndpoint" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// thumbnailRenderer = try values.decodeIfPresent(ThumbnailRenderer.self, forKey: .thumbnailRenderer) +// title = try values.decodeIfPresent(Title.self, forKey: .title) +// subtitle = try values.decodeIfPresent(Subtitle.self, forKey: .subtitle) +// navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) +// } +// struct ThumbnailRenderer: Codable { +// let musicThumbnailRenderer:MusicThumbnailRenderer? +// enum CodingKeys: String, CodingKey { +// case musicThumbnailRenderer = "musicThumbnailRenderer" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// musicThumbnailRenderer = try values.decodeIfPresent(MusicThumbnailRenderer.self, forKey: .musicThumbnailRenderer) +// } +// struct MusicThumbnailRenderer: Codable { +// let thumbnail:Thumbnail? +// enum CodingKeys: String, CodingKey { +// case thumbnail = "thumbnail" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) +// } +// struct Thumbnail: Codable { +// let thumbnails:[Thumbnails]? +// enum CodingKeys: String, CodingKey { +// case thumbnails = "thumbnails" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// thumbnails = try values.decodeIfPresent([Thumbnails].self, forKey: .thumbnails) +// } +// struct Thumbnails: Codable { +// let url:String? +// enum CodingKeys: String, CodingKey { +// case url = "url" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// url = try values.decodeIfPresent(String.self, forKey: .url) +// } +// } +// } +// } +// } +// struct Title: Codable { +// let runs:[Run]? +// enum CodingKeys: String, CodingKey { +// case runs = "runs" +// +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// runs = try values.decodeIfPresent([Run].self, forKey: .runs) +// } +// struct Run: Codable { +// let text:String? +// enum CodingKeys: String, CodingKey { +// case text = "text" +// +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// text = try values.decodeIfPresent(String.self, forKey: .text) +// } +// } +// } +// struct Subtitle: Codable { +// let runs:[Run]? +// enum CodingKeys: String, CodingKey { +// case runs = "runs" +// +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// runs = try values.decodeIfPresent([Run].self, forKey: .runs) +// } +// struct Run: Codable { +// let text:String? +// enum CodingKeys: String, CodingKey { +// case text = "text" +// +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// text = try values.decodeIfPresent(String.self, forKey: .text) +// } +// } +// } +// struct NavigationEndpoint: Codable { +// ///列表/专辑类型 +// let browseEndpoint:BrowseEndpoint? +// ///音视频类型 +// let watchEndpoint:WatchEndpoint? +// enum CodingKeys: String, CodingKey { +// case browseEndpoint = "browseEndpoint" +// case watchEndpoint = "watchEndpoint" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint) +// watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint) +// } +// 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) +// } +// } +// } +// } +// struct WatchEndpoint: Codable { +// ///音视频ID +// let videoId:String? +// ///音视频所在列表ID +// let playlistId:String? +// ///音视频类型 +// let watchEndpointMusicSupportedConfigs:WatchEndpointMusicSupportedConfigs? +// enum CodingKeys: String, CodingKey { +// case videoId = "videoId" +// case playlistId = "playlistId" +// case watchEndpointMusicSupportedConfigs = "watchEndpointMusicSupportedConfigs" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// videoId = try values.decodeIfPresent(String.self, forKey: .videoId) +// playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId) +// watchEndpointMusicSupportedConfigs = try values.decodeIfPresent(WatchEndpointMusicSupportedConfigs.self, forKey: .watchEndpointMusicSupportedConfigs) +// } +// struct WatchEndpointMusicSupportedConfigs: Codable { +// let watchEndpointMusicConfig:WatchEndpointMusicConfig? +// enum CodingKeys: String, CodingKey { +// case watchEndpointMusicConfig = "watchEndpointMusicConfig" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// watchEndpointMusicConfig = try values.decodeIfPresent(WatchEndpointMusicConfig.self, forKey: .watchEndpointMusicConfig) +// } +// struct WatchEndpointMusicConfig: Codable { +// let musicVideoType:String? +// enum CodingKeys: String, CodingKey { +// case musicVideoType = "musicVideoType" +// } +// init(from decoder: Decoder) throws { +// let values = try decoder.container(keyedBy: CodingKeys.self) +// musicVideoType = try values.decodeIfPresent(String.self, forKey: .musicVideoType) +// } +// } +// } +// } +// } +// } + } + } + } + } + } + } + } + } + } +} diff --git a/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonArtistMore.swift b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonArtistMore.swift new file mode 100644 index 0000000..ee0c87e --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonArtistMore.swift @@ -0,0 +1,274 @@ +// +// MPPositive_JsonArtistMore.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/15. +// + +import UIKit + +struct JsonArtistMore: Codable { + ///数据展示 + let contents:Contents? + ///扩展数据展示,continuation编码获取 + let continuationContents:ContinuationContents? + enum CodingKeys: String, CodingKey { + case contents = "contents" + case continuationContents = "continuationContents" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + contents = try values.decodeIfPresent(Contents.self, forKey: .contents) + continuationContents = try values.decodeIfPresent(ContinuationContents.self, forKey: .continuationContents) + } + struct Contents: Codable { + let singleColumnBrowseResultsRenderer:SingleColumnBrowseResultsRenderer? + enum CodingKeys: String, CodingKey { + case singleColumnBrowseResultsRenderer = "singleColumnBrowseResultsRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + singleColumnBrowseResultsRenderer = try values.decodeIfPresent(SingleColumnBrowseResultsRenderer.self, forKey: .singleColumnBrowseResultsRenderer) + } + struct SingleColumnBrowseResultsRenderer: Codable { + ///通常只有1位数据 + let tabs : [Tab]? + enum CodingKeys: String, CodingKey { + case tabs = "tabs" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + tabs = try values.decodeIfPresent([Tab].self, forKey: .tabs) + } + struct Tab : Codable { + let tabRenderer : TabRenderer? + enum CodingKeys: String, CodingKey { + case tabRenderer = "tabRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + tabRenderer = try values.decodeIfPresent(TabRenderer.self, forKey: .tabRenderer) + } + struct TabRenderer: Codable { + let content:Content? + + enum CodingKeys: String, CodingKey { + case content = "content" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + content = try values.decodeIfPresent(Content.self, forKey: .content) + } + struct Content: Codable { + let sectionListRenderer:SectionListRenderer? + enum CodingKeys: String, CodingKey { + case sectionListRenderer = "sectionListRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + sectionListRenderer = try values.decodeIfPresent(SectionListRenderer.self, forKey: .sectionListRenderer) + } + + struct SectionListRenderer: Codable { + let contents:[Content]? + enum CodingKeys: String, CodingKey { + case contents = "contents" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + contents = try values.decodeIfPresent([Content].self, forKey: .contents) + } + struct Content: Codable { + ///音视频内容 + let musicPlaylistShelfRenderer:MusicPlaylistShelfRenderer? + ///专辑列表内容 + let gridRenderer:GridRenderer? + enum CodingKeys: String, CodingKey { + case musicPlaylistShelfRenderer = "musicPlaylistShelfRenderer" + case gridRenderer = "gridRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicPlaylistShelfRenderer = try values.decodeIfPresent(MusicPlaylistShelfRenderer.self, forKey: .musicPlaylistShelfRenderer) + gridRenderer = try values.decodeIfPresent(GridRenderer.self, forKey: .gridRenderer) + } + struct MusicPlaylistShelfRenderer: Codable { + ///歌单列表id + let playlistId:String? + ///内容组 + let contents:[Content]? + ///继续编码 + let continuations:[Continuation]? + enum CodingKeys: String, CodingKey { + case playlistId = "playlistId" + case contents = "contents" + case continuations = "continuations" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId) + contents = try values.decodeIfPresent([Content].self, forKey: .contents) + continuations = try values.decodeIfPresent([Continuation].self, forKey: .continuations) + } + struct Content: Codable { + let musicResponsiveListItemRenderer: RootMusicResponsiveListItemRenderer? + enum CodingKeys: String, CodingKey { + case musicResponsiveListItemRenderer = "musicResponsiveListItemRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicResponsiveListItemRenderer = try values.decodeIfPresent(RootMusicResponsiveListItemRenderer.self, forKey: .musicResponsiveListItemRenderer) + } + } + struct Continuation: Codable { + let nextContinuationData:NextContinuationData? + enum CodingKeys: String, CodingKey { + case nextContinuationData = "nextContinuationData" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + nextContinuationData = try values.decodeIfPresent(NextContinuationData.self, forKey: .nextContinuationData) + } + struct NextContinuationData: Codable { + let continuation:String? + let clickTrackingParams:String? + enum CodingKeys: String, CodingKey { + case continuation = "continuation" + case clickTrackingParams = "clickTrackingParams" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + continuation = try values.decodeIfPresent(String.self, forKey: .continuation) + clickTrackingParams = try values.decodeIfPresent(String.self, forKey: .clickTrackingParams) + } + + + } + } + } + struct GridRenderer: Codable { + ///内容组 + let items:[Item]? + ///继续编码 + let continuations:[Continuation]? + enum CodingKeys: String, CodingKey { + case items = "items" + case continuations = "continuations" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + items = try values.decodeIfPresent([Item].self, forKey: .items) + continuations = try values.decodeIfPresent([Continuation].self, forKey: .continuations) + } + struct Item: Codable { + let musicTwoRowItemRenderer: RootMusicTwoRowItemRenderer? + + enum CodingKeys: String, CodingKey { + case musicTwoRowItemRenderer = "musicTwoRowItemRenderer" + + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicTwoRowItemRenderer = try values.decodeIfPresent(RootMusicTwoRowItemRenderer.self, forKey: .musicTwoRowItemRenderer) + } + } + struct Continuation: Codable { + let nextContinuationData:NextContinuationData? + enum CodingKeys: String, CodingKey { + case nextContinuationData = "nextContinuationData" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + nextContinuationData = try values.decodeIfPresent(NextContinuationData.self, forKey: .nextContinuationData) + } + struct NextContinuationData: Codable { + let continuation:String? + let clickTrackingParams:String? + enum CodingKeys: String, CodingKey { + case continuation = "continuation" + case clickTrackingParams = "clickTrackingParams" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + continuation = try values.decodeIfPresent(String.self, forKey: .continuation) + clickTrackingParams = try values.decodeIfPresent(String.self, forKey: .clickTrackingParams) + } + + + } + } + } + } + } + } + } + } + } + } + struct ContinuationContents: Codable { + let musicPlaylistShelfContinuation:MusicPlaylistShelfContinuation? + enum CodingKeys: String, CodingKey { + case musicPlaylistShelfContinuation = "musicPlaylistShelfContinuation" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicPlaylistShelfContinuation = try values.decodeIfPresent(MusicPlaylistShelfContinuation.self, forKey: .musicPlaylistShelfContinuation) + } + struct MusicPlaylistShelfContinuation: Codable { + ///内容组 + let contents:[Content]? + ///继续编码组 + let continuations : [Continuation]? + enum CodingKeys: String, CodingKey { + case contents = "contents" + case continuations = "continuations" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + contents = try values.decodeIfPresent([Content].self, forKey: .contents) + continuations = try values.decodeIfPresent([Continuation].self, forKey: .continuations) + } + struct Content: Codable { + let musicResponsiveListItemRenderer:RootMusicResponsiveListItemRenderer? + let musicTwoRowItemRenderer:RootMusicTwoRowItemRenderer? + + enum CodingKeys: String, CodingKey { + case musicResponsiveListItemRenderer = "musicResponsiveListItemRenderer" + case musicTwoRowItemRenderer = "musicTwoRowItemRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicResponsiveListItemRenderer = try values.decodeIfPresent(RootMusicResponsiveListItemRenderer.self, forKey: .musicResponsiveListItemRenderer) + musicTwoRowItemRenderer = try values.decodeIfPresent(RootMusicTwoRowItemRenderer.self, forKey: .musicTwoRowItemRenderer) + } + } + ///续页编码 + struct Continuation: Codable { + let nextContinuationData:NextContinuationData? + enum CodingKeys: String, CodingKey { + case nextContinuationData = "nextContinuationData" + } + + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + nextContinuationData = try values.decodeIfPresent(NextContinuationData.self, forKey: .nextContinuationData) + } + //MARK: - 续页编码 + struct NextContinuationData: Codable { + let continuation:String? + let clickTrackingParams:String? + enum CodingKeys: String, CodingKey { + case continuation = "continuation" + case clickTrackingParams = "clickTrackingParams" + } + + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + continuation = try values.decodeIfPresent(String.self, forKey: .continuation) + clickTrackingParams = try values.decodeIfPresent(String.self, forKey: .clickTrackingParams) + } + } + } + } + } +} diff --git a/MusicPlayer/MP/MPPositive/Models/JsonStructs/MPPositive_JsonBrowse.swift b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonBrowse.swift similarity index 71% rename from MusicPlayer/MP/MPPositive/Models/JsonStructs/MPPositive_JsonBrowse.swift rename to MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonBrowse.swift index 5d158d0..666ba26 100644 --- a/MusicPlayer/MP/MPPositive/Models/JsonStructs/MPPositive_JsonBrowse.swift +++ b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonBrowse.swift @@ -70,15 +70,12 @@ struct JsonBrowses: Codable { struct TabRenderer : Codable { ///内容总汇(包含content以及第一阶段ctoke吗) let content : Content? - let trackingParams : String? enum CodingKeys: String, CodingKey { case content = "content" - case trackingParams = "trackingParams" } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) content = try values.decodeIfPresent(Content.self, forKey: .content) - trackingParams = try values.decodeIfPresent(String.self, forKey: .trackingParams) } struct Content : Codable { let sectionListRenderer : SectionListRenderer? @@ -124,7 +121,7 @@ struct JsonBrowses: Codable { struct MusicCarouselShelfRenderer: Codable { ///指向模块标题 let header:Header? - ///指向音乐内容 + ///指向模块内容 let contents:[Content]? enum CodingKeys: String, CodingKey { case header = "header" @@ -497,24 +494,32 @@ struct JsonBrowses: Codable { } //MARK: - 图像信息数据结构 -///单曲/视频结构(通常是四组件构成,封面,一级标题,二级标题,三级标题,额外包含ID内容) +///单曲/视频结构(通常是四组件构成,封面,一级标题,二级标题,额外包含ID内容) struct RootMusicResponsiveListItemRenderer: Codable { ///指向封面图像 let thumbnail:Thumbnail? - ///指向标题歌手专辑(通常有3位,0位是标题,1位是歌手,3位是专辑/列表) + ///指向标题歌手专辑(通常有多位,0位是标题,后续都为副标题) let flexColumns:[FlexColumn]? - ///指向列表ID和视频ID - let overlay:Overlay? + ///菜单操作(某些情况下flexColumns无法拿到playListId) + let menu:Menu? + ///单曲/视频ID(playlistItemData存在说明这条数据单曲/视频) + let playlistItemData:PlaylistItemData? + ///专辑/歌单ID(navigationEndpoint存在说明这条数据是专辑/歌单) + let navigationEndpoint:NavigationEndpoint? enum CodingKeys: String, CodingKey { case thumbnail = "thumbnail" - case overlay = "overlay" case flexColumns = "flexColumns" + case menu = "menu" + case playlistItemData = "playlistItemData" + case navigationEndpoint = "navigationEndpoint" } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) - overlay = try values.decodeIfPresent(Overlay.self, forKey: .overlay) flexColumns = try values.decodeIfPresent([FlexColumn].self, forKey: .flexColumns) + menu = try values.decodeIfPresent(Menu.self, forKey: .menu) + playlistItemData = try values.decodeIfPresent(PlaylistItemData.self, forKey: .playlistItemData) + navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) } //含有封面图像 struct Thumbnail: Codable { @@ -551,18 +556,12 @@ struct RootMusicResponsiveListItemRenderer: Codable { struct Thumbnails: Codable { ///封面图片路径 let url:String? - let width:CGFloat? - let height:CGFloat? enum CodingKeys: String, CodingKey { case url = "url" - case width = "width" - case height = "height" } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) url = try values.decodeIfPresent(String.self, forKey: .url) - width = try values.decodeIfPresent(CGFloat.self, forKey: .width) - height = try values.decodeIfPresent(CGFloat.self, forKey: .height) } } } @@ -596,12 +595,10 @@ struct RootMusicResponsiveListItemRenderer: Codable { let values = try decoder.container(keyedBy: CodingKeys.self) runs = try values.decodeIfPresent([Run].self, forKey: .runs) } - //MARK: - 文本内容,标题/作者/专辑 struct Run: Codable { - ///关键文本内容(代表各级标题) + ///标题文本 let text:String? - ///指向预览ID - let navigationEndpoint: NavigationEndpoint? + let navigationEndpoint:NavigationEndpoint? enum CodingKeys: String, CodingKey { case text = "text" case navigationEndpoint = "navigationEndpoint" @@ -612,100 +609,6 @@ struct RootMusicResponsiveListItemRenderer: Codable { navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) } struct NavigationEndpoint: Codable { - let browseEndpoint:BrowseEndpoint? - - enum CodingKeys: String, CodingKey { - case browseEndpoint = "browseEndpoint" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint) - - } - //MARK: - 展示内容块的预览内容 - struct BrowseEndpoint: Codable { - ///预览ID(作者/歌单/专辑都有,关键内容) - 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) - } - //MARK: - Browse类型 作者/歌单/专辑 - 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) - } - } - } - } - } - } - } - } - } - //含有列表ID和视频ID - struct Overlay: Codable { - let musicItemThumbnailOverlayRenderer:MusicItemThumbnailOverlayRenderer? - enum CodingKeys: String, CodingKey { - case musicItemThumbnailOverlayRenderer = "musicItemThumbnailOverlayRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - musicItemThumbnailOverlayRenderer = try values.decodeIfPresent(MusicItemThumbnailOverlayRenderer.self, forKey: .musicItemThumbnailOverlayRenderer) - } - struct MusicItemThumbnailOverlayRenderer: Codable { - let content:Content? - enum CodingKeys: String, CodingKey { - case content = "content" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - content = try values.decodeIfPresent(Content.self, forKey: .content) - } - struct Content: Codable { - let musicPlayButtonRenderer:MusicPlayButtonRenderer? - enum CodingKeys: String, CodingKey { - case musicPlayButtonRenderer = "musicPlayButtonRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - musicPlayButtonRenderer = try values.decodeIfPresent(MusicPlayButtonRenderer.self, forKey: .musicPlayButtonRenderer) - } - struct MusicPlayButtonRenderer: Codable { - let playNavigationEndpoint:PlayNavigationEndpoint? - enum CodingKeys: String, CodingKey { - case playNavigationEndpoint = "playNavigationEndpoint" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - playNavigationEndpoint = try values.decodeIfPresent(PlayNavigationEndpoint.self, forKey: .playNavigationEndpoint) - } - struct PlayNavigationEndpoint: Codable { let watchEndpoint:WatchEndpoint? enum CodingKeys: String, CodingKey { case watchEndpoint = "watchEndpoint" @@ -714,51 +617,14 @@ struct RootMusicResponsiveListItemRenderer: Codable { let values = try decoder.container(keyedBy: CodingKeys.self) watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint) } - - //MARK: - 关键内容,视频ID/列表ID/参数 struct WatchEndpoint: Codable { - ///视频ID - let videoId:String? - ///视频列表 let playlistId:String? - ///参数 - let params:String? - ///播放类型 - let watchEndpointMusicSupportedConfigs:WatchEndpointMusicSupportedConfigs? enum CodingKeys: String, CodingKey { - case videoId = "videoId" case playlistId = "playlistId" - case params = "params" - case watchEndpointMusicSupportedConfigs = "watchEndpointMusicSupportedConfigs" } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) - videoId = try values.decodeIfPresent(String.self, forKey: .videoId) playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId) - params = try values.decodeIfPresent(String.self, forKey: .params) - watchEndpointMusicSupportedConfigs = try values.decodeIfPresent(WatchEndpointMusicSupportedConfigs.self, forKey: .watchEndpointMusicSupportedConfigs) - } - struct WatchEndpointMusicSupportedConfigs: Codable { - let watchEndpointMusicConfig:WatchEndpointMusicConfig? - enum CodingKeys: String, CodingKey { - case watchEndpointMusicConfig = "watchEndpointMusicConfig" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - watchEndpointMusicConfig = try values.decodeIfPresent(WatchEndpointMusicConfig.self, forKey: .watchEndpointMusicConfig) - } - //MARK: - 敲定Video类型 - struct WatchEndpointMusicConfig: Codable { - ///这个值存在,那么这个预览例就是Video,具体是什么由这个值判断 - let musicVideoType:String? - enum CodingKeys: String, CodingKey { - case musicVideoType = "musicVideoType" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - musicVideoType = try values.decodeIfPresent(String.self, forKey: .musicVideoType) - } - } } } } @@ -766,33 +632,148 @@ struct RootMusicResponsiveListItemRenderer: Codable { } } } + //菜单操作 + struct Menu: Codable { + let menuRenderer:MenuRenderer? + enum CodingKeys: String, CodingKey { + case menuRenderer = "menuRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + menuRenderer = try values.decodeIfPresent(MenuRenderer.self, forKey: .menuRenderer) + } + struct MenuRenderer: Codable { + let items:[Item]? + enum CodingKeys: String, CodingKey { + case items = "items" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + items = try values.decodeIfPresent([Item].self, forKey: .items) + } + struct Item: Codable { + let menuNavigationItemRenderer:MenuNavigationItemRenderer? + enum CodingKeys: String, CodingKey { + case menuNavigationItemRenderer = "menuNavigationItemRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + menuNavigationItemRenderer = try values.decodeIfPresent(MenuNavigationItemRenderer.self, forKey: .menuNavigationItemRenderer) + } + struct MenuNavigationItemRenderer: Codable { + let navigationEndpoint:NavigationEndpoint? + enum CodingKeys: String, CodingKey { + case navigationEndpoint = "navigationEndpoint" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) + } + + struct NavigationEndpoint: Codable { + let watchEndpoint:WatchEndpoint? + enum CodingKeys: String, CodingKey { + case watchEndpoint = "watchEndpoint" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint) + } + struct WatchEndpoint: Codable { + let playlistId:String? + enum CodingKeys: String, CodingKey { + case playlistId = "playlistId" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId) + } + } + } + } + } + } + } + struct PlaylistItemData: Codable { + let videoId:String? + enum CodingKeys: String, CodingKey { + case videoId = "videoId" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + videoId = try values.decodeIfPresent(String.self, forKey: .videoId) + } + } + struct NavigationEndpoint: Codable { + let browseEndpoint:BrowseEndpoint? + enum CodingKeys: String, CodingKey { + case browseEndpoint = "browseEndpoint" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint) + } + 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) + } + } + } + } + } + } ///列表/专辑结构(通常是三组件构成,封面,一级标题,二级标题,额外包含ID内容) struct RootMusicTwoRowItemRenderer: Codable { - ///指向图像内容 + ///内容预览图片 let thumbnailRenderer:ThumbnailRenderer? - ///指向主标题 + ///内容标题 let title:Title? - ///指向副标题 + ///内容副标题 let subtitle:Subtitle? - ///指向列表ID和视频ID - let thumbnailOverlay:ThumbnailOverlay? - ///指向视频内容 + ///内容iD和编码 let navigationEndpoint:NavigationEndpoint? enum CodingKeys: String, CodingKey { case thumbnailRenderer = "thumbnailRenderer" case title = "title" case subtitle = "subtitle" - case thumbnailOverlay = "thumbnailOverlay" case navigationEndpoint = "navigationEndpoint" } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) - self.thumbnailRenderer = try values.decodeIfPresent(ThumbnailRenderer.self, forKey: .thumbnailRenderer) - self.title = try values.decodeIfPresent(Title.self, forKey: .title) - self.subtitle = try values.decodeIfPresent(Subtitle.self, forKey: .subtitle) - self.thumbnailOverlay = try values.decodeIfPresent(ThumbnailOverlay.self, forKey: .thumbnailOverlay) - self.navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) + thumbnailRenderer = try values.decodeIfPresent(ThumbnailRenderer.self, forKey: .thumbnailRenderer) + title = try values.decodeIfPresent(Title.self, forKey: .title) + subtitle = try values.decodeIfPresent(Subtitle.self, forKey: .subtitle) + navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) } struct ThumbnailRenderer: Codable { let musicThumbnailRenderer:MusicThumbnailRenderer? @@ -801,7 +782,7 @@ struct RootMusicTwoRowItemRenderer: Codable { } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) - self.musicThumbnailRenderer = try values.decodeIfPresent(MusicThumbnailRenderer.self, forKey: .musicThumbnailRenderer) + musicThumbnailRenderer = try values.decodeIfPresent(MusicThumbnailRenderer.self, forKey: .musicThumbnailRenderer) } struct MusicThumbnailRenderer: Codable { let thumbnail:Thumbnail? @@ -810,35 +791,25 @@ struct RootMusicTwoRowItemRenderer: Codable { } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) - self.thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) + thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) } struct Thumbnail: Codable { - ///封面图片组(默认取最后一位,图像内容最大最高清) let thumbnails:[Thumbnails]? enum CodingKeys: String, CodingKey { case thumbnails = "thumbnails" } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) - self.thumbnails = try values.decodeIfPresent([Thumbnails].self, forKey: .thumbnails) + thumbnails = try values.decodeIfPresent([Thumbnails].self, forKey: .thumbnails) } - //MARK: - 封面图片 - ///封面图片 struct Thumbnails: Codable { - ///封面图片路径 let url:String? - let width:CGFloat? - let height:CGFloat? enum CodingKeys: String, CodingKey { case url = "url" - case width = "width" - case height = "height" } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) url = try values.decodeIfPresent(String.self, forKey: .url) - width = try values.decodeIfPresent(CGFloat.self, forKey: .width) - height = try values.decodeIfPresent(CGFloat.self, forKey: .height) } } } @@ -848,78 +819,21 @@ struct RootMusicTwoRowItemRenderer: Codable { let runs:[Run]? enum CodingKeys: String, CodingKey { case runs = "runs" + } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) - self.runs = try values.decodeIfPresent([Run].self, forKey: .runs) + runs = try values.decodeIfPresent([Run].self, forKey: .runs) } - //MARK: - 文本内容,标题/作者/专辑 struct Run: Codable { - ///关键文本内容(代表各级标题) let text:String? - ///指向预览ID - let navigationEndpoint: NavigationEndpoint? enum CodingKeys: String, CodingKey { case text = "text" - case navigationEndpoint = "navigationEndpoint" + } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) text = try values.decodeIfPresent(String.self, forKey: .text) - navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) - } - struct NavigationEndpoint: Codable { - let browseEndpoint:BrowseEndpoint? - - enum CodingKeys: String, CodingKey { - case browseEndpoint = "browseEndpoint" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint) - - } - //MARK: - 展示内容块的预览内容 - struct BrowseEndpoint: Codable { - ///预览ID(作者/歌单/专辑都有,关键内容) - 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) - } - //MARK: - Browse类型 作者/歌单/专辑 - 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) - } - } - } - } } } } @@ -927,166 +841,111 @@ struct RootMusicTwoRowItemRenderer: Codable { let runs:[Run]? enum CodingKeys: String, CodingKey { case runs = "runs" + } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) - self.runs = try values.decodeIfPresent([Run].self, forKey: .runs) + runs = try values.decodeIfPresent([Run].self, forKey: .runs) } - //MARK: - 文本内容,标题/作者/专辑 struct Run: Codable { - ///关键文本内容(代表各级标题) let text:String? - ///指向预览ID - let navigationEndpoint: NavigationEndpoint? enum CodingKeys: String, CodingKey { case text = "text" - case navigationEndpoint = "navigationEndpoint" + } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) text = try values.decodeIfPresent(String.self, forKey: .text) - navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) - } - struct NavigationEndpoint: Codable { - let browseEndpoint:BrowseEndpoint? - - enum CodingKeys: String, CodingKey { - case browseEndpoint = "browseEndpoint" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint) - - } - //MARK: - 展示内容块的预览内容 - struct BrowseEndpoint: Codable { - ///预览ID(作者/歌单/专辑都有,关键内容) - 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) - } - //MARK: - Browse类型 作者/歌单/专辑 - 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) - } - } - } - } - } - } - } - struct ThumbnailOverlay: Codable { - let musicItemThumbnailOverlayRenderer:MusicItemThumbnailOverlayRenderer? - enum CodingKeys: String, CodingKey { - case musicItemThumbnailOverlayRenderer = "musicItemThumbnailOverlayRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - self.musicItemThumbnailOverlayRenderer = try values.decodeIfPresent(MusicItemThumbnailOverlayRenderer.self, forKey: .musicItemThumbnailOverlayRenderer) - } - struct MusicItemThumbnailOverlayRenderer: Codable { - let content:Content? - enum CodingKeys: String, CodingKey { - case content = "content" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - self.content = try values.decodeIfPresent(Content.self, forKey: .content) - } - struct Content: Codable { - let musicPlayButtonRenderer:MusicPlayButtonRenderer? - enum CodingKeys: String, CodingKey { - case musicPlayButtonRenderer = "musicPlayButtonRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - self.musicPlayButtonRenderer = try values.decodeIfPresent(MusicPlayButtonRenderer.self, forKey: .musicPlayButtonRenderer) - } - struct MusicPlayButtonRenderer: Codable { - let playNavigationEndpoint:PlayNavigationEndpoint? - enum CodingKeys: String, CodingKey { - case playNavigationEndpoint = "playNavigationEndpoint" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - self.playNavigationEndpoint = try values.decodeIfPresent(PlayNavigationEndpoint.self, forKey: .playNavigationEndpoint) - } - struct PlayNavigationEndpoint: Codable { - let watchPlaylistEndpoint:WatchPlaylistEndpoint? - enum CodingKeys: String, CodingKey { - case watchPlaylistEndpoint = "watchPlaylistEndpoint" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - watchPlaylistEndpoint = try values.decodeIfPresent(WatchPlaylistEndpoint.self, forKey: .watchPlaylistEndpoint) - } - - //MARK: - 列表/专辑ID - struct WatchPlaylistEndpoint: Codable { - ///视频列表 - let playlistId:String? - enum CodingKeys: String, CodingKey { - case playlistId = "playlistId" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId) - } - } - } - } } } } struct NavigationEndpoint: Codable { + ///列表/专辑类型 + let browseEndpoint:BrowseEndpoint? + ///音视频类型 let watchEndpoint:WatchEndpoint? enum CodingKeys: String, CodingKey { + case browseEndpoint = "browseEndpoint" case watchEndpoint = "watchEndpoint" - } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) - self.watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint) - + browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint) + watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint) } - struct WatchEndpoint: Codable { - let videoId:String? - + struct BrowseEndpoint: Codable { + let browseId:String? + let params:String? + let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs? enum CodingKeys: String, CodingKey { - case videoId = "videoId" - + case browseId = "browseId" + case params = "params" + case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs" } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) - self.videoId = try values.decodeIfPresent(String.self, forKey: .videoId) - + 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) + } + } + } + } + struct WatchEndpoint: Codable { + ///音视频ID + let videoId:String? + ///音视频所在列表ID + let playlistId:String? + ///音视频类型 + let watchEndpointMusicSupportedConfigs:WatchEndpointMusicSupportedConfigs? + enum CodingKeys: String, CodingKey { + case videoId = "videoId" + case playlistId = "playlistId" + case watchEndpointMusicSupportedConfigs = "watchEndpointMusicSupportedConfigs" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + videoId = try values.decodeIfPresent(String.self, forKey: .videoId) + playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId) + watchEndpointMusicSupportedConfigs = try values.decodeIfPresent(WatchEndpointMusicSupportedConfigs.self, forKey: .watchEndpointMusicSupportedConfigs) + } + struct WatchEndpointMusicSupportedConfigs: Codable { + let watchEndpointMusicConfig:WatchEndpointMusicConfig? + enum CodingKeys: String, CodingKey { + case watchEndpointMusicConfig = "watchEndpointMusicConfig" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + watchEndpointMusicConfig = try values.decodeIfPresent(WatchEndpointMusicConfig.self, forKey: .watchEndpointMusicConfig) + } + struct WatchEndpointMusicConfig: Codable { + let musicVideoType:String? + enum CodingKeys: String, CodingKey { + case musicVideoType = "musicVideoType" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicVideoType = try values.decodeIfPresent(String.self, forKey: .musicVideoType) + } + } } } } diff --git a/MusicPlayer/MP/MPPositive/Models/JsonStructs/MPPositive_JsonListAlbum.swift b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonListAlbum.swift similarity index 100% rename from MusicPlayer/MP/MPPositive/Models/JsonStructs/MPPositive_JsonListAlbum.swift rename to MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonListAlbum.swift diff --git a/MusicPlayer/MP/MPPositive/Models/JsonStructs/MPPositive_JsonLyrics.swift b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonLyrics.swift similarity index 100% rename from MusicPlayer/MP/MPPositive/Models/JsonStructs/MPPositive_JsonLyrics.swift rename to MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonLyrics.swift diff --git a/MusicPlayer/MP/MPPositive/Models/JsonStructs/MPPositive_JsonNext.swift b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonNext.swift similarity index 100% rename from MusicPlayer/MP/MPPositive/Models/JsonStructs/MPPositive_JsonNext.swift rename to MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonNext.swift diff --git a/MusicPlayer/MP/MPPositive/Models/JsonStructs/MPPositive_JsonPlayer.swift b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonPlayer.swift similarity index 100% rename from MusicPlayer/MP/MPPositive/Models/JsonStructs/MPPositive_JsonPlayer.swift rename to MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonPlayer.swift diff --git a/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonRecommend.swift b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonRecommend.swift new file mode 100644 index 0000000..605743b --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonRecommend.swift @@ -0,0 +1,119 @@ +// +// MPPositive_Recommend.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/20. +// + +import UIKit + +struct JsonRecommend: Codable { + let contents:Contents? + enum CodingKeys: String, CodingKey { + case contents = "contents" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + contents = try values.decodeIfPresent(Contents.self, forKey: .contents) + } + struct Contents: Codable { + let sectionListRenderer:SectionListRenderer? + enum CodingKeys: String, CodingKey { + case sectionListRenderer = "sectionListRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + sectionListRenderer = try values.decodeIfPresent(SectionListRenderer.self, forKey: .sectionListRenderer) + } + struct SectionListRenderer: Codable { + let contents:[Content]? + enum CodingKeys: String, CodingKey { + case contents = "contents" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + contents = try values.decodeIfPresent([Content].self, forKey: .contents) + } + struct Content: Codable { + let musicCarouselShelfRenderer:MusicCarouselShelfRenderer? + enum CodingKeys: String, CodingKey { + case musicCarouselShelfRenderer = "musicCarouselShelfRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicCarouselShelfRenderer = try values.decodeIfPresent(MusicCarouselShelfRenderer.self, forKey: .musicCarouselShelfRenderer) + } + struct MusicCarouselShelfRenderer: Codable { + ///头部标题文本 + let header:Header? + ///内容组 + let contents:[Content]? + enum CodingKeys: String, CodingKey { + case header = "header" + case contents = "contents" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + header = try values.decodeIfPresent(Header.self, forKey: .header) + contents = try values.decodeIfPresent([Content].self, forKey: .contents) + } + struct Header: Codable { + let musicCarouselShelfBasicHeaderRenderer:MusicCarouselShelfBasicHeaderRenderer? + enum CodingKeys: String, CodingKey { + case musicCarouselShelfBasicHeaderRenderer = "musicCarouselShelfBasicHeaderRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicCarouselShelfBasicHeaderRenderer = try values.decodeIfPresent(MusicCarouselShelfBasicHeaderRenderer.self, forKey: .musicCarouselShelfBasicHeaderRenderer) + } + struct MusicCarouselShelfBasicHeaderRenderer: Codable { + let title:Title? + enum CodingKeys: String, CodingKey { + case title = "title" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + title = try values.decodeIfPresent(Title.self, forKey: .title) + } + struct Title: Codable { + let runs:[Run]? + enum CodingKeys: String, CodingKey { + case runs = "runs" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + runs = try values.decodeIfPresent([Run].self, forKey: .runs) + } + + struct Run: Codable { + ///歌词 + let text:String? + enum CodingKeys: String, CodingKey { + case text = "text" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + text = try values.decodeIfPresent(String.self, forKey: .text) + } + } + } + } + } + struct Content: Codable { + let musicResponsiveListItemRenderer:RootMusicResponsiveListItemRenderer? + let musicTwoRowItemRenderer:RootMusicTwoRowItemRenderer? + enum CodingKeys: String, CodingKey { + case musicResponsiveListItemRenderer = "musicResponsiveListItemRenderer" + case musicTwoRowItemRenderer = "musicTwoRowItemRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicResponsiveListItemRenderer = try values.decodeIfPresent(RootMusicResponsiveListItemRenderer.self, forKey: .musicResponsiveListItemRenderer) + musicTwoRowItemRenderer = try values.decodeIfPresent(RootMusicTwoRowItemRenderer.self, forKey: .musicTwoRowItemRenderer) + } + } + } + } + } + } +} diff --git a/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonSearchResults.swift b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonSearchResults.swift new file mode 100644 index 0000000..cab15fc --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonSearchResults.swift @@ -0,0 +1,469 @@ +// +// MPPositive_JsonSearchResults.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/12. +// + +import UIKit +//MARK: - 搜索结果结构 +///搜索预览结果结构 +struct JsonSearchPreviewResults: Codable { + let contents:Contents? + enum CodingKeys: String, CodingKey { + case contents = "contents" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + contents = try values.decodeIfPresent(Contents.self, forKey: .contents) + } + struct Contents: Codable { + let tabbedSearchResultsRenderer:TabbedSearchResultsRenderer? + enum CodingKeys: String, CodingKey { + case tabbedSearchResultsRenderer = "tabbedSearchResultsRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + tabbedSearchResultsRenderer = try values.decodeIfPresent(TabbedSearchResultsRenderer.self, forKey: .tabbedSearchResultsRenderer) + } + struct TabbedSearchResultsRenderer: Codable { + let tabs:[Tab]? + enum CodingKeys: String, CodingKey { + case tabs = "tabs" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + tabs = try values.decodeIfPresent([Tab].self, forKey: .tabs) + } + struct Tab:Codable { + let tabRenderer:TabRenderer? + enum CodingKeys: String, CodingKey { + case tabRenderer = "tabRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + tabRenderer = try values.decodeIfPresent(TabRenderer.self, forKey: .tabRenderer) + } + struct TabRenderer: Codable { + let content:Content? + enum CodingKeys: String, CodingKey { + case content = "content" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + content = try values.decodeIfPresent(Content.self, forKey: .content) + } + struct Content: Codable { + let sectionListRenderer:SectionListRenderer? + enum CodingKeys: String, CodingKey { + case sectionListRenderer = "sectionListRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + sectionListRenderer = try values.decodeIfPresent(SectionListRenderer.self, forKey: .sectionListRenderer) + } + struct SectionListRenderer: Codable { + ///模块(每个模块内容不一样) + let contents:[Content]? + enum CodingKeys: String, CodingKey { + case contents = "contents" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + contents = try values.decodeIfPresent([Content].self, forKey: .contents) + } + //MARK: - 模块 + struct Content: Codable { + ///最佳结果 + let musicCardShelfRenderer:MusicCardShelfRenderer? + ///其他结果(同时还有更多内容键值) + let musicShelfRenderer:MusicShelfRenderer? + enum CodingKeys: String, CodingKey { + case musicCardShelfRenderer = "musicCardShelfRenderer" + case musicShelfRenderer = "musicShelfRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicCardShelfRenderer = try values.decodeIfPresent(MusicCardShelfRenderer.self, forKey: .musicCardShelfRenderer) + musicShelfRenderer = try values.decodeIfPresent(MusicShelfRenderer.self, forKey: .musicShelfRenderer) + } + //MARK: - 不同模块携带的内容 + ///最佳结果 + struct MusicCardShelfRenderer: Codable { + ///最佳结果封面 + let thumbnail:Thumbnail? + ///最佳结果标题(附带单曲ID) + let title:Title? + ///最佳结果副标题 + let subtitle:Subtitle? + ///菜单操作(某些情况下flexColumns无法拿到playListId) + let menu:Menu? + ///最佳结果组头标题 + let header:Header? + ///最佳结果其他内容,第0位是无用数据,获取时跳过 + let contents:[Content]? + enum CodingKeys: String, CodingKey { + case thumbnail = "thumbnail" + case title = "title" + case subtitle = "subtitle" + case menu = "menu" + case header = "header" + case contents = "contents" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) + title = try values.decodeIfPresent(Title.self, forKey: .title) + subtitle = try values.decodeIfPresent(Subtitle.self, forKey: .subtitle) + menu = try values.decodeIfPresent(Menu.self, forKey: .menu) + header = try values.decodeIfPresent(Header.self, forKey: .header) + contents = try values.decodeIfPresent([Content].self, forKey: .contents) + } + ///最佳结果封面 + struct Thumbnail: Codable { + let musicThumbnailRenderer:MusicThumbnailRenderer? + enum CodingKeys: String, CodingKey { + case musicThumbnailRenderer = "musicThumbnailRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicThumbnailRenderer = try values.decodeIfPresent(MusicThumbnailRenderer.self, forKey: .musicThumbnailRenderer) + } + struct MusicThumbnailRenderer: Codable { + let thumbnail:Thumbnail? + enum CodingKeys: String, CodingKey { + case thumbnail = "thumbnail" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) + } + struct Thumbnail: Codable { + let thumbnails:[Thumbnails]? + enum CodingKeys: String, CodingKey { + case thumbnails = "thumbnails" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + thumbnails = try values.decodeIfPresent([Thumbnails].self, forKey: .thumbnails) + } + struct Thumbnails: Codable { + let url:String? + enum CodingKeys: String, CodingKey { + case url = "url" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + url = try values.decodeIfPresent(String.self, forKey: .url) + } + } + } + } + } + ///最佳结果标题 + struct Title: Codable { + let runs:[Run]? + enum CodingKeys: String, CodingKey { + case runs = "runs" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + runs = try values.decodeIfPresent([Run].self, forKey: .runs) + } + struct Run: Codable { + ///标题文本 + let text:String? + let navigationEndpoint:NavigationEndpoint? + enum CodingKeys: String, CodingKey { + case text = "text" + case navigationEndpoint = "navigationEndpoint" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + text = try values.decodeIfPresent(String.self, forKey: .text) + navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) + } + 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 videoId:String? + enum CodingKeys: String, CodingKey { + case videoId = "videoId" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + videoId = try values.decodeIfPresent(String.self, forKey: .videoId) + } + } + struct BrowseEndpoint: Codable { + let browseId:String? + let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs? + enum CodingKeys: String, CodingKey { + case browseId = "browseId" + case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + browseId = try values.decodeIfPresent(String.self, forKey: .browseId) + 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) + } + } + } + } + } + } + } + ///最佳结果副标题 + struct Subtitle: Codable { + let runs:[Run]? + enum CodingKeys: String, CodingKey { + case runs = "runs" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + runs = try values.decodeIfPresent([Run].self, forKey: .runs) + } + struct Run: Codable { + ///标题文本 + let text:String? + enum CodingKeys: String, CodingKey { + case text = "text" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + text = try values.decodeIfPresent(String.self, forKey: .text) + } + } + } + ///菜单操作 + struct Menu: Codable { + let menuRenderer:MenuRenderer? + enum CodingKeys: String, CodingKey { + case menuRenderer = "menuRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + menuRenderer = try values.decodeIfPresent(MenuRenderer.self, forKey: .menuRenderer) + } + struct MenuRenderer: Codable { + let items:[Item]? + enum CodingKeys: String, CodingKey { + case items = "items" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + items = try values.decodeIfPresent([Item].self, forKey: .items) + } + struct Item: Codable { + let menuNavigationItemRenderer:MenuNavigationItemRenderer? + enum CodingKeys: String, CodingKey { + case menuNavigationItemRenderer = "menuNavigationItemRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + menuNavigationItemRenderer = try values.decodeIfPresent(MenuNavigationItemRenderer.self, forKey: .menuNavigationItemRenderer) + } + struct MenuNavigationItemRenderer: Codable { + let navigationEndpoint:NavigationEndpoint? + enum CodingKeys: String, CodingKey { + case navigationEndpoint = "navigationEndpoint" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) + } + + struct NavigationEndpoint: Codable { + let watchEndpoint:WatchEndpoint? + enum CodingKeys: String, CodingKey { + case watchEndpoint = "watchEndpoint" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint) + } + struct WatchEndpoint: Codable { + let playlistId:String? + enum CodingKeys: String, CodingKey { + case playlistId = "playlistId" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId) + } + } + } + } + } + } + } + ///最佳结果组头 + struct Header: Codable { + let musicCardShelfHeaderBasicRenderer:MusicCardShelfHeaderBasicRenderer? + enum CodingKeys: String, CodingKey { + case musicCardShelfHeaderBasicRenderer = "musicCardShelfHeaderBasicRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicCardShelfHeaderBasicRenderer = try values.decodeIfPresent(MusicCardShelfHeaderBasicRenderer.self, forKey: .musicCardShelfHeaderBasicRenderer) + } + struct MusicCardShelfHeaderBasicRenderer: Codable { + let title:Title? + enum CodingKeys: String, CodingKey { + case title = "title" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + title = try values.decodeIfPresent(Title.self, forKey: .title) + } + struct Title:Codable { + let runs:[Run]? + enum CodingKeys: String, CodingKey { + case runs = "runs" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + runs = try values.decodeIfPresent([Run].self, forKey: .runs) + } + + struct Run: Codable { + ///标题文本 + let text:String? + enum CodingKeys: String, CodingKey { + case text = "text" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + text = try values.decodeIfPresent(String.self, forKey: .text) + } + } + } + } + } + ///最佳结果其他内容 + struct Content: Codable { + let musicResponsiveListItemRenderer:RootMusicResponsiveListItemRenderer? + enum CodingKeys: String, CodingKey { + case musicResponsiveListItemRenderer = "musicResponsiveListItemRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicResponsiveListItemRenderer = try values.decodeIfPresent(RootMusicResponsiveListItemRenderer.self, forKey: .musicResponsiveListItemRenderer) + } + } + } + ///其他结果 + struct MusicShelfRenderer: Codable { + ///模块标题 + let title:Title? + ///模块内容 + let contents:[Content]? + ///更多内容 + let bottomEndpoint:BottomEndpoint? + enum CodingKeys: String, CodingKey { + case title = "title" + case contents = "contents" + case bottomEndpoint = "bottomEndpoint" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + title = try values.decodeIfPresent(Title.self, forKey: .title) + contents = try values.decodeIfPresent([Content].self, forKey: .contents) + bottomEndpoint = try values.decodeIfPresent(BottomEndpoint.self, forKey: .bottomEndpoint) + } + struct Title:Codable { + let runs:[Run]? + enum CodingKeys: String, CodingKey { + case runs = "runs" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + runs = try values.decodeIfPresent([Run].self, forKey: .runs) + } + + struct Run: Codable { + ///标题文本 + let text:String? + enum CodingKeys: String, CodingKey { + case text = "text" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + text = try values.decodeIfPresent(String.self, forKey: .text) + } + } + } + struct Content: Codable { + let musicResponsiveListItemRenderer:RootMusicResponsiveListItemRenderer? + enum CodingKeys: String, CodingKey { + case musicResponsiveListItemRenderer = "musicResponsiveListItemRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicResponsiveListItemRenderer = try values.decodeIfPresent(RootMusicResponsiveListItemRenderer.self, forKey: .musicResponsiveListItemRenderer) + } + } + struct BottomEndpoint: Codable { + let searchEndpoint:SearchEndpoint? + enum CodingKeys: String, CodingKey { + case searchEndpoint = "searchEndpoint" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + searchEndpoint = try values.decodeIfPresent(SearchEndpoint.self, forKey: .searchEndpoint) + } + struct SearchEndpoint: Codable { + ///当前搜索文本 + let query:String? + ///更多内容参数 + let params:String? + enum CodingKeys: String, CodingKey { + case query = "query" + case params = "params" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + query = try values.decodeIfPresent(String.self, forKey: .query) + params = try values.decodeIfPresent(String.self, forKey: .params) + } + } + } + } + } + } + } + } + } + } + } +} diff --git a/MusicPlayer/MP/MPPositive/Models/JsonStructs/MPPositive_JsonSearchSuggestions.swift b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonSearchSuggestions.swift similarity index 100% rename from MusicPlayer/MP/MPPositive/Models/JsonStructs/MPPositive_JsonSearchSuggestions.swift rename to MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonSearchSuggestions.swift diff --git a/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonSearchTypeContinuation.swift b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonSearchTypeContinuation.swift new file mode 100644 index 0000000..1e8f461 --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonSearchTypeContinuation.swift @@ -0,0 +1,82 @@ +// +// MPPositive_JsonSearchTypeContinuation.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/14. +// + +import UIKit +///搜索分类结果继续结构 +struct JsonSearchTypeContinuation: Codable { + let continuationContents:ContinuationContents? + enum CodingKeys: String, CodingKey { + case continuationContents = "continuationContents" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + continuationContents = try values.decodeIfPresent(ContinuationContents.self, forKey: .continuationContents) + } + struct ContinuationContents: Codable { + let musicShelfContinuation:MusicShelfContinuation? + enum CodingKeys: String, CodingKey { + case musicShelfContinuation = "musicShelfContinuation" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicShelfContinuation = try values.decodeIfPresent(MusicShelfContinuation.self, forKey: .musicShelfContinuation) + } + struct MusicShelfContinuation: Codable { + ///内容块 + let contents:[Content]? + ///继续请求块 + let continuations:[Continuation]? + enum CodingKeys: String, CodingKey { + case contents = "contents" + case continuations = "continuations" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + contents = try values.decodeIfPresent([Content].self, forKey: .contents) + continuations = try values.decodeIfPresent([Continuation].self, forKey: .continuations) + } + ///内容块 + struct Content: Codable { + let musicResponsiveListItemRenderer:RootMusicResponsiveListItemRenderer? + + enum CodingKeys: String, CodingKey { + case musicResponsiveListItemRenderer = "musicResponsiveListItemRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicResponsiveListItemRenderer = try values.decodeIfPresent(RootMusicResponsiveListItemRenderer.self, forKey: .musicResponsiveListItemRenderer) + } + } + ///继续请求块 + struct Continuation: Codable { + let nextContinuationData:NextContinuationData? + enum CodingKeys: String, CodingKey { + case nextContinuationData = "nextContinuationData" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + nextContinuationData = try values.decodeIfPresent(NextContinuationData.self, forKey: .nextContinuationData) + } + struct NextContinuationData: Codable { + ///继续请求编码 + let continuation:String? + ///继续请求参数 + let clickTrackingParams:String? + enum CodingKeys: String, CodingKey { + case continuation = "continuation" + case clickTrackingParams = "clickTrackingParams" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + continuation = try values.decodeIfPresent(String.self, forKey: .continuation) + clickTrackingParams = try values.decodeIfPresent(String.self, forKey: .clickTrackingParams) + } + } + } + } + } +} diff --git a/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonSearchTypeResults.swift b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonSearchTypeResults.swift new file mode 100644 index 0000000..81d9dd9 --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonSearchTypeResults.swift @@ -0,0 +1,144 @@ +// +// MPPositive_JsonSearchTypeResults.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/14. +// + +import UIKit + +///搜索分类结果结构(该分类详情) +struct JsonSearchTypeResults: Codable { + let contents:Contents? + enum CodingKeys: String, CodingKey { + case contents = "contents" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + contents = try values.decodeIfPresent(Contents.self, forKey: .contents) + } + struct Contents: Codable { + let tabbedSearchResultsRenderer:TabbedSearchResultsRenderer? + enum CodingKeys: String, CodingKey { + case tabbedSearchResultsRenderer = "tabbedSearchResultsRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + tabbedSearchResultsRenderer = try values.decodeIfPresent(TabbedSearchResultsRenderer.self, forKey: .tabbedSearchResultsRenderer) + } + struct TabbedSearchResultsRenderer: Codable { + let tabs:[Tab]? + enum CodingKeys: String, CodingKey { + case tabs = "tabs" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + tabs = try values.decodeIfPresent([Tab].self, forKey: .tabs) + } + struct Tab:Codable { + let tabRenderer:TabRenderer? + enum CodingKeys: String, CodingKey { + case tabRenderer = "tabRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + tabRenderer = try values.decodeIfPresent(TabRenderer.self, forKey: .tabRenderer) + } + struct TabRenderer: Codable { + let content:Content? + enum CodingKeys: String, CodingKey { + case content = "content" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + content = try values.decodeIfPresent(Content.self, forKey: .content) + } + struct Content: Codable { + let sectionListRenderer:SectionListRenderer? + enum CodingKeys: String, CodingKey { + case sectionListRenderer = "sectionListRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + sectionListRenderer = try values.decodeIfPresent(SectionListRenderer.self, forKey: .sectionListRenderer) + } + struct SectionListRenderer: Codable { + ///模块(每个模块内容不一样) + let contents:[Content]? + enum CodingKeys: String, CodingKey { + case contents = "contents" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + contents = try values.decodeIfPresent([Content].self, forKey: .contents) + } + struct Content:Codable { + let musicShelfRenderer:MusicShelfRenderer? + enum CodingKeys: String, CodingKey { + case musicShelfRenderer = "musicShelfRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicShelfRenderer = try values.decodeIfPresent(MusicShelfRenderer.self, forKey: .musicShelfRenderer) + } + struct MusicShelfRenderer: Codable { + ///内容块 + let contents:[Content]? + ///继续请求块 + let continuations:[Continuation]? + enum CodingKeys: String, CodingKey { + case contents = "contents" + case continuations = "continuations" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + contents = try values.decodeIfPresent([Content].self, forKey: .contents) + continuations = try values.decodeIfPresent([Continuation].self, forKey: .continuations) + } + ///内容块 + struct Content: Codable { + let musicResponsiveListItemRenderer:RootMusicResponsiveListItemRenderer? + + enum CodingKeys: String, CodingKey { + case musicResponsiveListItemRenderer = "musicResponsiveListItemRenderer" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + musicResponsiveListItemRenderer = try values.decodeIfPresent(RootMusicResponsiveListItemRenderer.self, forKey: .musicResponsiveListItemRenderer) + } + } + ///继续请求块 + struct Continuation: Codable { + let nextContinuationData:NextContinuationData? + enum CodingKeys: String, CodingKey { + case nextContinuationData = "nextContinuationData" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + nextContinuationData = try values.decodeIfPresent(NextContinuationData.self, forKey: .nextContinuationData) + } + struct NextContinuationData: Codable { + ///继续请求编码 + let continuation:String? + ///继续请求参数 + let clickTrackingParams:String? + enum CodingKeys: String, CodingKey { + case continuation = "continuation" + case clickTrackingParams = "clickTrackingParams" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + continuation = try values.decodeIfPresent(String.self, forKey: .continuation) + clickTrackingParams = try values.decodeIfPresent(String.self, forKey: .clickTrackingParams) + } + } + } + } + } + } + } + } + } + } + } +} diff --git a/MusicPlayer/MP/MPPositive/Models/JsonStructs/MPPositive_JsonSearchResults.swift b/MusicPlayer/MP/MPPositive/Models/JsonStructs/MPPositive_JsonSearchResults.swift deleted file mode 100644 index c15e666..0000000 --- a/MusicPlayer/MP/MPPositive/Models/JsonStructs/MPPositive_JsonSearchResults.swift +++ /dev/null @@ -1,1009 +0,0 @@ -// -// MPPositive_JsonSearchResults.swift -// MusicPlayer -// -// Created by Mr.Zhou on 2024/5/12. -// - -import UIKit -//MARK: - 搜索结果结构 -///搜索预览结果结构 -struct JsonSearchPreviewResults: Codable { - let contents:Contents? - enum CodingKeys: String, CodingKey { - case contents = "contents" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - contents = try values.decodeIfPresent(Contents.self, forKey: .contents) - } - struct Contents: Codable { - let tabbedSearchResultsRenderer:TabbedSearchResultsRenderer? - enum CodingKeys: String, CodingKey { - case tabbedSearchResultsRenderer = "tabbedSearchResultsRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - tabbedSearchResultsRenderer = try values.decodeIfPresent(TabbedSearchResultsRenderer.self, forKey: .tabbedSearchResultsRenderer) - } - struct TabbedSearchResultsRenderer: Codable { - let tabs:[Tab]? - enum CodingKeys: String, CodingKey { - case tabs = "tabs" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - tabs = try values.decodeIfPresent([Tab].self, forKey: .tabs) - } - struct Tab:Codable { - let tabRenderer:TabRenderer? - enum CodingKeys: String, CodingKey { - case tabRenderer = "tabRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - tabRenderer = try values.decodeIfPresent(TabRenderer.self, forKey: .tabRenderer) - } - struct TabRenderer: Codable { - let content:Content? - enum CodingKeys: String, CodingKey { - case content = "content" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - content = try values.decodeIfPresent(Content.self, forKey: .content) - } - struct Content: Codable { - let sectionListRenderer:SectionListRenderer? - enum CodingKeys: String, CodingKey { - case sectionListRenderer = "sectionListRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - sectionListRenderer = try values.decodeIfPresent(SectionListRenderer.self, forKey: .sectionListRenderer) - } - struct SectionListRenderer: Codable { - ///模块(每个模块内容不一样) - let contents:[Content]? - enum CodingKeys: String, CodingKey { - case contents = "contents" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - contents = try values.decodeIfPresent([Content].self, forKey: .contents) - } - //MARK: - 模块 - struct Content: Codable { - ///最佳结果 - let musicCardShelfRenderer:MusicCardShelfRenderer? - ///其他结果(同时还有更多内容键值) - let musicShelfRenderer:MusicShelfRenderer? - enum CodingKeys: String, CodingKey { - case musicCardShelfRenderer = "musicCardShelfRenderer" - case musicShelfRenderer = "musicShelfRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - musicCardShelfRenderer = try values.decodeIfPresent(MusicCardShelfRenderer.self, forKey: .musicCardShelfRenderer) - musicShelfRenderer = try values.decodeIfPresent(MusicShelfRenderer.self, forKey: .musicShelfRenderer) - } - //MARK: - 不同模块携带的内容 - ///最佳结果 - struct MusicCardShelfRenderer: Codable { - ///最佳结果封面 - let thumbnail:Thumbnail? - ///最佳结果标题(附带单曲ID) - let title:Title? - ///最佳结果副标题 - let subtitle:Subtitle? - ///最佳结果组头标题 - let header:Header? - ///最佳结果其他内容,第0位是无用数据,获取时跳过 - let contents:[Content]? - enum CodingKeys: String, CodingKey { - case thumbnail = "thumbnail" - case title = "title" - case subtitle = "subtitle" - case header = "header" - case contents = "contents" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) - title = try values.decodeIfPresent(Title.self, forKey: .title) - subtitle = try values.decodeIfPresent(Subtitle.self, forKey: .subtitle) - header = try values.decodeIfPresent(Header.self, forKey: .header) - contents = try values.decodeIfPresent([Content].self, forKey: .contents) - } - ///最佳结果封面 - struct Thumbnail: Codable { - let musicThumbnailRenderer:MusicThumbnailRenderer? - enum CodingKeys: String, CodingKey { - case musicThumbnailRenderer = "musicThumbnailRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - musicThumbnailRenderer = try values.decodeIfPresent(MusicThumbnailRenderer.self, forKey: .musicThumbnailRenderer) - } - struct MusicThumbnailRenderer: Codable { - let thumbnail:Thumbnail? - enum CodingKeys: String, CodingKey { - case thumbnail = "thumbnail" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) - } - struct Thumbnail: Codable { - let thumbnails:[Thumbnails]? - enum CodingKeys: String, CodingKey { - case thumbnails = "thumbnails" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - thumbnails = try values.decodeIfPresent([Thumbnails].self, forKey: .thumbnails) - } - struct Thumbnails: Codable { - let url:String? - enum CodingKeys: String, CodingKey { - case url = "url" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - url = try values.decodeIfPresent(String.self, forKey: .url) - } - } - } - } - } - ///最佳结果标题 - struct Title: Codable { - let runs:[Run]? - enum CodingKeys: String, CodingKey { - case runs = "runs" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - runs = try values.decodeIfPresent([Run].self, forKey: .runs) - } - struct Run: Codable { - ///标题文本 - let text:String? - let navigationEndpoint:NavigationEndpoint? - enum CodingKeys: String, CodingKey { - case text = "text" - case navigationEndpoint = "navigationEndpoint" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - text = try values.decodeIfPresent(String.self, forKey: .text) - navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) - } - 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 videoId:String? - enum CodingKeys: String, CodingKey { - case videoId = "videoId" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - videoId = try values.decodeIfPresent(String.self, forKey: .videoId) - } - } - struct BrowseEndpoint: Codable { - let browseId:String? - let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs? - enum CodingKeys: String, CodingKey { - case browseId = "browseId" - case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - browseId = try values.decodeIfPresent(String.self, forKey: .browseId) - 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) - } - } - } - } - } - } - } - ///最佳结果副标题 - struct Subtitle: Codable { - let runs:[Run]? - enum CodingKeys: String, CodingKey { - case runs = "runs" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - runs = try values.decodeIfPresent([Run].self, forKey: .runs) - } - struct Run: Codable { - ///标题文本 - let text:String? - enum CodingKeys: String, CodingKey { - case text = "text" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - text = try values.decodeIfPresent(String.self, forKey: .text) - } - } - } - ///最佳结果组头 - struct Header: Codable { - let musicCardShelfHeaderBasicRenderer:MusicCardShelfHeaderBasicRenderer? - enum CodingKeys: String, CodingKey { - case musicCardShelfHeaderBasicRenderer = "musicCardShelfHeaderBasicRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - musicCardShelfHeaderBasicRenderer = try values.decodeIfPresent(MusicCardShelfHeaderBasicRenderer.self, forKey: .musicCardShelfHeaderBasicRenderer) - } - struct MusicCardShelfHeaderBasicRenderer: Codable { - let title:Title? - enum CodingKeys: String, CodingKey { - case title = "title" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - title = try values.decodeIfPresent(Title.self, forKey: .title) - } - struct Title:Codable { - let runs:[Run]? - enum CodingKeys: String, CodingKey { - case runs = "runs" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - runs = try values.decodeIfPresent([Run].self, forKey: .runs) - } - - struct Run: Codable { - ///标题文本 - let text:String? - enum CodingKeys: String, CodingKey { - case text = "text" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - text = try values.decodeIfPresent(String.self, forKey: .text) - } - } - } - } - } - ///最佳结果其他内容 - struct Content: Codable { - let musicResponsiveListItemRenderer:MusicResponsiveListItemRenderer? - enum CodingKeys: String, CodingKey { - case musicResponsiveListItemRenderer = "musicResponsiveListItemRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - musicResponsiveListItemRenderer = try values.decodeIfPresent(MusicResponsiveListItemRenderer.self, forKey: .musicResponsiveListItemRenderer) - } - struct MusicResponsiveListItemRenderer: Codable { - ///封面 - let thumbnail:Thumbnail? - ///文本内容(第0位是标题,其他拼成副标题) - let flexColumns:[FlexColumn]? - ///单曲/视频ID(playlistItemData存在说明这条数据单曲/视频) - let playlistItemData:PlaylistItemData? - ///专辑/歌单ID/歌手(navigationEndpoint存在说明这条数据是专辑/歌单/歌手) - let navigationEndpoint:NavigationEndpoint? - enum CodingKeys: String, CodingKey { - case thumbnail = "thumbnail" - case flexColumns = "flexColumns" - case playlistItemData = "playlistItemData" - case navigationEndpoint = "navigationEndpoint" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) - flexColumns = try values.decodeIfPresent([FlexColumn].self, forKey: .flexColumns) - playlistItemData = try values.decodeIfPresent(PlaylistItemData.self, forKey: .playlistItemData) - navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) - } - struct Thumbnail: Codable { - let musicThumbnailRenderer:MusicThumbnailRenderer? - enum CodingKeys: String, CodingKey { - case musicThumbnailRenderer = "musicThumbnailRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - musicThumbnailRenderer = try values.decodeIfPresent(MusicThumbnailRenderer.self, forKey: .musicThumbnailRenderer) - } - struct MusicThumbnailRenderer: Codable { - let thumbnail:Thumbnail? - enum CodingKeys: String, CodingKey { - case thumbnail = "thumbnail" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) - } - struct Thumbnail: Codable { - let thumbnails:[Thumbnails]? - enum CodingKeys: String, CodingKey { - case thumbnails = "thumbnails" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - thumbnails = try values.decodeIfPresent([Thumbnails].self, forKey: .thumbnails) - } - struct Thumbnails: Codable { - let url:String? - enum CodingKeys: String, CodingKey { - case url = "url" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - url = try values.decodeIfPresent(String.self, forKey: .url) - } - } - } - } - } - struct FlexColumn: Codable { - let musicResponsiveListItemFlexColumnRenderer:MusicResponsiveListItemFlexColumnRenderer? - enum CodingKeys: String, CodingKey { - case musicResponsiveListItemFlexColumnRenderer = "musicResponsiveListItemFlexColumnRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - musicResponsiveListItemFlexColumnRenderer = try values.decodeIfPresent(MusicResponsiveListItemFlexColumnRenderer.self, forKey: .musicResponsiveListItemFlexColumnRenderer) - } - struct MusicResponsiveListItemFlexColumnRenderer: Codable { - let text:Text? - enum CodingKeys: String, CodingKey { - case text = "text" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - text = try values.decodeIfPresent(Text.self, forKey: .text) - } - struct Text: Codable { - let runs:[Run]? - enum CodingKeys: String, CodingKey { - case runs = "runs" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - runs = try values.decodeIfPresent([Run].self, forKey: .runs) - } - struct Run: Codable { - ///标题文本 - let text:String? - enum CodingKeys: String, CodingKey { - case text = "text" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - text = try values.decodeIfPresent(String.self, forKey: .text) - } - } - } - } - } - struct PlaylistItemData: Codable { - let videoId:String? - enum CodingKeys: String, CodingKey { - case videoId = "videoId" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - videoId = try values.decodeIfPresent(String.self, forKey: .videoId) - } - } - struct NavigationEndpoint: Codable { - let browseEndpoint:BrowseEndpoint? - enum CodingKeys: String, CodingKey { - case browseEndpoint = "browseEndpoint" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint) - } - struct BrowseEndpoint: Codable { - let browseId:String? - let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs? - enum CodingKeys: String, CodingKey { - case browseId = "browseId" - case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - browseId = try values.decodeIfPresent(String.self, forKey: .browseId) - 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) - } - } - } - } - } - } - } - } - ///其他结果 - struct MusicShelfRenderer: Codable { - ///模块标题 - let title:Title? - ///模块内容 - let contents:[Content]? - ///更多内容 - let bottomEndpoint:BottomEndpoint? - enum CodingKeys: String, CodingKey { - case title = "title" - case contents = "contents" - case bottomEndpoint = "bottomEndpoint" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - title = try values.decodeIfPresent(Title.self, forKey: .title) - contents = try values.decodeIfPresent([Content].self, forKey: .contents) - bottomEndpoint = try values.decodeIfPresent(BottomEndpoint.self, forKey: .bottomEndpoint) - } - struct Title:Codable { - let runs:[Run]? - enum CodingKeys: String, CodingKey { - case runs = "runs" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - runs = try values.decodeIfPresent([Run].self, forKey: .runs) - } - - struct Run: Codable { - ///标题文本 - let text:String? - enum CodingKeys: String, CodingKey { - case text = "text" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - text = try values.decodeIfPresent(String.self, forKey: .text) - } - } - } - struct Content: Codable { - let musicResponsiveListItemRenderer:MusicResponsiveListItemRenderer? - enum CodingKeys: String, CodingKey { - case musicResponsiveListItemRenderer = "musicResponsiveListItemRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - musicResponsiveListItemRenderer = try values.decodeIfPresent(MusicResponsiveListItemRenderer.self, forKey: .musicResponsiveListItemRenderer) - } - struct MusicResponsiveListItemRenderer: Codable { - ///封面 - let thumbnail:Thumbnail? - ///文本内容(第0位是标题,其他拼成副标题) - let flexColumns:[FlexColumn]? - ///单曲/视频ID(playlistItemData存在说明这条数据单曲/视频) - let playlistItemData:PlaylistItemData? - ///专辑/歌单ID(navigationEndpoint存在说明这条数据是专辑/歌单) - let navigationEndpoint:NavigationEndpoint? - enum CodingKeys: String, CodingKey { - case thumbnail = "thumbnail" - case flexColumns = "flexColumns" - case playlistItemData = "playlistItemData" - case navigationEndpoint = "navigationEndpoint" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) - flexColumns = try values.decodeIfPresent([FlexColumn].self, forKey: .flexColumns) - playlistItemData = try values.decodeIfPresent(PlaylistItemData.self, forKey: .playlistItemData) - navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) - } - struct Thumbnail: Codable { - let musicThumbnailRenderer:MusicThumbnailRenderer? - enum CodingKeys: String, CodingKey { - case musicThumbnailRenderer = "musicThumbnailRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - musicThumbnailRenderer = try values.decodeIfPresent(MusicThumbnailRenderer.self, forKey: .musicThumbnailRenderer) - } - struct MusicThumbnailRenderer: Codable { - let thumbnail:Thumbnail? - enum CodingKeys: String, CodingKey { - case thumbnail = "thumbnail" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) - } - struct Thumbnail: Codable { - let thumbnails:[Thumbnails]? - enum CodingKeys: String, CodingKey { - case thumbnails = "thumbnails" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - thumbnails = try values.decodeIfPresent([Thumbnails].self, forKey: .thumbnails) - } - struct Thumbnails: Codable { - let url:String? - enum CodingKeys: String, CodingKey { - case url = "url" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - url = try values.decodeIfPresent(String.self, forKey: .url) - } - } - } - } - } - struct FlexColumn: Codable { - let musicResponsiveListItemFlexColumnRenderer:MusicResponsiveListItemFlexColumnRenderer? - enum CodingKeys: String, CodingKey { - case musicResponsiveListItemFlexColumnRenderer = "musicResponsiveListItemFlexColumnRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - musicResponsiveListItemFlexColumnRenderer = try values.decodeIfPresent(MusicResponsiveListItemFlexColumnRenderer.self, forKey: .musicResponsiveListItemFlexColumnRenderer) - } - struct MusicResponsiveListItemFlexColumnRenderer: Codable { - let text:Text? - enum CodingKeys: String, CodingKey { - case text = "text" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - text = try values.decodeIfPresent(Text.self, forKey: .text) - } - struct Text: Codable { - let runs:[Run]? - enum CodingKeys: String, CodingKey { - case runs = "runs" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - runs = try values.decodeIfPresent([Run].self, forKey: .runs) - } - struct Run: Codable { - ///标题文本 - let text:String? - enum CodingKeys: String, CodingKey { - case text = "text" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - text = try values.decodeIfPresent(String.self, forKey: .text) - } - } - } - } - } - struct PlaylistItemData: Codable { - let videoId:String? - enum CodingKeys: String, CodingKey { - case videoId = "videoId" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - videoId = try values.decodeIfPresent(String.self, forKey: .videoId) - } - } - struct NavigationEndpoint: Codable { - let browseEndpoint:BrowseEndpoint? - enum CodingKeys: String, CodingKey { - case browseEndpoint = "browseEndpoint" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint) - } - struct BrowseEndpoint: Codable { - let browseId:String? - let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs? - enum CodingKeys: String, CodingKey { - case browseId = "browseId" - case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - browseId = try values.decodeIfPresent(String.self, forKey: .browseId) - 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) - } - } - } - } - } - } - } - struct BottomEndpoint: Codable { - let searchEndpoint:SearchEndpoint? - enum CodingKeys: String, CodingKey { - case searchEndpoint = "searchEndpoint" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - searchEndpoint = try values.decodeIfPresent(SearchEndpoint.self, forKey: .searchEndpoint) - } - struct SearchEndpoint: Codable { - ///当前搜索文本 - let query:String? - ///更多内容参数 - let params:String? - enum CodingKeys: String, CodingKey { - case query = "query" - case params = "params" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - query = try values.decodeIfPresent(String.self, forKey: .query) - params = try values.decodeIfPresent(String.self, forKey: .params) - } - } - } - } - } - } - } - } - } - } - } -} -///搜索分类结果结构(该分类详情) -struct JsonSearchTypeResults: Codable { - let contents:Contents? - enum CodingKeys: String, CodingKey { - case contents = "contents" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - contents = try values.decodeIfPresent(Contents.self, forKey: .contents) - } - struct Contents: Codable { - let tabbedSearchResultsRenderer:TabbedSearchResultsRenderer? - enum CodingKeys: String, CodingKey { - case tabbedSearchResultsRenderer = "tabbedSearchResultsRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - tabbedSearchResultsRenderer = try values.decodeIfPresent(TabbedSearchResultsRenderer.self, forKey: .tabbedSearchResultsRenderer) - } - struct TabbedSearchResultsRenderer: Codable { - let tabs:[Tab]? - enum CodingKeys: String, CodingKey { - case tabs = "tabs" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - tabs = try values.decodeIfPresent([Tab].self, forKey: .tabs) - } - struct Tab:Codable { - let tabRenderer:TabRenderer? - enum CodingKeys: String, CodingKey { - case tabRenderer = "tabRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - tabRenderer = try values.decodeIfPresent(TabRenderer.self, forKey: .tabRenderer) - } - struct TabRenderer: Codable { - let content:Content? - enum CodingKeys: String, CodingKey { - case content = "content" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - content = try values.decodeIfPresent(Content.self, forKey: .content) - } - struct Content: Codable { - let sectionListRenderer:SectionListRenderer? - enum CodingKeys: String, CodingKey { - case sectionListRenderer = "sectionListRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - sectionListRenderer = try values.decodeIfPresent(SectionListRenderer.self, forKey: .sectionListRenderer) - } - struct SectionListRenderer: Codable { - ///模块(每个模块内容不一样) - let contents:[Content]? - enum CodingKeys: String, CodingKey { - case contents = "contents" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - contents = try values.decodeIfPresent([Content].self, forKey: .contents) - } - struct Content:Codable { - let musicShelfRenderer:MusicShelfRenderer? - enum CodingKeys: String, CodingKey { - case musicShelfRenderer = "musicShelfRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - musicShelfRenderer = try values.decodeIfPresent(MusicShelfRenderer.self, forKey: .musicShelfRenderer) - } - struct MusicShelfRenderer: Codable { - ///内容块 - let contents:[Content]? - ///继续请求块 - let continuations:Continuations? - enum CodingKeys: String, CodingKey { - case contents = "contents" - case continuations = "continuations" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - contents = try values.decodeIfPresent([Content].self, forKey: .contents) - continuations = try values.decodeIfPresent(Continuations.self, forKey: .continuations) - } - ///内容块 - struct Content: Codable { - let musicResponsiveListItemRenderer:MusicResponsiveListItemRenderer? - enum CodingKeys: String, CodingKey { - case musicResponsiveListItemRenderer = "musicResponsiveListItemRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - musicResponsiveListItemRenderer = try values.decodeIfPresent(MusicResponsiveListItemRenderer.self, forKey: .musicResponsiveListItemRenderer) - } - struct MusicResponsiveListItemRenderer: Codable { - ///封面 - let thumbnail:Thumbnail? - ///文本内容(第0位是标题,其他拼成副标题) - let flexColumns:[FlexColumn]? - ///单曲/视频ID(playlistItemData存在说明这条数据单曲/视频) - let playlistItemData:PlaylistItemData? - ///专辑/歌单ID(navigationEndpoint存在说明这条数据是专辑/歌单) - let navigationEndpoint:NavigationEndpoint? - enum CodingKeys: String, CodingKey { - case thumbnail = "thumbnail" - case flexColumns = "flexColumns" - case playlistItemData = "playlistItemData" - case navigationEndpoint = "navigationEndpoint" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) - flexColumns = try values.decodeIfPresent([FlexColumn].self, forKey: .flexColumns) - playlistItemData = try values.decodeIfPresent(PlaylistItemData.self, forKey: .playlistItemData) - navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint) - } - struct Thumbnail: Codable { - let musicThumbnailRenderer:MusicThumbnailRenderer? - enum CodingKeys: String, CodingKey { - case musicThumbnailRenderer = "musicThumbnailRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - musicThumbnailRenderer = try values.decodeIfPresent(MusicThumbnailRenderer.self, forKey: .musicThumbnailRenderer) - } - struct MusicThumbnailRenderer: Codable { - let thumbnail:Thumbnail? - enum CodingKeys: String, CodingKey { - case thumbnail = "thumbnail" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) - } - struct Thumbnail: Codable { - let thumbnails:[Thumbnails]? - enum CodingKeys: String, CodingKey { - case thumbnails = "thumbnails" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - thumbnails = try values.decodeIfPresent([Thumbnails].self, forKey: .thumbnails) - } - struct Thumbnails: Codable { - let url:String? - enum CodingKeys: String, CodingKey { - case url = "url" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - url = try values.decodeIfPresent(String.self, forKey: .url) - } - } - } - } - } - struct FlexColumn: Codable { - let musicResponsiveListItemFlexColumnRenderer:MusicResponsiveListItemFlexColumnRenderer? - enum CodingKeys: String, CodingKey { - case musicResponsiveListItemFlexColumnRenderer = "musicResponsiveListItemFlexColumnRenderer" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - musicResponsiveListItemFlexColumnRenderer = try values.decodeIfPresent(MusicResponsiveListItemFlexColumnRenderer.self, forKey: .musicResponsiveListItemFlexColumnRenderer) - } - struct MusicResponsiveListItemFlexColumnRenderer: Codable { - let text:Text? - enum CodingKeys: String, CodingKey { - case text = "text" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - text = try values.decodeIfPresent(Text.self, forKey: .text) - } - struct Text: Codable { - let runs:[Run]? - enum CodingKeys: String, CodingKey { - case runs = "runs" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - runs = try values.decodeIfPresent([Run].self, forKey: .runs) - } - struct Run: Codable { - ///标题文本 - let text:String? - enum CodingKeys: String, CodingKey { - case text = "text" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - text = try values.decodeIfPresent(String.self, forKey: .text) - } - } - } - } - } - struct PlaylistItemData: Codable { - let videoId:String? - enum CodingKeys: String, CodingKey { - case videoId = "videoId" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - videoId = try values.decodeIfPresent(String.self, forKey: .videoId) - } - } - struct NavigationEndpoint: Codable { - let browseEndpoint:BrowseEndpoint? - enum CodingKeys: String, CodingKey { - case browseEndpoint = "browseEndpoint" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint) - } - struct BrowseEndpoint: Codable { - let browseId:String? - let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs? - enum CodingKeys: String, CodingKey { - case browseId = "browseId" - case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - browseId = try values.decodeIfPresent(String.self, forKey: .browseId) - 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) - } - } - } - } - } - } - } - ///继续请求块 - struct Continuations: Codable { - let nextContinuationData:NextContinuationData? - enum CodingKeys: String, CodingKey { - case nextContinuationData = "nextContinuationData" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - nextContinuationData = try values.decodeIfPresent(NextContinuationData.self, forKey: .nextContinuationData) - } - struct NextContinuationData: Codable { - ///继续请求编码 - let continuation:String? - ///继续请求参数 - let clickTrackingParams:String? - enum CodingKeys: String, CodingKey { - case continuation = "continuation" - case clickTrackingParams = "clickTrackingParams" - } - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - continuation = try values.decodeIfPresent(String.self, forKey: .continuation) - clickTrackingParams = try values.decodeIfPresent(String.self, forKey: .clickTrackingParams) - } - - } - } - } - } - } - } - } - } - } - } -} diff --git a/MusicPlayer/MP/MPPositive/Models/Models/MPPositive_ArtistHeaderModel.swift b/MusicPlayer/MP/MPPositive/Models/Models/MPPositive_ArtistHeaderModel.swift new file mode 100644 index 0000000..877cfd0 --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Models/Models/MPPositive_ArtistHeaderModel.swift @@ -0,0 +1,21 @@ +// +// MPPositive_ArtistHeaderModel.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/15. +// + +import UIKit +///艺术家头部模型 +class MPPositive_ArtistHeaderModel: NSObject { + ///名字 + var title:String? + ///大头照组 + var thumbnails:[String]? + ///当前订阅总数 + var subscriptions:String? + ///已订阅文本 + var subscriptionedText:String? + ///艺术家介绍 + var fordescription:String? +} diff --git a/MusicPlayer/MP/MPPositive/Models/Models/MPPositive_BrowseItemModel.swift b/MusicPlayer/MP/MPPositive/Models/Models/MPPositive_BrowseItemModel.swift index 176e85f..4d5dd03 100644 --- a/MusicPlayer/MP/MPPositive/Models/Models/MPPositive_BrowseItemModel.swift +++ b/MusicPlayer/MP/MPPositive/Models/Models/MPPositive_BrowseItemModel.swift @@ -8,37 +8,27 @@ import UIKit ///b面预览个体模型 class MPPositive_BrowseItemModel: NSObject { - ///封面 - var coverUrl:String! + ///预览图片 + var coverUrls:[String]! ///一级标题 - var maintitle:String! + var title:String! ///二级标题 var subtitle:String! - ///三级标题(通常是专辑名/歌单/播放次数) - var thirdtitle:String! - ///item音乐内容(无值则不能直接播放音乐) - var musicVideo:BrowseItemMusicVideo! - ///item预览内容 - var browseContent:BrowseItemContent! + ///音视频ID + var videoId:String? + ///音视频所在列表ID + var playListId:String? + ///列表专辑预览ID + var browseId:String? + ///列表专辑预览参数 + var params:String? + ///艺术家Id + var artistId:String? + ///页面类型 + var pageType:String? ///是单曲/视频OR列表/歌单 var itemType:BrowseItemType! } -struct BrowseItemMusicVideo { - ///音乐ID - var videoId:String? - ///列表ID - var playListId:String? - ///音乐类型 - var musicVideoType:String? -} -struct BrowseItemContent{ - ///预览ID - var browseId:String? - ///预览参数 - var params:String? - ///预览类型 - var pageType:String? -} ///预览个体类型 enum BrowseItemType: Int{ ///单曲/视频 diff --git a/MusicPlayer/MP/MPPositive/Models/Models/MPPositive_SearchResultItemModel.swift b/MusicPlayer/MP/MPPositive/Models/Models/MPPositive_SearchResultItemModel.swift index fdb7efc..95258cb 100644 --- a/MusicPlayer/MP/MPPositive/Models/Models/MPPositive_SearchResultItemModel.swift +++ b/MusicPlayer/MP/MPPositive/Models/Models/MPPositive_SearchResultItemModel.swift @@ -7,17 +7,17 @@ import UIKit ///预览结果个体模型 -class MPPositive_SearchResultItemModel: NSObject { - ///预览图片 - var reviewUrls:[String]? - ///一级标题 - var title:String? - ///二级标题 - var subtitle:String? - ///单曲视频/VideoID - var videoId:String? - ///预览ID(可以是歌单/专辑/艺术家) - var browseId:String? - ///类型 - var itemType:BrowseItemType? -} +//class MPPositive_SearchResultItemModel: NSObject { +// ///预览图片 +// var reviewUrls:[String]? +// ///一级标题 +// var title:String? +// ///二级标题 +// var subtitle:String? +// ///单曲视频/VideoID +// var videoId:String? +// ///预览ID(可以是歌单/专辑/艺术家) +// var browseId:String? +// ///类型 +// var itemType:BrowseItemType? +//} diff --git a/MusicPlayer/MP/MPPositive/Models/Models/MPPositive_SongItemModel.swift b/MusicPlayer/MP/MPPositive/Models/Models/MPPositive_SongItemModel.swift index b5f267a..2fbebb7 100644 --- a/MusicPlayer/MP/MPPositive/Models/Models/MPPositive_SongItemModel.swift +++ b/MusicPlayer/MP/MPPositive/Models/Models/MPPositive_SongItemModel.swift @@ -10,8 +10,10 @@ import UIKit class MPPositive_SongItemModel: NSObject { ///序列号(在当前列表中的排序) var index:Int! - ///资源路径(等级制,默认取第一条最低质量) - var resourceUrls:[String]? + ///视频源路径(等级制,默认取第一条最低质量) + var resourceUrls:[String]? + ///音频资源路径(等级制,默认取第一条最低质量) + var audioUrls:[String]? ///封面路径(默认拿最后一条最清晰) var coverUrls:[String]? ///预览图片(默认拿最后一条最清晰) diff --git a/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_ArtistContentListViewModel.swift b/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_ArtistContentListViewModel.swift new file mode 100644 index 0000000..de51266 --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_ArtistContentListViewModel.swift @@ -0,0 +1,73 @@ +// +// MPPositive_ArtistContentListViewModel.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/15. +// + +import UIKit + +class MPPositive_ArtistContentListViewModel: NSObject { + ///模块标题 + var title:String? + ///模块内容组 + var itemViews:[MPPositive_BrowseItemViewModel] = []{ + didSet{ + print("用户加载\(title ?? "")的新内容") + if completionBlock != nil { + completionBlock!() + } + } + } + ///查询更多内容需要的id + var browseId:String? + ///查询更多内容需要的编码 + var params:String? + ///当前分页信息 + var continuation:String? + ///当前分页键值 + var itct:String? + ///请求完成 + var completionBlock:(() -> Void)? + + init(_ title: String?, itemViews: [MPPositive_BrowseItemViewModel], browseId: String?, params:String?) { + super.init() + self.title = title + self.itemViews = itemViews + self.browseId = browseId + self.params = params + } + + ///请求艺术家分类详情信息 + func requestArtistType() { + //检索是否存在moreActionId和moreActionParams + guard let id = self.browseId, let params = params else { + print("当前\(title ?? "")已是全部内容") + return + } + //清空数据(原始数据为初始预览) + itemViews = [] + //调用艺术家更多接口补全信息 + MP_NetWorkManager.shared.requestArtistMore(id, params: params) { [weak self] (items, continuation, itct) in + guard let self = self else {return} + //对内容模块组进行追加 + itemViews.append(contentsOf: items) + self.continuation = continuation + self.itct = itct + } + } + ///继续请求艺术家分类详情信息 + func requestArtistContinuation() { + guard let continuation = self.continuation, let itct = self.itct else { + //没有更多了 + return + } + MP_NetWorkManager.shared.requestArtistMoreContinuation(continuation, itct: itct) { [weak self] (items, continuation, itct) in + guard let self = self else {return} + //对内容模块组进行追加 + itemViews.append(contentsOf: items) + self.continuation = continuation + self.itct = itct + } + } +} diff --git a/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_ArtistViewModel.swift b/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_ArtistViewModel.swift new file mode 100644 index 0000000..498ce03 --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_ArtistViewModel.swift @@ -0,0 +1,15 @@ +// +// MPPositive_ArtistViewModel.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/15. +// + +import UIKit + +class MPPositive_ArtistViewModel: NSObject { + ///头部模块 + var header:MPPositive_ArtistHeaderModel! + ///列表数据组(由预览模块组成) + var lists:[MPPositive_ArtistContentListViewModel] = [] +} diff --git a/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_BrowseItemViewModel.swift b/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_BrowseItemViewModel.swift index 0e5965f..fdc5c69 100644 --- a/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_BrowseItemViewModel.swift +++ b/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_BrowseItemViewModel.swift @@ -11,9 +11,9 @@ import Kingfisher class MPPositive_BrowseItemViewModel: NSObject { ///封面图片路径 var coverUrl:URL? - ///主标题(一级标题直接展示) + ///主标题(一级标题) var title:String! - ///次标题(二级标题与三级标题拼接) + ///次标题(二级标题) var subtitle:String! ///预览例实体 var browseItem:MPPositive_BrowseItemModel! @@ -25,19 +25,16 @@ class MPPositive_BrowseItemViewModel: NSObject { //实现与ui交互的数据配置 private func confirgue (_ browseItem:MPPositive_BrowseItemModel) { //封面 - if let url = URL(string: browseItem.coverUrl ?? "") { + if let url = URL(string: browseItem.coverUrls?.last ?? "") { self.coverUrl = url }else { print("No Cover") } //标题处理 - title = browseItem.maintitle + title = browseItem.title if browseItem.subtitle != nil { subtitle = browseItem.subtitle } - if browseItem.thirdtitle != nil { - subtitle = (subtitle ?? "")+"·"+browseItem.thirdtitle - } } ///将路径转为图片 func setUrltoImage(_ imageView:UIImageView) { diff --git a/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_ListAlbumListViewModel.swift b/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_ListAlbumListViewModel.swift index f9a18f6..657a074 100644 --- a/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_ListAlbumListViewModel.swift +++ b/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_ListAlbumListViewModel.swift @@ -12,4 +12,6 @@ class MPPositive_ListAlbumListViewModel: NSObject { var header:MPPositive_ListHeaderViewModel! ///列表数据组(由预览模块组成) var items:[MPPositive_BrowseItemViewModel] = [] + + } diff --git a/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_RecommendListViewModel.swift b/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_RecommendListViewModel.swift new file mode 100644 index 0000000..7e36068 --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_RecommendListViewModel.swift @@ -0,0 +1,15 @@ +// +// MPPositive_RecommendListViewModel.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/20. +// + +import UIKit + +class MPPositive_RecommendListViewModel: NSObject { + ///组标题 + var title:String? + ///组内容组 + var items:[MPPositive_BrowseItemViewModel] = [] +} diff --git a/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_SearchResultItemViewModel.swift b/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_SearchResultItemViewModel.swift index cbaa3d6..7ba5943 100644 --- a/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_SearchResultItemViewModel.swift +++ b/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_SearchResultItemViewModel.swift @@ -15,14 +15,14 @@ class MPPositive_SearchResultItemViewModel: NSObject { ///副标题 var subtitle:String? ///搜索结果个体 - var item:MPPositive_SearchResultItemModel! - init(_ resultItem:MPPositive_SearchResultItemModel) { + var item:MPPositive_BrowseItemModel! + init(_ resultItem:MPPositive_BrowseItemModel) { super.init() item = resultItem configure() } private func configure() { - if let url = URL(string: item.reviewUrls?.last ?? "") { + if let url = URL(string: item.coverUrls?.last ?? "") { reviewUrl = url } if item.title != nil { diff --git a/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_SearchResultListViewModel.swift b/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_SearchResultListViewModel.swift index 7e8fbc2..5be4c00 100644 --- a/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_SearchResultListViewModel.swift +++ b/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_SearchResultListViewModel.swift @@ -34,7 +34,7 @@ class MPPositive_SearchResultListViewModel: NSObject { ///请求分类详情数据 func requestSearchType() { guard let query = self.query, let params = self.params else { - print("当前模块已是全部内容") + print("当前\(title ?? "")已是全部内容") return } //调用搜索分页结果接口补全全部的内容模块组 @@ -47,4 +47,19 @@ class MPPositive_SearchResultListViewModel: NSObject { self.itct = itct } } + ///请求分类继续内容 + func requestSearchContinuation() { + guard let continuation = self.continuation, let itct = self.itct else { + //没有更多了 + return + } + MP_NetWorkManager.shared.requestSearchTypeContinuation(continuation, itct: itct) { [weak self] (items, continuation, itct) in + guard let self = self else {return} + //对全部的内容模块组进行追加 + allItemViews.append(contentsOf: items) + //记录分页内容 + self.continuation = continuation + self.itct = itct + } + } } diff --git a/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_SongViewModel.swift b/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_SongViewModel.swift index c8a3c85..e968a31 100644 --- a/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_SongViewModel.swift +++ b/MusicPlayer/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_SongViewModel.swift @@ -13,6 +13,8 @@ class MPPositive_SongViewModel: NSObject { var index:Int! ///音乐资源路径 var resourcePlayerItem:AVPlayerItem! + ///资源加载路径 + var resourceAsset:AVURLAsset! ///封面 var coverUrl:URL? ///标题 @@ -23,38 +25,35 @@ class MPPositive_SongViewModel: NSObject { var lyrics:String? ///相关内容ID var relatedId:String? - ///是否完成预加载 - var isPreloading:Bool? ///是否收藏 var isCollection:Bool? ///是否下载 var isDlownd:Bool? ///音乐实体 var song:MPPositive_SongItemModel! - ///观察是否执行KVO - var isKvo:Bool = false + ///是否进行过预加载 + var isPloading:Bool = false init(_ song:MPPositive_SongItemModel) { super.init() self.song = song configure() } deinit { - if isKvo == true { - resourcePlayerItem.removeObserver(self, forKeyPath: "playbackLikelyToKeepUp") - isKvo = false - } + } //数据配置 private func configure() { index = song.index //资源路径默认取第一条 - if song.resourceUrls?.first != nil { - let first = URL(string: song.resourceUrls!.first!) - resourcePlayerItem = .init(url: first!) + if song.resourceUrls?.first != nil, let first = URL(string: song.resourceUrls?.first ?? ""){ + //创建一个资产链接并允许它预加载 + resourceAsset = .init(url: first, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true]) + //创建PlayerItem + resourcePlayerItem = .init(asset: resourceAsset) } //封面路径默认取最后一条 - if song.coverUrls?.first != nil { - coverUrl = .init(string: song.coverUrls!.last!) + if song.reviewUrls?.first != nil { + coverUrl = .init(string: song.reviewUrls!.last!) } //标题 if song.title != nil { @@ -79,44 +78,59 @@ class MPPositive_SongViewModel: NSObject { //检索是否下载 - } - //MARK: - 资源预加载 - //检测资源是否能被预加载 - private func canBePreloaded() -> Bool { - return self.isPreloading ?? false - } - ///异步预加载 - func preloadPlayerItem() { //执行预加载 - guard canBePreloaded() == false else { - print("\(title ?? "")已经预加载了") - return + if isPloading == false { + preloadAsset(resourceAsset) } - print(resourcePlayerItem.status) - //手动触发,以此加载数据 - self.resourcePlayerItem.seek(to: .zero) {[weak self] _ in - guard let self = self else {return} - //实行异步监听预加载 - DispatchQueue.global(qos: .background).async { - if self.isKvo == false { - //为playerItem添加监听 - self.resourcePlayerItem.addObserver(self, forKeyPath: "playbackLikelyToKeepUp", options: .new, context: nil) - self.isKvo = true + } + //执行预加载 + func preloadAsset(_ asset:AVURLAsset) { + //执行预加载 + if #available(iOS 16, *) { + //ios16以上的情况 + Task{ + do{ + let playable = try await asset.load(.isPlayable) + if playable == true { + print("\(self.title ?? "")预加载成功") + self.isPloading = true + }else { + //检索预加载失败原因 + switch asset.status(of: .isPlayable) { + case .failed(let erro): + print("\(title ?? "")预加载失败,失败原因:\(erro.localizedDescription)") + default: + break + } + } + }catch{ + print("预加载失败:\(error.localizedDescription)") } } - } - } - override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { - if keyPath == "playbackLikelyToKeepUp" { - if let playbackLikelyToKeepUp = change?[.newKey] as? Bool, playbackLikelyToKeepUp == true { - //当前资源已经预加载到合适的程度,移除KVO监听 - print("\(title ?? "")预加载到合适的进度") - if isKvo == true { - resourcePlayerItem.removeObserver(self, forKeyPath: "playbackLikelyToKeepUp") - isKvo = false + }else { + //ios16以下的情况 + let keys = ["playable"] + asset.loadValuesAsynchronously(forKeys: keys) { + [weak self] in + guard let self = self else {return} + for key in keys { + var error: NSError? = nil + let status = asset.statusOfValue(forKey: key, error: &error) + switch status { + case .loaded: + // key成功加载,资源准备就绪 + DispatchQueue.main.async { + print("\(self.title ?? "")预加载成功") + self.isPloading = true + } + case .failed: + print("\(title ?? "")预加载失败,失败原因:\(error?.localizedDescription ?? "")") + case .cancelled: + print("\(title ?? "")预加载被取消了") + default: + break + } } - //表示已经完成了预加载 - isPreloading = true } } } diff --git a/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_BrowseLoadViewModel.swift b/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_BrowseLoadViewModel.swift index bfd7604..742bbd2 100644 --- a/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_BrowseLoadViewModel.swift +++ b/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_BrowseLoadViewModel.swift @@ -10,8 +10,6 @@ import UIKit class MPPositive_BrowseLoadViewModel: NSObject { ///预览模块数据组(通过网络请求刷新) var browseModuleLists:[MPPositive_BrowseModuleListViewModel] = [] - ///列表展示内容(通过网络请求刷新) - var listAlbumList:MPPositive_ListAlbumListViewModel! override init() { super.init() //当网络请求工具触发browse请求闭包时 @@ -25,14 +23,6 @@ class MPPositive_BrowseLoadViewModel: NSObject { //通知首页刷新UI NotificationCenter.notificationKey.post(notificationName: .positive_browses_reload) } - //当网络请求工具触发列表请求闭包时 - MP_NetWorkManager.shared.listRequestResultBlock = { - [weak self] (list) in - guard let self = self else {return} - listAlbumList = list - //通知首页刷新UI - NotificationCenter.notificationKey.post(notificationName: .positive_list_reload) - } } ///刷新预览数据 func reloadBrowseLists() { @@ -41,11 +31,4 @@ class MPPositive_BrowseLoadViewModel: NSObject { //调用网络请求工具的预览请求 MP_NetWorkManager.shared.requestBrowseDatas() } - ///请求列表数据 - func requestListOrAlbum(_ item:MPPositive_BrowseItemViewModel) { - //清空列表内容 - listAlbumList = nil - //调用网络请求工具的列表请求 - MP_NetWorkManager.shared.requestAlbumOrListDatas(item) - } } diff --git a/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_PlayerLoadViewModel.swift b/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_PlayerLoadViewModel.swift index e9439f5..e4d0637 100644 --- a/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_PlayerLoadViewModel.swift +++ b/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_PlayerLoadViewModel.swift @@ -68,7 +68,6 @@ class MPPositive_PlayerLoadViewModel: NSObject { //比较videoID,去掉已经补完的内容 array = array.filter({!videoIDs.contains($0.videoId)}) group = DispatchGroup() - var numbers = 0 //去重完毕,对剩下内容补完 for item in array { group?.enter() @@ -81,7 +80,8 @@ class MPPositive_PlayerLoadViewModel: NSObject { group?.enter() //补全资源路径组和封面路径组 improveDataforResouceAndCover(item) {[weak self] resourceUrls, coverUrls in - item.resourceUrls = resourceUrls + item.resourceUrls = resourceUrls.1 + item.audioUrls = resourceUrls.0 item.coverUrls = coverUrls //补全完成,转化为ViewModel,并添加进listViewVideos self?.listViewVideos.append(.init(item)) @@ -96,6 +96,28 @@ class MPPositive_PlayerLoadViewModel: NSObject { self.group = nil }) } + ///重新获取指定歌曲资源 + func remakeImproveData(_ completion:@escaping (() -> Void)) { + //当前歌曲不能播放,需要重新配置资源 + improveDataforResouceAndCover(currentVideo.song) {[weak self] resourceUrls, coverUrls in + guard let self = self else {return} + currentVideo.song.resourceUrls = resourceUrls.1 + currentVideo.song.audioUrls = resourceUrls.0 + //成功更新资源,将重新补完的歌曲,放进listViewVideos中 + listViewVideos.forEach({ item in + if item.song.videoId == self.currentVideo.song.videoId { + item.song.resourceUrls = self.currentVideo.song.resourceUrls + item.song.audioUrls = self.currentVideo.song.audioUrls + } + }) + currentVideo.resourceAsset = .init(url: .init(string: currentVideo.song.resourceUrls!.first!)!) + currentVideo.resourcePlayerItem = .init(asset: currentVideo.resourceAsset!) + //当值变化时通知播放器页面,更新UI + NotificationCenter.notificationKey.post(notificationName: .positive_player_reload) + completion() + } + } + ///移除选中的song,并更新listViewVideos,移除相同index的值 func removeData(_ targetVideoId:String) { let targetIndex = songVideos.firstIndex(where: {$0.videoId == targetVideoId}) ?? 0 @@ -126,7 +148,7 @@ class MPPositive_PlayerLoadViewModel: NSObject { } } ///调用player对资源路径和封面路径补全 - private func improveDataforResouceAndCover(_ song:MPPositive_SongItemModel, completion:@escaping(([String]?, [String]?) -> Void)) { + private func improveDataforResouceAndCover(_ song:MPPositive_SongItemModel, completion:@escaping((([String],[String]), [String]?) -> Void)) { //单曲补全需要调用player接口 MP_NetWorkManager.shared.requestPlayer(song) { resourceUrls, coverUrls in completion(resourceUrls,coverUrls) diff --git a/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_RecommendLoadViewModel.swift b/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_RecommendLoadViewModel.swift new file mode 100644 index 0000000..eb493ea --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_RecommendLoadViewModel.swift @@ -0,0 +1,19 @@ +// +// MPPositive_RecommendLoadViewModel.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/20. +// + +import UIKit +///相关内容 +class MPPositive_RecommendLoadViewModel: NSObject { + ///相关内容组 + var sectionLists:[MPPositive_RecommendListViewModel]! + + /// 初始化方法 + /// - Parameter browseId: 相关内容Id + init(_ browseId:String) { + super.init() + } +} diff --git a/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_LoadSearchResultsViewModel.swift b/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_SearchResultsLoadViewModel.swift similarity index 94% rename from MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_LoadSearchResultsViewModel.swift rename to MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_SearchResultsLoadViewModel.swift index 73db009..a68556a 100644 --- a/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_LoadSearchResultsViewModel.swift +++ b/MusicPlayer/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_SearchResultsLoadViewModel.swift @@ -7,7 +7,7 @@ import UIKit ///搜索结果数据管理模型 -class MPPositive_LoadSearchResultsViewModel: NSObject { +class MPPositive_SearchResultsLoadViewModel: NSObject { ///模块组 var sectionLists:[MPPositive_SearchResultListViewModel]!{ didSet{ diff --git a/MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,艺术家页)/MPPositive_ArtistShowViewController.swift b/MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,艺术家页)/MPPositive_ArtistShowViewController.swift new file mode 100644 index 0000000..517d348 --- /dev/null +++ b/MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,艺术家页)/MPPositive_ArtistShowViewController.swift @@ -0,0 +1,194 @@ +// +// MPPositive_ArtistShowViewController.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/15. +// + +import UIKit + +class MPPositive_ArtistShowViewController: MPPositive_BaseViewController { + ///头视图 + private lazy var headView:MPPositive_ArtistShowHeaderView = .init(frame: .init(x: 0, y: 0, width: screen_Width, height: 385*width)) + ///艺术家Label + private lazy var nameLabel:UILabel = { + let label:UILabel = createLabel(font: .systemFont(ofSize: 20*width, weight: .regular), textColor: .white, textAlignment: .left) + label.alpha = 0 + return label + }() + //MARK: - 分页栏设置 + //分页栏View + private lazy var segmentView:JXSegmentedView = { + var jxSegmentView = JXSegmentedView() + jxSegmentView.backgroundColor = .init(hex: "1A1A1A") + return jxSegmentView + }() + //数据源 + private lazy var dataSource:JXSegmentedTitleDataSource = { + var dataSource = JXSegmentedTitleDataSource() + //标题未选中状态 + dataSource.titleNormalColor = .init(hex: "#666666") + dataSource.titleNormalFont = .systemFont(ofSize: 16*width, weight: .regular) + //标题选中状态 + dataSource.titleSelectedColor = .init(hex: "#80F988") + dataSource.titleSelectedFont = .systemFont(ofSize: 16*width, weight: .bold) + //是否颜色过度 + dataSource.isTitleColorGradientEnabled = true + dataSource.isSelectedAnimable = true + dataSource.isItemTransitionEnabled = true + return dataSource + }() + //指示器 + private lazy var indicator:JXSegmentedIndicatorLineView = { + let indicator = JXSegmentedIndicatorLineView() + indicator.indicatorWidth = 16*width + indicator.indicatorHeight = 3*width + indicator.indicatorCornerRadius = 1.5*width + indicator.indicatorColor = .init(hex: "#80F988") + indicator.indicatorPosition = .bottom + indicator.verticalOffset = 5*width + return indicator + }() + ///分页内容承载框 + fileprivate lazy var pagingView: JXPagingView = { + let pagingView = JXPagingView(delegate: self) + pagingView.backgroundColor = .clear + pagingView.isHidden = true + pagingView.mainTableView.backgroundColor = .clear + //禁止弹簧效果 + pagingView.mainTableView.bounces = false + return pagingView + }() + private var artist:MPPositive_ArtistViewModel!{ + didSet{ + if artist != nil { + pagingView.isHidden = false + //更新头部视图数据 + headView.artist = artist + //更新分页数据源 + dataSource.titles = artist.lists.compactMap({$0.title}) + nameLabel.text = artist.header.title + dataSource.reloadData(selectedIndex: 0) + segmentView.reloadData() + } + } + } + + /// 艺术家页面 + /// - Parameter browseId: 艺术家Id + init(_ browseId:String) { + super.init(nibName: nil, bundle: nil) + //进行网络请求 + MP_NetWorkManager.shared.requestArtist(browseId) { [weak self] result in + DispatchQueue.main.async { + [weak self] in + guard let self = self else {return} + artist = result + } + } + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } + override func viewDidLoad() { + super.viewDidLoad() + setPopBtn() + setTitle("") + configure() + } + private func configure() { + segmentView.dataSource = dataSource + segmentView.indicators = [indicator] + view.addSubview(pagingView) + pagingView.snp.makeConstraints { make in + make.top.equalToSuperview() + make.left.right.bottom.equalToSuperview().priority(999) + } + segmentView.listContainer = pagingView.listContainerView + pagingView.listContainerView.backgroundColor = .clear + pagingView.listContainerView.listCellBackgroundColor = .clear + navView.addSubview(nameLabel) + nameLabel.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.left.equalToSuperview().offset(68*width) + make.right.equalToSuperview().offset(-16*width) + } + pagingView.pinSectionHeaderVerticalOffset = Int(statusBarHeight + (50*width)) + } +} +//MARK: - JXPagingViewDelegate +extension MPPositive_ArtistShowViewController: JXPagingViewDelegate{ + func pagingView(_ pagingView: JXPagingView, mainTableViewDidScroll scrollView: UIScrollView) { + //状态栏加导航栏高度 + let allHeight = statusBarHeight + (50*width) + let maxHeight = headView.frame.height - allHeight + let currentOffset = scrollView.contentOffset + if currentOffset.y <= maxHeight { + //随着滚动变化header的透明度 + let value:CGFloat = currentOffset.y/maxHeight + let topValue:CGFloat = 1-value + if value >= 0.8 { + nameLabel.alpha = 1 + headView.alpha = 0 + }else { + nameLabel.alpha = value + headView.alpha = topValue + } + } + } + //头部高度 + func tableHeaderViewHeight(in pagingView: JXPagingView) -> Int { + return Int(headView.frame.height) + } + //头部View内容 + func tableHeaderView(in pagingView: JXPagingView) -> UIView { + return headView + } + // 悬浮分页栏的高度 + func heightForPinSectionHeader(in pagingView: JXPagingView) -> Int { + return Int(60 * width) + } + + // 分页栏 + func viewForPinSectionHeader(in pagingView: JXPagingView) -> UIView { + return segmentView + } + //分页数量 + func numberOfLists(in pagingView: JXPagingView) -> Int { + return dataSource.titles.count + } + //要展现的View + func pagingView(_ pagingView: JXPagingView, initListAtIndex index: Int) -> JXPagingViewListViewDelegate { + let showView:MPPositive_ArtistShowTypeView = .init(frame: .init(x: 0, y: 0, width: screen_Width, height: screen_Height-headView.frame.height-(60 * width)), list: artist.lists[index]) + showView.header = artist.header + showView.chooseItemBlock = { + [weak self] (item) in + guard let self = self else {return} + switch item.browseItem.itemType { + case .artist: + //用户查看艺术家 + let artistVC = MPPositive_ArtistShowViewController(item.browseItem.browseId ?? "") + navigationController?.pushViewController(artistVC, animated: true) + case .list: + //列表专辑 + let listVC = MPPositive_ListShowViewController(item.browseItem.browseId ?? "", params: "") + navigationController?.pushViewController(listVC, animated: true) + case .single: + //单曲/视频跳转 + //触发next请求,优先获取列表全部单曲基础数据(不完善) + MP_NetWorkManager.shared.requestNextList(item.browseItem.playListId ?? "", videoId: item.browseItem.videoId ?? ""){ [weak self] listSongs in + guard let self = self else {return} + //回掉的数据并不完善,生成一个playerloadViewModel + let lodaViewModel = MPPositive_PlayerLoadViewModel(listSongs, currentVideoId: item.browseItem.videoId ?? "") + lodaViewModel.improveData(item.browseItem.videoId ?? "") + MP_PlayerManager.shared.loadPlayer = lodaViewModel + NotificationCenter.notificationKey.post(notificationName: .pup_player_vc) + } + case .none: + break + } + } + return showView + } +} diff --git a/MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,播放器页)/MPPositive_HomeViewController.swift b/MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,艺术家页)/MPPositive_HomeViewController.swift similarity index 82% rename from MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,播放器页)/MPPositive_HomeViewController.swift rename to MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,艺术家页)/MPPositive_HomeViewController.swift index 3195531..2392171 100644 --- a/MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,播放器页)/MPPositive_HomeViewController.swift +++ b/MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,艺术家页)/MPPositive_HomeViewController.swift @@ -43,11 +43,6 @@ class MPPositive_HomeViewController: MPPositive_BaseViewController{ //开始获取预览页数据 loadViewModel.reloadBrowseLists() NotificationCenter.notificationKey.add(observer: self, selector: #selector(reloadAction(_ :)), notificationName: .positive_browses_reload) - NotificationCenter.notificationKey.add(observer: self, selector: #selector(listAction(_ :)), notificationName: .positive_list_reload) - -// let item = MPPositive_DownloadItemModel.create() -// item.resourcePath = "11" -// MPPositive_DownloadItemModel.save() } deinit { NotificationCenter.default.removeObserver(self) @@ -81,17 +76,10 @@ class MPPositive_HomeViewController: MPPositive_BaseViewController{ self?.tableView.reloadData() } } - //用户要展示列表内容且列表内容刷新完成 - @objc private func listAction(_ sender:Notification) { - let listVC = MPPositive_ListShowViewController() - listVC.listOrAlbum = loadViewModel.listAlbumList - navigationController?.pushViewController(listVC, animated: true) - } //MARK: - 点击 //点击顶部右侧弹出菜单 @objc private func menuRightClick(_ sender:UIButton) { -// let array = MPPositive_DownloadItemModel.fetchAll() -// print(array) + } } //MARK: - tableView @@ -113,17 +101,18 @@ extension MPPositive_HomeViewController: UITableViewDataSource, UITableViewDeleg case .single: //单曲/视频跳转 //触发next请求,优先获取列表全部单曲基础数据(不完善) - MP_NetWorkManager.shared.requestNextList(item){ [weak self] listSongs in + MP_NetWorkManager.shared.requestNextList(item.browseItem.playListId ?? "", videoId: item.browseItem.videoId ?? ""){ [weak self] listSongs in guard let self = self else {return} //回掉的数据并不完善,生成一个playerloadViewModel - let lodaViewModel = MPPositive_PlayerLoadViewModel(listSongs, currentVideoId: item.browseItem.musicVideo.videoId ?? "") - lodaViewModel.improveData(item.browseItem.musicVideo.videoId ?? "") + let lodaViewModel = MPPositive_PlayerLoadViewModel(listSongs, currentVideoId: item.browseItem.videoId ?? "") + lodaViewModel.improveData(item.browseItem.videoId ?? "") MP_PlayerManager.shared.loadPlayer = lodaViewModel NotificationCenter.notificationKey.post(notificationName: .pup_player_vc) } case .list: - //列表/专辑跳转 - loadViewModel.requestListOrAlbum(item) + //列表专辑 + let listVC = MPPositive_ListShowViewController(item.browseItem.browseId ?? "", params: item.browseItem.params ?? "") + navigationController?.pushViewController(listVC, animated: true) default: break } diff --git a/MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,播放器页)/MPPositive_ListShowViewController.swift b/MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,艺术家页)/MPPositive_ListShowViewController.swift similarity index 89% rename from MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,播放器页)/MPPositive_ListShowViewController.swift rename to MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,艺术家页)/MPPositive_ListShowViewController.swift index 336e18f..b048f99 100644 --- a/MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,播放器页)/MPPositive_ListShowViewController.swift +++ b/MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,艺术家页)/MPPositive_ListShowViewController.swift @@ -68,17 +68,43 @@ class MPPositive_ListShowViewController: MPPositive_BaseViewController { }() private let MPPositive_MusicItemShowTableViewCellID = "MPPositive_MusicItemShowTableViewCell" //传递的列表/专辑值 - var listOrAlbum:MPPositive_ListAlbumListViewModel! + private var listOrAlbum:MPPositive_ListAlbumListViewModel!{ + didSet{ + DispatchQueue.main.async { + [weak self] in + guard let self = self else {return} + if listOrAlbum != nil { + reload() + tableView.reloadData() + } + } + } + } + + /// 生成列表控制器 + /// - Parameters: + /// - browseId: 列表的id + /// - params: 列表的编码 + init(_ browseId:String, params:String) { + super.init(nibName: nil, bundle: nil) + //发起网络请求 + MP_NetWorkManager.shared.requestAlbumOrListDatas(browseId, params: params) { [weak self] result in + guard let self = self else {return} + listOrAlbum = result + } + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } override func viewDidLoad() { super.viewDidLoad() setTitle("") setPopBtn() configure() -// MP_NetWorkManager.shared.testFunction() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - reload() } //页面刷新 private func reload() { @@ -206,7 +232,7 @@ class MPPositive_ListShowViewController: MPPositive_BaseViewController { //MARK: - tableView extension MPPositive_ListShowViewController: UITableViewDataSource, UITableViewDelegate { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return listOrAlbum.items.count + return listOrAlbum?.items.count ?? 0 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_MusicItemShowTableViewCellID, for: indexPath) as! MPPositive_MusicItemShowTableViewCell @@ -215,11 +241,11 @@ extension MPPositive_ListShowViewController: UITableViewDataSource, UITableViewD } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { //触发next请求,优先获取列表全部单曲基础数据(不完善) - MP_NetWorkManager.shared.requestNextList(listOrAlbum.items[indexPath.row]){ [weak self] listSongs in + MP_NetWorkManager.shared.requestNextList(listOrAlbum.items[indexPath.row].browseItem.playListId ?? "", videoId: listOrAlbum.items[indexPath.row].browseItem.videoId ?? ""){ [weak self] listSongs in guard let self = self else {return} //回掉的数据并不完善,生成一个playerloadViewModel - let lodaViewModel = MPPositive_PlayerLoadViewModel(listSongs, currentVideoId: listOrAlbum.items[indexPath.row].browseItem.musicVideo.videoId ?? "") - lodaViewModel.improveData(listOrAlbum.items[indexPath.row].browseItem.musicVideo.videoId ?? "") + let lodaViewModel = MPPositive_PlayerLoadViewModel(listSongs, currentVideoId: listOrAlbum.items[indexPath.row].browseItem.videoId ?? "") + lodaViewModel.improveData(listOrAlbum.items[indexPath.row].browseItem.videoId ?? "") MP_PlayerManager.shared.loadPlayer = lodaViewModel //发布弹出音乐播放器的通知 NotificationCenter.notificationKey.post(notificationName: .pup_player_vc) diff --git a/MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,播放器页)/MPPositive_MoreContentViewController.swift b/MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,艺术家页)/MPPositive_MoreContentViewController.swift similarity index 100% rename from MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,播放器页)/MPPositive_MoreContentViewController.swift rename to MusicPlayer/MP/MPPositive/ViewControllers/Home(首页,各项列表页,艺术家页)/MPPositive_MoreContentViewController.swift diff --git a/MusicPlayer/MP/MPPositive/ViewControllers/Player(播放器)/MPPositive_PlayerViewController.swift b/MusicPlayer/MP/MPPositive/ViewControllers/Player(播放器)/MPPositive_PlayerViewController.swift index 2c438fb..7c8a4b1 100644 --- a/MusicPlayer/MP/MPPositive/ViewControllers/Player(播放器)/MPPositive_PlayerViewController.swift +++ b/MusicPlayer/MP/MPPositive/ViewControllers/Player(播放器)/MPPositive_PlayerViewController.swift @@ -63,7 +63,7 @@ class MPPositive_PlayerViewController: MPPositive_BaseViewController, UIViewCont let blurEffect = UIBlurEffect(style: .dark) // 创建一个可交互的毛玻璃视图 let blurEffectView = UIVisualEffectView(effect: blurEffect) - blurEffectView.alpha = 0.8 + blurEffectView.alpha = 1 blurEffectView.isUserInteractionEnabled = false return blurEffectView }() @@ -131,6 +131,18 @@ class MPPositive_PlayerViewController: MPPositive_BaseViewController, UIViewCont let value = currentTime/duration coverView.sliderView.value = Float(value) } + //当缓存变化时 + MP_PlayerManager.shared.cacheValueBlock = { [weak self] (value, duration) in + guard let self = self else { return } + if value < duration { + //进度缓存中 + let float = value/duration + coverView.progressView.setProgress(Float(float), animated: false) + }else { + //进度缓存满了 + coverView.progressView.setProgress(1, animated: false) + } + } switch MP_PlayerManager.shared.getPlayState() { case .Null://说明播放器还未尝试过播放 playBtn.isSelected = false diff --git a/MusicPlayer/MP/MPPositive/ViewControllers/Player(播放器)/MPPositive_RecommendViewController.swift b/MusicPlayer/MP/MPPositive/ViewControllers/Player(播放器)/MPPositive_RecommendViewController.swift new file mode 100644 index 0000000..b0cbe35 --- /dev/null +++ b/MusicPlayer/MP/MPPositive/ViewControllers/Player(播放器)/MPPositive_RecommendViewController.swift @@ -0,0 +1,17 @@ +// +// MPPositive_RecommendViewController.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/20. +// + +import UIKit +///相关内容推荐 +class MPPositive_RecommendViewController: MPPositive_BaseViewController { + + override func viewDidLoad() { + super.viewDidLoad() + setTitle("Recommend") + setPopBtn() + } +} diff --git a/MusicPlayer/MP/MPPositive/ViewControllers/Search(搜索页)/MPPositive_SearchResultShowViewController.swift b/MusicPlayer/MP/MPPositive/ViewControllers/Search(搜索页)/MPPositive_SearchResultShowViewController.swift index e9838ab..4e14d43 100644 --- a/MusicPlayer/MP/MPPositive/ViewControllers/Search(搜索页)/MPPositive_SearchResultShowViewController.swift +++ b/MusicPlayer/MP/MPPositive/ViewControllers/Search(搜索页)/MPPositive_SearchResultShowViewController.swift @@ -78,6 +78,33 @@ class MPPositive_SearchResultShowViewController: MPPositive_BaseViewController { [weak self] in self?.view?.endEditing(true) } + resultsShowView.chooseItemBlock = { + [weak self] (item) in + guard let self = self else {return} + switch item.item.itemType { + case .artist: + //用户查看艺术家 + let artistVC = MPPositive_ArtistShowViewController(item.item.browseId ?? "") + navigationController?.pushViewController(artistVC, animated: true) + case .list: + //列表专辑 + let listVC = MPPositive_ListShowViewController(item.item.browseId ?? "", params: "") + navigationController?.pushViewController(listVC, animated: true) + case .single: + //单曲/视频跳转 + //触发next请求,优先获取列表全部单曲基础数据(不完善) + MP_NetWorkManager.shared.requestNextList(item.item.playListId ?? "", videoId: item.item.videoId ?? ""){ [weak self] listSongs in + guard let self = self else {return} + //回掉的数据并不完善,生成一个playerloadViewModel + let lodaViewModel = MPPositive_PlayerLoadViewModel(listSongs, currentVideoId: item.item.videoId ?? "") + lodaViewModel.improveData(item.item.videoId ?? "") + MP_PlayerManager.shared.loadPlayer = lodaViewModel + NotificationCenter.notificationKey.post(notificationName: .pup_player_vc) + } + case .none: + break + } + } } deinit{ debounceTimer = nil diff --git a/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistDescriptionTableViewCell.swift b/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistDescriptionTableViewCell.swift new file mode 100644 index 0000000..c5114a4 --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistDescriptionTableViewCell.swift @@ -0,0 +1,43 @@ +// +// MPPositive_ArtistDescriptionTableViewCell.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/16. +// + +import UIKit + +class MPPositive_ArtistDescriptionTableViewCell: UITableViewCell { + + lazy var titleLabel:UILabel = createLabel(font: .systemFont(ofSize: 14*width, weight: .regular), textColor: .white, textAlignment: .left, lines: 0) + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + selectionStyle = .none + backgroundColor = .clear + configure() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + private func configure() { + contentView.addSubview(titleLabel) + titleLabel.snp.makeConstraints { make in + make.left.equalToSuperview().offset(18*width) + make.right.equalToSuperview().offset(-18*width) + make.top.equalToSuperview().offset(10*width).priority(999) + make.bottom.equalToSuperview().offset(10*width).priority(999) + } + } +} diff --git a/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowCollectionViewCell.swift b/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowCollectionViewCell.swift new file mode 100644 index 0000000..29ebf40 --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowCollectionViewCell.swift @@ -0,0 +1,56 @@ +// +// MPPositive_ArtistShowCollectionViewCell.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/16. +// + +import UIKit +///艺术家展示cell +class MPPositive_ArtistShowCollectionViewCell: UICollectionViewCell { + ///艺术家头像 + private lazy var avatarImageView:UIImageView = { + let imageView:UIImageView = .init() + imageView.contentMode = .scaleAspectFill + imageView.layer.masksToBounds = true + imageView.layer.cornerRadius = 82*width + return imageView + }() + ///艺术家名字 + private lazy var titleLabel:UILabel = createLabel("Title", font: .systemFont(ofSize: 14*width, weight: .regular), textColor: .white, textAlignment: .center) + ///艺术家订阅数量 + private lazy var subtitleLabel:UILabel = createLabel("Title", font: .systemFont(ofSize: 12*width, weight: .regular), textColor: .init(hex: "#FFFFFF", alpha: 0.6), textAlignment: .center) + + var itemView:MPPositive_BrowseItemViewModel!{ + didSet{ + itemView.setUrltoImage(avatarImageView) + titleLabel.text = itemView.title + subtitleLabel.text = itemView.subtitle + } + } + override init(frame: CGRect) { + super.init(frame: frame) + backgroundColor = .clear + configure() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } + private func configure() { + addSubview(avatarImageView) + avatarImageView.snp.makeConstraints { make in + make.left.top.right.equalToSuperview() + make.height.equalTo(164*width) + } + addSubview(titleLabel) + titleLabel.snp.makeConstraints { make in + make.left.right.equalToSuperview() + make.top.equalTo(avatarImageView.snp.bottom).offset(16*width) + } + addSubview(subtitleLabel) + subtitleLabel.snp.makeConstraints { make in + make.left.right.bottom.equalToSuperview() + } + } +} diff --git a/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowHeaderView.swift b/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowHeaderView.swift new file mode 100644 index 0000000..270945d --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowHeaderView.swift @@ -0,0 +1,86 @@ +// +// MPPositive_ArtistShowHeaderView.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/15. +// + +import UIKit +import Kingfisher +class MPPositive_ArtistShowHeaderView: UIView { + //艺术家图片 + private lazy var reviewImageView:UIImageView = { + let imageView:UIImageView = .init() + imageView.contentMode = .scaleAspectFill + return imageView + }() + //艺术家名字 + private lazy var nameLabel:UILabel = createLabel(font: .systemFont(ofSize: 32*width, weight: .semibold), textColor: .white, textAlignment: .left) + //艺术家当前订阅量label + private lazy var followersLabel:UILabel = createLabel(font: .systemFont(ofSize: 14*width, weight: .regular), textColor: .white, textAlignment: .left) + //是否收藏艺术家按钮 + private lazy var collectionBtn:UIButton = { + let btn = UIButton() + btn.setImage(UIImage(named: "Artist_Collection'logo"), for: .normal) + btn.setImage(UIImage(named: "Artist_Collectioned'logo"), for: .selected) + btn.setBackgroundImage(UIImage(named: "Artist_Collection'bg"), for: .normal) + btn.setBackgroundImage(UIImage(named: "Artist_Collectioned'bg"), for: .selected) + btn.addTarget(self, action: #selector(collectionClick(_ :)), for: .touchUpInside) + return btn + }() + //阴影 + private lazy var maskImageView:UIImageView = { + let imageView:UIImageView = .init(image: .init(named: "List_Cover'mask")) + imageView.contentMode = .scaleAspectFill + imageView.isUserInteractionEnabled = false + return imageView + }() + var artist:MPPositive_ArtistViewModel!{ + didSet{ + reviewImageView.kf.setImage(with: URL(string: artist.header.thumbnails?.last ?? ""), placeholder: placeholderImage) + nameLabel.text = artist.header.title + followersLabel.text = (artist.header.subscriptions ?? "")+" "+(artist.header.subscriptionedText ?? "") + } + } + override init(frame: CGRect) { + super.init(frame: frame) + backgroundColor = .clear + configure() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } + private func configure() { + addSubview(reviewImageView) + reviewImageView.snp.makeConstraints { make in + make.left.right.top.bottom.equalToSuperview() + } + addSubview(maskImageView) + maskImageView.snp.makeConstraints { make in + make.left.right.bottom.equalToSuperview() + make.height.equalTo(225*width) + } + addSubview(collectionBtn) + collectionBtn.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-18*width).priority(999) + make.bottom.equalToSuperview().offset(-50*width).priority(999) + make.width.height.equalTo(72*width) + } + addSubview(nameLabel) + nameLabel.snp.makeConstraints { make in + make.left.equalToSuperview().offset(18*width).priority(999) + make.bottom.equalToSuperview().offset(-80*width).priority(999) + make.right.equalTo(collectionBtn.snp.left).offset(-10*width).priority(999) + } + addSubview(followersLabel) + followersLabel.snp.makeConstraints { make in + make.left.right.equalTo(nameLabel) + make.bottom.equalTo(collectionBtn) + } + } + //收藏这位艺术家 + @objc private func collectionClick(_ sender:UIButton) { + + } +} diff --git a/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowListCollectionViewCell.swift b/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowListCollectionViewCell.swift new file mode 100644 index 0000000..2fffe2e --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowListCollectionViewCell.swift @@ -0,0 +1,55 @@ +// +// MPPositive_ArtistShowListCollectionViewCell.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/16. +// + +import UIKit + +class MPPositive_ArtistShowListCollectionViewCell: UICollectionViewCell { + //预览图 + private lazy var coverImageView:UIImageView = { + let imageView:UIImageView = .init() + imageView.contentMode = .scaleAspectFill + imageView.layer.masksToBounds = true + imageView.layer.cornerRadius = 16*width + return imageView + }() + //标题Label + private lazy var titleLabel:UILabel = createLabel("Title", font: .systemFont(ofSize: 14*width, weight: .regular), textColor: .white, textAlignment: .left) + //副标题 + private lazy var subtitleLabel:UILabel = createLabel("Title", font: .systemFont(ofSize: 12*width, weight: .regular), textColor: .init(hex: "#FFFFFF", alpha: 0.6), textAlignment: .left) + var itemView:MPPositive_BrowseItemViewModel!{ + didSet{ + itemView.setUrltoImage(coverImageView) + titleLabel.text = itemView.title + subtitleLabel.text = itemView.subtitle + } + } + override init(frame: CGRect) { + super.init(frame: frame) + backgroundColor = .clear + configure() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } + private func configure() { + addSubview(coverImageView) + coverImageView.snp.makeConstraints { make in + make.left.top.right.equalToSuperview() + make.height.equalTo(167*width) + } + addSubview(titleLabel) + titleLabel.snp.makeConstraints { make in + make.left.right.equalToSuperview() + make.top.equalTo(coverImageView.snp.bottom).offset(16*width) + } + addSubview(subtitleLabel) + subtitleLabel.snp.makeConstraints { make in + make.left.right.bottom.equalToSuperview() + } + } +} diff --git a/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowListableViewCell.swift b/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowListableViewCell.swift new file mode 100644 index 0000000..c3e10fa --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowListableViewCell.swift @@ -0,0 +1,123 @@ +// +// MPPositive_ArtistShowListableViewCell.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/16. +// + +import UIKit + +class MPPositive_ArtistShowListableViewCell: UITableViewCell { + ///艺术家Layout类型 + enum ArtistType:Int { + case List = 0 + case Artist = 1 + var layout:UICollectionViewFlowLayout { + let layout = UICollectionViewFlowLayout() + layout.itemSize = .init(width: 164*width, height: 223*width) + switch self { + case .List: + layout.sectionInset = .init(top: 15*width, left: 18*width, bottom: 40*width, right: 18*width) + layout.minimumInteritemSpacing = 10*width + layout.minimumLineSpacing = 16*width + layout.scrollDirection = .vertical + case .Artist: + layout.sectionInset = .init(top: 15*width, left: 18*width, bottom: 40*width, right: 18*width) + layout.minimumLineSpacing = 10*width + layout.scrollDirection = .horizontal + } + return layout + } + + } + //展示CollectionViewCell + private lazy var collectionView:UICollectionView = { + let collectionView:UICollectionView = .init(frame: .init(x: 0, y: 0, width: screen_Width, height: screen_Height), collectionViewLayout: showType.layout) + collectionView.showsVerticalScrollIndicator = false + collectionView.showsHorizontalScrollIndicator = false + collectionView.backgroundColor = .clear + collectionView.dataSource = self + collectionView.delegate = self + collectionView.register(MPPositive_ArtistShowListCollectionViewCell.self, forCellWithReuseIdentifier: MPPositive_ArtistShowListCollectionViewCellID) + collectionView.register(MPPositive_ArtistShowCollectionViewCell.self, forCellWithReuseIdentifier: MPPositive_ArtistShowCollectionViewCellID) + return collectionView + }() + private let MPPositive_ArtistShowListCollectionViewCellID = "MPPositive_ArtistShowListCollectionViewCell" + private let MPPositive_ArtistShowCollectionViewCellID = "MPPositive_ArtistShowCollectionViewCell" + var itemViews:[MPPositive_BrowseItemViewModel]! + ///列表展示类型 + var showType:ArtistType = .List{ + didSet{ + collectionView.collectionViewLayout = showType.layout + collectionView.reloadData() + } + } + //选中内容 + var chooseItemBlock:((MPPositive_BrowseItemViewModel) -> Void)? + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + selectionStyle = .none + backgroundColor = .clear + configure() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } + override func awakeFromNib() { + super.awakeFromNib() + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + private func configure() { + contentView.addSubview(collectionView) + collectionView.snp.makeConstraints { make in + make.left.right.top.equalToSuperview() + make.bottom.equalToSuperview().offset(-1*width).priority(999) + } + } + //经过计算设置tableViewCell真实高度 + override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize { + let size = super.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: horizontalFittingPriority, verticalFittingPriority: verticalFittingPriority) + collectionView.layoutIfNeeded() + switch showType { + case .List: + //纵向 + let height = collectionView.collectionViewLayout.collectionViewContentSize.height + return CGSize(width: size.width, height: size.height + height) + case .Artist: + //横向 + let height = showType.layout.itemSize.height + showType.layout.sectionInset.top + showType.layout.sectionInset.bottom + return CGSize(width: size.width, height: size.height + height) + } + } +} +//MARK: - tableView +extension MPPositive_ArtistShowListableViewCell:UICollectionViewDataSource, UICollectionViewDelegate { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return itemViews?.count ?? 0 + } + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + switch showType { + case .List: + //纵向 + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MPPositive_ArtistShowListCollectionViewCellID, for: indexPath) as! MPPositive_ArtistShowListCollectionViewCell + cell.itemView = itemViews[indexPath.row] + return cell + case .Artist: + //横向 + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MPPositive_ArtistShowCollectionViewCellID, for: indexPath) as! MPPositive_ArtistShowCollectionViewCell + cell.itemView = itemViews[indexPath.row] + return cell + } + } + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + if chooseItemBlock != nil { + chooseItemBlock!(itemViews[indexPath.row]) + } + } +} diff --git a/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowSongTableViewCell.swift b/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowSongTableViewCell.swift new file mode 100644 index 0000000..74d83dd --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowSongTableViewCell.swift @@ -0,0 +1,105 @@ +// +// MPPositive_ArtistShowSongTableViewCell.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/16. +// + +import UIKit + +class MPPositive_ArtistShowSongTableViewCell: UITableViewCell { + //特殊图片(展示预览图片) + private lazy var iconImageView:UIImageView = { + let imageView:UIImageView = .init() + imageView.contentMode = .scaleAspectFill + imageView.layer.masksToBounds = true + return imageView + }() + private lazy var titleLabel:UILabel = createLabel(font: .systemFont(ofSize: 14*width, weight: .regular), textColor: .white, textAlignment: .left) + private lazy var subtitleLabel:UILabel = createLabel(font: .systemFont(ofSize: 12*width, weight: .regular), textColor: .init(hex: "#FFFFFF", alpha: 0.6), textAlignment: .left) + ///更多按钮 + private lazy var moreBtn:UIButton = { + let btn:UIButton = .init() + btn.setBackgroundImage(UIImage(named: "Song_More'logo"), for: .normal) + btn.addTarget(self, action: #selector(moreActionClick(_ :)), for: .touchUpInside) + return btn + }() + ///下载状态按钮 + private lazy var loadBtn:UIButton = { + let btn:UIButton = .init() + btn.setBackgroundImage(UIImage(named: "Song_Unload'logo"), for: .normal) + btn.setBackgroundImage(UIImage(named: "Song_Loaded'logo"), for: .selected) + btn.addTarget(self, action: #selector(loadActionClick(_ :)), for: .touchUpInside) + return btn + }() + var itemView:MPPositive_BrowseItemViewModel!{ + didSet{ + itemView.setUrltoImage(iconImageView) + titleLabel.text = itemView.title + subtitleLabel.text = itemView.subtitle + } + } + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + selectionStyle = .none + backgroundColor = .clear + configure() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + private func configure() { + contentView.addSubview(iconImageView) + iconImageView.snp.makeConstraints { make in + make.width.height.equalTo(60*width) + make.top.equalToSuperview().offset(8*width).priority(999) + make.bottom.equalToSuperview().offset(-8*width) + make.left.equalToSuperview().offset(18*width) + } + contentView.addSubview(moreBtn) + moreBtn.snp.makeConstraints { make in + make.width.height.equalTo(24*width) + make.centerY.equalTo(iconImageView.snp.centerY) + make.right.equalToSuperview().offset(-18*width) + } + contentView.addSubview(loadBtn) + loadBtn.snp.makeConstraints { make in + make.width.height.equalTo(24*width) + make.centerY.equalTo(iconImageView.snp.centerY) + make.right.equalToSuperview().offset(-54*width) + } + contentView.addSubview(titleLabel) + titleLabel.snp.makeConstraints { make in + make.top.equalTo(iconImageView.snp.top).offset(10*width) + make.left.equalTo(iconImageView.snp.right).offset(12*width) + make.right.equalTo(loadBtn.snp.left).offset(-10*width) + } + contentView.addSubview(subtitleLabel) + subtitleLabel.snp.makeConstraints { make in + make.bottom.equalTo(iconImageView.snp.bottom).offset(-10*width) + make.left.equalTo(titleLabel.snp.left) + make.right.equalTo(titleLabel.snp.right) + } + } + + //点击更多 + @objc private func moreActionClick(_ sender:UIButton) { + + } + //点击下载 + @objc private func loadActionClick(_ sender:UIButton) { + + } +} diff --git a/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowTypeView.swift b/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowTypeView.swift new file mode 100644 index 0000000..83a4573 --- /dev/null +++ b/MusicPlayer/MP/MPPositive/Views/Home/MPPositive_ArtistShowTypeView.swift @@ -0,0 +1,197 @@ +// +// MPPositive_ArtistShowTypeView.swift +// MusicPlayer +// +// Created by Mr.Zhou on 2024/5/15. +// + +import UIKit +import MJRefresh +class MPPositive_ArtistShowTypeView: UIView, JXPagingViewListViewDelegate { + //tableView + private lazy var tableView:UITableView = { + let tableView = UITableView() + if #available(iOS 15.0, *) { + tableView.sectionHeaderTopPadding = 0 + } + tableView.backgroundColor = .clear + tableView.separatorStyle = .none + tableView.estimatedRowHeight = 200 + tableView.rowHeight = UITableView.automaticDimension + tableView.dataSource = self + tableView.delegate = self + tableView.register(MPPositive_ArtistShowSongTableViewCell.self, forCellReuseIdentifier: MPPositive_ArtistShowSongTableViewCellID) + tableView.register(MPPositive_ArtistShowListableViewCell.self, forCellReuseIdentifier: MPPositive_ArtistShowListableViewCellID) + tableView.register(MPPositive_ArtistDescriptionTableViewCell.self, forCellReuseIdentifier: MPPositive_ArtistDescriptionTableViewCellID) + //添加一个上拉加载 + let footer = MJRefreshAutoGifFooter { + [weak self] in + self?.footerRefresh() + } + footer.setTitle("Pull Up", for: .idle) + footer.setTitle("Release Refresh", for: .pulling) + footer.setTitle("Loading...", for: .refreshing) + footer.setTitle("No Data", for: .noMoreData) + tableView.mj_footer = footer + return tableView + }() + private let MPPositive_ArtistShowSongTableViewCellID = "MPPositive_ArtistShowSongTableViewCell" + private let MPPositive_ArtistShowListableViewCellID = "MPPositive_ArtistShowListableViewCell" + private let MPPositive_ArtistDescriptionTableViewCellID = "MPPositive_ArtistDescriptionTableViewCell" + private var sectionList:MPPositive_ArtistContentListViewModel!{ + didSet{ + if sectionList != nil { + //检索当前数据是否为全部 + if sectionList.browseId != nil && sectionList.params != nil { + //当前数据并不完整,需要初次补全一部分 + sectionList.requestArtistType() + }else { + //当前数据完整 + tableView.reloadData() + tableView.mj_footer?.endRefreshing() + } + sectionList.completionBlock = { + [weak self] in + self?.tableView.reloadData() + self?.tableView.mj_footer?.endRefreshing() + } + }else { + tableView.reloadData() + } + } + } + var header:MPPositive_ArtistHeaderModel! + //scroll滚动回调 + fileprivate var listViewDidScrollCallback: ((UIScrollView) -> ())? + //选中内容 + var chooseItemBlock:((MPPositive_BrowseItemViewModel) -> Void)? + init(frame: CGRect, list:MPPositive_ArtistContentListViewModel) { + super.init(frame: frame) + backgroundColor = .init(hex: "#151718") + //赋值 + DispatchQueue.main.async { + [weak self] in + self?.sectionList = list + } + addSubview(tableView) + tableView.snp.makeConstraints { make in + make.left.top.right.bottom.equalToSuperview() + } + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } + //上拉刷新 + @objc private func footerRefresh() { + guard sectionList.continuation != nil, sectionList.itct != nil else { + tableView.mj_footer?.endRefreshingWithNoMoreData() + return + } + sectionList.requestArtistContinuation() + } + + //MARK: - 遵循分页代理 + func scrollViewDidScroll(_ scrollView: UIScrollView) { + listViewDidScrollCallback?(scrollView) + } + //获取当前视图 + func listView() -> UIView { + return self + } + //获取当前视图中的ScrollView + func listScrollView() -> UIScrollView { + return tableView + } + //当前视图滚动时回调闭包 + func listViewDidScrollCallback(callback: @escaping (UIScrollView) -> ()) { + listViewDidScrollCallback = callback + } +} +//MARK: - tableView +extension MPPositive_ArtistShowTypeView:UITableViewDataSource, UITableViewDelegate { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if let first = sectionList?.itemViews.first { + switch first.browseItem.itemType { + case .single: + return sectionList.itemViews.count + case .list: + return 1 + case .artist: + return 2 + default: + return 0 + } + }else { + return 0 + } + } + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + if let first = sectionList?.itemViews.first { + switch first.browseItem.itemType { + case .single: + let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_ArtistShowSongTableViewCellID) as! MPPositive_ArtistShowSongTableViewCell + cell.itemView = sectionList.itemViews[indexPath.row] + return cell + case .list: + let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_ArtistShowListableViewCellID, for: indexPath) as! MPPositive_ArtistShowListableViewCell + cell.itemViews = sectionList.itemViews + cell.chooseItemBlock = { + [weak self] item in + guard let self = self else {return} + if chooseItemBlock != nil { + chooseItemBlock!(item) + } + } + cell.showType = .List + return cell + case .artist: + switch indexPath.row { + case 0: + let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_ArtistShowListableViewCellID, for: indexPath) as! MPPositive_ArtistShowListableViewCell + cell.itemViews = sectionList.itemViews + cell.chooseItemBlock = { + [weak self] item in + guard let self = self else {return} + if chooseItemBlock != nil { + chooseItemBlock!(item) + } + } + cell.showType = .Artist + return cell + default: + let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_ArtistDescriptionTableViewCellID, for: indexPath) as! MPPositive_ArtistDescriptionTableViewCell + cell.titleLabel.text = header?.fordescription ?? "" + return cell + } + default: + let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_ArtistShowSongTableViewCellID) as! MPPositive_ArtistShowSongTableViewCell + + return cell + } + }else { + let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_ArtistShowSongTableViewCellID) as! MPPositive_ArtistShowSongTableViewCell + + return cell + } + } + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if let first = sectionList?.itemViews.first { + switch first.browseItem.itemType { + case .single: + //当前是单曲分页,点击cell可以直接触发事件块 + if chooseItemBlock != nil { + chooseItemBlock!(sectionList.itemViews[indexPath.row]) + } + case .list: + //当前是歌单专辑分页,用户点击不能触发 + break + case .artist: + //当前是艺术家页,用户点击不能触发 + break + default: + break + } + } + } +} diff --git a/MusicPlayer/MP/MPPositive/Views/Player/MPPositive_PlayerCoverView.swift b/MusicPlayer/MP/MPPositive/Views/Player/MPPositive_PlayerCoverView.swift index 91edf2c..4628484 100644 --- a/MusicPlayer/MP/MPPositive/Views/Player/MPPositive_PlayerCoverView.swift +++ b/MusicPlayer/MP/MPPositive/Views/Player/MPPositive_PlayerCoverView.swift @@ -8,6 +8,9 @@ import UIKit //B面播放器封面View(封面,标题,副标题,收藏,下载,进度条View) class MPPositive_PlayerCoverView: UIView { + //下载进度条View + private var loadView = CircularProgressView() + ///封面 lazy var coverImageView:UIImageView = { let imageView = UIImageView() @@ -44,6 +47,14 @@ class MPPositive_PlayerCoverView: UIView { sliderView.addTarget(self, action: #selector(seekProgressClick(_:forEvent:)), for: .touchUpInside) return sliderView }() + ///缓存条View + lazy var progressView:UIProgressView = { + let progressView:UIProgressView = .init() + progressView.isUserInteractionEnabled = true + progressView.progressTintColor = .init(hex: "#FFFFFF", alpha: 0.3) + progressView.trackTintColor = .clear + return progressView + }() ///当前播放时间值Label lazy var durationLabel:UILabel = createLabel("00:00" ,font: .systemFont(ofSize: 12*width, weight: .medium), textColor: .init(hex: "#FFFFFF", alpha: 0.85), textAlignment: .left) ///最大播放时间值Label @@ -93,14 +104,18 @@ class MPPositive_PlayerCoverView: UIView { make.centerY.equalTo(loadBtn.snp.centerY) make.width.height.equalTo(24*width) } - //配置进度条和时间label - addSubview(sliderView) - sliderView.snp.makeConstraints { make in + addSubview(progressView) + progressView.snp.makeConstraints { make in make.top.equalTo(subtitleLabel.snp.bottom).offset(25*width) make.centerX.equalToSuperview() make.width.equalTo(335*width) make.height.equalTo(6*width) } + //配置进度条和时间label + addSubview(sliderView) + sliderView.snp.makeConstraints { make in + make.left.right.top.bottom.equalTo(progressView) + } addSubview(durationLabel) durationLabel.snp.makeConstraints { make in make.left.equalTo(sliderView.snp.left) @@ -137,13 +152,57 @@ class MPPositive_PlayerCoverView: UIView { } //点击下载 @objc private func loadActionClick(_ sender:UIButton) { + // 添加圆形进度条到下载按钮位置 + addCircularProgressBar(over: sender) + + self.loadBtn.setBackgroundImage(UIImage(named: ""), for: .normal) + self.loadBtn.setImage(UIImage(named: "download"), for: .normal) + //下载,检索当前播放音乐是否存在 if MP_PlayerManager.shared.loadPlayer.currentVideo != nil { - //当前音乐存在,执行音乐下载 - //处理完成 - let item = MPPositive_DownloadItemModel.create() - - MPPositive_DownloadItemModel.save() + + // 下载视频 + if let currentVideo = MP_PlayerManager.shared.loadPlayer.currentVideo, let videoURLString = currentVideo.song.resourceUrls?.first, let videoURL = URL(string: videoURLString) { + let videoId = currentVideo.song.videoId ?? "default_video_id" + DownloadManager.shared.downloadVideo(from: videoURL, videoId: videoId, progressView: loadView, completion: { [weak self] result in + switch result { + case .success(let fileURL): + let item = MPPositive_DownloadItemModel.create() + item.resourcePath = "\(fileURL)" + item.coverImage = URL(string: MP_PlayerManager.shared.loadPlayer.currentVideo.song.coverUrls!.first!) + item.reviewImage = URL(string: MP_PlayerManager.shared.loadPlayer.currentVideo.song.reviewUrls!.first!) + item.title = MP_PlayerManager.shared.loadPlayer.currentVideo.song.title + item.longBylineText = MP_PlayerManager.shared.loadPlayer.currentVideo.song.longBylineText + item.lengthText = MP_PlayerManager.shared.loadPlayer.currentVideo.song.lengthText + item.shortBylineText = MP_PlayerManager.shared.loadPlayer.currentVideo.song.shortBylineText + item.lyrics = MP_PlayerManager.shared.loadPlayer.currentVideo.lyrics + item.videoId = MP_PlayerManager.shared.loadPlayer.currentVideo.song.videoId + item.relatedID = MP_PlayerManager.shared.loadPlayer.currentVideo.song.relatedID + + MPPositive_DownloadItemModel.save() + DispatchQueue.main.async { + self?.loadBtn.setBackgroundImage(UIImage(named: "Song_Loaded'logo"), for: .normal) + self?.loadBtn.setImage(UIImage(named: ""), for: .normal) + } + + self?.loadView.removeFromSuperview() + case .failure(let error): + print("Download failed with error: \(error)") + self?.loadView.removeFromSuperview() + } + }) + } } } + // 添加圆形进度条 + private func addCircularProgressBar(over button: UIButton) { + loadView.removeFromSuperview() // 移除先前的进度视图(如果有) + + loadView = CircularProgressView(frame: button.bounds) + addSubview(loadView) + loadView.snp.makeConstraints { make in + make.center.equalTo(button) + make.width.height.equalTo(button) + } + } } diff --git a/MusicPlayer/MP/MPPositive/Views/Player/MPPositive_PlayerListShowTableViewCell.swift b/MusicPlayer/MP/MPPositive/Views/Player/MPPositive_PlayerListShowTableViewCell.swift index 4a250ad..28fecb4 100644 --- a/MusicPlayer/MP/MPPositive/Views/Player/MPPositive_PlayerListShowTableViewCell.swift +++ b/MusicPlayer/MP/MPPositive/Views/Player/MPPositive_PlayerListShowTableViewCell.swift @@ -30,7 +30,7 @@ class MPPositive_PlayerListShowTableViewCell: UITableViewCell { var song:MPPositive_SongItemModel!{ didSet{ //判断是否当前播放 - if song.videoId == MP_PlayerManager.shared.loadPlayer.currentVideo.song.videoId { + if song.videoId == MP_PlayerManager.shared.loadPlayer.currentVideo?.song?.videoId { titleLabel.textColor = .init(hex: "#80F988") subtitleLabel.textColor = .init(hex: "#80F988") }else { diff --git a/MusicPlayer/MP/MPPositive/Views/Player/MPPositive_PlayerSilder.swift b/MusicPlayer/MP/MPPositive/Views/Player/MPPositive_PlayerSilder.swift index ddab745..63ca37b 100644 --- a/MusicPlayer/MP/MPPositive/Views/Player/MPPositive_PlayerSilder.swift +++ b/MusicPlayer/MP/MPPositive/Views/Player/MPPositive_PlayerSilder.swift @@ -8,12 +8,118 @@ import UIKit ///b面播放器进度条(展示缓存效果,聚焦时进行尺寸变化) class MPPositive_PlayerSilder: UISlider { - - override init(frame: CGRect) { + //滑块图片 + var thumbImage:UIImage = .init(named: "Player_Slider'logo")! + //滑轨槽高度 + var trackHeight: CGFloat = 6*width + //进度渐变色 + var minTrackColors: [UIColor]! + //槽位渐变色 + var maxTrackColors:[UIColor]! + //进度渐变色定位列表(与渐变色数量保持一致) + var minTrackLocations:[CGFloat]! + //槽位渐变色定位列表(与渐变色数量保持一致) + var maxTrackLocations:[CGFloat]! + + //初始化 + override init(frame:CGRect) { super.init(frame: frame) + setUpLayout() } required init?(coder: NSCoder) { super.init(coder: coder) } + private func setUpLayout() { + layer.masksToBounds = false + setThumbImage(thumbImage, for: .normal) + //设置进度图片 + let minTrackImg = makeTrackImage(rect: frame, colors: [UIColor.white], locations: [0,1]) + setMinimumTrackImage(minTrackImg, for: .normal) + // 设置槽位 + let maxTrackImg = makeTrackImage(rect: frame, colors: [UIColor(hex: "#FFFFFF", alpha: 0.1)], locations: [0,1]) + setMaximumTrackImage(maxTrackImg, for: .normal) + } + + /// 滑块设置 + /// - Parameters: + /// - rect: 滑块大小 + /// - color: 滑块颜色 + /// - Returns: 返回的滑块图片 + private func makeThumbImage(rect: CGRect, color:UIColor) -> UIImage { + let lineWidth: CGFloat = 2 + //开始绘制 + UIGraphicsBeginImageContextWithOptions(rect.size, false, 0) + //填充内部颜色 + color.setFill() + //曲线路径 + let oval = UIBezierPath(ovalIn: rect) + //填充路径 + oval.fill() + //设置路径颜色为白色 + UIColor.white.setStroke() + //路径宽度 + oval.lineWidth = lineWidth + oval.stroke() + //转为图片 + let thumbImg = UIGraphicsGetImageFromCurrentImageContext()! + //转化结束 + UIGraphicsEndImageContext() + return thumbImg + } + + + /// 生成滑轨图片 + /// - Parameters: + /// - rect: 滑轨大小 + /// - colors: 颜色列表 + /// - locations: 位置分布列表 + /// - Returns: 生成的图片 + private func makeTrackImage(rect: CGRect, colors:[UIColor], locations:[CGFloat]) -> UIImage { + let rect = CGRect(x: rect.minX, y: rect.minY, width: rect.width, height: self.trackHeight) + //开始绘制 + UIGraphicsBeginImageContextWithOptions(rect.size, false, 0) + let ctx = UIGraphicsGetCurrentContext()! + // 创建并设置路径 + let cornerRadius: CGFloat = rect.height * 0.5 + let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).cgPath + // 添加路径到图形上下文 + ctx.addPath(path) + ctx.clip() + // 使用rgb颜色空间 + let colorSpace = CGColorSpaceCreateDeviceRGB() + //获取cgcolors + var cgColors:[CGColor] = [] + colors.forEach { item in + cgColors.append(item.cgColor) + } + // 定义渐变色 + let gradient:CGGradient = CGGradient(colorsSpace: colorSpace, colors: cgColors as CFArray, locations: locations)! + // 渐变开始位置 + let start = CGPoint(x: self.bounds.minX, y: self.bounds.minY) + // 渐变结束位置 + let end = CGPoint(x: self.bounds.maxX, y: self.bounds.minY) + // 绘制渐变 + ctx.drawLinearGradient(gradient, start: start, end: end, options: .drawsBeforeStartLocation) + //转为图片 + let trackImg = UIGraphicsGetImageFromCurrentImageContext()! + UIGraphicsEndImageContext() + return trackImg + } + // 重写【thumb】显示区域 方法 + override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect { + let rect = super.thumbRect(forBounds: bounds, trackRect: rect, value: value) + // 设置thumb投影效果 + // (这样设置的投影效果,如果调用setValue(_:animated:)的时候,animated参数为true,会有阴影和thumb不同步的问题,目前还不知到怎么解决) + self.layer.shadowColor = UIColor.black.cgColor + self.layer.shadowOffset = CGSize(width: 0, height: 0) + self.layer.shadowOpacity = 0.15 + self.layer.shadowRadius = 3 + self.layer.shadowPath = UIBezierPath(cgPath: CGPath(ellipseIn: rect.insetBy(dx: 3, dy: 3), transform: nil)).cgPath + return rect + } + // 重写【track】显示区域 方法 + override func trackRect(forBounds bounds: CGRect) -> CGRect { + return CGRect(x: 0, y: 0, width: bounds.width, height: self.trackHeight) + } } diff --git a/MusicPlayer/MP/MPPositive/Views/Search/MPPositive_SearchResultPreviewShowView.swift b/MusicPlayer/MP/MPPositive/Views/Search/MPPositive_SearchResultPreviewShowView.swift index deb1ff7..6067425 100644 --- a/MusicPlayer/MP/MPPositive/Views/Search/MPPositive_SearchResultPreviewShowView.swift +++ b/MusicPlayer/MP/MPPositive/Views/Search/MPPositive_SearchResultPreviewShowView.swift @@ -37,6 +37,8 @@ class MPPositive_SearchResultPreviewShowView: UIView, JXSegmentedListContainerVi } var scrollBlock:(() -> Void)? var chooseMoreIndexBlock:((Int) -> Void)? + //选中内容 + var chooseItemBlock:((MPPositive_SearchResultItemViewModel) -> Void)? init(frame: CGRect, sectionLists:[MPPositive_SearchResultListViewModel]) { super.init(frame: frame) backgroundColor = .init(hex: "1A1A1A") @@ -111,4 +113,9 @@ extension MPPositive_SearchResultPreviewShowView:UITableViewDataSource, UITableV func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return 50*width } + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if chooseItemBlock != nil { + chooseItemBlock!(sectionLists[indexPath.section].previewItemViews[indexPath.row]) + } + } } diff --git a/MusicPlayer/MP/MPPositive/Views/Search/MPPositive_SearchResultTypeShowView.swift b/MusicPlayer/MP/MPPositive/Views/Search/MPPositive_SearchResultTypeShowView.swift index 6281f04..c46e6b4 100644 --- a/MusicPlayer/MP/MPPositive/Views/Search/MPPositive_SearchResultTypeShowView.swift +++ b/MusicPlayer/MP/MPPositive/Views/Search/MPPositive_SearchResultTypeShowView.swift @@ -6,6 +6,7 @@ // import UIKit +import MJRefresh ///对搜索结果进行分类详情展示 class MPPositive_SearchResultTypeShowView: UIView, JXSegmentedListContainerViewListDelegate { //tableView @@ -21,41 +22,56 @@ class MPPositive_SearchResultTypeShowView: UIView, JXSegmentedListContainerViewL tableView.dataSource = self tableView.delegate = self tableView.register(MPPositive_SearchResultShowTableViewCell.self, forCellReuseIdentifier: MPPositive_SearchResultShowTableViewCellID) + //添加一个上拉加载 + let footer = MJRefreshAutoGifFooter { + [weak self] in + self?.footerRefresh() + } + footer.setTitle("Pull Up", for: .idle) + footer.setTitle("Release Refresh", for: .pulling) + footer.setTitle("Loading...", for: .refreshing) + footer.setTitle("No Data", for: .noMoreData) + tableView.mj_footer = footer return tableView }() private let MPPositive_SearchResultShowTableViewCellID = "MPPositive_SearchResultShowTableViewCell" //对应的分类详情展示 - private var sectionList:MPPositive_SearchResultListViewModel!{ + var sectionList:MPPositive_SearchResultListViewModel!{ didSet{ - DispatchQueue.main.async { - [weak self] in - guard let self = self else {return} - if sectionList != nil { - if sectionList.allItemViews.count == 0 { - //开始请求内容 - sectionList.requestSearchType() - } - sectionList.completionBlock = { - self.tableView.reloadData() - } - }else { - tableView.reloadData() + if sectionList != nil { + if sectionList.allItemViews.count == 0 { + //开始请求内容 + sectionList.requestSearchType() } + sectionList.completionBlock = { + [weak self] in + self?.tableView.reloadData() + self?.tableView.mj_footer?.endRefreshing() + } + }else { + tableView.reloadData() } } } var scrollBlock:(() -> Void)? - init(frame: CGRect, sectionList:MPPositive_SearchResultListViewModel) { + init(frame: CGRect, list:MPPositive_SearchResultListViewModel) { super.init(frame: frame) backgroundColor = .init(hex: "1A1A1A") - self.sectionList = sectionList + DispatchQueue.main.async { + [weak self] in + self?.sectionList = list + } configure() } required init?(coder: NSCoder) { super.init(coder: coder) } + override func awakeFromNib() { + super.awakeFromNib() + } + //MARK: - 分页代理 func listView() -> UIView { return self @@ -67,6 +83,14 @@ class MPPositive_SearchResultTypeShowView: UIView, JXSegmentedListContainerViewL make.left.top.right.bottom.equalToSuperview() } } + //上拉刷新 + @objc private func footerRefresh() { + guard sectionList.continuation != nil, sectionList.itct != nil else { + tableView.mj_footer?.endRefreshingWithNoMoreData() + return + } + sectionList.requestSearchContinuation() + } } //MARK: - tableView extension MPPositive_SearchResultTypeShowView:UITableViewDataSource, UITableViewDelegate { diff --git a/MusicPlayer/MP/MPPositive/Views/Search/MPPositive_SearchResultsShowView.swift b/MusicPlayer/MP/MPPositive/Views/Search/MPPositive_SearchResultsShowView.swift index 12066f0..5482bea 100644 --- a/MusicPlayer/MP/MPPositive/Views/Search/MPPositive_SearchResultsShowView.swift +++ b/MusicPlayer/MP/MPPositive/Views/Search/MPPositive_SearchResultsShowView.swift @@ -9,7 +9,7 @@ import UIKit class MPPositive_SearchResultsShowView: UIView { ///搜索结果管理模型 - var loadModel:MPPositive_LoadSearchResultsViewModel!{ + var loadModel:MPPositive_SearchResultsLoadViewModel!{ didSet{ DispatchQueue.main.async { [weak self] in @@ -25,6 +25,7 @@ class MPPositive_SearchResultsShowView: UIView { dataSource.titles = loadModel?.sectionLists.compactMap({$0.title}) ?? [] dataSource.reloadData(selectedIndex: 0) segmentView.reloadData() + emptyImageView.isHidden = !(dataSource.titles.count == 0) } } } @@ -68,10 +69,18 @@ class MPPositive_SearchResultsShowView: UIView { listContainerView.backgroundColor = .clear return listContainerView }() + //数据空图片 + private lazy var emptyImageView:UIImageView = { + let imageView = UIImageView(image: UIImage(named: "empty")) + imageView.contentMode = .scaleAspectFill + return imageView + }() var scrollBlock:(() -> Void)? + //选中内容 + var chooseItemBlock:((MPPositive_SearchResultItemViewModel) -> Void)? override init(frame: CGRect) { super.init(frame: frame) - backgroundColor = .clear + backgroundColor = .init(hex: "1A1A1A") configure() } @@ -80,6 +89,12 @@ class MPPositive_SearchResultsShowView: UIView { } //配置 private func configure() { + addSubview(emptyImageView) + emptyImageView.snp.makeConstraints { make in + make.center.equalToSuperview() + make.width.equalTo(211*width) + make.height.equalTo(172*width) + } segmentView.indicators = [indicator] segmentView.dataSource = dataSource //配置View @@ -120,10 +135,19 @@ extension MPPositive_SearchResultsShowView: JXSegmentedListContainerViewDataSour } segmentView.selectItemAt(index: selectedIndex) } + showView.chooseItemBlock = { + [weak self] item in + guard let self = self else { + return + } + if chooseItemBlock != nil { + chooseItemBlock!(item) + } + } return showView }else { //展示分类结果 - let showView:MPPositive_SearchResultTypeShowView = .init(frame: listContainerView.frame, sectionList: loadModel.sectionLists[index]) + let showView:MPPositive_SearchResultTypeShowView = .init(frame: listContainerView.frame, list: loadModel.sectionLists[index]) showView.scrollBlock = { [weak self] in if self?.scrollBlock != nil { diff --git a/Podfile b/Podfile index bf2714a..891a368 100644 --- a/Podfile +++ b/Podfile @@ -21,4 +21,7 @@ pod "Kingfisher" #分页工具 pod 'JXSegmentedView' pod 'JXPagingView/Paging' +#刷新支持 +pod 'MJRefresh' + end diff --git a/Podfile.lock b/Podfile.lock index e913de3..3302729 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,11 +1,14 @@ PODS: - Alamofire (5.9.1) - - IQKeyboardManagerSwift (6.5.13) + - IQKeyboardManagerSwift (6.5.16) - JXPagingView/Paging (2.1.3) - JXSegmentedView (1.3.3) - Kingfisher (7.11.0) - - SnapKit (5.6.0) - - SVProgressHUD (2.2.5) + - MJRefresh (3.7.9) + - SnapKit (5.7.1) + - SVProgressHUD (2.3.1): + - SVProgressHUD/Core (= 2.3.1) + - SVProgressHUD/Core (2.3.1) - SwiftDate (6.3.1) DEPENDENCIES: @@ -14,6 +17,7 @@ DEPENDENCIES: - JXPagingView/Paging - JXSegmentedView - Kingfisher + - MJRefresh - SnapKit - SVProgressHUD - SwiftDate @@ -25,20 +29,22 @@ SPEC REPOS: - JXPagingView - JXSegmentedView - Kingfisher + - MJRefresh - SnapKit - SVProgressHUD - SwiftDate SPEC CHECKSUMS: Alamofire: f36a35757af4587d8e4f4bfa223ad10be2422b8c - IQKeyboardManagerSwift: 69b5fb9960edff37263d45c44fd97427e1f8c22b + IQKeyboardManagerSwift: 12d89768845bb77b55cc092ecc2b1f9370f06b76 JXPagingView: afdd2e9af09c90160dd232b970d603cc6e7ddd0e JXSegmentedView: 651b60fcf705258ba9395edd53876dbd2853fb68 Kingfisher: b9c985d864d43515f404f1ef4a8ce7d802ace3ac - SnapKit: e01d52ebb8ddbc333eefe2132acf85c8227d9c25 - SVProgressHUD: 1428aafac632c1f86f62aa4243ec12008d7a51d6 + MJRefresh: ff9e531227924c84ce459338414550a05d2aea78 + SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a + SVProgressHUD: 4837c74bdfe2e51e8821c397825996a8d7de6e22 SwiftDate: 72d28954e8e1c6c1c0f917ccc8005e4f83c7d4b2 -PODFILE CHECKSUM: c0bbca53cdc7c53ea7a9dbc8d75b7ae964a1dbc2 +PODFILE CHECKSUM: ba88795291c32ea83d380e5384537ca7f5568cd7 COCOAPODS: 1.15.2 diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Debug.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Debug.swift index cb20c6c..b5008db 100644 --- a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Debug.swift +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Debug.swift @@ -51,9 +51,9 @@ public extension IQKeyboardManager { // Registering for keyboard notification. NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardDidShow(_:)), name: UIResponder.keyboardDidShowNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardDidHide(_:)), name: UIResponder.keyboardDidHideNotification, object: nil) + + NotificationCenter.default.addObserver(self, selector: #selector(applicationDidBecomeActive(_:)), name: UIApplication.didBecomeActiveNotification, object: nil) // Registering for UITextField notification. registerTextFieldViewClass(UITextField.self, didBeginEditingNotificationName: UITextField.textDidBeginEditingNotification.rawValue, didEndEditingNotificationName: UITextField.textDidEndEditingNotification.rawValue) @@ -69,9 +69,9 @@ public extension IQKeyboardManager { // Unregistering for keyboard notification. NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil) - NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardDidShowNotification, object: nil) NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil) - NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardDidHideNotification, object: nil) + + NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil) // Unregistering for UITextField notification. unregisterTextFieldViewClass(UITextField.self, didBeginEditingNotificationName: UITextField.textDidBeginEditingNotification.rawValue, didEndEditingNotificationName: UITextField.textDidEndEditingNotification.rawValue) diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Position.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Position.swift index fcacb5c..b9a3937 100644 --- a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Position.swift +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Position.swift @@ -37,7 +37,6 @@ public extension IQKeyboardManager { static var startingTextViewContentInsets: Int = 0 static var startingTextViewScrollIndicatorInsets: Int = 0 static var isTextViewContentInsetChanged: Int = 0 - static var hasPendingAdjustRequest: Int = 0 } /** @@ -136,33 +135,24 @@ public extension IQKeyboardManager { } } - /** To know if we have any pending request to adjust view position. */ - private var hasPendingAdjustRequest: Bool { - get { - return objc_getAssociatedObject(self, &AssociatedKeys.hasPendingAdjustRequest) as? Bool ?? false - } - set(newValue) { - objc_setAssociatedObject(self, &AssociatedKeys.hasPendingAdjustRequest, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } - } + @objc internal func applicationDidBecomeActive(_ notificatin: Notification) { - internal func optimizedAdjustPosition() { - if !hasPendingAdjustRequest { - hasPendingAdjustRequest = true - OperationQueue.main.addOperation { - self.adjustPosition() - self.hasPendingAdjustRequest = false - } + guard privateIsEnabled(), + keyboardShowing, + topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) == false, let textFieldView = textFieldView, + textFieldView.isAlertViewTextField() == false else { + return } - } + self.adjustPosition() + } // swiftlint:disable function_body_length /* Adjusting RootViewController's frame according to interface orientation. */ - private func adjustPosition() { + internal func adjustPosition() { // We are unable to get textField object while keyboard showing on WKWebView's textField. (Bug ID: #11) - guard hasPendingAdjustRequest, - let textFieldView = textFieldView, + guard UIApplication.shared.applicationState == .active, + let textFieldView = textFieldView, let rootController = textFieldView.parentContainerViewController(), let window = keyWindow(), let textFieldViewRectInWindow = textFieldView.superview?.convert(textFieldView.frame, to: window), @@ -177,16 +167,20 @@ public extension IQKeyboardManager { var rootViewOrigin = rootController.view.frame.origin // Maintain keyboardDistanceFromTextField - var specialKeyboardDistanceFromTextField = textFieldView.keyboardDistanceFromTextField + let specialKeyboardDistanceFromTextField: CGFloat if let searchBar = textFieldView.textFieldSearchBar() { specialKeyboardDistanceFromTextField = searchBar.keyboardDistanceFromTextField + } else { + specialKeyboardDistanceFromTextField = textFieldView.keyboardDistanceFromTextField } let newKeyboardDistanceFromTextField = (specialKeyboardDistanceFromTextField == kIQUseDefaultKeyboardDistance) ? keyboardDistanceFromTextField : specialKeyboardDistanceFromTextField - var kbSize = keyboardFrame.size + let kbSize: CGSize + let originalKbSize: CGSize + // Calculating actual keyboard covered size respect to window, keyboard frame may be different when hardware keyboard is attached (Bug ID: #469) (Bug ID: #381) (Bug ID: #1506) do { var kbFrame = keyboardFrame @@ -196,9 +190,7 @@ public extension IQKeyboardManager { kbFrame.origin.y -= topViewBeginSafeAreaInsets.bottom kbFrame.size.height += topViewBeginSafeAreaInsets.bottom - // Calculating actual keyboard covered size respect to window, keyboard frame may be different when hardware keyboard is attached (Bug ID: #469) (Bug ID: #381) (Bug ID: #1506) let intersectRect = kbFrame.intersection(window.frame) - if intersectRect.isNull { kbSize = CGSize(width: kbFrame.size.width, height: 0) } else { @@ -206,6 +198,15 @@ public extension IQKeyboardManager { } } + do { + let intersectRect = keyboardFrame.intersection(window.frame) + if intersectRect.isNull { + originalKbSize = CGSize(width: keyboardFrame.size.width, height: 0) + } else { + originalKbSize = intersectRect.size + } + } + let statusBarHeight: CGFloat let navigationBarAreaHeight: CGFloat @@ -224,39 +225,35 @@ public extension IQKeyboardManager { navigationBarAreaHeight = statusBarHeight } - let layoutAreaHeight: CGFloat = rootController.view.layoutMargins.bottom + let layoutAreaHeight: CGFloat = rootController.view.directionalLayoutMargins.top - let isTextView: Bool - let isNonScrollableTextView: Bool + let isScrollableTextView: Bool if let textView = textFieldView as? UIScrollView, textFieldView.responds(to: #selector(getter: UITextView.isEditable)) { - - isTextView = true - isNonScrollableTextView = !textView.isScrollEnabled + isScrollableTextView = textView.isScrollEnabled } else { - isTextView = false - isNonScrollableTextView = false + isScrollableTextView = false } - let topLayoutGuide: CGFloat = max(navigationBarAreaHeight, layoutAreaHeight) + 5 + let topLayoutGuide: CGFloat = max(navigationBarAreaHeight, layoutAreaHeight) // Validation of textView for case where there is a tab bar at the bottom or running on iPhone X and textView is at the bottom. - let bottomLayoutGuide: CGFloat = (isTextView && !isNonScrollableTextView) ? 0 : rootController.view.layoutMargins.bottom - let visibleHeight: CGFloat = window.frame.height-kbSize.height + let bottomLayoutGuide: CGFloat = isScrollableTextView ? 0 : rootController.view.directionalLayoutMargins.bottom // Move positive = textField is hidden. // Move negative = textField is showing. // Calculating move position. - var move: CGFloat + var moveUp: CGFloat - // Special case: when the textView is not scrollable, then we'll be scrolling to the bottom part and let hide the top part above - if isNonScrollableTextView { - move = textFieldViewRectInWindow.maxY - visibleHeight + bottomLayoutGuide - } else { - move = min(textFieldViewRectInRootSuperview.minY-(topLayoutGuide), textFieldViewRectInWindow.maxY - visibleHeight + bottomLayoutGuide) + do { + let visibleHeight: CGFloat = window.frame.height-kbSize.height + + let topMovement: CGFloat = textFieldViewRectInRootSuperview.minY-topLayoutGuide + let bottomMovement: CGFloat = textFieldViewRectInWindow.maxY - visibleHeight + bottomLayoutGuide + moveUp = min(topMovement, bottomMovement) } - showLog("Need to move: \(move)") + showLog("Need to move: \(moveUp), will be moving \(moveUp < 0 ? "down" : "up")") var superScrollView: UIScrollView? var superView = textFieldView.superviewOfClassType(UIScrollView.self) as? UIScrollView @@ -299,9 +296,9 @@ public extension IQKeyboardManager { } } - startingContentInsets = UIEdgeInsets() - startingScrollIndicatorInsets = UIEdgeInsets() - startingContentOffset = CGPoint.zero + startingContentInsets = .zero + startingScrollIndicatorInsets = .zero + startingContentOffset = .zero self.lastScrollView = nil } else if superScrollView != lastScrollView { // If both scrollView's are different, then reset lastScrollView to it's original frame and setting current scrollView as last scrollView. @@ -374,11 +371,11 @@ public extension IQKeyboardManager { var shouldContinue = false - if move > 0 { - shouldContinue = move > (-scrollView.contentOffset.y - scrollView.contentInset.top) + if moveUp > 0 { + shouldContinue = moveUp > (-scrollView.contentOffset.y - scrollView.contentInset.top) } else if let tableView = scrollView.superviewOfClassType(UITableView.self) as? UITableView { - + // Special treatment for UITableView due to their cell reusing logic shouldContinue = scrollView.contentOffset.y > 0 if shouldContinue, let tableCell = textFieldView.superviewOfClassType(UITableViewCell.self) as? UITableViewCell, let indexPath = tableView.indexPath(for: tableCell), let previousIndexPath = tableView.previousIndexPath(of: indexPath) { @@ -387,11 +384,11 @@ public extension IQKeyboardManager { if !previousCellRect.isEmpty { let previousCellRectInRootSuperview = tableView.convert(previousCellRect, to: rootController.view.superview) - move = min(0, previousCellRectInRootSuperview.maxY - topLayoutGuide) + moveUp = min(0, previousCellRectInRootSuperview.maxY - topLayoutGuide) } } } else if let collectionView = scrollView.superviewOfClassType(UICollectionView.self) as? UICollectionView { - + // Special treatment for UITableView due to their cell reusing logic shouldContinue = scrollView.contentOffset.y > 0 if shouldContinue, let collectionCell = textFieldView.superviewOfClassType(UICollectionViewCell.self) as? UICollectionViewCell, let indexPath = collectionView.indexPath(for: collectionCell), let previousIndexPath = collectionView.previousIndexPath(of: indexPath), let attributes = collectionView.layoutAttributesForItem(at: previousIndexPath) { @@ -400,23 +397,15 @@ public extension IQKeyboardManager { if !previousCellRect.isEmpty { let previousCellRectInRootSuperview = collectionView.convert(previousCellRect, to: rootController.view.superview) - move = min(0, previousCellRectInRootSuperview.maxY - topLayoutGuide) + moveUp = min(0, previousCellRectInRootSuperview.maxY - topLayoutGuide) } } } else { - if isNonScrollableTextView { - shouldContinue = textFieldViewRectInWindow.maxY < visibleHeight + bottomLayoutGuide + shouldContinue = textFieldViewRectInRootSuperview.minY < topLayoutGuide - if shouldContinue { - move = min(0, textFieldViewRectInWindow.maxY - visibleHeight + bottomLayoutGuide) - } - } else { - shouldContinue = textFieldViewRectInRootSuperview.minY < topLayoutGuide - - if shouldContinue { - move = min(0, textFieldViewRectInRootSuperview.minY - topLayoutGuide) - } + if shouldContinue { + moveUp = min(0, textFieldViewRectInRootSuperview.minY - topLayoutGuide) } } @@ -439,21 +428,16 @@ public extension IQKeyboardManager { if let lastViewRect = lastView.superview?.convert(lastView.frame, to: scrollView) { // Calculating the expected Y offset from move and scrollView's contentOffset. - var shouldOffsetY = scrollView.contentOffset.y - min(scrollView.contentOffset.y, -move) + var shouldOffsetY = scrollView.contentOffset.y - min(scrollView.contentOffset.y, -moveUp) // Rearranging the expected Y offset according to the view. - - if isNonScrollableTextView { - shouldOffsetY = min(shouldOffsetY, lastViewRect.maxY - visibleHeight + bottomLayoutGuide) - } else { - shouldOffsetY = min(shouldOffsetY, lastViewRect.minY) - } + shouldOffsetY = min(shouldOffsetY, lastViewRect.minY) // [_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type // nextScrollView == nil If processing scrollView is last scrollView in upper hierarchy (there is no other scrollView upper hierrchy.) // [_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type // shouldOffsetY >= 0 shouldOffsetY must be greater than in order to keep distance from navigationBar (Bug ID: #92) - if isTextView, !isNonScrollableTextView, + if isScrollableTextView, nextScrollView == nil, shouldOffsetY >= 0 { @@ -467,14 +451,14 @@ public extension IQKeyboardManager { shouldOffsetY = min(shouldOffsetY, scrollView.contentOffset.y + expectedFixDistance) // Setting move to 0 because now we don't want to move any view anymore (All will be managed by our contentInset logic. - move = 0 + moveUp = 0 } else { // Subtracting the Y offset from the move variable, because we are going to change scrollView's contentOffset.y to shouldOffsetY. - move -= (shouldOffsetY-scrollView.contentOffset.y) + moveUp -= (shouldOffsetY-scrollView.contentOffset.y) } } else { // Subtracting the Y offset from the move variable, because we are going to change scrollView's contentOffset.y to shouldOffsetY. - move -= (shouldOffsetY-scrollView.contentOffset.y) + moveUp -= (shouldOffsetY-scrollView.contentOffset.y) } let newContentOffset = CGPoint(x: scrollView.contentOffset.x, y: shouldOffsetY) @@ -482,7 +466,7 @@ public extension IQKeyboardManager { if scrollView.contentOffset.equalTo(newContentOffset) == false { showLog("old contentOffset: \(scrollView.contentOffset) new contentOffset: \(newContentOffset)") - self.showLog("Remaining Move: \(move)") + self.showLog("Remaining Move: \(moveUp)") // Getting problem while using `setContentOffset:animated:`, So I used animation API. UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in @@ -508,7 +492,7 @@ public extension IQKeyboardManager { lastView = scrollView superScrollView = nextScrollView } else { - move = 0 + moveUp = 0 break } } @@ -518,7 +502,7 @@ public extension IQKeyboardManager { lastScrollView.shouldIgnoreContentInsetAdjustment == false { var bottomInset: CGFloat = (kbSize.height)-(window.frame.height-lastScrollViewRect.maxY) - var bottomScrollIndicatorInset = bottomInset - newKeyboardDistanceFromTextField + var bottomScrollIndicatorInset = bottomInset - newKeyboardDistanceFromTextField - topViewBeginSafeAreaInsets.bottom // Update the insets so that the scroll vew doesn't shift incorrectly when the offset is near the bottom of the scroll view. bottomInset = max(startingContentInsets.bottom, bottomInset) @@ -559,9 +543,9 @@ public extension IQKeyboardManager { // Special case for UITextView(Readjusting textView.contentInset when textView hight is too big to fit on screen) // _lastScrollView If not having inside any scrollView, (now contentInset manages the full screen textView. // [_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type - if let textView = textFieldView as? UIScrollView, textView.isScrollEnabled, textFieldView.responds(to: #selector(getter: UITextView.isEditable)) { + if isScrollableTextView, let textView = textFieldView as? UIScrollView { - let keyboardYPosition = window.frame.height - (kbSize.height-newKeyboardDistanceFromTextField) + let keyboardYPosition = window.frame.height - originalKbSize.height var rootSuperViewFrameInWindow = window.frame if let rootSuperview = rootController.view.superview { rootSuperViewFrameInWindow = rootSuperview.convert(rootSuperview.bounds, to: window) @@ -606,9 +590,9 @@ public extension IQKeyboardManager { } // +Positive or zero. - if move >= 0 { + if moveUp >= 0 { - rootViewOrigin.y = max(rootViewOrigin.y - move, min(0, -(kbSize.height-newKeyboardDistanceFromTextField))) + rootViewOrigin.y = max(rootViewOrigin.y - moveUp, min(0, -originalKbSize.height)) if rootController.view.frame.origin.equalTo(rootViewOrigin) == false { showLog("Moving Upward") @@ -638,7 +622,7 @@ public extension IQKeyboardManager { // disturbDistance positive = frame not disturbed. if disturbDistance <= 0 { - rootViewOrigin.y -= max(move, disturbDistance) + rootViewOrigin.y -= max(moveUp, disturbDistance) if rootController.view.frame.origin.equalTo(rootViewOrigin) == false { showLog("Moving Downward") @@ -673,8 +657,6 @@ public extension IQKeyboardManager { internal func restorePosition() { - hasPendingAdjustRequest = false - // Setting rootViewController frame to it's original position. // (Bug ID: #18) guard topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) == false, let rootViewController = rootViewController else { return @@ -684,8 +666,6 @@ public extension IQKeyboardManager { // Used UIViewAnimationOptionBeginFromCurrentState to minimize strange animations. UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in - self.showLog("Restoring \(rootViewController) origin to: \(self.topViewBeginOrigin)") - // Setting it's new frame var rect = rootViewController.view.frame rect.origin = self.topViewBeginOrigin @@ -697,6 +677,8 @@ public extension IQKeyboardManager { rootViewController.view.setNeedsLayout() rootViewController.view.layoutIfNeeded() } + + self.showLog("Restoring \(rootViewController) origin to: \(self.topViewBeginOrigin)") }) } diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Toolbar.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Toolbar.swift index 0dc7ef5..dbc930a 100644 --- a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Toolbar.swift +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Toolbar.swift @@ -65,15 +65,34 @@ public extension IQKeyboardManager { } rightConfiguration.accessibilityLabel = toolbarDoneBarButtonItemAccessibilityLabel ?? "Done" - // If only one object is found, then adding only Done button. - if (siblings.count <= 1 && previousNextDisplayMode == .default) || previousNextDisplayMode == .alwaysHide { + let isTableCollectionView: Bool + if textField.superviewOfClassType(UITableView.self) != nil || + textField.superviewOfClassType(UICollectionView.self) != nil { + isTableCollectionView = true + } else { + isTableCollectionView = false + } - textField.addKeyboardToolbarWithTarget(target: self, titleText: (shouldShowToolbarPlaceholder ? textField.drawingToolbarPlaceholder: nil), titleAccessibilityLabel: toolbarTitlBarButtonItemAccessibilityLabel, rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: nil, nextBarButtonConfiguration: nil) - - textField.inputAccessoryView?.tag = IQKeyboardManager.kIQDoneButtonToolbarTag // (Bug ID: #78) - - } else if previousNextDisplayMode == .default || previousNextDisplayMode == .alwaysShow { + let shouldHavePreviousNext: Bool + switch previousNextDisplayMode { + case .default: + // If the textField is part of UITableView/UICollectionView then we should be exposing previous/next too + // Because at this time we don't know the previous or next cell if it contains another textField to move. + if isTableCollectionView { + shouldHavePreviousNext = true + } else if siblings.count <= 1 { + // If only one object is found, then adding only Done button. + shouldHavePreviousNext = false + } else { + shouldHavePreviousNext = true + } + case .alwaysShow: + shouldHavePreviousNext = true + case .alwaysHide: + shouldHavePreviousNext = false + } + if shouldHavePreviousNext { let prevConfiguration: IQBarButtonItemConfiguration if let doneBarButtonItemImage = toolbarPreviousBarButtonItemImage { @@ -99,6 +118,22 @@ public extension IQKeyboardManager { textField.addKeyboardToolbarWithTarget(target: self, titleText: (shouldShowToolbarPlaceholder ? textField.drawingToolbarPlaceholder: nil), titleAccessibilityLabel: toolbarTitlBarButtonItemAccessibilityLabel, rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: prevConfiguration, nextBarButtonConfiguration: nextConfiguration) textField.inputAccessoryView?.tag = IQKeyboardManager.kIQPreviousNextButtonToolbarTag // (Bug ID: #78) + + if isTableCollectionView { + // In case of UITableView (Special), the next/previous buttons should always be enabled. (Bug ID: #56) + textField.keyboardToolbar.previousBarButton.isEnabled = true + textField.keyboardToolbar.nextBarButton.isEnabled = true + } else { + // If firstTextField, then previous should not be enabled. + textField.keyboardToolbar.previousBarButton.isEnabled = (siblings.first != textField) + // If lastTextField then next should not be enaled. + textField.keyboardToolbar.nextBarButton.isEnabled = (siblings.last != textField) + } + + } else { + textField.addKeyboardToolbarWithTarget(target: self, titleText: (shouldShowToolbarPlaceholder ? textField.drawingToolbarPlaceholder: nil), titleAccessibilityLabel: toolbarTitlBarButtonItemAccessibilityLabel, rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: nil, nextBarButtonConfiguration: nil) + + textField.inputAccessoryView?.tag = IQKeyboardManager.kIQDoneButtonToolbarTag // (Bug ID: #78) } let toolbar = textField.keyboardToolbar @@ -143,11 +178,6 @@ public extension IQKeyboardManager { toolbar.titleBarButton.title = nil } - // In case of UITableView (Special), the next/previous buttons has to be refreshed everytime. (Bug ID: #56) - - textField.keyboardToolbar.previousBarButton.isEnabled = (siblings.first != textField) // If firstTextField, then previous should not be enabled. - textField.keyboardToolbar.nextBarButton.isEnabled = (siblings.last != textField) // If lastTextField then next should not be enaled. - let elapsedTime = CACurrentMediaTime() - startTime showLog("<<<<< \(#function) ended: \(elapsedTime) seconds <<<<<", indentation: -1) } diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+UIKeyboardNotification.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+UIKeyboardNotification.swift index 40d42c2..d2e436e 100644 --- a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+UIKeyboardNotification.swift +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+UIKeyboardNotification.swift @@ -161,7 +161,11 @@ public extension IQKeyboardManager { } // Getting keyboard animation duration - animationDuration = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval ?? 0.25 + if let duration = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval, duration != 0 { + animationDuration = duration + } else { + animationDuration = 0.25 + } // Getting UIKeyboardSize. if let kbFrame = info[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect { @@ -215,7 +219,7 @@ public extension IQKeyboardManager { textFieldView.isAlertViewTextField() == false { // keyboard is already showing. adjust position. - optimizedAdjustPosition() + self.adjustPosition() } } @@ -223,26 +227,6 @@ public extension IQKeyboardManager { showLog("⌨️<<<<< \(#function) ended: \(elapsedTime) seconds <<<<<", indentation: -1) } - /* UIKeyboardDidShowNotification. */ - @objc internal func keyboardDidShow(_ notification: Notification) { - - guard privateIsEnabled(), - let textFieldView = textFieldView, - let parentController = textFieldView.parentContainerViewController(), (parentController.modalPresentationStyle == UIModalPresentationStyle.formSheet || parentController.modalPresentationStyle == UIModalPresentationStyle.pageSheet), - textFieldView.isAlertViewTextField() == false else { - return - } - - let startTime = CACurrentMediaTime() - showLog("⌨️>>>>> \(#function) started >>>>>", indentation: 1) - showLog("Notification Object:\(notification.object ?? "NULL")") - - self.optimizedAdjustPosition() - - let elapsedTime = CACurrentMediaTime() - startTime - showLog("⌨️<<<<< \(#function) ended: \(elapsedTime) seconds <<<<<", indentation: -1) - } - /* UIKeyboardWillHideNotification. So setting rootViewController to it's default frame. */ @objc internal func keyboardWillHide(_ notification: Notification?) { @@ -264,7 +248,11 @@ public extension IQKeyboardManager { } // Getting keyboard animation duration - animationDuration = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval ?? 0.25 + if let duration = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval, duration != 0 { + animationDuration = duration + } else { + animationDuration = 0.25 + } } // If not enabled then do nothing. @@ -339,29 +327,14 @@ public extension IQKeyboardManager { // Reset all values lastScrollView = nil - keyboardFrame = CGRect.zero + keyboardFrame = .zero notifyKeyboardSize(size: keyboardFrame.size) - startingContentInsets = UIEdgeInsets() - startingScrollIndicatorInsets = UIEdgeInsets() + startingContentInsets = .zero + startingScrollIndicatorInsets = .zero startingContentOffset = CGPoint.zero - // topViewBeginRect = CGRectZero //Commented due to #82 - - let elapsedTime = CACurrentMediaTime() - startTime - showLog("⌨️<<<<< \(#function) ended: \(elapsedTime) seconds <<<<<", indentation: -1) - } - - @objc internal func keyboardDidHide(_ notification: Notification) { - - let startTime = CACurrentMediaTime() - showLog("⌨️>>>>> \(#function) started >>>>>", indentation: 1) - showLog("Notification Object:\(notification.object ?? "NULL")") - topViewBeginOrigin = IQKeyboardManager.kIQCGPointInvalid topViewBeginSafeAreaInsets = .zero - keyboardFrame = CGRect.zero - notifyKeyboardSize(size: keyboardFrame.size) - let elapsedTime = CACurrentMediaTime() - startTime showLog("⌨️<<<<< \(#function) ended: \(elapsedTime) seconds <<<<<", indentation: -1) } diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+UITextFieldViewNotification.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+UITextFieldViewNotification.swift index b82b4fc..dd707f2 100644 --- a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+UITextFieldViewNotification.swift +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+UITextFieldViewNotification.swift @@ -168,7 +168,7 @@ internal extension IQKeyboardManager { textFieldView.isAlertViewTextField() == false { // keyboard is already showing. adjust position. - optimizedAdjustPosition() + self.adjustPosition() } } diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager.swift index dd82c00..c0580a6 100644 --- a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager.swift +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager.swift @@ -318,12 +318,6 @@ Codeless drop-in universal library allows to prevent issues of keyboard sliding // Creating gesture for @shouldResignOnTouchOutside. (Enhancement ID: #14) resignFirstResponderGesture.isEnabled = shouldResignOnTouchOutside - // Loading IQToolbar, IQTitleBarButtonItem, IQBarButtonItem to fix first time keyboard appearance delay (Bug ID: #550) - // If you experience exception breakpoint issue at below line then try these solutions https://stackoverflow.com/questions/27375640/all-exception-break-point-is-stopping-for-no-reason-on-simulator - let textField = UITextField() - textField.addDoneOnKeyboardWithTarget(nil, action: #selector(self.doneAction(_:))) - textField.addPreviousNextDoneOnKeyboardWithTarget(nil, previousAction: #selector(self.previousAction(_:)), nextAction: #selector(self.nextAction(_:)), doneAction: #selector(self.doneAction(_:))) - disabledDistanceHandlingClasses.append(UITableViewController.self) disabledDistanceHandlingClasses.append(UIAlertController.self) disabledToolbarClasses.append(UIAlertController.self) @@ -333,6 +327,14 @@ Codeless drop-in universal library allows to prevent issues of keyboard sliding toolbarPreviousNextAllowedClasses.append(IQPreviousNextView.self) touchResignedGestureIgnoreClasses.append(UIControl.self) touchResignedGestureIgnoreClasses.append(UINavigationBar.self) + + // Loading IQToolbar, IQTitleBarButtonItem, IQBarButtonItem to fix first time keyboard appearance delay (Bug ID: #550) + // If you experience exception breakpoint issue at below line then try these solutions https://stackoverflow.com/questions/27375640/all-exception-break-point-is-stopping-for-no-reason-on-simulator + DispatchQueue.main.async { + let textField = UITextField() + textField.addDoneOnKeyboardWithTarget(nil, action: #selector(self.doneAction(_:))) + textField.addPreviousNextDoneOnKeyboardWithTarget(nil, previousAction: #selector(self.previousAction(_:)), nextAction: #selector(self.nextAction(_:)), doneAction: #selector(self.doneAction(_:))) + } } deinit { @@ -389,7 +391,7 @@ Codeless drop-in universal library allows to prevent issues of keyboard sliding textFieldView.isAlertViewTextField() == false else { return } - optimizedAdjustPosition() + self.adjustPosition() } } diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardReturnKeyHandler.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardReturnKeyHandler.swift index 6844ce2..48ba38c 100644 --- a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardReturnKeyHandler.swift +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardReturnKeyHandler.swift @@ -30,13 +30,28 @@ private final class IQTextFieldViewInfoModal: NSObject { fileprivate weak var textFieldDelegate: UITextFieldDelegate? fileprivate weak var textViewDelegate: UITextViewDelegate? fileprivate weak var textFieldView: UIView? - fileprivate var originalReturnKeyType = UIReturnKeyType.default + fileprivate let originalReturnKeyType: UIReturnKeyType - init(textFieldView: UIView?, textFieldDelegate: UITextFieldDelegate?, textViewDelegate: UITextViewDelegate?, originalReturnKeyType: UIReturnKeyType = .default) { - self.textFieldView = textFieldView - self.textFieldDelegate = textFieldDelegate - self.textViewDelegate = textViewDelegate - self.originalReturnKeyType = originalReturnKeyType + init(textField: UITextField) { + self.textFieldView = textField + self.textFieldDelegate = textField.delegate + self.originalReturnKeyType = textField.returnKeyType + } + + init(textView: UITextView) { + self.textFieldView = textView + self.textViewDelegate = textView.delegate + self.originalReturnKeyType = textView.returnKeyType + } + + func restore() { + if let textField = textFieldView as? UITextField { + textField.returnKeyType = originalReturnKeyType + textField.delegate = textFieldDelegate + } else if let textView = textFieldView as? UITextView { + textView.returnKeyType = originalReturnKeyType + textView.delegate = textViewDelegate + } } } @@ -60,9 +75,9 @@ Manages the return key to work like next/done in a view hierarchy. didSet { - for modal in textFieldInfoCache { + for model in textFieldInfoCache { - if let view = modal.textFieldView { + if let view = model.textFieldView { updateReturnKeyTypeOnTextField(view) } } @@ -86,20 +101,9 @@ Manages the return key to work like next/done in a view hierarchy. deinit { - for modal in textFieldInfoCache { - - if let textField = modal.textFieldView as? UITextField { - textField.returnKeyType = modal.originalReturnKeyType - - textField.delegate = modal.textFieldDelegate - - } else if let textView = modal.textFieldView as? UITextView { - - textView.returnKeyType = modal.originalReturnKeyType - - textView.delegate = modal.textViewDelegate - } - } +// for model in textFieldInfoCache { +// model.restore() +// } textFieldInfoCache.removeAll() } @@ -110,12 +114,12 @@ Manages the return key to work like next/done in a view hierarchy. // MARK: Private Functions private func textFieldViewCachedInfo(_ textField: UIView) -> IQTextFieldViewInfoModal? { - for modal in textFieldInfoCache { + for model in textFieldInfoCache { - if let view = modal.textFieldView { + if let view = model.textFieldView { if view == textField { - return modal + return model } } } @@ -178,22 +182,16 @@ Manages the return key to work like next/done in a view hierarchy. */ @objc public func addTextFieldView(_ view: UIView) { - let modal = IQTextFieldViewInfoModal(textFieldView: view, textFieldDelegate: nil, textViewDelegate: nil) - if let textField = view as? UITextField { - - modal.originalReturnKeyType = textField.returnKeyType - modal.textFieldDelegate = textField.delegate + let model = IQTextFieldViewInfoModal(textField: textField) + textFieldInfoCache.append(model) textField.delegate = self } else if let textView = view as? UITextView { - - modal.originalReturnKeyType = textView.returnKeyType - modal.textViewDelegate = textView.delegate + let model = IQTextFieldViewInfoModal(textView: textView) + textFieldInfoCache.append(model) textView.delegate = self } - - textFieldInfoCache.append(modal) } /** @@ -203,20 +201,10 @@ Manages the return key to work like next/done in a view hierarchy. */ @objc public func removeTextFieldView(_ view: UIView) { - if let modal = textFieldViewCachedInfo(view) { - - if let textField = view as? UITextField { - - textField.returnKeyType = modal.originalReturnKeyType - textField.delegate = modal.textFieldDelegate - } else if let textView = view as? UITextView { - - textView.returnKeyType = modal.originalReturnKeyType - textView.delegate = modal.textViewDelegate - } + if let model = textFieldViewCachedInfo(view) { + model.restore() if let index = textFieldInfoCache.firstIndex(where: { $0.textFieldView == view}) { - textFieldInfoCache.remove(at: index) } } @@ -344,8 +332,8 @@ extension IQKeyboardReturnKeyHandler: UITextFieldDelegate { if aDelegate == nil { - if let modal = textFieldViewCachedInfo(textField) { - aDelegate = modal.textFieldDelegate + if let model = textFieldViewCachedInfo(textField) { + aDelegate = model.textFieldDelegate } } @@ -358,23 +346,22 @@ extension IQKeyboardReturnKeyHandler: UITextFieldDelegate { if aDelegate == nil { - if let modal = textFieldViewCachedInfo(textField) { - aDelegate = modal.textFieldDelegate + if let model = textFieldViewCachedInfo(textField) { + aDelegate = model.textFieldDelegate } } aDelegate?.textFieldDidEndEditing?(textField) } - @available(iOS 10.0, *) @objc public func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) { var aDelegate: UITextFieldDelegate? = delegate if aDelegate == nil { - if let modal = textFieldViewCachedInfo(textField) { - aDelegate = modal.textFieldDelegate + if let model = textFieldViewCachedInfo(textField) { + aDelegate = model.textFieldDelegate } } @@ -469,8 +456,8 @@ extension IQKeyboardReturnKeyHandler: UITextViewDelegate { if aDelegate == nil { - if let modal = textFieldViewCachedInfo(textView) { - aDelegate = modal.textViewDelegate + if let model = textFieldViewCachedInfo(textView) { + aDelegate = model.textViewDelegate } } @@ -483,8 +470,8 @@ extension IQKeyboardReturnKeyHandler: UITextViewDelegate { if aDelegate == nil { - if let modal = textFieldViewCachedInfo(textView) { - aDelegate = modal.textViewDelegate + if let model = textFieldViewCachedInfo(textView) { + aDelegate = model.textViewDelegate } } @@ -517,8 +504,8 @@ extension IQKeyboardReturnKeyHandler: UITextViewDelegate { if aDelegate == nil { - if let modal = textFieldViewCachedInfo(textView) { - aDelegate = modal.textViewDelegate + if let model = textFieldViewCachedInfo(textView) { + aDelegate = model.textViewDelegate } } @@ -531,15 +518,14 @@ extension IQKeyboardReturnKeyHandler: UITextViewDelegate { if aDelegate == nil { - if let modal = textFieldViewCachedInfo(textView) { - aDelegate = modal.textViewDelegate + if let model = textFieldViewCachedInfo(textView) { + aDelegate = model.textViewDelegate } } aDelegate?.textViewDidChangeSelection?(textView) } - @available(iOS 10.0, *) @objc public func textView(_ aTextView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool { if delegate == nil { @@ -554,7 +540,6 @@ extension IQKeyboardReturnKeyHandler: UITextViewDelegate { return true } - @available(iOS 10.0, *) @objc public func textView(_ aTextView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool { if delegate == nil { @@ -598,8 +583,11 @@ extension IQKeyboardReturnKeyHandler: UITextViewDelegate { return true } +} #if swift(>=5.7) +@available(iOSApplicationExtension, unavailable) +extension IQKeyboardReturnKeyHandler { @available(iOS 16.0, *) public func textView(_ aTextView: UITextView, editMenuForTextIn range: NSRange, suggestedActions: [UIMenuElement]) -> UIMenu? { if delegate == nil { @@ -620,8 +608,8 @@ extension IQKeyboardReturnKeyHandler: UITextViewDelegate { if aDelegate == nil { - if let modal = textFieldViewCachedInfo(aTextView) { - aDelegate = modal.textViewDelegate + if let model = textFieldViewCachedInfo(aTextView) { + aDelegate = model.textViewDelegate } } @@ -634,12 +622,74 @@ extension IQKeyboardReturnKeyHandler: UITextViewDelegate { if aDelegate == nil { - if let modal = textFieldViewCachedInfo(aTextView) { - aDelegate = modal.textViewDelegate + if let model = textFieldViewCachedInfo(aTextView) { + aDelegate = model.textViewDelegate } } aDelegate?.textView?(aTextView, willDismissEditMenuWith: animator) } -#endif } +#endif + +#if swift(>=5.9) +@available(iOSApplicationExtension, unavailable) +extension IQKeyboardReturnKeyHandler { + + @available(iOS 17.0, *) + public func textView(_ aTextView: UITextView, primaryActionFor textItem: UITextItem, defaultAction: UIAction) -> UIAction? { + if delegate == nil { + + if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { + if unwrapDelegate.responds(to: #selector(textView as (UITextView, UITextItem, UIAction) -> UIAction?)) { + return unwrapDelegate.textView?(aTextView, primaryActionFor: textItem, defaultAction: defaultAction) + } + } + } + + return nil + } + + @available(iOS 17.0, *) + public func textView(_ aTextView: UITextView, menuConfigurationFor textItem: UITextItem, defaultMenu: UIMenu) -> UITextItem.MenuConfiguration? { + if delegate == nil { + + if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { + if unwrapDelegate.responds(to: #selector(textView as (UITextView, UITextItem, UIMenu) -> UITextItem.MenuConfiguration?)) { + return unwrapDelegate.textView?(aTextView, menuConfigurationFor: textItem, defaultMenu: defaultMenu) + } + } + } + + return nil + } + + @available(iOS 17.0, *) + public func textView(_ textView: UITextView, textItemMenuWillDisplayFor textItem: UITextItem, animator: UIContextMenuInteractionAnimating) { + var aDelegate: UITextViewDelegate? = delegate + + if aDelegate == nil { + + if let model = textFieldViewCachedInfo(textView) { + aDelegate = model.textViewDelegate + } + } + + aDelegate?.textView?(textView, textItemMenuWillDisplayFor: textItem, animator: animator) + } + + @available(iOS 17.0, *) + public func textView(_ textView: UITextView, textItemMenuWillEndFor textItem: UITextItem, animator: UIContextMenuInteractionAnimating) { + var aDelegate: UITextViewDelegate? = delegate + + if aDelegate == nil { + + if let model = textFieldViewCachedInfo(textView) { + aDelegate = model.textViewDelegate + } + } + + aDelegate?.textView?(textView, textItemMenuWillEndFor: textItem, animator: animator) + } +} +#endif diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQPlaceholderable.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQPlaceholderable.swift new file mode 100644 index 0000000..d8021b4 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQPlaceholderable.swift @@ -0,0 +1,38 @@ +// +// IQPlaceholderable.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation +import UIKit + +@available(iOSApplicationExtension, unavailable) +public protocol IQPlaceholderable: AnyObject { + + var placeholder: String? { get set } + var attributedPlaceholder: NSAttributedString? { get set } +} + +@available(iOSApplicationExtension, unavailable) +extension UITextField: IQPlaceholderable { } + +@available(iOSApplicationExtension, unavailable) +extension IQTextView: IQPlaceholderable { } diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQTextView.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQTextView.swift index 1437c85..329d486 100644 --- a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQTextView.swift +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQTextView.swift @@ -42,10 +42,6 @@ import UIKit NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), name: UITextView.textDidChangeNotification, object: self) } - deinit { - IQ_PlaceholderLabel.removeFromSuperview() - } - private var placeholderInsets: UIEdgeInsets { return UIEdgeInsets(top: self.textContainerInset.top, left: self.textContainerInset.left + self.textContainer.lineFragmentPadding, bottom: self.textContainerInset.bottom, right: self.textContainerInset.right + self.textContainer.lineFragmentPadding) } @@ -53,12 +49,12 @@ import UIKit private var placeholderExpectedFrame: CGRect { let placeholderInsets = self.placeholderInsets let maxWidth = self.frame.width-placeholderInsets.left-placeholderInsets.right - let expectedSize = IQ_PlaceholderLabel.sizeThatFits(CGSize(width: maxWidth, height: self.frame.height-placeholderInsets.top-placeholderInsets.bottom)) + let expectedSize = placeholderLabel.sizeThatFits(CGSize(width: maxWidth, height: self.frame.height-placeholderInsets.top-placeholderInsets.bottom)) return CGRect(x: placeholderInsets.left, y: placeholderInsets.top, width: maxWidth, height: expectedSize.height) } - lazy var IQ_PlaceholderLabel: UILabel = { + lazy var placeholderLabel: UILabel = { let label = UILabel() label.autoresizingMask = [.flexibleWidth, .flexibleHeight] @@ -83,11 +79,11 @@ import UIKit @IBInspectable open var placeholderTextColor: UIColor? { get { - return IQ_PlaceholderLabel.textColor + return placeholderLabel.textColor } set { - IQ_PlaceholderLabel.textColor = newValue + placeholderLabel.textColor = newValue } } @@ -95,11 +91,11 @@ import UIKit @IBInspectable open var placeholder: String? { get { - return IQ_PlaceholderLabel.text + return placeholderLabel.text } set { - IQ_PlaceholderLabel.text = newValue + placeholderLabel.text = newValue refreshPlaceholder() } } @@ -107,11 +103,11 @@ import UIKit /** @abstract To set textView's placeholder attributed text. Default is nil. */ open var attributedPlaceholder: NSAttributedString? { get { - return IQ_PlaceholderLabel.attributedText + return placeholderLabel.attributedText } set { - IQ_PlaceholderLabel.attributedText = newValue + placeholderLabel.attributedText = newValue refreshPlaceholder() } } @@ -119,15 +115,16 @@ import UIKit @objc override open func layoutSubviews() { super.layoutSubviews() - IQ_PlaceholderLabel.frame = placeholderExpectedFrame + placeholderLabel.frame = placeholderExpectedFrame } @objc internal func refreshPlaceholder() { - if !text.isEmpty || !attributedText.string.isEmpty { - IQ_PlaceholderLabel.alpha = 0 + let text: String = text ?? attributedText?.string ?? "" + if text.isEmpty { + placeholderLabel.alpha = 1 } else { - IQ_PlaceholderLabel.alpha = 1 + placeholderLabel.alpha = 0 } } @@ -150,16 +147,16 @@ import UIKit didSet { if let unwrappedFont = font { - IQ_PlaceholderLabel.font = unwrappedFont + placeholderLabel.font = unwrappedFont } else { - IQ_PlaceholderLabel.font = UIFont.systemFont(ofSize: 12) + placeholderLabel.font = UIFont.systemFont(ofSize: 12) } } } @objc override open var textAlignment: NSTextAlignment { didSet { - IQ_PlaceholderLabel.textAlignment = textAlignment + placeholderLabel.textAlignment = textAlignment } } diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift index 771a2ef..0adf974 100644 --- a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift @@ -109,8 +109,4 @@ import UIKit } } } - - deinit { - target = nil - } } diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift index ef11a83..396e376 100644 --- a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift @@ -135,8 +135,4 @@ import UIKit @objc required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } - - deinit { - customView = nil - } } diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift index 72d91db..6597663 100644 --- a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift @@ -139,12 +139,7 @@ import UIKit privateFixedSpaceBarButton = IQBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil) } privateFixedSpaceBarButton!.isSystemItem = true - - if #available(iOS 10, *) { - privateFixedSpaceBarButton!.width = 6 - } else { - privateFixedSpaceBarButton!.width = 20 - } + privateFixedSpaceBarButton!.width = 6 return privateFixedSpaceBarButton! } diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift index 55d9c25..9587cfb 100644 --- a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift @@ -68,53 +68,7 @@ import UIKit @available(iOSApplicationExtension, unavailable) @objc public extension UIImage { - static func keyboardLeftImage() -> UIImage? { - - struct Static { - static var keyboardLeftImage: UIImage? - } - - if Static.keyboardLeftImage == nil { - - // swiftlint:disable line_length - let base64Data = "iVBORw0KGgoAAAANSUhEUgAAACQAAAA/CAYAAACIEWrAAAAAAXNSR0IArs4c6QAABtFJREFUaAXFmV1oHFUUx++d3SSbj/0k6Uc2u7Ob7QeVSqBSP7AUm1JpS0tb+6nFYhELxfahDxVU9KmgD0UU7ENRLLRQodRqNbVJY5IGXwRBEPHBh2x2ZpPQaDC7W2qSzc5c/3ebDTN3d5Pd7Gw6L3PPOcM5vzn33I+5Q8gTvJqbm52RYPAdIEg5DFuusdz3dq/X7XA6ewiVTvrcnvBkMvE9GNgTAQoGg16pztFLKX02mwhKOrwe99rJZPL2sgO1tbX5aiWpDzDPGHuFEvq01+2ZpEZltdutra3NjpranxC0Q4zFCLsVVZRjdtFQLTmycuUKZq/pA8zGvBiM3IiqynHoM8sCFGoJrSIO1o9u2SDCIDPXAXMCeo3bqg4UCARaJYkMEELXiTCEkauAOQm9nrPNj/+cwso7aiZQS6VBdFMeDDLz1ZAaM8Hw2FXLUHj1apnaawYIpWHxJRkjl5GZ09Az0VYVIFmWw6iXAWRGFgMynV2KxpWzhWD4s5Z3GeaZNXZGeTflwzDyGWDOFIPhQJZmqN3vX0clG7qJtHLnpktnFwFz3qQrIFgGJK+WN+D1+jGaVolxGNM/jsbVd0V9IdkSoEggsJFJlE96K8Qgus4uDMfVD0R9MbniGgr7/R1YsXkB58FgEH04HFdKhuGQFWUIo2kTZaQXQ9snvjGG9nsY2h+J+sXkJQO1BwKbMYv0YNX2ikF0ws4Pq8pFUV+KvCSgkD/0PCaMbnSTWwyCzJwDzKeivlS5bCBsOV/EsL6LAE5jEMYvSs4C5pJRX267LKBwILAVw/oOgjQZAz1mYaejinrZqF9Ku+QdY0SWOzkMaqbRGAgwOjJzKqqqXxj1S22jDBa/wsHgDqxNtwFTb3w6C0PYyWFVvWrUV9JetMsibfIuRuktkDuMgQCjYRdzYnhEvW7UV9peEKg9GNyDOeYmYOpMgRjLYD9zHDA3THoLhKIzdSgQ2k+p9A1imGEImUXNHEM3WQ7D36dghlAzhyRKeFfU8IcMV1rTtSOxePy2QWdpMw8oEggdwxp0DVFE2wy66SBg+LCv2mUa9mFZfhORrmA0mWCwz5zWdW0/uolPiFW95msIMGckQr8EjAkSo2mKMH0vMtNTVZI559lMtAdC5zCSPhEDAuaRppG9yqg6INqqJVNk5m1k5nMxAGAYYLYro8qywXAGiWYyvYSxUREIXUdtdnIKelM9ic9ZLWeXDnxdRmppdnMeEAMgUTex0XoN+lnRVg05C8Qd828pW5FvKUwD3w0pylE8lq4GhNHnPBBX+v3+tjpbTT+lZK3xId5GprqQqUNozog2K2UTEHfMDwdqJBtOKsh6MRAmxru6Ql+Jkdi0aLNKzgPijvnxia2e9WFhfUoMhC1qb1rP7BsZGZkSbVbI8xOj0Vnsn9gDMjO9DcH/MOp5G925o1aydeFko0G0WSEXBOKOh8bH/57OpDuxbPwuBsKM0Omw195taWkxbWXF55YiFwXizsbGxibSWqYTFf2b6ByZ2uqsb+jmZ82irRK5YA2JDkOekEdykXuA2CzaMP5+YanUzujkZDLfVr6mJCDu1ufzubxOZzeq6AUxDGrtVz1FXo4lYgnRVq5cMhB3zLvH1dD4I2poS14gdOuMru3A6Ps3z1aGYsEaEv1MTEw8fDQzvRP6QdGG4bep1mbv52fRebYyFGUBcb/j4+OPpmbTuzFz4yzIfCHdHQ6cK/IzabOldKlsIO4ao++/tK7tQe3cE0OhOzcSh+N+9mxaNJYgl1VDBfzVtcsyvtnobtGG+euvWV3rjMfjY6JtIXlJGTI4nMH/iQPI1A8GXbaJN13Pz6j5gi3aFpIrBeK+01E1dhAL77d5gShd47DZB/mZdZ6tiKLSLjO6tUeCoes4qjlsVPI2uk/RCNumKMqwaBNlKzKU85nBr4JXkamvc4rcHW8t87NrvjPN6YrdrQTiMTTU1OtY+67lBaQk+9+Dn2Xn2QwKq4G4a21IVd5Apq4Y4jxuUuonNvv97Jl2nnHukSJ6K9Q0EpQvYwZ/S3SGmhrPMH27qqp/ijbTV6porFTGT90u/NxdgXnKtEtATTXZKD3scTb1JFKpcWOcqgLxQIC643F7fNi6PGcMjHYjZvUjrkZPb/Jh8kHOVnUgHiiRTHQjUy5kyrx1obSBSuSI1+Xqm0ylsjP6sgBxKGTqHn6D1yNTpq0LslSPXxNH3c6mAXTfqJUTI4+76IXT3AvY5L1f4MFUhrBdy5ahHAAy1e91uzD46Es53dydYv7qWnYgHhxQgx6XexZQ2+dgZojGDuCf2p0nAsQhEqnkzz63awpz0hacve+LjqjZA7H/AWSbJ/TPf3CuAAAAAElFTkSuQmCC" - // swiftlint:enable line_length - - if let data = Data(base64Encoded: base64Data, options: .ignoreUnknownCharacters) { - Static.keyboardLeftImage = UIImage(data: data, scale: 3) - } - - // Support for RTL languages like Arabic, Persia etc... (Bug ID: #448) - Static.keyboardLeftImage = Static.keyboardLeftImage?.imageFlippedForRightToLeftLayoutDirection() - } - - return Static.keyboardLeftImage - } - - static func keyboardRightImage() -> UIImage? { - - struct Static { - static var keyboardRightImage: UIImage? - } - - if Static.keyboardRightImage == nil { - - // swiftlint:disable line_length - let base64Data = "iVBORw0KGgoAAAANSUhEUgAAACQAAAA/CAYAAACIEWrAAAAAAXNSR0IArs4c6QAABu5JREFUaAXFmXtsFEUcx2f3rj0Kvd29k9LHtXfXqyjGV2J8EF/hIQgp4VnahPgIxviH0ZgYNSbGmBg1McaYGGOM+o8k+EINMQjIo6UoBAVEEBGQXnvbS1ttw91epUDbu/E7lb3bm22Pu97uOQnszO+3ne/nvjM7sw9CMsXRFAi83jhnTnUmVPqacEXSGfIHPhMEoYUSejpJyKJIJNJfehxCRIiWwZktDIYBCESY56BCZ319ve9/AQr5/c8CY7VRXBDIXJfo6Kyrq2swxktRZ0NWFgoEPocza3lBDF9P6rKwsGegp4fP2dVmQzYWjkTaCCVf8iKADIou0un3+0N8zq42A2JlvEvt2QBHPv2vmfkfFvrLiNAZqq+fm4naV9OBmEISTj0MpzaZ5AShXhAd+xrr6q435SwO6Je9sVsRc+ojDNdjxiCrw8GBcUoXq6p6is9Z1TY6pPeZglOPQ/1DPaAfAVnjFMQODN/Neszqo2OqDmNa/DuPJM/G+nSn8RxYOgux9Upl5a748PBfxpwV9SmBWOexhLbdIyserEvzs8QEYSYRxFZJUfZommbpip4TaAJKi+/0SnIlEYS7jVBwqQJutXkkqT2WSPQZc8XUrwo0AZXQdntkaQYg7jWKYU4hJrZJlXKnNqxFjbnp1vMCmoDStL2KJDsBdT8n5hJFoRXAP8Q0TeVyBTfzBmI9xxNah1eRU9j7FnJKLrTbZLf7QDyRiHC5gpoFAbGe4cJ+TPRRTPTFRiU4V45/rV5FOYRzuo25QuoFA7HOsST8qCjyBcyhpUYxAJVRSloVSToMp7qMuXzr0wJincc17SCc0uDUMqMYg8JEb/W65aNYNs4Zc/nUpw3EOodTh+DUEFb15QDBKpAuTiJi8ZSl4wA/m47mUSkKiPUPwcNeWR6ghDRzUA60W+DUSTh1Og+WiVOKBmK9YBIfVRQlCqdW8FC4J16nyPJpgOe1IVsCxKAgeAxOReDUyiwoTCik13olz9lYIn6SnZurWAbERODUcY+idMGpVYBK30mwOm5d1sCpMMBPlAzoCtRvsiSdEdmDAweF/Go4pcKpX6eCstQhXQRr0O9w6hTWqTWIpTXYUMKpVXCqD079op9vPKZPNgatqGP4/pAl9wlRENnTTFqHQaG9wiN5/oZTR3it9Il8woo2nDrjUeRjcGod+nPqfTIoYDVjnToPp37W4+xoKxATgFN/ym7lCKZ4C6xJQ7EcqJZjsx7BOQdZmxXbgZhIPBE/h9uTn1BdD4gyFssUYQmgkoDaz2IlAWJCEAxLlcpBDFULoMpZLFOERdgXBWxF+4z7TyZvYy1YH1wginQvoNLrlC6XIvT5rDHVEzYeRYdINhrXJ10LK7yapPSbUgI58AC6CQAbdAj9SCntpmOjC9X+/kipgJxN/uBmALTqEOkjpecujY8t6uvv72WxUgBNvO6B1iSve8jxkdHLSwYGBgZ1QLuByuHMFoit1AUzR3psNJl8ADDnMzF7HXLhveXXuB9qNgqyOubMkXFCl0aj0Rifs8WhIAnOcPjJVsA8yAsC5xAZTixTYzHNnLPBIbwsrcA68y0u7Qd4QThzIDFyYflQLDbM5/S2pQ5VV1fPcjkc27BLLdAF9CMej/YPXxxpHhoa+kePTXa0DKiqqqpylqtiO0TuMwvRDlzaKwYHB0fMueyIJUBer1eSKmbuwJzJekPCpODM7tFUclVfX9/FbOnJW0UDhTwembil79H9XWYJujOlCmuiJHrJnJs8UhQQXhd7MF92YYe+ne8eE3hbWI20IH6Zz+Vqm3bcXCcbcz6f7xo8M7Nd2wSDgdoKGHaXWBAM639aDtXU1FS5nGV78Pe3sE6MBc58BRi2gY4Z4/nWCwZin6/EctdeCNxoEqHkC8A8hPi4KZdnoCCgQCBQi/nSjnkzj+8fzmwGzKOIJ/lcIe285xD7XOUgwj48QZhgUpR8AphHioVh4HkBsc9U7HMV3LnO9Gsp/bhb7dmIOF71FV+uOmSNtbUBwVnWgb2pkZejNPVBWFWfRBx3oNaUnEDssxTuxdvhTMAkl6LvhXvVp03xIgNTDhnmzLXss9RkMHg+f6erN2I5DPstkzrEPkOJoqMdw1TH/+AUpW91q5EX+LhVbRNQoDZwA54t2aVdYxahbwDmJXPcukgWUFNDw01UxHZAyBxeArv2q7i0X+HjVrfTQI0+3634wrMHMLPNIvRlwLxmjlsfmQDCCnwb3iTtxpzx8hK4tF/Epf0mH7er7Qw1NNyBzndh11Z4kVSKPtfdq77Nx+1sO7GiVeCNpBN3e9mFpp4BzLvZQftbExhNfv89mD87IOfGJollhjwV7o28b798DoWgLzgfD3bnAfdEjtNsT/0LGvgrBSkuN9gAAAAASUVORK5CYII=" - // swiftlint:enable line_length - - if let data = Data(base64Encoded: base64Data, options: .ignoreUnknownCharacters) { - Static.keyboardRightImage = UIImage(data: data, scale: 3) - } - - // Support for RTL languages like Arabic, Persia etc... (Bug ID: #448) - Static.keyboardRightImage = Static.keyboardRightImage?.imageFlippedForRightToLeftLayoutDirection() - } - - return Static.keyboardRightImage - } - - static func keyboardUpImage() -> UIImage? { + static func keyboardPreviousImage() -> UIImage? { struct Static { static var keyboardUpImage: UIImage? @@ -137,7 +91,7 @@ import UIKit return Static.keyboardUpImage } - static func keyboardDownImage() -> UIImage? { + static func keyboardNextImage() -> UIImage? { struct Static { static var keyboardDownImage: UIImage? @@ -159,24 +113,6 @@ import UIKit return Static.keyboardDownImage } - - static func keyboardPreviousImage() -> UIImage? { - - if #available(iOS 10, *) { - return keyboardUpImage() - } else { - return keyboardLeftImage() - } - } - - static func keyboardNextImage() -> UIImage? { - - if #available(iOS 10, *) { - return keyboardDownImage() - } else { - return keyboardRightImage() - } - } } /** @@ -207,7 +143,15 @@ UIView category methods to add IQToolbar on UIKeyboard. return unwrappedToolbar } else { - let frame = CGRect(origin: .zero, size: .init(width: UIScreen.main.bounds.width, height: 44)) + var width: CGFloat = 0 + + if #available(iOS 13.0, *) { + width = window?.windowScene?.screen.bounds.width ?? .zero + } else { + width = UIScreen.main.bounds.width + } + + let frame = CGRect(origin: .zero, size: .init(width: width, height: 44)) let newToolbar = IQToolbar(frame: frame) objc_setAssociatedObject(self, &AssociatedKeys.keyboardToolbar, newToolbar, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) @@ -253,12 +197,13 @@ UIView category methods to add IQToolbar on UIKeyboard. return nil } else if self.toolbarPlaceholder?.isEmpty == false { return self.toolbarPlaceholder - } else if self.responds(to: #selector(getter: UITextField.placeholder)) { + } else if let placeholderable: IQPlaceholderable = self as? IQPlaceholderable { - if let textField = self as? UITextField { - return textField.placeholder - } else if let textView = self as? IQTextView { - return textView.placeholder + if let placeholder = placeholderable.attributedPlaceholder?.string, + !placeholder.isEmpty { + return placeholder + } else if let placeholder = placeholderable.placeholder { + return placeholder } else { return nil } diff --git a/Pods/MJRefresh/LICENSE b/Pods/MJRefresh/LICENSE new file mode 100644 index 0000000..11bf234 --- /dev/null +++ b/Pods/MJRefresh/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013-2015 MJRefresh (https://github.com/CoderMJLee/MJRefresh) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Pods/MJRefresh/MJRefresh/Base/MJRefreshAutoFooter.h b/Pods/MJRefresh/MJRefresh/Base/MJRefreshAutoFooter.h new file mode 100644 index 0000000..e4eb872 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Base/MJRefreshAutoFooter.h @@ -0,0 +1,34 @@ +// +// MJRefreshAutoFooter.h +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#if __has_include() +#import +#else +#import "MJRefreshFooter.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface MJRefreshAutoFooter : MJRefreshFooter +/** 是否自动刷新(默认为YES) */ +@property (assign, nonatomic, getter=isAutomaticallyRefresh) BOOL automaticallyRefresh; + +/** 当底部控件出现多少时就自动刷新(默认为1.0,也就是底部控件完全出现时,才会自动刷新) */ +@property (assign, nonatomic) CGFloat appearencePercentTriggerAutoRefresh MJRefreshDeprecated("请使用triggerAutomaticallyRefreshPercent属性"); + +/** 当底部控件出现多少时就自动刷新(默认为1.0,也就是底部控件完全出现时,才会自动刷新) */ +@property (assign, nonatomic) CGFloat triggerAutomaticallyRefreshPercent; + +/** 自动触发次数, 默认为 1, 仅在拖拽 ScrollView 时才生效, + + 如果为 -1, 则为无限触发 + */ +@property (nonatomic) NSInteger autoTriggerTimes; +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/Base/MJRefreshAutoFooter.m b/Pods/MJRefresh/MJRefresh/Base/MJRefreshAutoFooter.m new file mode 100644 index 0000000..66616e1 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Base/MJRefreshAutoFooter.m @@ -0,0 +1,216 @@ +// +// MJRefreshAutoFooter.m +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshAutoFooter.h" +#import "NSBundle+MJRefresh.h" +#import "UIView+MJExtension.h" +#import "UIScrollView+MJExtension.h" +#import "UIScrollView+MJRefresh.h" + +@interface MJRefreshAutoFooter() +/** 一个新的拖拽 */ +@property (nonatomic) BOOL triggerByDrag; +@property (nonatomic) NSInteger leftTriggerTimes; +@end + +@implementation MJRefreshAutoFooter + +#pragma mark - 初始化 +- (void)willMoveToSuperview:(UIView *)newSuperview +{ + [super willMoveToSuperview:newSuperview]; + + if (newSuperview) { // 新的父控件 + if (self.hidden == NO) { + self.scrollView.mj_insetB += self.mj_h; + } + + // 设置位置 + self.mj_y = _scrollView.mj_contentH + self.ignoredScrollViewContentInsetBottom; + } else { // 被移除了 + if (self.hidden == NO) { + self.scrollView.mj_insetB -= self.mj_h; + } + } +} + +#pragma mark - 过期方法 +- (void)setAppearencePercentTriggerAutoRefresh:(CGFloat)appearencePercentTriggerAutoRefresh +{ + self.triggerAutomaticallyRefreshPercent = appearencePercentTriggerAutoRefresh; +} + +- (CGFloat)appearencePercentTriggerAutoRefresh +{ + return self.triggerAutomaticallyRefreshPercent; +} + +#pragma mark - 实现父类的方法 +- (void)prepare +{ + [super prepare]; + + // 默认底部控件100%出现时才会自动刷新 + self.triggerAutomaticallyRefreshPercent = 1.0; + + // 设置为默认状态 + self.automaticallyRefresh = YES; + + self.autoTriggerTimes = 1; +} + +- (void)scrollViewContentSizeDidChange:(NSDictionary *)change +{ + [super scrollViewContentSizeDidChange:change]; + + CGSize size = [change[NSKeyValueChangeNewKey] CGSizeValue]; + CGFloat contentHeight = size.height == 0 ? self.scrollView.mj_contentH : size.height; + // 设置位置 + CGFloat y = contentHeight + self.ignoredScrollViewContentInsetBottom; + if (self.mj_y != y) { + self.mj_y = y; + } +} + +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change +{ + [super scrollViewContentOffsetDidChange:change]; + + if (self.state != MJRefreshStateIdle || !self.automaticallyRefresh || self.mj_y == 0) return; + + if (_scrollView.mj_insetT + _scrollView.mj_contentH > _scrollView.mj_h) { // 内容超过一个屏幕 + // 这里的_scrollView.mj_contentH替换掉self.mj_y更为合理 + if (_scrollView.mj_offsetY >= _scrollView.mj_contentH - _scrollView.mj_h + self.mj_h * self.triggerAutomaticallyRefreshPercent + _scrollView.mj_insetB - self.mj_h) { + // 防止手松开时连续调用 + CGPoint old = [change[@"old"] CGPointValue]; + CGPoint new = [change[@"new"] CGPointValue]; + if (new.y <= old.y) return; + + if (_scrollView.isDragging) { + self.triggerByDrag = YES; + } + // 当底部刷新控件完全出现时,才刷新 + [self beginRefreshing]; + } + } +} + +- (void)scrollViewPanStateDidChange:(NSDictionary *)change +{ + [super scrollViewPanStateDidChange:change]; + + if (self.state != MJRefreshStateIdle) return; + + UIGestureRecognizerState panState = _scrollView.panGestureRecognizer.state; + + switch (panState) { + // 手松开 + case UIGestureRecognizerStateEnded: { + if (_scrollView.mj_insetT + _scrollView.mj_contentH <= _scrollView.mj_h) { // 不够一个屏幕 + if (_scrollView.mj_offsetY >= - _scrollView.mj_insetT) { // 向上拽 + self.triggerByDrag = YES; + [self beginRefreshing]; + } + } else { // 超出一个屏幕 + if (_scrollView.mj_offsetY >= _scrollView.mj_contentH + _scrollView.mj_insetB - _scrollView.mj_h) { + self.triggerByDrag = YES; + [self beginRefreshing]; + } + } + } + break; + + case UIGestureRecognizerStateBegan: { + [self resetTriggerTimes]; + } + break; + + default: + break; + } +} + +- (BOOL)unlimitedTrigger { + return self.leftTriggerTimes == -1; +} + +- (void)beginRefreshing +{ + if (self.triggerByDrag && self.leftTriggerTimes <= 0 && !self.unlimitedTrigger) { + return; + } + + [super beginRefreshing]; +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + if (state == MJRefreshStateRefreshing) { + [self executeRefreshingCallback]; + } else if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { + if (self.triggerByDrag) { + if (!self.unlimitedTrigger) { + self.leftTriggerTimes -= 1; + } + self.triggerByDrag = NO; + } + + if (MJRefreshStateRefreshing == oldState) { + if (self.scrollView.pagingEnabled) { + CGPoint offset = self.scrollView.contentOffset; + offset.y -= self.scrollView.mj_insetB; + [UIView animateWithDuration:self.slowAnimationDuration animations:^{ + self.scrollView.contentOffset = offset; + + if (self.endRefreshingAnimationBeginAction) { + self.endRefreshingAnimationBeginAction(); + } + } completion:^(BOOL finished) { + if (self.endRefreshingCompletionBlock) { + self.endRefreshingCompletionBlock(); + } + }]; + return; + } + + if (self.endRefreshingCompletionBlock) { + self.endRefreshingCompletionBlock(); + } + } + } +} + +- (void)resetTriggerTimes { + self.leftTriggerTimes = self.autoTriggerTimes; +} + +- (void)setHidden:(BOOL)hidden +{ + BOOL lastHidden = self.isHidden; + + [super setHidden:hidden]; + + if (!lastHidden && hidden) { + self.state = MJRefreshStateIdle; + + self.scrollView.mj_insetB -= self.mj_h; + } else if (lastHidden && !hidden) { + self.scrollView.mj_insetB += self.mj_h; + + // 设置位置 + self.mj_y = _scrollView.mj_contentH + self.ignoredScrollViewContentInsetBottom; + } +} + +- (void)setAutoTriggerTimes:(NSInteger)autoTriggerTimes { + _autoTriggerTimes = autoTriggerTimes; + self.leftTriggerTimes = autoTriggerTimes; +} +@end diff --git a/Pods/MJRefresh/MJRefresh/Base/MJRefreshBackFooter.h b/Pods/MJRefresh/MJRefresh/Base/MJRefreshBackFooter.h new file mode 100644 index 0000000..8484372 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Base/MJRefreshBackFooter.h @@ -0,0 +1,21 @@ +// +// MJRefreshBackFooter.h +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#if __has_include() +#import +#else +#import "MJRefreshFooter.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface MJRefreshBackFooter : MJRefreshFooter + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/Base/MJRefreshBackFooter.m b/Pods/MJRefresh/MJRefresh/Base/MJRefreshBackFooter.m new file mode 100644 index 0000000..4990ca5 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Base/MJRefreshBackFooter.m @@ -0,0 +1,158 @@ +// +// MJRefreshBackFooter.m +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshBackFooter.h" +#import "NSBundle+MJRefresh.h" +#import "UIView+MJExtension.h" +#import "UIScrollView+MJExtension.h" +#import "UIScrollView+MJRefresh.h" + +@interface MJRefreshBackFooter() +@property (assign, nonatomic) NSInteger lastRefreshCount; +@property (assign, nonatomic) CGFloat lastBottomDelta; +@end + +@implementation MJRefreshBackFooter + +#pragma mark - 初始化 +- (void)willMoveToSuperview:(UIView *)newSuperview +{ + [super willMoveToSuperview:newSuperview]; + + [self scrollViewContentSizeDidChange:nil]; +} + +#pragma mark - 实现父类的方法 +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change +{ + [super scrollViewContentOffsetDidChange:change]; + + // 如果正在刷新,直接返回 + if (self.state == MJRefreshStateRefreshing) return; + + _scrollViewOriginalInset = self.scrollView.mj_inset; + + // 当前的contentOffset + CGFloat currentOffsetY = self.scrollView.mj_offsetY; + // 尾部控件刚好出现的offsetY + CGFloat happenOffsetY = [self happenOffsetY]; + // 如果是向下滚动到看不见尾部控件,直接返回 + if (currentOffsetY <= happenOffsetY) return; + + CGFloat pullingPercent = (currentOffsetY - happenOffsetY) / self.mj_h; + + // 如果已全部加载,仅设置pullingPercent,然后返回 + if (self.state == MJRefreshStateNoMoreData) { + self.pullingPercent = pullingPercent; + return; + } + + if (self.scrollView.isDragging) { + self.pullingPercent = pullingPercent; + // 普通 和 即将刷新 的临界点 + CGFloat normal2pullingOffsetY = happenOffsetY + self.mj_h; + + if (self.state == MJRefreshStateIdle && currentOffsetY > normal2pullingOffsetY) { + // 转为即将刷新状态 + self.state = MJRefreshStatePulling; + } else if (self.state == MJRefreshStatePulling && currentOffsetY <= normal2pullingOffsetY) { + // 转为普通状态 + self.state = MJRefreshStateIdle; + } + } else if (self.state == MJRefreshStatePulling) {// 即将刷新 && 手松开 + // 开始刷新 + [self beginRefreshing]; + } else if (pullingPercent < 1) { + self.pullingPercent = pullingPercent; + } +} + +- (void)scrollViewContentSizeDidChange:(NSDictionary *)change +{ + [super scrollViewContentSizeDidChange:change]; + + CGSize size = [change[NSKeyValueChangeNewKey] CGSizeValue]; + CGFloat contentHeight = size.height == 0 ? self.scrollView.mj_contentH : size.height; + // 内容的高度 + contentHeight += self.ignoredScrollViewContentInsetBottom; + // 表格的高度 + CGFloat scrollHeight = self.scrollView.mj_h - self.scrollViewOriginalInset.top - self.scrollViewOriginalInset.bottom + self.ignoredScrollViewContentInsetBottom; + // 设置位置 + CGFloat y = MAX(contentHeight, scrollHeight); + if (self.mj_y != y) { + self.mj_y = y; + } +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 根据状态来设置属性 + if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { + // 刷新完毕 + if (MJRefreshStateRefreshing == oldState) { + [UIView animateWithDuration:self.slowAnimationDuration animations:^{ + if (self.endRefreshingAnimationBeginAction) { + self.endRefreshingAnimationBeginAction(); + } + + self.scrollView.mj_insetB -= self.lastBottomDelta; + // 自动调整透明度 + if (self.isAutomaticallyChangeAlpha) self.alpha = 0.0; + } completion:^(BOOL finished) { + self.pullingPercent = 0.0; + + if (self.endRefreshingCompletionBlock) { + self.endRefreshingCompletionBlock(); + } + }]; + } + + CGFloat deltaH = [self heightForContentBreakView]; + // 刚刷新完毕 + if (MJRefreshStateRefreshing == oldState && deltaH > 0 && self.scrollView.mj_totalDataCount != self.lastRefreshCount) { + self.scrollView.mj_offsetY = self.scrollView.mj_offsetY; + } + } else if (state == MJRefreshStateRefreshing) { + // 记录刷新前的数量 + self.lastRefreshCount = self.scrollView.mj_totalDataCount; + + [UIView animateWithDuration:self.fastAnimationDuration animations:^{ + CGFloat bottom = self.mj_h + self.scrollViewOriginalInset.bottom; + CGFloat deltaH = [self heightForContentBreakView]; + if (deltaH < 0) { // 如果内容高度小于view的高度 + bottom -= deltaH; + } + self.lastBottomDelta = bottom - self.scrollView.mj_insetB; + self.scrollView.mj_insetB = bottom; + self.scrollView.mj_offsetY = [self happenOffsetY] + self.mj_h; + } completion:^(BOOL finished) { + [self executeRefreshingCallback]; + }]; + } +} +#pragma mark - 私有方法 +#pragma mark 获得scrollView的内容 超出 view 的高度 +- (CGFloat)heightForContentBreakView +{ + CGFloat h = self.scrollView.frame.size.height - self.scrollViewOriginalInset.bottom - self.scrollViewOriginalInset.top; + return self.scrollView.contentSize.height - h; +} + +#pragma mark 刚好看到上拉刷新控件时的contentOffset.y +- (CGFloat)happenOffsetY +{ + CGFloat deltaH = [self heightForContentBreakView]; + if (deltaH > 0) { + return deltaH - self.scrollViewOriginalInset.top; + } else { + return - self.scrollViewOriginalInset.top; + } +} +@end diff --git a/Pods/MJRefresh/MJRefresh/Base/MJRefreshComponent.h b/Pods/MJRefresh/MJRefresh/Base/MJRefreshComponent.h new file mode 100644 index 0000000..f098101 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Base/MJRefreshComponent.h @@ -0,0 +1,151 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// MJRefreshComponent.h +// MJRefresh +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// 刷新控件的基类 + +#import +#if __has_include() +#import +#else +#import "MJRefreshConst.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +/** 刷新控件的状态 */ +typedef NS_ENUM(NSInteger, MJRefreshState) { + /** 普通闲置状态 */ + MJRefreshStateIdle = 1, + /** 松开就可以进行刷新的状态 */ + MJRefreshStatePulling, + /** 正在刷新中的状态 */ + MJRefreshStateRefreshing, + /** 即将刷新的状态 */ + MJRefreshStateWillRefresh, + /** 所有数据加载完毕,没有更多的数据了 */ + MJRefreshStateNoMoreData +}; + +/** 进入刷新状态的回调 */ +typedef void (^MJRefreshComponentRefreshingBlock)(void) MJRefreshDeprecated("first deprecated in 3.3.0 - Use `MJRefreshComponentAction` instead"); +/** 开始刷新后的回调(进入刷新状态后的回调) */ +typedef void (^MJRefreshComponentBeginRefreshingCompletionBlock)(void) MJRefreshDeprecated("first deprecated in 3.3.0 - Use `MJRefreshComponentAction` instead"); +/** 结束刷新后的回调 */ +typedef void (^MJRefreshComponentEndRefreshingCompletionBlock)(void) MJRefreshDeprecated("first deprecated in 3.3.0 - Use `MJRefreshComponentAction` instead"); + +/** 刷新用到的回调类型 */ +typedef void (^MJRefreshComponentAction)(void); + +/** 刷新控件的基类 */ +@interface MJRefreshComponent : UIView +{ + /** 记录scrollView刚开始的inset */ + UIEdgeInsets _scrollViewOriginalInset; + /** 父控件 */ + __weak UIScrollView *_scrollView; +} + +#pragma mark - 刷新动画时间控制 +/** 快速动画时间(一般用在刷新开始的回弹动画), 默认 0.25 */ +@property (nonatomic) NSTimeInterval fastAnimationDuration; +/** 慢速动画时间(一般用在刷新结束后的回弹动画), 默认 0.4*/ +@property (nonatomic) NSTimeInterval slowAnimationDuration; +/** 关闭全部默认动画效果, 可以简单粗暴地解决 CollectionView 的回弹动画 bug */ +- (instancetype)setAnimationDisabled; + +#pragma mark - 刷新回调 +/** 正在刷新的回调 */ +@property (copy, nonatomic, nullable) MJRefreshComponentAction refreshingBlock; +/** 设置回调对象和回调方法 */ +- (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action; + +/** 回调对象 */ +@property (weak, nonatomic) id refreshingTarget; +/** 回调方法 */ +@property (assign, nonatomic) SEL refreshingAction; +/** 触发回调(交给子类去调用) */ +- (void)executeRefreshingCallback; + +#pragma mark - 刷新状态控制 +/** 进入刷新状态 */ +- (void)beginRefreshing; +- (void)beginRefreshingWithCompletionBlock:(void (^)(void))completionBlock; +/** 开始刷新后的回调(进入刷新状态后的回调) */ +@property (copy, nonatomic, nullable) MJRefreshComponentAction beginRefreshingCompletionBlock; +/** 带动画的结束刷新的回调 */ +@property (copy, nonatomic, nullable) MJRefreshComponentAction endRefreshingAnimateCompletionBlock MJRefreshDeprecated("first deprecated in 3.3.0 - Use `endRefreshingAnimationBeginAction` instead"); +@property (copy, nonatomic, nullable) MJRefreshComponentAction endRefreshingAnimationBeginAction; +/** 结束刷新的回调 */ +@property (copy, nonatomic, nullable) MJRefreshComponentAction endRefreshingCompletionBlock; +/** 结束刷新状态 */ +- (void)endRefreshing; +- (void)endRefreshingWithCompletionBlock:(void (^)(void))completionBlock; +/** 是否正在刷新 */ +@property (assign, nonatomic, readonly, getter=isRefreshing) BOOL refreshing; + +/** 刷新状态 一般交给子类内部实现 */ +@property (assign, nonatomic) MJRefreshState state; + +#pragma mark - 交给子类去访问 +/** 记录scrollView刚开始的inset */ +@property (assign, nonatomic, readonly) UIEdgeInsets scrollViewOriginalInset; +/** 父控件 */ +@property (weak, nonatomic, readonly) UIScrollView *scrollView; + +#pragma mark - 交给子类们去实现 +/** 初始化 */ +- (void)prepare NS_REQUIRES_SUPER; +/** 摆放子控件frame */ +- (void)placeSubviews NS_REQUIRES_SUPER; +/** 当scrollView的contentOffset发生改变的时候调用 */ +- (void)scrollViewContentOffsetDidChange:(nullable NSDictionary *)change NS_REQUIRES_SUPER; +/** 当scrollView的contentSize发生改变的时候调用 */ +- (void)scrollViewContentSizeDidChange:(nullable NSDictionary *)change NS_REQUIRES_SUPER; +/** 当scrollView的拖拽状态发生改变的时候调用 */ +- (void)scrollViewPanStateDidChange:(nullable NSDictionary *)change NS_REQUIRES_SUPER; + +/** 多语言配置 language 发生变化时调用 + + `MJRefreshConfig.defaultConfig.language` 发生改变时调用. + + ⚠️ 父类会调用 `placeSubviews` 方法, 请勿在 placeSubviews 中调用本方法, 造成死循环. 子类在需要重新布局时, 在配置完修改后, 最后再调用 super 方法, 否则可能导致配置修改后, 定位先于修改执行. + */ +- (void)i18nDidChange NS_REQUIRES_SUPER; + +#pragma mark - 其他 +/** 拉拽的百分比(交给子类重写) */ +@property (assign, nonatomic) CGFloat pullingPercent; +/** 根据拖拽比例自动切换透明度 */ +@property (assign, nonatomic, getter=isAutoChangeAlpha) BOOL autoChangeAlpha MJRefreshDeprecated("请使用automaticallyChangeAlpha属性"); +/** 根据拖拽比例自动切换透明度 */ +@property (assign, nonatomic, getter=isAutomaticallyChangeAlpha) BOOL automaticallyChangeAlpha; +@end + +@interface UILabel(MJRefresh) ++ (instancetype)mj_label; +- (CGFloat)mj_textWidth; +@end + +@interface MJRefreshComponent (ChainingGrammar) + +#pragma mark - <<< 为 Swift 扩展链式语法 >>> - +/// 自动变化透明度 +- (instancetype)autoChangeTransparency:(BOOL)isAutoChange; +/// 刷新开始后立即调用的回调 +- (instancetype)afterBeginningAction:(MJRefreshComponentAction)action; +/// 刷新动画开始后立即调用的回调 +- (instancetype)endingAnimationBeginningAction:(MJRefreshComponentAction)action; +/// 刷新结束后立即调用的回调 +- (instancetype)afterEndingAction:(MJRefreshComponentAction)action; + + +/// 需要子类必须实现 +/// @param scrollView 赋值给的 ScrollView 的 Header/Footer/Trailer +- (instancetype)linkTo:(UIScrollView *)scrollView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/Base/MJRefreshComponent.m b/Pods/MJRefresh/MJRefresh/Base/MJRefreshComponent.m new file mode 100644 index 0000000..785df18 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Base/MJRefreshComponent.m @@ -0,0 +1,323 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// MJRefreshComponent.m +// MJRefresh +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshComponent.h" +#import "MJRefreshConst.h" +#import "MJRefreshConfig.h" +#import "UIView+MJExtension.h" +#import "UIScrollView+MJExtension.h" +#import "UIScrollView+MJRefresh.h" +#import "NSBundle+MJRefresh.h" + +@interface MJRefreshComponent() +@property (strong, nonatomic) UIPanGestureRecognizer *pan; +@end + +@implementation MJRefreshComponent +#pragma mark - 初始化 +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + // 准备工作 + [self prepare]; + + // 默认是普通状态 + self.state = MJRefreshStateIdle; + self.fastAnimationDuration = 0.25; + self.slowAnimationDuration = 0.4; + } + return self; +} + +- (void)prepare +{ + // 基本属性 + self.autoresizingMask = UIViewAutoresizingFlexibleWidth; + self.backgroundColor = [UIColor clearColor]; +} + +- (void)layoutSubviews +{ + [self placeSubviews]; + + [super layoutSubviews]; +} + +- (void)placeSubviews{} + +- (void)willMoveToSuperview:(UIView *)newSuperview +{ + [super willMoveToSuperview:newSuperview]; + + // 如果不是UIScrollView,不做任何事情 + if (newSuperview && ![newSuperview isKindOfClass:[UIScrollView class]]) return; + + // 旧的父控件移除监听 + [self removeObservers]; + + if (newSuperview) { // 新的父控件 + // 记录UIScrollView + _scrollView = (UIScrollView *)newSuperview; + + // 设置宽度 + self.mj_w = _scrollView.mj_w; + // 设置位置 + self.mj_x = -_scrollView.mj_insetL; + + // 设置永远支持垂直弹簧效果 + _scrollView.alwaysBounceVertical = YES; + // 记录UIScrollView最开始的contentInset + _scrollViewOriginalInset = _scrollView.mj_inset; + + // 添加监听 + [self addObservers]; + } +} + +- (void)drawRect:(CGRect)rect +{ + [super drawRect:rect]; + + if (self.state == MJRefreshStateWillRefresh) { + // 预防view还没显示出来就调用了beginRefreshing + self.state = MJRefreshStateRefreshing; + } +} + +#pragma mark - KVO监听 +- (void)addObservers +{ + NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld; + [self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentOffset options:options context:nil]; + [self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentSize options:options context:nil]; + self.pan = self.scrollView.panGestureRecognizer; + [self.pan addObserver:self forKeyPath:MJRefreshKeyPathPanState options:options context:nil]; + + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(i18nDidChange) name:MJRefreshDidChangeLanguageNotification object:MJRefreshConfig.defaultConfig]; +} + +- (void)removeObservers +{ + [self.superview removeObserver:self forKeyPath:MJRefreshKeyPathContentOffset]; + [self.superview removeObserver:self forKeyPath:MJRefreshKeyPathContentSize]; + [self.pan removeObserver:self forKeyPath:MJRefreshKeyPathPanState]; + self.pan = nil; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + // 遇到这些情况就直接返回 + if (!self.userInteractionEnabled) return; + + // 这个就算看不见也需要处理 + if ([keyPath isEqualToString:MJRefreshKeyPathContentSize]) { + [self scrollViewContentSizeDidChange:change]; + } + + // 看不见 + if (self.hidden) return; + if ([keyPath isEqualToString:MJRefreshKeyPathContentOffset]) { + [self scrollViewContentOffsetDidChange:change]; + } else if ([keyPath isEqualToString:MJRefreshKeyPathPanState]) { + [self scrollViewPanStateDidChange:change]; + } +} + +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change{} +- (void)scrollViewContentSizeDidChange:(NSDictionary *)change{} +- (void)scrollViewPanStateDidChange:(NSDictionary *)change{} + +- (void)i18nDidChange { + [self placeSubviews]; +} + +#pragma mark - 公共方法 +#pragma mark 设置回调对象和回调方法 +- (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action +{ + self.refreshingTarget = target; + self.refreshingAction = action; +} + +- (void)setState:(MJRefreshState)state +{ + _state = state; + + // 加入主队列的目的是等setState:方法调用完毕、设置完文字后再去布局子控件 + MJRefreshDispatchAsyncOnMainQueue([self setNeedsLayout];) +} + +#pragma mark 进入刷新状态 +- (void)beginRefreshing +{ + [UIView animateWithDuration:self.fastAnimationDuration animations:^{ + self.alpha = 1.0; + }]; + self.pullingPercent = 1.0; + // 只要正在刷新,就完全显示 + if (self.window) { + self.state = MJRefreshStateRefreshing; + } else { + // 预防正在刷新中时,调用本方法使得header inset回置失败 + if (self.state != MJRefreshStateRefreshing) { + self.state = MJRefreshStateWillRefresh; + // 刷新(预防从另一个控制器回到这个控制器的情况,回来要重新刷新一下) + [self setNeedsDisplay]; + } + } +} + +- (void)beginRefreshingWithCompletionBlock:(void (^)(void))completionBlock +{ + self.beginRefreshingCompletionBlock = completionBlock; + + [self beginRefreshing]; +} + +#pragma mark 结束刷新状态 +- (void)endRefreshing +{ + MJRefreshDispatchAsyncOnMainQueue(self.state = MJRefreshStateIdle;) +} + +- (void)endRefreshingWithCompletionBlock:(void (^)(void))completionBlock +{ + self.endRefreshingCompletionBlock = completionBlock; + + [self endRefreshing]; +} + +#pragma mark 是否正在刷新 +- (BOOL)isRefreshing +{ + return self.state == MJRefreshStateRefreshing || self.state == MJRefreshStateWillRefresh; +} + +#pragma mark 自动切换透明度 +- (void)setAutoChangeAlpha:(BOOL)autoChangeAlpha +{ + self.automaticallyChangeAlpha = autoChangeAlpha; +} + +- (BOOL)isAutoChangeAlpha +{ + return self.isAutomaticallyChangeAlpha; +} + +- (void)setAutomaticallyChangeAlpha:(BOOL)automaticallyChangeAlpha +{ + _automaticallyChangeAlpha = automaticallyChangeAlpha; + + if (self.isRefreshing) return; + + if (automaticallyChangeAlpha) { + self.alpha = self.pullingPercent; + } else { + self.alpha = 1.0; + } +} + +#pragma mark 根据拖拽进度设置透明度 +- (void)setPullingPercent:(CGFloat)pullingPercent +{ + _pullingPercent = pullingPercent; + + if (self.isRefreshing) return; + + if (self.isAutomaticallyChangeAlpha) { + self.alpha = pullingPercent; + } +} + +#pragma mark - 内部方法 +- (void)executeRefreshingCallback +{ + if (self.refreshingBlock) { + self.refreshingBlock(); + } + if ([self.refreshingTarget respondsToSelector:self.refreshingAction]) { + MJRefreshMsgSend(MJRefreshMsgTarget(self.refreshingTarget), self.refreshingAction, self); + } + if (self.beginRefreshingCompletionBlock) { + self.beginRefreshingCompletionBlock(); + } +} + +#pragma mark - 刷新动画时间控制 +- (instancetype)setAnimationDisabled { + self.fastAnimationDuration = 0; + self.slowAnimationDuration = 0; + + return self; +} + +#pragma mark - <<< Deprecation compatible function >>> - +- (void)setEndRefreshingAnimateCompletionBlock:(MJRefreshComponentEndRefreshingCompletionBlock)endRefreshingAnimateCompletionBlock { + _endRefreshingAnimationBeginAction = endRefreshingAnimateCompletionBlock; +} +@end + +@implementation UILabel(MJRefresh) ++ (instancetype)mj_label +{ + UILabel *label = [[self alloc] init]; + label.font = MJRefreshLabelFont; + label.textColor = MJRefreshLabelTextColor; + label.autoresizingMask = UIViewAutoresizingFlexibleWidth; + label.textAlignment = NSTextAlignmentCenter; + label.backgroundColor = [UIColor clearColor]; + return label; +} + +- (CGFloat)mj_textWidth { + CGFloat stringWidth = 0; + CGSize size = CGSizeMake(MAXFLOAT, MAXFLOAT); + + if (self.attributedText) { + if (self.attributedText.length == 0) { return 0; } + stringWidth = [self.attributedText boundingRectWithSize:size + options:NSStringDrawingUsesLineFragmentOrigin + context:nil].size.width; + } else { + if (self.text.length == 0) { return 0; } + NSAssert(self.font != nil, @"请检查 mj_label's `font` 是否设置正确"); + stringWidth = [self.text boundingRectWithSize:size + options:NSStringDrawingUsesLineFragmentOrigin + attributes:@{NSFontAttributeName:self.font} + context:nil].size.width; + } + return stringWidth; +} +@end + + +#pragma mark - <<< 为 Swift 扩展链式语法 >>> - +@implementation MJRefreshComponent (ChainingGrammar) + +- (instancetype)autoChangeTransparency:(BOOL)isAutoChange { + self.automaticallyChangeAlpha = isAutoChange; + return self; +} +- (instancetype)afterBeginningAction:(MJRefreshComponentAction)action { + self.beginRefreshingCompletionBlock = action; + return self; +} +- (instancetype)endingAnimationBeginningAction:(MJRefreshComponentAction)action { + self.endRefreshingAnimationBeginAction = action; + return self; +} +- (instancetype)afterEndingAction:(MJRefreshComponentAction)action { + self.endRefreshingCompletionBlock = action; + return self; +} + +- (instancetype)linkTo:(UIScrollView *)scrollView { + return self; +} + +@end diff --git a/Pods/MJRefresh/MJRefresh/Base/MJRefreshFooter.h b/Pods/MJRefresh/MJRefresh/Base/MJRefreshFooter.h new file mode 100644 index 0000000..7b7c7b6 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Base/MJRefreshFooter.h @@ -0,0 +1,37 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// MJRefreshFooter.h +// MJRefresh +// +// Created by MJ Lee on 15/3/5. +// Copyright (c) 2015年 小码哥. All rights reserved. +// 上拉刷新控件 + +#if __has_include() +#import +#else +#import "MJRefreshComponent.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface MJRefreshFooter : MJRefreshComponent +/** 创建footer */ ++ (instancetype)footerWithRefreshingBlock:(MJRefreshComponentAction)refreshingBlock; +/** 创建footer */ ++ (instancetype)footerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; + +/** 提示没有更多的数据 */ +- (void)endRefreshingWithNoMoreData; +- (void)noticeNoMoreData MJRefreshDeprecated("使用endRefreshingWithNoMoreData"); + +/** 重置没有更多的数据(消除没有更多数据的状态) */ +- (void)resetNoMoreData; + +/** 忽略多少scrollView的contentInset的bottom */ +@property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetBottom; + +/** 自动根据有无数据来显示和隐藏(有数据就显示,没有数据隐藏。默认是NO) */ +@property (assign, nonatomic, getter=isAutomaticallyHidden) BOOL automaticallyHidden MJRefreshDeprecated("已废弃此属性,开发者请自行控制footer的显示和隐藏"); +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/Base/MJRefreshFooter.m b/Pods/MJRefresh/MJRefresh/Base/MJRefreshFooter.m new file mode 100644 index 0000000..8096fdb --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Base/MJRefreshFooter.m @@ -0,0 +1,71 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// MJRefreshFooter.m +// MJRefresh +// +// Created by MJ Lee on 15/3/5. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshFooter.h" +#import "UIScrollView+MJRefresh.h" +#import "UIView+MJExtension.h" + +@interface MJRefreshFooter() + +@end + +@implementation MJRefreshFooter +#pragma mark - 构造方法 ++ (instancetype)footerWithRefreshingBlock:(MJRefreshComponentAction)refreshingBlock +{ + MJRefreshFooter *cmp = [[self alloc] init]; + cmp.refreshingBlock = refreshingBlock; + return cmp; +} ++ (instancetype)footerWithRefreshingTarget:(id)target refreshingAction:(SEL)action +{ + MJRefreshFooter *cmp = [[self alloc] init]; + [cmp setRefreshingTarget:target refreshingAction:action]; + return cmp; +} + +#pragma mark - 重写父类的方法 +- (void)prepare +{ + [super prepare]; + + // 设置自己的高度 + self.mj_h = MJRefreshFooterHeight; + + // 默认不会自动隐藏 +// self.automaticallyHidden = NO; +} + +#pragma mark . 链式语法部分 . + +- (instancetype)linkTo:(UIScrollView *)scrollView { + scrollView.mj_footer = self; + return self; +} + +#pragma mark - 公共方法 +- (void)endRefreshingWithNoMoreData +{ + MJRefreshDispatchAsyncOnMainQueue(self.state = MJRefreshStateNoMoreData;) +} + +- (void)noticeNoMoreData +{ + [self endRefreshingWithNoMoreData]; +} + +- (void)resetNoMoreData +{ + MJRefreshDispatchAsyncOnMainQueue(self.state = MJRefreshStateIdle;) +} + +- (void)setAutomaticallyHidden:(BOOL)automaticallyHidden +{ + _automaticallyHidden = automaticallyHidden; +} +@end diff --git a/Pods/MJRefresh/MJRefresh/Base/MJRefreshHeader.h b/Pods/MJRefresh/MJRefresh/Base/MJRefreshHeader.h new file mode 100644 index 0000000..95d8cb2 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Base/MJRefreshHeader.h @@ -0,0 +1,35 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// MJRefreshHeader.h +// MJRefresh +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// 下拉刷新控件:负责监控用户下拉的状态 + +#if __has_include() +#import +#else +#import "MJRefreshComponent.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface MJRefreshHeader : MJRefreshComponent +/** 创建header */ ++ (instancetype)headerWithRefreshingBlock:(MJRefreshComponentAction)refreshingBlock; +/** 创建header */ ++ (instancetype)headerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; + +/** 这个key用来存储上一次下拉刷新成功的时间 */ +@property (copy, nonatomic) NSString *lastUpdatedTimeKey; +/** 上一次下拉刷新成功的时间 */ +@property (strong, nonatomic, readonly, nullable) NSDate *lastUpdatedTime; + +/** 忽略多少scrollView的contentInset的top */ +@property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetTop; + +/** 默认是关闭状态, 如果遇到 CollectionView 的动画异常问题可以尝试打开 */ +@property (nonatomic) BOOL isCollectionViewAnimationBug; +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/Base/MJRefreshHeader.m b/Pods/MJRefresh/MJRefresh/Base/MJRefreshHeader.m new file mode 100644 index 0000000..b276412 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Base/MJRefreshHeader.m @@ -0,0 +1,297 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// MJRefreshHeader.m +// MJRefresh +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshHeader.h" +#import "UIView+MJExtension.h" +#import "UIScrollView+MJExtension.h" +#import "UIScrollView+MJRefresh.h" + +NSString * const MJRefreshHeaderRefreshing2IdleBoundsKey = @"MJRefreshHeaderRefreshing2IdleBounds"; +NSString * const MJRefreshHeaderRefreshingBoundsKey = @"MJRefreshHeaderRefreshingBounds"; + +@interface MJRefreshHeader() +@property (assign, nonatomic) CGFloat insetTDelta; +@end + +@implementation MJRefreshHeader +#pragma mark - 构造方法 ++ (instancetype)headerWithRefreshingBlock:(MJRefreshComponentAction)refreshingBlock +{ + MJRefreshHeader *cmp = [[self alloc] init]; + cmp.refreshingBlock = refreshingBlock; + return cmp; +} ++ (instancetype)headerWithRefreshingTarget:(id)target refreshingAction:(SEL)action +{ + MJRefreshHeader *cmp = [[self alloc] init]; + [cmp setRefreshingTarget:target refreshingAction:action]; + return cmp; +} + +#pragma mark - 覆盖父类的方法 +- (void)prepare +{ + [super prepare]; + + // 设置key + self.lastUpdatedTimeKey = MJRefreshHeaderLastUpdatedTimeKey; + + // 设置高度 + self.mj_h = MJRefreshHeaderHeight; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + // 设置y值(当自己的高度发生改变了,肯定要重新调整Y值,所以放到placeSubviews方法中设置y值) + self.mj_y = - self.mj_h - self.ignoredScrollViewContentInsetTop; +} + +- (void)resetInset { + if (@available(iOS 11.0, *)) { + } else { + // 如果 iOS 10 及以下系统在刷新时, push 新的 VC, 等待刷新完成后回来, 会导致顶部 Insets.top 异常, 不能 resetInset, 检查一下这种特殊情况 + if (!self.window) { return; } + } + + // sectionheader停留解决 + CGFloat insetT = - self.scrollView.mj_offsetY > _scrollViewOriginalInset.top ? - self.scrollView.mj_offsetY : _scrollViewOriginalInset.top; + insetT = insetT > self.mj_h + _scrollViewOriginalInset.top ? self.mj_h + _scrollViewOriginalInset.top : insetT; + self.insetTDelta = _scrollViewOriginalInset.top - insetT; + // 避免 CollectionView 在使用根据 Autolayout 和 内容自动伸缩 Cell, 刷新时导致的 Layout 异常渲染问题 + if (fabs(self.scrollView.mj_insetT - insetT) > FLT_EPSILON) { + self.scrollView.mj_insetT = insetT; + } +} + +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change +{ + [super scrollViewContentOffsetDidChange:change]; + + // 在刷新的refreshing状态 + if (self.state == MJRefreshStateRefreshing) { + [self resetInset]; + return; + } + + // 跳转到下一个控制器时,contentInset可能会变 + _scrollViewOriginalInset = self.scrollView.mj_inset; + + // 当前的contentOffset + CGFloat offsetY = self.scrollView.mj_offsetY; + // 头部控件刚好出现的offsetY + CGFloat happenOffsetY = - self.scrollViewOriginalInset.top; + + // 如果是向上滚动到看不见头部控件,直接返回 + // >= -> > + if (offsetY > happenOffsetY) return; + + // 普通 和 即将刷新 的临界点 + CGFloat normal2pullingOffsetY = happenOffsetY - self.mj_h; + CGFloat pullingPercent = (happenOffsetY - offsetY) / self.mj_h; + + if (self.scrollView.isDragging) { // 如果正在拖拽 + self.pullingPercent = pullingPercent; + if (self.state == MJRefreshStateIdle && offsetY < normal2pullingOffsetY) { + // 转为即将刷新状态 + self.state = MJRefreshStatePulling; + } else if (self.state == MJRefreshStatePulling && offsetY >= normal2pullingOffsetY) { + // 转为普通状态 + self.state = MJRefreshStateIdle; + } + } else if (self.state == MJRefreshStatePulling) {// 即将刷新 && 手松开 + // 开始刷新 + [self beginRefreshing]; + } else if (pullingPercent < 1) { + self.pullingPercent = pullingPercent; + } +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 根据状态做事情 + if (state == MJRefreshStateIdle) { + if (oldState != MJRefreshStateRefreshing) return; + + [self headerEndingAction]; + } else if (state == MJRefreshStateRefreshing) { + [self headerRefreshingAction]; + } +} + +- (void)headerEndingAction { + // 保存刷新时间 + [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:self.lastUpdatedTimeKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; + + // 默认使用 UIViewAnimation 动画 + if (!self.isCollectionViewAnimationBug) { + // 恢复inset和offset + [UIView animateWithDuration:self.slowAnimationDuration animations:^{ + self.scrollView.mj_insetT += self.insetTDelta; + + if (self.endRefreshingAnimationBeginAction) { + self.endRefreshingAnimationBeginAction(); + } + // 自动调整透明度 + if (self.isAutomaticallyChangeAlpha) self.alpha = 0.0; + } completion:^(BOOL finished) { + self.pullingPercent = 0.0; + + if (self.endRefreshingCompletionBlock) { + self.endRefreshingCompletionBlock(); + } + }]; + + return; + } + + /** + 这个解决方法的思路出自 https://github.com/CoderMJLee/MJRefresh/pull/844 + 修改了用+ [UIView animateWithDuration: animations:]实现的修改contentInset的动画 + fix issue#225 https://github.com/CoderMJLee/MJRefresh/issues/225 + 另一种解法 pull#737 https://github.com/CoderMJLee/MJRefresh/pull/737 + + 同时, 处理了 Refreshing 中的动画替换. + */ + + // 由于修改 Inset 会导致 self.pullingPercent 联动设置 self.alpha, 故提前获取 alpha 值, 后续用于还原 alpha 动画 + CGFloat viewAlpha = self.alpha; + + self.scrollView.mj_insetT += self.insetTDelta; + // 禁用交互, 如果不禁用可能会引起渲染问题. + self.scrollView.userInteractionEnabled = NO; + + //CAAnimation keyPath 不支持 contentInset 用Bounds的动画代替 + CABasicAnimation *boundsAnimation = [CABasicAnimation animationWithKeyPath:@"bounds"]; + boundsAnimation.fromValue = [NSValue valueWithCGRect:CGRectOffset(self.scrollView.bounds, 0, self.insetTDelta)]; + boundsAnimation.duration = self.slowAnimationDuration; + //在delegate里移除 + boundsAnimation.removedOnCompletion = NO; + boundsAnimation.fillMode = kCAFillModeBoth; + boundsAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + boundsAnimation.delegate = self; + [boundsAnimation setValue:MJRefreshHeaderRefreshing2IdleBoundsKey forKey:@"identity"]; + + [self.scrollView.layer addAnimation:boundsAnimation forKey:MJRefreshHeaderRefreshing2IdleBoundsKey]; + + if (self.endRefreshingAnimationBeginAction) { + self.endRefreshingAnimationBeginAction(); + } + // 自动调整透明度的动画 + if (self.isAutomaticallyChangeAlpha) { + CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; + opacityAnimation.fromValue = @(viewAlpha); + opacityAnimation.toValue = @(0.0); + opacityAnimation.duration = self.slowAnimationDuration; + opacityAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + [self.layer addAnimation:opacityAnimation forKey:@"MJRefreshHeaderRefreshing2IdleOpacity"]; + + // 由于修改了 inset 导致, pullingPercent 被设置值, alpha 已经被提前修改为 0 了. 所以这里不用置 0, 但为了代码的严谨性, 不依赖其他的特殊实现方式, 这里还是置 0. + self.alpha = 0; + } +} + +- (void)headerRefreshingAction { + // 默认使用 UIViewAnimation 动画 + if (!self.isCollectionViewAnimationBug) { + [UIView animateWithDuration:self.fastAnimationDuration animations:^{ + if (self.scrollView.panGestureRecognizer.state != UIGestureRecognizerStateCancelled) { + CGFloat top = self.scrollViewOriginalInset.top + self.mj_h; + // 增加滚动区域top + self.scrollView.mj_insetT = top; + // 设置滚动位置 + CGPoint offset = self.scrollView.contentOffset; + offset.y = -top; + [self.scrollView setContentOffset:offset animated:NO]; + } + } completion:^(BOOL finished) { + [self executeRefreshingCallback]; + }]; + return; + } + + if (self.scrollView.panGestureRecognizer.state != UIGestureRecognizerStateCancelled) { + CGFloat top = self.scrollViewOriginalInset.top + self.mj_h; + // 禁用交互, 如果不禁用可能会引起渲染问题. + self.scrollView.userInteractionEnabled = NO; + + // CAAnimation keyPath不支持 contentOffset 用Bounds的动画代替 + CABasicAnimation *boundsAnimation = [CABasicAnimation animationWithKeyPath:@"bounds"]; + CGRect bounds = self.scrollView.bounds; + bounds.origin.y = -top; + boundsAnimation.fromValue = [NSValue valueWithCGRect:self.scrollView.bounds]; + boundsAnimation.toValue = [NSValue valueWithCGRect:bounds]; + boundsAnimation.duration = self.fastAnimationDuration; + //在delegate里移除 + boundsAnimation.removedOnCompletion = NO; + boundsAnimation.fillMode = kCAFillModeBoth; + boundsAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + boundsAnimation.delegate = self; + [boundsAnimation setValue:MJRefreshHeaderRefreshingBoundsKey forKey:@"identity"]; + [self.scrollView.layer addAnimation:boundsAnimation forKey:MJRefreshHeaderRefreshingBoundsKey]; + } else { + [self executeRefreshingCallback]; + } +} + +#pragma mark . 链式语法部分 . + +- (instancetype)linkTo:(UIScrollView *)scrollView { + scrollView.mj_header = self; + return self; +} + +#pragma mark - CAAnimationDelegate +- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { + NSString *identity = [anim valueForKey:@"identity"]; + if ([identity isEqualToString:MJRefreshHeaderRefreshing2IdleBoundsKey]) { + self.pullingPercent = 0.0; + self.scrollView.userInteractionEnabled = YES; + if (self.endRefreshingCompletionBlock) { + self.endRefreshingCompletionBlock(); + } + } else if ([identity isEqualToString:MJRefreshHeaderRefreshingBoundsKey]) { + // 避免出现 end 先于 Refreshing 状态 + if (self.state != MJRefreshStateIdle) { + CGFloat top = self.scrollViewOriginalInset.top + self.mj_h; + self.scrollView.mj_insetT = top; + // 设置最终滚动位置 + CGPoint offset = self.scrollView.contentOffset; + offset.y = -top; + [self.scrollView setContentOffset:offset animated:NO]; + } + self.scrollView.userInteractionEnabled = YES; + [self executeRefreshingCallback]; + } + + if ([self.scrollView.layer animationForKey:MJRefreshHeaderRefreshing2IdleBoundsKey]) { + [self.scrollView.layer removeAnimationForKey:MJRefreshHeaderRefreshing2IdleBoundsKey]; + } + + if ([self.scrollView.layer animationForKey:MJRefreshHeaderRefreshingBoundsKey]) { + [self.scrollView.layer removeAnimationForKey:MJRefreshHeaderRefreshingBoundsKey]; + } +} + +#pragma mark - 公共方法 +- (NSDate *)lastUpdatedTime +{ + return [[NSUserDefaults standardUserDefaults] objectForKey:self.lastUpdatedTimeKey]; +} + +- (void)setIgnoredScrollViewContentInsetTop:(CGFloat)ignoredScrollViewContentInsetTop { + _ignoredScrollViewContentInsetTop = ignoredScrollViewContentInsetTop; + + self.mj_y = - self.mj_h - _ignoredScrollViewContentInsetTop; +} + +@end diff --git a/Pods/MJRefresh/MJRefresh/Base/MJRefreshTrailer.h b/Pods/MJRefresh/MJRefresh/Base/MJRefreshTrailer.h new file mode 100644 index 0000000..ca4c7ea --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Base/MJRefreshTrailer.h @@ -0,0 +1,30 @@ +// +// MJRefreshTrailer.h +// MJRefresh +// +// Created by kinarobin on 2020/5/3. +// Copyright © 2020 小码哥. All rights reserved. +// + +#if __has_include() +#import +#else +#import "MJRefreshComponent.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface MJRefreshTrailer : MJRefreshComponent + +/** 创建trailer*/ ++ (instancetype)trailerWithRefreshingBlock:(MJRefreshComponentAction)refreshingBlock; +/** 创建trailer */ ++ (instancetype)trailerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; + +/** 忽略多少scrollView的contentInset的right */ +@property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetRight; + + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/Base/MJRefreshTrailer.m b/Pods/MJRefresh/MJRefresh/Base/MJRefreshTrailer.m new file mode 100644 index 0000000..da66f20 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Base/MJRefreshTrailer.m @@ -0,0 +1,179 @@ +// +// MJRefreshTrailer.m +// MJRefresh +// +// Created by kinarobin on 2020/5/3. +// Copyright © 2020 小码哥. All rights reserved. +// + +#import "MJRefreshTrailer.h" +#import "UIView+MJExtension.h" +#import "UIScrollView+MJRefresh.h" +#import "UIScrollView+MJExtension.h" + +@interface MJRefreshTrailer() +@property (assign, nonatomic) NSInteger lastRefreshCount; +@property (assign, nonatomic) CGFloat lastRightDelta; +@end + +@implementation MJRefreshTrailer + +#pragma mark - 构造方法 ++ (instancetype)trailerWithRefreshingBlock:(MJRefreshComponentAction)refreshingBlock { + MJRefreshTrailer *cmp = [[self alloc] init]; + cmp.refreshingBlock = refreshingBlock; + return cmp; +} + ++ (instancetype)trailerWithRefreshingTarget:(id)target refreshingAction:(SEL)action { + MJRefreshTrailer *cmp = [[self alloc] init]; + [cmp setRefreshingTarget:target refreshingAction:action]; + return cmp; +} + +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change { + [super scrollViewContentOffsetDidChange:change]; + + // 如果正在刷新,直接返回 + if (self.state == MJRefreshStateRefreshing) return; + + _scrollViewOriginalInset = self.scrollView.mj_inset; + + // 当前的contentOffset + CGFloat currentOffsetX = self.scrollView.mj_offsetX; + // 尾部控件刚好出现的offsetX + CGFloat happenOffsetX = [self happenOffsetX]; + // 如果是向右滚动到看不见右边控件,直接返回 + if (currentOffsetX <= happenOffsetX) return; + + CGFloat pullingPercent = (currentOffsetX - happenOffsetX) / self.mj_w; + + // 如果已全部加载,仅设置pullingPercent,然后返回 + if (self.state == MJRefreshStateNoMoreData) { + self.pullingPercent = pullingPercent; + return; + } + + if (self.scrollView.isDragging) { + self.pullingPercent = pullingPercent; + // 普通 和 即将刷新 的临界点 + CGFloat normal2pullingOffsetX = happenOffsetX + self.mj_w; + + if (self.state == MJRefreshStateIdle && currentOffsetX > normal2pullingOffsetX) { + self.state = MJRefreshStatePulling; + } else if (self.state == MJRefreshStatePulling && currentOffsetX <= normal2pullingOffsetX) { + // 转为普通状态 + self.state = MJRefreshStateIdle; + } + } else if (self.state == MJRefreshStatePulling) {// 即将刷新 && 手松开 + // 开始刷新 + [self beginRefreshing]; + } else if (pullingPercent < 1) { + self.pullingPercent = pullingPercent; + } +} + +- (void)setState:(MJRefreshState)state { + MJRefreshCheckState + // 根据状态来设置属性 + if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { + // 刷新完毕 + if (MJRefreshStateRefreshing == oldState) { + [UIView animateWithDuration:self.slowAnimationDuration animations:^{ + if (self.endRefreshingAnimationBeginAction) { + self.endRefreshingAnimationBeginAction(); + } + + self.scrollView.mj_insetR -= self.lastRightDelta; + // 自动调整透明度 + if (self.isAutomaticallyChangeAlpha) self.alpha = 0.0; + } completion:^(BOOL finished) { + self.pullingPercent = 0.0; + + if (self.endRefreshingCompletionBlock) { + self.endRefreshingCompletionBlock(); + } + }]; + } + + CGFloat deltaW = [self widthForContentBreakView]; + // 刚刷新完毕 + if (MJRefreshStateRefreshing == oldState && deltaW > 0 && self.scrollView.mj_totalDataCount != self.lastRefreshCount) { + self.scrollView.mj_offsetX = self.scrollView.mj_offsetX; + } + } else if (state == MJRefreshStateRefreshing) { + // 记录刷新前的数量 + self.lastRefreshCount = self.scrollView.mj_totalDataCount; + + [UIView animateWithDuration:self.fastAnimationDuration animations:^{ + CGFloat right = self.mj_w + self.scrollViewOriginalInset.right; + CGFloat deltaW = [self widthForContentBreakView]; + if (deltaW < 0) { // 如果内容宽度小于view的宽度 + right -= deltaW; + } + self.lastRightDelta = right - self.scrollView.mj_insetR; + self.scrollView.mj_insetR = right; + + // 设置滚动位置 + CGPoint offset = self.scrollView.contentOffset; + offset.x = [self happenOffsetX] + self.mj_w; + [self.scrollView setContentOffset:offset animated:NO]; + } completion:^(BOOL finished) { + [self executeRefreshingCallback]; + }]; + } +} + +- (void)scrollViewContentSizeDidChange:(NSDictionary *)change { + [super scrollViewContentSizeDidChange:change]; + + // 内容的宽度 + CGFloat contentWidth = self.scrollView.mj_contentW + self.ignoredScrollViewContentInsetRight; + // 表格的宽度 + CGFloat scrollWidth = self.scrollView.mj_w - self.scrollViewOriginalInset.left - self.scrollViewOriginalInset.right + self.ignoredScrollViewContentInsetRight; + // 设置位置和尺寸 + self.mj_x = MAX(contentWidth, scrollWidth); +} + +- (void)placeSubviews { + [super placeSubviews]; + + self.mj_h = _scrollView.mj_h; + // 设置自己的宽度 + self.mj_w = MJRefreshTrailWidth; +} + +- (void)willMoveToSuperview:(UIView *)newSuperview { + [super willMoveToSuperview:newSuperview]; + + if (newSuperview) { + // 设置支持水平弹簧效果 + _scrollView.alwaysBounceHorizontal = YES; + _scrollView.alwaysBounceVertical = NO; + } +} + +#pragma mark . 链式语法部分 . + +- (instancetype)linkTo:(UIScrollView *)scrollView { + scrollView.mj_trailer = self; + return self; +} + +#pragma mark - 刚好看到上拉刷新控件时的contentOffset.x +- (CGFloat)happenOffsetX { + CGFloat deltaW = [self widthForContentBreakView]; + if (deltaW > 0) { + return deltaW - self.scrollViewOriginalInset.left; + } else { + return - self.scrollViewOriginalInset.left; + } +} + +#pragma mark 获得scrollView的内容 超出 view 的宽度 +- (CGFloat)widthForContentBreakView { + CGFloat w = self.scrollView.frame.size.width - self.scrollViewOriginalInset.right - self.scrollViewOriginalInset.left; + return self.scrollView.contentSize.width - w; +} + +@end diff --git a/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.h b/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.h new file mode 100644 index 0000000..f346157 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.h @@ -0,0 +1,25 @@ +// +// MJRefreshAutoGifFooter.h +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#if __has_include() +#import +#else +#import "MJRefreshAutoStateFooter.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface MJRefreshAutoGifFooter : MJRefreshAutoStateFooter +@property (weak, nonatomic, readonly) UIImageView *gifView; + +/** 设置state状态下的动画图片images 动画持续时间duration*/ +- (instancetype)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; +- (instancetype)setImages:(NSArray *)images forState:(MJRefreshState)state; +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.m b/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.m new file mode 100644 index 0000000..213f69f --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.m @@ -0,0 +1,121 @@ +// +// MJRefreshAutoGifFooter.m +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshAutoGifFooter.h" +#import "NSBundle+MJRefresh.h" +#import "UIView+MJExtension.h" +#import "UIScrollView+MJExtension.h" +#import "UIScrollView+MJRefresh.h" + +@interface MJRefreshAutoGifFooter() +{ + __unsafe_unretained UIImageView *_gifView; +} +/** 所有状态对应的动画图片 */ +@property (strong, nonatomic) NSMutableDictionary *stateImages; +/** 所有状态对应的动画时间 */ +@property (strong, nonatomic) NSMutableDictionary *stateDurations; +@end + +@implementation MJRefreshAutoGifFooter +#pragma mark - 懒加载 +- (UIImageView *)gifView +{ + if (!_gifView) { + UIImageView *gifView = [[UIImageView alloc] init]; + [self addSubview:_gifView = gifView]; + } + return _gifView; +} + +- (NSMutableDictionary *)stateImages +{ + if (!_stateImages) { + self.stateImages = [NSMutableDictionary dictionary]; + } + return _stateImages; +} + +- (NSMutableDictionary *)stateDurations +{ + if (!_stateDurations) { + self.stateDurations = [NSMutableDictionary dictionary]; + } + return _stateDurations; +} + +#pragma mark - 公共方法 +- (instancetype)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state +{ + if (images == nil) return self; + + self.stateImages[@(state)] = images; + self.stateDurations[@(state)] = @(duration); + + /* 根据图片设置控件的高度 */ + UIImage *image = [images firstObject]; + if (image.size.height > self.mj_h) { + self.mj_h = image.size.height; + } + return self; +} + +- (instancetype)setImages:(NSArray *)images forState:(MJRefreshState)state +{ + return [self setImages:images duration:images.count * 0.1 forState:state]; +} + +#pragma mark - 实现父类的方法 +- (void)prepare +{ + [super prepare]; + + // 初始化间距 + self.labelLeftInset = 20; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + if (self.gifView.constraints.count) return; + + self.gifView.frame = self.bounds; + if (self.isRefreshingTitleHidden) { + self.gifView.contentMode = UIViewContentModeCenter; + } else { + self.gifView.contentMode = UIViewContentModeRight; + self.gifView.mj_w = self.mj_w * 0.5 - self.labelLeftInset - self.stateLabel.mj_textWidth * 0.5; + } +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 根据状态做事情 + if (state == MJRefreshStateRefreshing) { + NSArray *images = self.stateImages[@(state)]; + if (images.count == 0) return; + [self.gifView stopAnimating]; + + self.gifView.hidden = NO; + if (images.count == 1) { // 单张图片 + self.gifView.image = [images lastObject]; + } else { // 多张图片 + self.gifView.animationImages = images; + self.gifView.animationDuration = [self.stateDurations[@(state)] doubleValue]; + [self.gifView startAnimating]; + } + } else if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { + [self.gifView stopAnimating]; + self.gifView.hidden = YES; + } +} +@end + diff --git a/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.h b/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.h new file mode 100644 index 0000000..f8d1e04 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.h @@ -0,0 +1,25 @@ +// +// MJRefreshAutoNormalFooter.h +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#if __has_include() +#import +#else +#import "MJRefreshAutoStateFooter.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface MJRefreshAutoNormalFooter : MJRefreshAutoStateFooter +@property (weak, nonatomic, readonly) UIActivityIndicatorView *loadingView; + +/** 菊花的样式 */ +@property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle MJRefreshDeprecated("first deprecated in 3.2.2 - Use `loadingView` property"); +@end + + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.m b/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.m new file mode 100644 index 0000000..9e6a03d --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.m @@ -0,0 +1,81 @@ +// +// MJRefreshAutoNormalFooter.m +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshAutoNormalFooter.h" +#import "NSBundle+MJRefresh.h" +#import "UIView+MJExtension.h" +#import "UIScrollView+MJExtension.h" +#import "UIScrollView+MJRefresh.h" + +@interface MJRefreshAutoNormalFooter() +@property (weak, nonatomic) UIActivityIndicatorView *loadingView; +@end + +@implementation MJRefreshAutoNormalFooter +#pragma mark - 懒加载子控件 +- (UIActivityIndicatorView *)loadingView +{ + if (!_loadingView) { + UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:_activityIndicatorViewStyle]; + loadingView.hidesWhenStopped = YES; + [self addSubview:_loadingView = loadingView]; + } + return _loadingView; +} + +- (void)setActivityIndicatorViewStyle:(UIActivityIndicatorViewStyle)activityIndicatorViewStyle +{ + _activityIndicatorViewStyle = activityIndicatorViewStyle; + + [self.loadingView removeFromSuperview]; + self.loadingView = nil; + [self setNeedsLayout]; +} +#pragma mark - 重写父类的方法 +- (void)prepare +{ + [super prepare]; + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 + if (@available(iOS 13.0, *)) { + _activityIndicatorViewStyle = UIActivityIndicatorViewStyleMedium; + return; + } +#endif + + _activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + if (self.loadingView.constraints.count) return; + + // 圈圈 + CGFloat loadingCenterX = self.mj_w * 0.5; + if (!self.isRefreshingTitleHidden) { + loadingCenterX -= self.stateLabel.mj_textWidth * 0.5 + self.labelLeftInset; + } + CGFloat loadingCenterY = self.mj_h * 0.5; + self.loadingView.center = CGPointMake(loadingCenterX, loadingCenterY); +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 根据状态做事情 + if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { + [self.loadingView stopAnimating]; + } else if (state == MJRefreshStateRefreshing) { + [self.loadingView startAnimating]; + } +} + +@end diff --git a/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.h b/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.h new file mode 100644 index 0000000..c83622d --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.h @@ -0,0 +1,30 @@ +// +// MJRefreshAutoStateFooter.h +// MJRefresh +// +// Created by MJ Lee on 15/6/13. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#if __has_include() +#import +#else +#import "MJRefreshAutoFooter.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface MJRefreshAutoStateFooter : MJRefreshAutoFooter +/** 文字距离圈圈、箭头的距离 */ +@property (assign, nonatomic) CGFloat labelLeftInset; +/** 显示刷新状态的label */ +@property (weak, nonatomic, readonly) UILabel *stateLabel; + +/** 设置state状态下的文字 */ +- (instancetype)setTitle:(NSString *)title forState:(MJRefreshState)state; + +/** 隐藏刷新状态的文字 */ +@property (assign, nonatomic, getter=isRefreshingTitleHidden) BOOL refreshingTitleHidden; +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.m b/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.m new file mode 100644 index 0000000..e5ff652 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.m @@ -0,0 +1,119 @@ +// +// MJRefreshAutoStateFooter.m +// MJRefresh +// +// Created by MJ Lee on 15/6/13. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshAutoStateFooter.h" +#import "NSBundle+MJRefresh.h" + +@interface MJRefreshAutoFooter (TapTriggerFix) + +- (void)beginRefreshingWithoutValidation; +@end + + +@implementation MJRefreshAutoFooter (TapTriggerFix) + +- (void)beginRefreshingWithoutValidation { + [super beginRefreshing]; +} + +@end + +@interface MJRefreshAutoStateFooter() +{ + /** 显示刷新状态的label */ + __unsafe_unretained UILabel *_stateLabel; +} +/** 所有状态对应的文字 */ +@property (strong, nonatomic) NSMutableDictionary *stateTitles; +@end + +@implementation MJRefreshAutoStateFooter +#pragma mark - 懒加载 +- (NSMutableDictionary *)stateTitles +{ + if (!_stateTitles) { + self.stateTitles = [NSMutableDictionary dictionary]; + } + return _stateTitles; +} + +- (UILabel *)stateLabel +{ + if (!_stateLabel) { + [self addSubview:_stateLabel = [UILabel mj_label]]; + } + return _stateLabel; +} + +#pragma mark - 公共方法 +- (instancetype)setTitle:(NSString *)title forState:(MJRefreshState)state +{ + if (title == nil) return self; + self.stateTitles[@(state)] = title; + self.stateLabel.text = self.stateTitles[@(self.state)]; + return self; +} + +#pragma mark - 私有方法 +- (void)stateLabelClick +{ + if (self.state == MJRefreshStateIdle) { + [super beginRefreshingWithoutValidation]; + } +} + +- (void)textConfiguration { + // 初始化文字 + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshAutoFooterIdleText] forState:MJRefreshStateIdle]; + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshAutoFooterRefreshingText] forState:MJRefreshStateRefreshing]; + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshAutoFooterNoMoreDataText] forState:MJRefreshStateNoMoreData]; +} + +#pragma mark - 重写父类的方法 +- (void)prepare +{ + [super prepare]; + + // 初始化间距 + self.labelLeftInset = MJRefreshLabelLeftInset; + + [self textConfiguration]; + + // 监听label + self.stateLabel.userInteractionEnabled = YES; + [self.stateLabel addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(stateLabelClick)]]; +} + +- (void)i18nDidChange { + [self textConfiguration]; + + [super i18nDidChange]; +} + + +- (void)placeSubviews +{ + [super placeSubviews]; + + if (self.stateLabel.constraints.count) return; + + // 状态标签 + self.stateLabel.frame = self.bounds; +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + if (self.isRefreshingTitleHidden && state == MJRefreshStateRefreshing) { + self.stateLabel.text = nil; + } else { + self.stateLabel.text = self.stateTitles[@(state)]; + } +} +@end diff --git a/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.h b/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.h new file mode 100644 index 0000000..a7ba065 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.h @@ -0,0 +1,25 @@ +// +// MJRefreshBackGifFooter.h +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#if __has_include() +#import +#else +#import "MJRefreshBackStateFooter.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface MJRefreshBackGifFooter : MJRefreshBackStateFooter +@property (weak, nonatomic, readonly) UIImageView *gifView; + +/** 设置state状态下的动画图片images 动画持续时间duration*/ +- (instancetype)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; +- (instancetype)setImages:(NSArray *)images forState:(MJRefreshState)state; +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.m b/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.m new file mode 100644 index 0000000..23c626c --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.m @@ -0,0 +1,132 @@ +// +// MJRefreshBackGifFooter.m +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshBackGifFooter.h" +#import "NSBundle+MJRefresh.h" +#import "UIView+MJExtension.h" +#import "UIScrollView+MJExtension.h" +#import "UIScrollView+MJRefresh.h" + +@interface MJRefreshBackGifFooter() +{ + __unsafe_unretained UIImageView *_gifView; +} +/** 所有状态对应的动画图片 */ +@property (strong, nonatomic) NSMutableDictionary *stateImages; +/** 所有状态对应的动画时间 */ +@property (strong, nonatomic) NSMutableDictionary *stateDurations; +@end + +@implementation MJRefreshBackGifFooter +#pragma mark - 懒加载 +- (UIImageView *)gifView +{ + if (!_gifView) { + UIImageView *gifView = [[UIImageView alloc] init]; + [self addSubview:_gifView = gifView]; + } + return _gifView; +} + +- (NSMutableDictionary *)stateImages +{ + if (!_stateImages) { + self.stateImages = [NSMutableDictionary dictionary]; + } + return _stateImages; +} + +- (NSMutableDictionary *)stateDurations +{ + if (!_stateDurations) { + self.stateDurations = [NSMutableDictionary dictionary]; + } + return _stateDurations; +} + +#pragma mark - 公共方法 +- (instancetype)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state +{ + if (images == nil) return self; + + self.stateImages[@(state)] = images; + self.stateDurations[@(state)] = @(duration); + + /* 根据图片设置控件的高度 */ + UIImage *image = [images firstObject]; + if (image.size.height > self.mj_h) { + self.mj_h = image.size.height; + } + return self; +} + +- (instancetype)setImages:(NSArray *)images forState:(MJRefreshState)state +{ + return [self setImages:images duration:images.count * 0.1 forState:state]; +} + +#pragma mark - 实现父类的方法 +- (void)prepare +{ + [super prepare]; + + // 初始化间距 + self.labelLeftInset = 20; +} + +- (void)setPullingPercent:(CGFloat)pullingPercent +{ + [super setPullingPercent:pullingPercent]; + NSArray *images = self.stateImages[@(MJRefreshStateIdle)]; + if (self.state != MJRefreshStateIdle || images.count == 0) return; + [self.gifView stopAnimating]; + NSUInteger index = images.count * pullingPercent; + if (index >= images.count) index = images.count - 1; + self.gifView.image = images[index]; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + if (self.gifView.constraints.count) return; + + self.gifView.frame = self.bounds; + if (self.stateLabel.hidden) { + self.gifView.contentMode = UIViewContentModeCenter; + } else { + self.gifView.contentMode = UIViewContentModeRight; + self.gifView.mj_w = self.mj_w * 0.5 - self.labelLeftInset - self.stateLabel.mj_textWidth * 0.5; + } +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 根据状态做事情 + if (state == MJRefreshStatePulling || state == MJRefreshStateRefreshing) { + NSArray *images = self.stateImages[@(state)]; + if (images.count == 0) return; + + self.gifView.hidden = NO; + [self.gifView stopAnimating]; + if (images.count == 1) { // 单张图片 + self.gifView.image = [images lastObject]; + } else { // 多张图片 + self.gifView.animationImages = images; + self.gifView.animationDuration = [self.stateDurations[@(state)] doubleValue]; + [self.gifView startAnimating]; + } + } else if (state == MJRefreshStateIdle) { + self.gifView.hidden = NO; + } else if (state == MJRefreshStateNoMoreData) { + self.gifView.hidden = YES; + } +} +@end diff --git a/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.h b/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.h new file mode 100644 index 0000000..d255807 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.h @@ -0,0 +1,25 @@ +// +// MJRefreshBackNormalFooter.h +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#if __has_include() +#import +#else +#import "MJRefreshBackStateFooter.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface MJRefreshBackNormalFooter : MJRefreshBackStateFooter +@property (weak, nonatomic, readonly) UIImageView *arrowView; +@property (weak, nonatomic, readonly) UIActivityIndicatorView *loadingView; + +/** 菊花的样式 */ +@property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle MJRefreshDeprecated("first deprecated in 3.2.2 - Use `loadingView` property"); +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.m b/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.m new file mode 100644 index 0000000..932af76 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.m @@ -0,0 +1,132 @@ +// +// MJRefreshBackNormalFooter.m +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshBackNormalFooter.h" +#import "NSBundle+MJRefresh.h" +#import "UIView+MJExtension.h" + +@interface MJRefreshBackNormalFooter() +{ + __unsafe_unretained UIImageView *_arrowView; +} +@property (weak, nonatomic) UIActivityIndicatorView *loadingView; +@end + +@implementation MJRefreshBackNormalFooter +#pragma mark - 懒加载子控件 +- (UIImageView *)arrowView +{ + if (!_arrowView) { + UIImageView *arrowView = [[UIImageView alloc] initWithImage:[NSBundle mj_arrowImage]]; + [self addSubview:_arrowView = arrowView]; + } + return _arrowView; +} + + +- (UIActivityIndicatorView *)loadingView +{ + if (!_loadingView) { + UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:_activityIndicatorViewStyle]; + loadingView.hidesWhenStopped = YES; + [self addSubview:_loadingView = loadingView]; + } + return _loadingView; +} + +- (void)setActivityIndicatorViewStyle:(UIActivityIndicatorViewStyle)activityIndicatorViewStyle +{ + _activityIndicatorViewStyle = activityIndicatorViewStyle; + + [self.loadingView removeFromSuperview]; + self.loadingView = nil; + [self setNeedsLayout]; +} +#pragma mark - 重写父类的方法 +- (void)prepare +{ + [super prepare]; + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 + if (@available(iOS 13.0, *)) { + _activityIndicatorViewStyle = UIActivityIndicatorViewStyleMedium; + return; + } +#endif + + _activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + // 箭头的中心点 + CGFloat arrowCenterX = self.mj_w * 0.5; + if (!self.stateLabel.hidden) { + arrowCenterX -= self.labelLeftInset + self.stateLabel.mj_textWidth * 0.5; + } + CGFloat arrowCenterY = self.mj_h * 0.5; + CGPoint arrowCenter = CGPointMake(arrowCenterX, arrowCenterY); + + // 箭头 + if (self.arrowView.constraints.count == 0) { + self.arrowView.mj_size = self.arrowView.image.size; + self.arrowView.center = arrowCenter; + } + + // 圈圈 + if (self.loadingView.constraints.count == 0) { + self.loadingView.center = arrowCenter; + } + + self.arrowView.tintColor = self.stateLabel.textColor; +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 根据状态做事情 + if (state == MJRefreshStateIdle) { + if (oldState == MJRefreshStateRefreshing) { + self.arrowView.transform = CGAffineTransformMakeRotation(0.000001 - M_PI); + [UIView animateWithDuration:self.slowAnimationDuration animations:^{ + self.loadingView.alpha = 0.0; + } completion:^(BOOL finished) { + // 防止动画结束后,状态已经不是MJRefreshStateIdle + if (self.state != MJRefreshStateIdle) return; + + self.loadingView.alpha = 1.0; + [self.loadingView stopAnimating]; + + self.arrowView.hidden = NO; + }]; + } else { + self.arrowView.hidden = NO; + [self.loadingView stopAnimating]; + [UIView animateWithDuration:self.fastAnimationDuration animations:^{ + self.arrowView.transform = CGAffineTransformMakeRotation(0.000001 - M_PI); + }]; + } + } else if (state == MJRefreshStatePulling) { + self.arrowView.hidden = NO; + [self.loadingView stopAnimating]; + [UIView animateWithDuration:self.fastAnimationDuration animations:^{ + self.arrowView.transform = CGAffineTransformIdentity; + }]; + } else if (state == MJRefreshStateRefreshing) { + self.arrowView.hidden = YES; + [self.loadingView startAnimating]; + } else if (state == MJRefreshStateNoMoreData) { + self.arrowView.hidden = YES; + [self.loadingView stopAnimating]; + } +} + +@end diff --git a/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.h b/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.h new file mode 100644 index 0000000..c6897f4 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.h @@ -0,0 +1,29 @@ +// +// MJRefreshBackStateFooter.h +// MJRefresh +// +// Created by MJ Lee on 15/6/13. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#if __has_include() +#import +#else +#import "MJRefreshBackFooter.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface MJRefreshBackStateFooter : MJRefreshBackFooter +/** 文字距离圈圈、箭头的距离 */ +@property (assign, nonatomic) CGFloat labelLeftInset; +/** 显示刷新状态的label */ +@property (weak, nonatomic, readonly) UILabel *stateLabel; +/** 设置state状态下的文字 */ +- (instancetype)setTitle:(NSString *)title forState:(MJRefreshState)state; + +/** 获取state状态下的title */ +- (NSString *)titleForState:(MJRefreshState)state; +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.m b/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.m new file mode 100644 index 0000000..70f4024 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.m @@ -0,0 +1,93 @@ +// +// MJRefreshBackStateFooter.m +// MJRefresh +// +// Created by MJ Lee on 15/6/13. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshBackStateFooter.h" +#import "NSBundle+MJRefresh.h" + +@interface MJRefreshBackStateFooter() +{ + /** 显示刷新状态的label */ + __unsafe_unretained UILabel *_stateLabel; +} +/** 所有状态对应的文字 */ +@property (strong, nonatomic) NSMutableDictionary *stateTitles; +@end + +@implementation MJRefreshBackStateFooter +#pragma mark - 懒加载 +- (NSMutableDictionary *)stateTitles +{ + if (!_stateTitles) { + self.stateTitles = [NSMutableDictionary dictionary]; + } + return _stateTitles; +} + +- (UILabel *)stateLabel +{ + if (!_stateLabel) { + [self addSubview:_stateLabel = [UILabel mj_label]]; + } + return _stateLabel; +} + +#pragma mark - 公共方法 +- (instancetype)setTitle:(NSString *)title forState:(MJRefreshState)state +{ + if (title == nil) return self; + self.stateTitles[@(state)] = title; + self.stateLabel.text = self.stateTitles[@(self.state)]; + return self; +} + +- (NSString *)titleForState:(MJRefreshState)state { + return self.stateTitles[@(state)]; +} + +- (void)textConfiguration { + // 初始化文字 + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshBackFooterIdleText] forState:MJRefreshStateIdle]; + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshBackFooterPullingText] forState:MJRefreshStatePulling]; + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshBackFooterRefreshingText] forState:MJRefreshStateRefreshing]; + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshBackFooterNoMoreDataText] forState:MJRefreshStateNoMoreData]; +} + +#pragma mark - 重写父类的方法 +- (void)prepare +{ + [super prepare]; + + // 初始化间距 + self.labelLeftInset = MJRefreshLabelLeftInset; + [self textConfiguration]; +} + +- (void)i18nDidChange { + [self textConfiguration]; + + [super i18nDidChange]; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + if (self.stateLabel.constraints.count) return; + + // 状态标签 + self.stateLabel.frame = self.bounds; +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 设置状态文字 + self.stateLabel.text = self.stateTitles[@(state)]; +} +@end diff --git a/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshGifHeader.h b/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshGifHeader.h new file mode 100644 index 0000000..afa4a13 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshGifHeader.h @@ -0,0 +1,25 @@ +// +// MJRefreshGifHeader.h +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#if __has_include() +#import +#else +#import "MJRefreshStateHeader.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface MJRefreshGifHeader : MJRefreshStateHeader +@property (weak, nonatomic, readonly) UIImageView *gifView; + +/** 设置state状态下的动画图片images 动画持续时间duration*/ +- (instancetype)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; +- (instancetype)setImages:(NSArray *)images forState:(MJRefreshState)state; +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshGifHeader.m b/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshGifHeader.m new file mode 100644 index 0000000..707e466 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshGifHeader.m @@ -0,0 +1,135 @@ +// +// MJRefreshGifHeader.m +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshGifHeader.h" +#import "UIView+MJExtension.h" +#import "UIScrollView+MJExtension.h" + +@interface MJRefreshGifHeader() +{ + __unsafe_unretained UIImageView *_gifView; +} +/** 所有状态对应的动画图片 */ +@property (strong, nonatomic) NSMutableDictionary *stateImages; +/** 所有状态对应的动画时间 */ +@property (strong, nonatomic) NSMutableDictionary *stateDurations; +@end + +@implementation MJRefreshGifHeader +#pragma mark - 懒加载 +- (UIImageView *)gifView +{ + if (!_gifView) { + UIImageView *gifView = [[UIImageView alloc] init]; + [self addSubview:_gifView = gifView]; + } + return _gifView; +} + +- (NSMutableDictionary *)stateImages +{ + if (!_stateImages) { + self.stateImages = [NSMutableDictionary dictionary]; + } + return _stateImages; +} + +- (NSMutableDictionary *)stateDurations +{ + if (!_stateDurations) { + self.stateDurations = [NSMutableDictionary dictionary]; + } + return _stateDurations; +} + +#pragma mark - 公共方法 +- (instancetype)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state { + if (images == nil) return self; + + self.stateImages[@(state)] = images; + self.stateDurations[@(state)] = @(duration); + + /* 根据图片设置控件的高度 */ + UIImage *image = [images firstObject]; + if (image.size.height > self.mj_h) { + self.mj_h = image.size.height; + } + return self; +} + +- (instancetype)setImages:(NSArray *)images forState:(MJRefreshState)state +{ + return [self setImages:images duration:images.count * 0.1 forState:state]; +} + +#pragma mark - 实现父类的方法 +- (void)prepare +{ + [super prepare]; + + // 初始化间距 + self.labelLeftInset = 20; +} + +- (void)setPullingPercent:(CGFloat)pullingPercent +{ + [super setPullingPercent:pullingPercent]; + NSArray *images = self.stateImages[@(MJRefreshStateIdle)]; + if (self.state != MJRefreshStateIdle || images.count == 0) return; + // 停止动画 + [self.gifView stopAnimating]; + // 设置当前需要显示的图片 + NSUInteger index = images.count * pullingPercent; + if (index >= images.count) index = images.count - 1; + self.gifView.image = images[index]; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + if (self.gifView.constraints.count) return; + + self.gifView.frame = self.bounds; + if (self.stateLabel.hidden && self.lastUpdatedTimeLabel.hidden) { + self.gifView.contentMode = UIViewContentModeCenter; + } else { + self.gifView.contentMode = UIViewContentModeRight; + + CGFloat stateWidth = self.stateLabel.mj_textWidth; + CGFloat timeWidth = 0.0; + if (!self.lastUpdatedTimeLabel.hidden) { + timeWidth = self.lastUpdatedTimeLabel.mj_textWidth; + } + CGFloat textWidth = MAX(stateWidth, timeWidth); + self.gifView.mj_w = self.mj_w * 0.5 - textWidth * 0.5 - self.labelLeftInset; + } +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 根据状态做事情 + if (state == MJRefreshStatePulling || state == MJRefreshStateRefreshing) { + NSArray *images = self.stateImages[@(state)]; + if (images.count == 0) return; + + [self.gifView stopAnimating]; + if (images.count == 1) { // 单张图片 + self.gifView.image = [images lastObject]; + } else { // 多张图片 + self.gifView.animationImages = images; + self.gifView.animationDuration = [self.stateDurations[@(state)] doubleValue]; + [self.gifView startAnimating]; + } + } else if (state == MJRefreshStateIdle) { + [self.gifView stopAnimating]; + } +} +@end diff --git a/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshNormalHeader.h b/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshNormalHeader.h new file mode 100644 index 0000000..2bfef39 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshNormalHeader.h @@ -0,0 +1,26 @@ +// +// MJRefreshNormalHeader.h +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#if __has_include() +#import +#else +#import "MJRefreshStateHeader.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface MJRefreshNormalHeader : MJRefreshStateHeader +@property (weak, nonatomic, readonly) UIImageView *arrowView; +@property (weak, nonatomic, readonly) UIActivityIndicatorView *loadingView; + + +/** 菊花的样式 */ +@property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle MJRefreshDeprecated("first deprecated in 3.2.2 - Use `loadingView` property"); +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshNormalHeader.m b/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshNormalHeader.m new file mode 100644 index 0000000..84a66cb --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshNormalHeader.m @@ -0,0 +1,137 @@ +// +// MJRefreshNormalHeader.m +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshNormalHeader.h" +#import "NSBundle+MJRefresh.h" +#import "UIScrollView+MJRefresh.h" +#import "UIView+MJExtension.h" + +@interface MJRefreshNormalHeader() +{ + __unsafe_unretained UIImageView *_arrowView; +} +@property (weak, nonatomic) UIActivityIndicatorView *loadingView; +@end + +@implementation MJRefreshNormalHeader +#pragma mark - 懒加载子控件 +- (UIImageView *)arrowView +{ + if (!_arrowView) { + UIImageView *arrowView = [[UIImageView alloc] initWithImage:[NSBundle mj_arrowImage]]; + [self addSubview:_arrowView = arrowView]; + } + return _arrowView; +} + +- (UIActivityIndicatorView *)loadingView +{ + if (!_loadingView) { + UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:_activityIndicatorViewStyle]; + loadingView.hidesWhenStopped = YES; + [self addSubview:_loadingView = loadingView]; + } + return _loadingView; +} + +#pragma mark - 公共方法 +- (void)setActivityIndicatorViewStyle:(UIActivityIndicatorViewStyle)activityIndicatorViewStyle +{ + _activityIndicatorViewStyle = activityIndicatorViewStyle; + + [self.loadingView removeFromSuperview]; + self.loadingView = nil; + [self setNeedsLayout]; +} + +#pragma mark - 重写父类的方法 +- (void)prepare +{ + [super prepare]; + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 + if (@available(iOS 13.0, *)) { + _activityIndicatorViewStyle = UIActivityIndicatorViewStyleMedium; + return; + } +#endif + + _activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + // 箭头的中心点 + CGFloat arrowCenterX = self.mj_w * 0.5; + if (!self.stateLabel.hidden) { + CGFloat stateWidth = self.stateLabel.mj_textWidth; + CGFloat timeWidth = 0.0; + if (!self.lastUpdatedTimeLabel.hidden) { + timeWidth = self.lastUpdatedTimeLabel.mj_textWidth; + } + CGFloat textWidth = MAX(stateWidth, timeWidth); + arrowCenterX -= textWidth / 2 + self.labelLeftInset; + } + CGFloat arrowCenterY = self.mj_h * 0.5; + CGPoint arrowCenter = CGPointMake(arrowCenterX, arrowCenterY); + + // 箭头 + if (self.arrowView.constraints.count == 0) { + self.arrowView.mj_size = self.arrowView.image.size; + self.arrowView.center = arrowCenter; + } + + // 圈圈 + if (self.loadingView.constraints.count == 0) { + self.loadingView.center = arrowCenter; + } + + self.arrowView.tintColor = self.stateLabel.textColor; +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 根据状态做事情 + if (state == MJRefreshStateIdle) { + if (oldState == MJRefreshStateRefreshing) { + self.arrowView.transform = CGAffineTransformIdentity; + + [UIView animateWithDuration:self.slowAnimationDuration animations:^{ + self.loadingView.alpha = 0.0; + } completion:^(BOOL finished) { + // 如果执行完动画发现不是idle状态,就直接返回,进入其他状态 + if (self.state != MJRefreshStateIdle) return; + + self.loadingView.alpha = 1.0; + [self.loadingView stopAnimating]; + self.arrowView.hidden = NO; + }]; + } else { + [self.loadingView stopAnimating]; + self.arrowView.hidden = NO; + [UIView animateWithDuration:self.fastAnimationDuration animations:^{ + self.arrowView.transform = CGAffineTransformIdentity; + }]; + } + } else if (state == MJRefreshStatePulling) { + [self.loadingView stopAnimating]; + self.arrowView.hidden = NO; + [UIView animateWithDuration:self.fastAnimationDuration animations:^{ + self.arrowView.transform = CGAffineTransformMakeRotation(0.000001 - M_PI); + }]; + } else if (state == MJRefreshStateRefreshing) { + self.loadingView.alpha = 1.0; // 防止refreshing -> idle的动画完毕动作没有被执行 + [self.loadingView startAnimating]; + self.arrowView.hidden = YES; + } +} +@end diff --git a/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshStateHeader.h b/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshStateHeader.h new file mode 100644 index 0000000..8e1d108 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshStateHeader.h @@ -0,0 +1,39 @@ +// +// MJRefreshStateHeader.h +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#if __has_include() +#import +#else +#import "MJRefreshHeader.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface MJRefreshStateHeader : MJRefreshHeader +#pragma mark - 刷新时间相关 +/** 利用这个block来决定显示的更新时间文字 */ +@property (copy, nonatomic, nullable) NSString *(^lastUpdatedTimeText)(NSDate * _Nullable lastUpdatedTime); +/** 显示上一次刷新时间的label */ +@property (weak, nonatomic, readonly) UILabel *lastUpdatedTimeLabel; + +#pragma mark - 状态相关 +/** 文字距离圈圈、箭头的距离 */ +@property (assign, nonatomic) CGFloat labelLeftInset; +/** 显示刷新状态的label */ +@property (weak, nonatomic, readonly) UILabel *stateLabel; +/** 设置state状态下的文字 */ +- (instancetype)setTitle:(NSString *)title forState:(MJRefreshState)state; +@end + +@interface MJRefreshStateHeader (ChainingGrammar) + +- (instancetype)modifyLastUpdatedTimeText:(NSString * (^)(NSDate * _Nullable lastUpdatedTime))handler; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshStateHeader.m b/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshStateHeader.m new file mode 100644 index 0000000..62d1ddc --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Header/MJRefreshStateHeader.m @@ -0,0 +1,191 @@ +// +// MJRefreshStateHeader.m +// MJRefresh +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshStateHeader.h" +#import "MJRefreshConst.h" +#import "NSBundle+MJRefresh.h" +#import "UIView+MJExtension.h" +#import "UIScrollView+MJExtension.h" + +@interface MJRefreshStateHeader() +{ + /** 显示上一次刷新时间的label */ + __unsafe_unretained UILabel *_lastUpdatedTimeLabel; + /** 显示刷新状态的label */ + __unsafe_unretained UILabel *_stateLabel; +} +/** 所有状态对应的文字 */ +@property (strong, nonatomic) NSMutableDictionary *stateTitles; +@end + +@implementation MJRefreshStateHeader +#pragma mark - 懒加载 +- (NSMutableDictionary *)stateTitles +{ + if (!_stateTitles) { + self.stateTitles = [NSMutableDictionary dictionary]; + } + return _stateTitles; +} + +- (UILabel *)stateLabel +{ + if (!_stateLabel) { + [self addSubview:_stateLabel = [UILabel mj_label]]; + } + return _stateLabel; +} + +- (UILabel *)lastUpdatedTimeLabel +{ + if (!_lastUpdatedTimeLabel) { + [self addSubview:_lastUpdatedTimeLabel = [UILabel mj_label]]; + } + return _lastUpdatedTimeLabel; +} + +- (void)setLastUpdatedTimeText:(NSString * _Nonnull (^)(NSDate * _Nullable))lastUpdatedTimeText{ + _lastUpdatedTimeText = lastUpdatedTimeText; + // 重新设置key(重新显示时间) + self.lastUpdatedTimeKey = self.lastUpdatedTimeKey; +} + +#pragma mark - 公共方法 +- (instancetype)setTitle:(NSString *)title forState:(MJRefreshState)state +{ + if (title == nil) return self; + self.stateTitles[@(state)] = title; + self.stateLabel.text = self.stateTitles[@(self.state)]; + return self; +} + +#pragma mark key的处理 +- (void)setLastUpdatedTimeKey:(NSString *)lastUpdatedTimeKey +{ + [super setLastUpdatedTimeKey:lastUpdatedTimeKey]; + + // 如果label隐藏了,就不用再处理 + if (self.lastUpdatedTimeLabel.hidden) return; + + NSDate *lastUpdatedTime = [[NSUserDefaults standardUserDefaults] objectForKey:lastUpdatedTimeKey]; + + // 如果有block + if (self.lastUpdatedTimeText) { + self.lastUpdatedTimeLabel.text = self.lastUpdatedTimeText(lastUpdatedTime); + return; + } + + if (lastUpdatedTime) { + // 1.获得年月日 + NSCalendar *calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian]; + NSUInteger unitFlags = NSCalendarUnitYear| NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute; + NSDateComponents *cmp1 = [calendar components:unitFlags fromDate:lastUpdatedTime]; + NSDateComponents *cmp2 = [calendar components:unitFlags fromDate:[NSDate date]]; + + // 2.格式化日期 + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + BOOL isToday = NO; + if ([cmp1 day] == [cmp2 day]) { // 今天 + formatter.dateFormat = @" HH:mm"; + isToday = YES; + } else if ([cmp1 year] == [cmp2 year]) { // 今年 + formatter.dateFormat = @"MM-dd HH:mm"; + } else { + formatter.dateFormat = @"yyyy-MM-dd HH:mm"; + } + NSString *time = [formatter stringFromDate:lastUpdatedTime]; + + // 3.显示日期 + self.lastUpdatedTimeLabel.text = [NSString stringWithFormat:@"%@%@%@", + [NSBundle mj_localizedStringForKey:MJRefreshHeaderLastTimeText], + isToday ? [NSBundle mj_localizedStringForKey:MJRefreshHeaderDateTodayText] : @"", + time]; + } else { + self.lastUpdatedTimeLabel.text = [NSString stringWithFormat:@"%@%@", + [NSBundle mj_localizedStringForKey:MJRefreshHeaderLastTimeText], + [NSBundle mj_localizedStringForKey:MJRefreshHeaderNoneLastDateText]]; + } +} + + +- (void)textConfiguration { + // 初始化文字 + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshHeaderIdleText] forState:MJRefreshStateIdle]; + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshHeaderPullingText] forState:MJRefreshStatePulling]; + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshHeaderRefreshingText] forState:MJRefreshStateRefreshing]; + self.lastUpdatedTimeKey = MJRefreshHeaderLastUpdatedTimeKey; +} + +#pragma mark - 覆盖父类的方法 +- (void)prepare +{ + [super prepare]; + + // 初始化间距 + self.labelLeftInset = MJRefreshLabelLeftInset; + [self textConfiguration]; +} + +- (void)i18nDidChange { + [self textConfiguration]; + + [super i18nDidChange]; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + if (self.stateLabel.hidden) return; + + BOOL noConstrainsOnStatusLabel = self.stateLabel.constraints.count == 0; + + if (self.lastUpdatedTimeLabel.hidden) { + // 状态 + if (noConstrainsOnStatusLabel) self.stateLabel.frame = self.bounds; + } else { + CGFloat stateLabelH = self.mj_h * 0.5; + // 状态 + if (noConstrainsOnStatusLabel) { + self.stateLabel.mj_x = 0; + self.stateLabel.mj_y = 0; + self.stateLabel.mj_w = self.mj_w; + self.stateLabel.mj_h = stateLabelH; + } + + // 更新时间 + if (self.lastUpdatedTimeLabel.constraints.count == 0) { + self.lastUpdatedTimeLabel.mj_x = 0; + self.lastUpdatedTimeLabel.mj_y = stateLabelH; + self.lastUpdatedTimeLabel.mj_w = self.mj_w; + self.lastUpdatedTimeLabel.mj_h = self.mj_h - self.lastUpdatedTimeLabel.mj_y; + } + } +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 设置状态文字 + self.stateLabel.text = self.stateTitles[@(state)]; + + // 重新设置key(重新显示时间) + self.lastUpdatedTimeKey = self.lastUpdatedTimeKey; +} +@end + +#pragma mark - <<< 为 Swift 扩展链式语法 >>> - +@implementation MJRefreshStateHeader (ChainingGrammar) + +- (instancetype)modifyLastUpdatedTimeText:(NSString * _Nonnull (^)(NSDate * _Nullable))handler { + self.lastUpdatedTimeText = handler; + return self; +} + +@end diff --git a/Pods/MJRefresh/MJRefresh/Custom/Trailer/MJRefreshNormalTrailer.h b/Pods/MJRefresh/MJRefresh/Custom/Trailer/MJRefreshNormalTrailer.h new file mode 100644 index 0000000..97385d7 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Trailer/MJRefreshNormalTrailer.h @@ -0,0 +1,23 @@ +// +// MJRefreshNormalTrailer.h +// MJRefresh +// +// Created by kinarobin on 2020/5/3. +// Copyright © 2020 小码哥. All rights reserved. +// + +#if __has_include() +#import +#else +#import "MJRefreshStateTrailer.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface MJRefreshNormalTrailer : MJRefreshStateTrailer + +@property (weak, nonatomic, readonly) UIImageView *arrowView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/Custom/Trailer/MJRefreshNormalTrailer.m b/Pods/MJRefresh/MJRefresh/Custom/Trailer/MJRefreshNormalTrailer.m new file mode 100644 index 0000000..4b269f2 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Trailer/MJRefreshNormalTrailer.m @@ -0,0 +1,80 @@ +// +// MJRefreshNormalTrailer.m +// MJRefresh +// +// Created by kinarobin on 2020/5/3. +// Copyright © 2020 小码哥. All rights reserved. +// + +#import "MJRefreshNormalTrailer.h" +#import "NSBundle+MJRefresh.h" +#import "UIView+MJExtension.h" + +@interface MJRefreshNormalTrailer() { + __unsafe_unretained UIImageView *_arrowView; +} +@end + +@implementation MJRefreshNormalTrailer +#pragma mark - 懒加载子控件 +- (UIImageView *)arrowView { + if (!_arrowView) { + UIImageView *arrowView = [[UIImageView alloc] initWithImage:[NSBundle mj_trailArrowImage]]; + [self addSubview:_arrowView = arrowView]; + } + return _arrowView; +} + +- (void)placeSubviews { + [super placeSubviews]; + + CGSize arrowSize = self.arrowView.image.size; + // 箭头的中心点 + CGPoint selfCenter = CGPointMake(self.mj_w * 0.5, self.mj_h * 0.5); + CGPoint arrowCenter = CGPointMake(arrowSize.width * 0.5 + 5, self.mj_h * 0.5); + BOOL stateHidden = self.stateLabel.isHidden; + + if (self.arrowView.constraints.count == 0) { + self.arrowView.mj_size = self.arrowView.image.size; + self.arrowView.center = stateHidden ? selfCenter : arrowCenter ; + } + self.arrowView.tintColor = self.stateLabel.textColor; + + if (stateHidden) return; + + BOOL noConstrainsOnStatusLabel = self.stateLabel.constraints.count == 0; + CGFloat stateLabelW = ceil(self.stateLabel.font.pointSize); + // 状态 + if (noConstrainsOnStatusLabel) { + BOOL arrowHidden = self.arrowView.isHidden; + CGFloat stateCenterX = (self.mj_w + arrowSize.width) * 0.5; + self.stateLabel.center = arrowHidden ? selfCenter : CGPointMake(stateCenterX, self.mj_h * 0.5); + self.stateLabel.mj_size = CGSizeMake(stateLabelW, self.mj_h) ; + } +} + +- (void)setState:(MJRefreshState)state { + MJRefreshCheckState + // 根据状态做事情 + if (state == MJRefreshStateIdle) { + if (oldState == MJRefreshStateRefreshing) { + [UIView animateWithDuration:self.fastAnimationDuration animations:^{ + self.arrowView.transform = CGAffineTransformMakeRotation(M_PI); + } completion:^(BOOL finished) { + self.arrowView.transform = CGAffineTransformIdentity; + }]; + } else { + [UIView animateWithDuration:self.fastAnimationDuration animations:^{ + self.arrowView.transform = CGAffineTransformIdentity; + }]; + } + } else if (state == MJRefreshStatePulling) { + [UIView animateWithDuration:self.fastAnimationDuration animations:^{ + self.arrowView.transform = CGAffineTransformMakeRotation(M_PI); + }]; + } +} + + + +@end diff --git a/Pods/MJRefresh/MJRefresh/Custom/Trailer/MJRefreshStateTrailer.h b/Pods/MJRefresh/MJRefresh/Custom/Trailer/MJRefreshStateTrailer.h new file mode 100644 index 0000000..92ac203 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Trailer/MJRefreshStateTrailer.h @@ -0,0 +1,28 @@ +// +// MJRefreshStateTrailer.h +// MJRefresh +// +// Created by kinarobin on 2020/5/3. +// Copyright © 2020 小码哥. All rights reserved. +// + +#if __has_include() +#import +#else +#import "MJRefreshTrailer.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + + +@interface MJRefreshStateTrailer : MJRefreshTrailer + +#pragma mark - 状态相关 +/** 显示刷新状态的label */ +@property (weak, nonatomic, readonly) UILabel *stateLabel; +/** 设置state状态下的文字 */ +- (instancetype)setTitle:(NSString *)title forState:(MJRefreshState)state; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/Custom/Trailer/MJRefreshStateTrailer.m b/Pods/MJRefresh/MJRefresh/Custom/Trailer/MJRefreshStateTrailer.m new file mode 100644 index 0000000..3ce0ba6 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/Custom/Trailer/MJRefreshStateTrailer.m @@ -0,0 +1,87 @@ +// +// MJRefreshStateTrailer.m +// MJRefresh +// +// Created by kinarobin on 2020/5/3. +// Copyright © 2020 小码哥. All rights reserved. +// + +#import "MJRefreshStateTrailer.h" +#import "NSBundle+MJRefresh.h" +#import "UIView+MJExtension.h" + +@interface MJRefreshStateTrailer() { + /** 显示刷新状态的label */ + __unsafe_unretained UILabel *_stateLabel; +} +/** 所有状态对应的文字 */ +@property (strong, nonatomic) NSMutableDictionary *stateTitles; +@end + +@implementation MJRefreshStateTrailer +#pragma mark - 懒加载 +- (NSMutableDictionary *)stateTitles { + if (!_stateTitles) { + self.stateTitles = [NSMutableDictionary dictionary]; + } + return _stateTitles; +} + +- (UILabel *)stateLabel { + if (!_stateLabel) { + UILabel *stateLabel = [UILabel mj_label]; + stateLabel.numberOfLines = 0; + [self addSubview:_stateLabel = stateLabel]; + } + return _stateLabel; +} + +#pragma mark - 公共方法 +- (instancetype)setTitle:(NSString *)title forState:(MJRefreshState)state { + if (title == nil) return self; + self.stateTitles[@(state)] = title; + self.stateLabel.text = self.stateTitles[@(self.state)]; + return self; +} + +- (void)textConfiguration { + // 初始化文字 + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshTrailerIdleText] forState:MJRefreshStateIdle]; + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshTrailerPullingText] forState:MJRefreshStatePulling]; + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshTrailerPullingText] forState:MJRefreshStateRefreshing]; +} + +#pragma mark - 覆盖父类的方法 +- (void)prepare { + [super prepare]; + + [self textConfiguration]; +} + +- (void)i18nDidChange { + [self textConfiguration]; + + [super i18nDidChange]; +} + +- (void)setState:(MJRefreshState)state { + MJRefreshCheckState + // 设置状态文字 + self.stateLabel.text = self.stateTitles[@(state)]; +} + +- (void)placeSubviews { + [super placeSubviews]; + + if (self.stateLabel.hidden) return; + + BOOL noConstrainsOnStatusLabel = self.stateLabel.constraints.count == 0; + CGFloat stateLabelW = ceil(self.stateLabel.font.pointSize); + // 状态 + if (noConstrainsOnStatusLabel) { + self.stateLabel.center = CGPointMake(self.mj_w * 0.5, self.mj_h * 0.5); + self.stateLabel.mj_size = CGSizeMake(stateLabelW, self.mj_h) ; + } +} + +@end diff --git a/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/arrow@2x.png b/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/arrow@2x.png new file mode 100755 index 0000000..b1078de Binary files /dev/null and b/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/arrow@2x.png differ diff --git a/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/en.lproj/Localizable.strings b/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/en.lproj/Localizable.strings new file mode 100644 index 0000000..bf56786 Binary files /dev/null and b/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/en.lproj/Localizable.strings differ diff --git a/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/ko.lproj/Localizable.strings b/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/ko.lproj/Localizable.strings new file mode 100644 index 0000000..ac25579 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/ko.lproj/Localizable.strings @@ -0,0 +1,16 @@ +"MJRefreshHeaderIdleText" = "아래로 당겨 새로고침"; +"MJRefreshHeaderPullingText" = "놓으면 새로고침"; +"MJRefreshHeaderRefreshingText" = "로딩중..."; + +"MJRefreshAutoFooterIdleText" = "탭 또는 위로 당겨 로드함"; +"MJRefreshAutoFooterRefreshingText" = "로딩중..."; +"MJRefreshAutoFooterNoMoreDataText" = "더이상 데이터 없음"; + +"MJRefreshBackFooterIdleText" = "위로 당겨 더 로드 가능"; +"MJRefreshBackFooterPullingText" = "놓으면 더 로드됨."; +"MJRefreshBackFooterRefreshingText" = "로딩중..."; +"MJRefreshBackFooterNoMoreDataText" = "더이상 데이터 없음"; + +"MJRefreshHeaderLastTimeText" = "마지막 업데이트: "; +"MJRefreshHeaderDateTodayText" = "오늘"; +"MJRefreshHeaderNoneLastDateText" = "기록 없음"; diff --git a/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/ru.lproj/Localizable.strings b/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/ru.lproj/Localizable.strings new file mode 100644 index 0000000..7890e7b Binary files /dev/null and b/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/ru.lproj/Localizable.strings differ diff --git a/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/trail_arrow@2x.png b/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/trail_arrow@2x.png new file mode 100644 index 0000000..a45f933 Binary files /dev/null and b/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/trail_arrow@2x.png differ diff --git a/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/uk.lproj/Localizable.strings b/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/uk.lproj/Localizable.strings new file mode 100644 index 0000000..3557940 Binary files /dev/null and b/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/uk.lproj/Localizable.strings differ diff --git a/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/zh-Hans.lproj/Localizable.strings b/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/zh-Hans.lproj/Localizable.strings new file mode 100644 index 0000000..1066e3d Binary files /dev/null and b/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/zh-Hans.lproj/Localizable.strings differ diff --git a/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/zh-Hant.lproj/Localizable.strings b/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/zh-Hant.lproj/Localizable.strings new file mode 100644 index 0000000..17417b5 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/MJRefresh.bundle/zh-Hant.lproj/Localizable.strings @@ -0,0 +1,19 @@ +"MJRefreshHeaderIdleText" = "下拉可以刷新"; +"MJRefreshHeaderPullingText" = "鬆開立即刷新"; +"MJRefreshHeaderRefreshingText" = "正在刷新數據中..."; + +"MJRefreshTrailerIdleText" = "滑動查看圖文詳情"; +"MJRefreshTrailerPullingText" = "釋放查看圖文詳情"; + +"MJRefreshAutoFooterIdleText" = "點擊或上拉加載更多"; +"MJRefreshAutoFooterRefreshingText" = "正在加載更多的數據..."; +"MJRefreshAutoFooterNoMoreDataText" = "已經全部加載完畢"; + +"MJRefreshBackFooterIdleText" = "上拉可以加載更多"; +"MJRefreshBackFooterPullingText" = "鬆開立即加載更多"; +"MJRefreshBackFooterRefreshingText" = "正在加載更多的數據..."; +"MJRefreshBackFooterNoMoreDataText" = "已經全部加載完畢"; + +"MJRefreshHeaderLastTimeText" = "最後更新:"; +"MJRefreshHeaderDateTodayText" = "今天"; +"MJRefreshHeaderNoneLastDateText" = "無記錄"; diff --git a/Pods/MJRefresh/MJRefresh/MJRefresh.h b/Pods/MJRefresh/MJRefresh/MJRefresh.h new file mode 100644 index 0000000..d878212 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/MJRefresh.h @@ -0,0 +1,42 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh + +#import + +#if __has_include() +FOUNDATION_EXPORT double MJRefreshVersionNumber; +FOUNDATION_EXPORT const unsigned char MJRefreshVersionString[]; + +#import +#import +#import + +#import +#import + +#import +#import +#import +#import + +#import +#import +#import +#import +#else +#import "UIScrollView+MJRefresh.h" +#import "UIScrollView+MJExtension.h" +#import "UIView+MJExtension.h" + +#import "MJRefreshNormalHeader.h" +#import "MJRefreshGifHeader.h" + +#import "MJRefreshBackNormalFooter.h" +#import "MJRefreshBackGifFooter.h" +#import "MJRefreshAutoNormalFooter.h" +#import "MJRefreshAutoGifFooter.h" + +#import "MJRefreshNormalTrailer.h" +#import "MJRefreshConfig.h" +#import "NSBundle+MJRefresh.h" +#import "MJRefreshConst.h" +#endif diff --git a/Pods/MJRefresh/MJRefresh/MJRefreshConfig.h b/Pods/MJRefresh/MJRefresh/MJRefreshConfig.h new file mode 100644 index 0000000..b2c808f --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/MJRefreshConfig.h @@ -0,0 +1,36 @@ +// +// MJRefreshConfig.h +// +// Created by Frank on 2018/11/27. +// Copyright © 2018 小码哥. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MJRefreshConfig : NSObject + +/** 默认使用的语言版本, 默认为 nil. 将随系统的语言自动改变 */ +@property (copy, nonatomic, nullable) NSString *languageCode; + +/** 默认使用的语言资源文件名, 默认为 nil, 即默认的 Localizable.strings. + + - Attention: 文件名不包含后缀.strings + */ +@property (copy, nonatomic, nullable) NSString *i18nFilename; +/** i18n 多语言资源加载自定义 Bundle. + + - Attention: 默认为 nil 采用内置逻辑. 这里设置后将忽略内置逻辑的多语言模式, 采用自定义的多语言 bundle + */ +@property (nonatomic, nullable) NSBundle *i18nBundle; + +/** Singleton Config instance */ +@property (class, nonatomic, readonly) MJRefreshConfig *defaultConfig; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/MJRefreshConfig.m b/Pods/MJRefresh/MJRefresh/MJRefreshConfig.m new file mode 100644 index 0000000..680b95a --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/MJRefreshConfig.m @@ -0,0 +1,42 @@ +// +// MJRefreshConfig.m +// +// Created by Frank on 2018/11/27. +// Copyright © 2018 小码哥. All rights reserved. +// + +#import "MJRefreshConfig.h" +#import "MJRefreshConst.h" +#import "NSBundle+MJRefresh.h" + +@interface MJRefreshConfig (Bundle) + ++ (void)resetLanguageResourceCache; + +@end + +@implementation MJRefreshConfig + +static MJRefreshConfig *mj_RefreshConfig = nil; + ++ (instancetype)defaultConfig { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + mj_RefreshConfig = [[self alloc] init]; + }); + return mj_RefreshConfig; +} + +- (void)setLanguageCode:(NSString *)languageCode { + if ([languageCode isEqualToString:_languageCode]) { + return; + } + + _languageCode = languageCode; + // 重置语言资源 + [MJRefreshConfig resetLanguageResourceCache]; + [NSNotificationCenter.defaultCenter + postNotificationName:MJRefreshDidChangeLanguageNotification object:self]; +} + +@end diff --git a/Pods/MJRefresh/MJRefresh/MJRefreshConst.h b/Pods/MJRefresh/MJRefresh/MJRefreshConst.h new file mode 100644 index 0000000..6881115 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/MJRefreshConst.h @@ -0,0 +1,115 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +#import +#import +#import + +// 弱引用 +#define MJWeakSelf __weak typeof(self) weakSelf = self; + +// 日志输出 +#ifdef DEBUG +#define MJRefreshLog(...) NSLog(__VA_ARGS__) +#else +#define MJRefreshLog(...) +#endif + +// 过期提醒 +#define MJRefreshDeprecated(DESCRIPTION) __attribute__((deprecated(DESCRIPTION))) + +// 运行时objc_msgSend +#define MJRefreshMsgSend(...) ((void (*)(void *, SEL, UIView *))objc_msgSend)(__VA_ARGS__) +#define MJRefreshMsgTarget(target) (__bridge void *)(target) + +// RGB颜色 +#define MJRefreshColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0] + +// 文字颜色 +#define MJRefreshLabelTextColor MJRefreshColor(90, 90, 90) + +// 字体大小 +#define MJRefreshLabelFont [UIFont boldSystemFontOfSize:14] + +// 常量 +UIKIT_EXTERN const CGFloat MJRefreshLabelLeftInset; +UIKIT_EXTERN const CGFloat MJRefreshHeaderHeight; +UIKIT_EXTERN const CGFloat MJRefreshFooterHeight; +UIKIT_EXTERN const CGFloat MJRefreshTrailWidth; +UIKIT_EXTERN const CGFloat MJRefreshFastAnimationDuration; +UIKIT_EXTERN const CGFloat MJRefreshSlowAnimationDuration; + + +UIKIT_EXTERN NSString *const MJRefreshKeyPathContentOffset; +UIKIT_EXTERN NSString *const MJRefreshKeyPathContentSize; +UIKIT_EXTERN NSString *const MJRefreshKeyPathContentInset; +UIKIT_EXTERN NSString *const MJRefreshKeyPathPanState; + +UIKIT_EXTERN NSString *const MJRefreshHeaderLastUpdatedTimeKey; + +UIKIT_EXTERN NSString *const MJRefreshHeaderIdleText; +UIKIT_EXTERN NSString *const MJRefreshHeaderPullingText; +UIKIT_EXTERN NSString *const MJRefreshHeaderRefreshingText; + +UIKIT_EXTERN NSString *const MJRefreshTrailerIdleText; +UIKIT_EXTERN NSString *const MJRefreshTrailerPullingText; + +UIKIT_EXTERN NSString *const MJRefreshAutoFooterIdleText; +UIKIT_EXTERN NSString *const MJRefreshAutoFooterRefreshingText; +UIKIT_EXTERN NSString *const MJRefreshAutoFooterNoMoreDataText; + +UIKIT_EXTERN NSString *const MJRefreshBackFooterIdleText; +UIKIT_EXTERN NSString *const MJRefreshBackFooterPullingText; +UIKIT_EXTERN NSString *const MJRefreshBackFooterRefreshingText; +UIKIT_EXTERN NSString *const MJRefreshBackFooterNoMoreDataText; + +UIKIT_EXTERN NSString *const MJRefreshHeaderLastTimeText; +UIKIT_EXTERN NSString *const MJRefreshHeaderDateTodayText; +UIKIT_EXTERN NSString *const MJRefreshHeaderNoneLastDateText; + +UIKIT_EXTERN NSString *const MJRefreshDidChangeLanguageNotification; + +// 状态检查 +#define MJRefreshCheckState \ +MJRefreshState oldState = self.state; \ +if (state == oldState) return; \ +[super setState:state]; + +// 异步主线程执行,不强持有Self +#define MJRefreshDispatchAsyncOnMainQueue(x) \ +__weak typeof(self) weakSelf = self; \ +dispatch_async(dispatch_get_main_queue(), ^{ \ +typeof(weakSelf) self = weakSelf; \ +{x} \ +}); + +/// 替换方法实现 +/// @param _fromClass 源类 +/// @param _originSelector 源类的 Selector +/// @param _toClass 目标类 +/// @param _newSelector 目标类的 Selector +CG_INLINE BOOL MJRefreshExchangeImplementations( + Class _fromClass, SEL _originSelector, + Class _toClass, SEL _newSelector) { + if (!_fromClass || !_toClass) { + return NO; + } + + Method oriMethod = class_getInstanceMethod(_fromClass, _originSelector); + Method newMethod = class_getInstanceMethod(_toClass, _newSelector); + if (!newMethod) { + return NO; + } + + BOOL isAddedMethod = class_addMethod(_fromClass, _originSelector, + method_getImplementation(newMethod), + method_getTypeEncoding(newMethod)); + if (isAddedMethod) { + // 如果 class_addMethod 成功了,说明之前 fromClass 里并不存在 originSelector,所以要用一个空的方法代替它,以避免 class_replaceMethod 后,后续 toClass 的这个方法被调用时可能会 crash + IMP emptyIMP = imp_implementationWithBlock(^(id selfObject) {}); + IMP oriMethodIMP = method_getImplementation(oriMethod) ?: emptyIMP; + const char *oriMethodTypeEncoding = method_getTypeEncoding(oriMethod) ?: "v@:"; + class_replaceMethod(_toClass, _newSelector, oriMethodIMP, oriMethodTypeEncoding); + } else { + method_exchangeImplementations(oriMethod, newMethod); + } + return YES; +} diff --git a/Pods/MJRefresh/MJRefresh/MJRefreshConst.m b/Pods/MJRefresh/MJRefresh/MJRefreshConst.m new file mode 100644 index 0000000..704d4c7 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/MJRefreshConst.m @@ -0,0 +1,39 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +#import + +const CGFloat MJRefreshLabelLeftInset = 25; +const CGFloat MJRefreshHeaderHeight = 54.0; +const CGFloat MJRefreshFooterHeight = 44.0; +const CGFloat MJRefreshTrailWidth = 60.0; +const CGFloat MJRefreshFastAnimationDuration = 0.25; +const CGFloat MJRefreshSlowAnimationDuration = 0.4; + + +NSString *const MJRefreshKeyPathContentOffset = @"contentOffset"; +NSString *const MJRefreshKeyPathContentInset = @"contentInset"; +NSString *const MJRefreshKeyPathContentSize = @"contentSize"; +NSString *const MJRefreshKeyPathPanState = @"state"; + +NSString *const MJRefreshHeaderLastUpdatedTimeKey = @"MJRefreshHeaderLastUpdatedTimeKey"; + +NSString *const MJRefreshHeaderIdleText = @"MJRefreshHeaderIdleText"; +NSString *const MJRefreshHeaderPullingText = @"MJRefreshHeaderPullingText"; +NSString *const MJRefreshHeaderRefreshingText = @"MJRefreshHeaderRefreshingText"; + +NSString *const MJRefreshTrailerIdleText = @"MJRefreshTrailerIdleText"; +NSString *const MJRefreshTrailerPullingText = @"MJRefreshTrailerPullingText"; + +NSString *const MJRefreshAutoFooterIdleText = @"MJRefreshAutoFooterIdleText"; +NSString *const MJRefreshAutoFooterRefreshingText = @"MJRefreshAutoFooterRefreshingText"; +NSString *const MJRefreshAutoFooterNoMoreDataText = @"MJRefreshAutoFooterNoMoreDataText"; + +NSString *const MJRefreshBackFooterIdleText = @"MJRefreshBackFooterIdleText"; +NSString *const MJRefreshBackFooterPullingText = @"MJRefreshBackFooterPullingText"; +NSString *const MJRefreshBackFooterRefreshingText = @"MJRefreshBackFooterRefreshingText"; +NSString *const MJRefreshBackFooterNoMoreDataText = @"MJRefreshBackFooterNoMoreDataText"; + +NSString *const MJRefreshHeaderLastTimeText = @"MJRefreshHeaderLastTimeText"; +NSString *const MJRefreshHeaderDateTodayText = @"MJRefreshHeaderDateTodayText"; +NSString *const MJRefreshHeaderNoneLastDateText = @"MJRefreshHeaderNoneLastDateText"; + +NSString *const MJRefreshDidChangeLanguageNotification = @"MJRefreshDidChangeLanguageNotification"; diff --git a/Pods/MJRefresh/MJRefresh/NSBundle+MJRefresh.h b/Pods/MJRefresh/MJRefresh/NSBundle+MJRefresh.h new file mode 100644 index 0000000..a1f56f4 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/NSBundle+MJRefresh.h @@ -0,0 +1,21 @@ +// +// NSBundle+MJRefresh.h +// MJRefresh +// +// Created by MJ Lee on 16/6/13. +// Copyright © 2016年 小码哥. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSBundle (MJRefresh) ++ (instancetype)mj_refreshBundle; ++ (UIImage *)mj_arrowImage; ++ (UIImage *)mj_trailArrowImage; ++ (NSString *)mj_localizedStringForKey:(NSString *)key value:(nullable NSString *)value; ++ (NSString *)mj_localizedStringForKey:(NSString *)key; +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/NSBundle+MJRefresh.m b/Pods/MJRefresh/MJRefresh/NSBundle+MJRefresh.m new file mode 100644 index 0000000..c19cbe8 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/NSBundle+MJRefresh.m @@ -0,0 +1,116 @@ +// +// NSBundle+MJRefresh.m +// MJRefresh +// +// Created by MJ Lee on 16/6/13. +// Copyright © 2016年 小码哥. All rights reserved. +// + +#import "NSBundle+MJRefresh.h" +#import "MJRefreshComponent.h" +#import "MJRefreshConfig.h" + +static NSBundle *mj_defaultI18nBundle = nil; +static NSBundle *mj_systemI18nBundle = nil; + +@implementation NSBundle (MJRefresh) ++ (instancetype)mj_refreshBundle +{ + static NSBundle *refreshBundle = nil; + if (refreshBundle == nil) { +#ifdef SWIFT_PACKAGE + NSBundle *containnerBundle = SWIFTPM_MODULE_BUNDLE; +#else + NSBundle *containnerBundle = [NSBundle bundleForClass:[MJRefreshComponent class]]; +#endif + refreshBundle = [NSBundle bundleWithPath:[containnerBundle pathForResource:@"MJRefresh" ofType:@"bundle"]]; + } + return refreshBundle; +} + ++ (UIImage *)mj_arrowImage +{ + static UIImage *arrowImage = nil; + if (arrowImage == nil) { + arrowImage = [[UIImage imageWithContentsOfFile:[[self mj_refreshBundle] pathForResource:@"arrow@2x" ofType:@"png"]] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + } + return arrowImage; +} + ++ (UIImage *)mj_trailArrowImage { + static UIImage *arrowImage = nil; + if (arrowImage == nil) { + arrowImage = [[UIImage imageWithContentsOfFile:[[self mj_refreshBundle] pathForResource:@"trail_arrow@2x" ofType:@"png"]] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + } + return arrowImage; +} + ++ (NSString *)mj_localizedStringForKey:(NSString *)key +{ + return [self mj_localizedStringForKey:key value:nil]; +} + ++ (NSString *)mj_localizedStringForKey:(NSString *)key value:(NSString *)value +{ + NSString *table = MJRefreshConfig.defaultConfig.i18nFilename; + + // 如果没有缓存, 则走初始化逻辑 + if (mj_defaultI18nBundle == nil) { + NSString *language = MJRefreshConfig.defaultConfig.languageCode; + // 如果配置中没有配置语言 + if (!language) { + language = [NSLocale preferredLanguages].firstObject; + } + NSBundle *bundle = MJRefreshConfig.defaultConfig.i18nBundle; + // 首先优先使用公共配置中的 i18nBundle, 如果为空则使用 mainBundle + bundle = bundle ? bundle : NSBundle.mainBundle; + // 按语言选取语言包 + NSString *i18nFolderPath = [bundle pathForResource:language ofType:@"lproj"]; + mj_defaultI18nBundle = [NSBundle bundleWithPath:i18nFolderPath]; + // 检查语言包, 如果没有查找到, 则默认使用 mainBundle + mj_defaultI18nBundle = mj_defaultI18nBundle ? mj_defaultI18nBundle : NSBundle.mainBundle; + + // 获取 MJRefresh 自有的语言包 + if (mj_systemI18nBundle == nil) { + mj_systemI18nBundle = [self mj_defaultI18nBundleWithLanguage:language]; + } + } + // 首先在 MJRefresh 内置语言文件中寻找 + value = [mj_systemI18nBundle localizedStringForKey:key value:value table:nil]; + // 然后在 MainBundle 对应语言文件中寻找 + value = [mj_defaultI18nBundle localizedStringForKey:key value:value table:table]; + return value; +} + ++ (NSBundle *)mj_defaultI18nBundleWithLanguage:(NSString *)language { + if ([language hasPrefix:@"en"]) { + language = @"en"; + } else if ([language hasPrefix:@"zh"]) { + if ([language rangeOfString:@"Hans"].location != NSNotFound) { + language = @"zh-Hans"; // 简体中文 + } else { // zh-Hant\zh-HK\zh-TW + language = @"zh-Hant"; // 繁體中文 + } + } else if ([language hasPrefix:@"ko"]) { + language = @"ko"; + } else if ([language hasPrefix:@"ru"]) { + language = @"ru"; + } else if ([language hasPrefix:@"uk"]) { + language = @"uk"; + } else { + language = @"en"; + } + + // 从MJRefresh.bundle中查找资源 + return [NSBundle bundleWithPath:[[NSBundle mj_refreshBundle] pathForResource:language ofType:@"lproj"]]; +} +@end + +@implementation MJRefreshConfig (Bundle) + ++ (void)resetLanguageResourceCache { + mj_defaultI18nBundle = nil; + mj_systemI18nBundle = nil; +} + +@end diff --git a/Pods/MJRefresh/MJRefresh/PrivacyInfo.xcprivacy b/Pods/MJRefresh/MJRefresh/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..2d55cfe --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/PrivacyInfo.xcprivacy @@ -0,0 +1,23 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + CA92.1 + + + + NSPrivacyCollectedDataTypes + + + diff --git a/Pods/MJRefresh/MJRefresh/UICollectionViewLayout+MJRefresh.h b/Pods/MJRefresh/MJRefresh/UICollectionViewLayout+MJRefresh.h new file mode 100644 index 0000000..df0423d --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/UICollectionViewLayout+MJRefresh.h @@ -0,0 +1,20 @@ +// +// UICollectionViewLayout+MJRefresh.h +// +// 该类是用来解决 Footer 在底端加载完成后, 仍停留在原处的 bug. +// 此问题出现在 iOS 14 及以下系统上. +// Reference: https://github.com/CoderMJLee/MJRefresh/issues/1552 +// +// Created by jiasong on 2021/11/15. +// Copyright © 2021 小码哥. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface UICollectionViewLayout (MJRefresh) + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/UICollectionViewLayout+MJRefresh.m b/Pods/MJRefresh/MJRefresh/UICollectionViewLayout+MJRefresh.m new file mode 100644 index 0000000..00d030e --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/UICollectionViewLayout+MJRefresh.m @@ -0,0 +1,45 @@ +// +// UICollectionViewLayout+MJRefresh.m +// +// 该类是用来解决 Footer 在底端加载完成后, 仍停留在原处的 bug. +// 此问题出现在 iOS 14 及以下系统上. +// Reference: https://github.com/CoderMJLee/MJRefresh/issues/1552 +// +// Created by jiasong on 2021/11/15. +// Copyright © 2021 小码哥. All rights reserved. +// + +#import "UICollectionViewLayout+MJRefresh.h" +#import "MJRefreshConst.h" +#import "MJRefreshFooter.h" +#import "UIScrollView+MJRefresh.h" + +@implementation UICollectionViewLayout (MJRefresh) + ++ (void)load { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + MJRefreshExchangeImplementations(self.class, @selector(finalizeCollectionViewUpdates), + self.class, @selector(mj_finalizeCollectionViewUpdates)); + }); +} + +- (void)mj_finalizeCollectionViewUpdates { + [self mj_finalizeCollectionViewUpdates]; + + __kindof MJRefreshFooter *footer = self.collectionView.mj_footer; + CGSize newSize = self.collectionViewContentSize; + CGSize oldSize = self.collectionView.contentSize; + if (footer != nil && !CGSizeEqualToSize(newSize, oldSize)) { + NSDictionary *changed = @{ + NSKeyValueChangeNewKey: [NSValue valueWithCGSize:newSize], + NSKeyValueChangeOldKey: [NSValue valueWithCGSize:oldSize], + }; + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + [footer scrollViewContentSizeDidChange:changed]; + [CATransaction commit]; + } +} + +@end diff --git a/Pods/MJRefresh/MJRefresh/UIScrollView+MJExtension.h b/Pods/MJRefresh/MJRefresh/UIScrollView+MJExtension.h new file mode 100644 index 0000000..1b46d59 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/UIScrollView+MJExtension.h @@ -0,0 +1,28 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// UIScrollView+Extension.h +// MJRefresh +// +// Created by MJ Lee on 14-5-28. +// Copyright (c) 2014年 小码哥. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface UIScrollView (MJExtension) +@property (readonly, nonatomic) UIEdgeInsets mj_inset; + +@property (assign, nonatomic) CGFloat mj_insetT; +@property (assign, nonatomic) CGFloat mj_insetB; +@property (assign, nonatomic) CGFloat mj_insetL; +@property (assign, nonatomic) CGFloat mj_insetR; + +@property (assign, nonatomic) CGFloat mj_offsetX; +@property (assign, nonatomic) CGFloat mj_offsetY; + +@property (assign, nonatomic) CGFloat mj_contentW; +@property (assign, nonatomic) CGFloat mj_contentH; +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/UIScrollView+MJExtension.m b/Pods/MJRefresh/MJRefresh/UIScrollView+MJExtension.m new file mode 100644 index 0000000..1c43721 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/UIScrollView+MJExtension.m @@ -0,0 +1,153 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// UIScrollView+Extension.m +// MJRefresh +// +// Created by MJ Lee on 14-5-28. +// Copyright (c) 2014年 小码哥. All rights reserved. +// + +#import "UIScrollView+MJExtension.h" +#import + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability-new" + +@implementation UIScrollView (MJExtension) + +static BOOL respondsToAdjustedContentInset_; + ++ (void)load +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + respondsToAdjustedContentInset_ = [self instancesRespondToSelector:@selector(adjustedContentInset)]; + }); +} + +- (UIEdgeInsets)mj_inset +{ +#ifdef __IPHONE_11_0 + if (respondsToAdjustedContentInset_) { + return self.adjustedContentInset; + } +#endif + return self.contentInset; +} + +- (void)setMj_insetT:(CGFloat)mj_insetT +{ + UIEdgeInsets inset = self.contentInset; + inset.top = mj_insetT; +#ifdef __IPHONE_11_0 + if (respondsToAdjustedContentInset_) { + inset.top -= (self.adjustedContentInset.top - self.contentInset.top); + } +#endif + self.contentInset = inset; +} + +- (CGFloat)mj_insetT +{ + return self.mj_inset.top; +} + +- (void)setMj_insetB:(CGFloat)mj_insetB +{ + UIEdgeInsets inset = self.contentInset; + inset.bottom = mj_insetB; +#ifdef __IPHONE_11_0 + if (respondsToAdjustedContentInset_) { + inset.bottom -= (self.adjustedContentInset.bottom - self.contentInset.bottom); + } +#endif + self.contentInset = inset; +} + +- (CGFloat)mj_insetB +{ + return self.mj_inset.bottom; +} + +- (void)setMj_insetL:(CGFloat)mj_insetL +{ + UIEdgeInsets inset = self.contentInset; + inset.left = mj_insetL; +#ifdef __IPHONE_11_0 + if (respondsToAdjustedContentInset_) { + inset.left -= (self.adjustedContentInset.left - self.contentInset.left); + } +#endif + self.contentInset = inset; +} + +- (CGFloat)mj_insetL +{ + return self.mj_inset.left; +} + +- (void)setMj_insetR:(CGFloat)mj_insetR +{ + UIEdgeInsets inset = self.contentInset; + inset.right = mj_insetR; +#ifdef __IPHONE_11_0 + if (respondsToAdjustedContentInset_) { + inset.right -= (self.adjustedContentInset.right - self.contentInset.right); + } +#endif + self.contentInset = inset; +} + +- (CGFloat)mj_insetR +{ + return self.mj_inset.right; +} + +- (void)setMj_offsetX:(CGFloat)mj_offsetX +{ + CGPoint offset = self.contentOffset; + offset.x = mj_offsetX; + self.contentOffset = offset; +} + +- (CGFloat)mj_offsetX +{ + return self.contentOffset.x; +} + +- (void)setMj_offsetY:(CGFloat)mj_offsetY +{ + CGPoint offset = self.contentOffset; + offset.y = mj_offsetY; + self.contentOffset = offset; +} + +- (CGFloat)mj_offsetY +{ + return self.contentOffset.y; +} + +- (void)setMj_contentW:(CGFloat)mj_contentW +{ + CGSize size = self.contentSize; + size.width = mj_contentW; + self.contentSize = size; +} + +- (CGFloat)mj_contentW +{ + return self.contentSize.width; +} + +- (void)setMj_contentH:(CGFloat)mj_contentH +{ + CGSize size = self.contentSize; + size.height = mj_contentH; + self.contentSize = size; +} + +- (CGFloat)mj_contentH +{ + return self.contentSize.height; +} +@end +#pragma clang diagnostic pop diff --git a/Pods/MJRefresh/MJRefresh/UIScrollView+MJRefresh.h b/Pods/MJRefresh/MJRefresh/UIScrollView+MJRefresh.h new file mode 100644 index 0000000..8ce3282 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/UIScrollView+MJRefresh.h @@ -0,0 +1,36 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// UIScrollView+MJRefresh.h +// MJRefresh +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// 给ScrollView增加下拉刷新、上拉刷新、 左滑刷新的功能 + +#import +#if __has_include() +#import +#else +#import "MJRefreshConst.h" +#endif + +@class MJRefreshHeader, MJRefreshFooter, MJRefreshTrailer; + +NS_ASSUME_NONNULL_BEGIN + +@interface UIScrollView (MJRefresh) +/** 下拉刷新控件 */ +@property (strong, nonatomic, nullable) MJRefreshHeader *mj_header; +@property (strong, nonatomic, nullable) MJRefreshHeader *header MJRefreshDeprecated("使用mj_header"); +/** 上拉刷新控件 */ +@property (strong, nonatomic, nullable) MJRefreshFooter *mj_footer; +@property (strong, nonatomic, nullable) MJRefreshFooter *footer MJRefreshDeprecated("使用mj_footer"); + +/** 左滑刷新控件 */ +@property (strong, nonatomic, nullable) MJRefreshTrailer *mj_trailer; + +#pragma mark - other +- (NSInteger)mj_totalDataCount; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/UIScrollView+MJRefresh.m b/Pods/MJRefresh/MJRefresh/UIScrollView+MJRefresh.m new file mode 100644 index 0000000..3bb85da --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/UIScrollView+MJRefresh.m @@ -0,0 +1,120 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// UIScrollView+MJRefresh.m +// MJRefresh +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "UIScrollView+MJRefresh.h" +#import "MJRefreshHeader.h" +#import "MJRefreshFooter.h" +#import "MJRefreshTrailer.h" +#import + +@implementation UIScrollView (MJRefresh) + +#pragma mark - header +static const char MJRefreshHeaderKey = '\0'; +- (void)setMj_header:(MJRefreshHeader *)mj_header +{ + if (mj_header != self.mj_header) { + // 删除旧的,添加新的 + [self.mj_header removeFromSuperview]; + + if (mj_header) { + [self insertSubview:mj_header atIndex:0]; + } + // 存储新的 + objc_setAssociatedObject(self, &MJRefreshHeaderKey, + mj_header, OBJC_ASSOCIATION_RETAIN); + } +} + +- (MJRefreshHeader *)mj_header +{ + return objc_getAssociatedObject(self, &MJRefreshHeaderKey); +} + +#pragma mark - footer +static const char MJRefreshFooterKey = '\0'; +- (void)setMj_footer:(MJRefreshFooter *)mj_footer +{ + if (mj_footer != self.mj_footer) { + // 删除旧的,添加新的 + [self.mj_footer removeFromSuperview]; + if (mj_footer) { + [self insertSubview:mj_footer atIndex:0]; + } + // 存储新的 + objc_setAssociatedObject(self, &MJRefreshFooterKey, + mj_footer, OBJC_ASSOCIATION_RETAIN); + } +} + +- (MJRefreshFooter *)mj_footer +{ + return objc_getAssociatedObject(self, &MJRefreshFooterKey); +} + +#pragma mark - footer +static const char MJRefreshTrailerKey = '\0'; +- (void)setMj_trailer:(MJRefreshTrailer *)mj_trailer { + if (mj_trailer != self.mj_trailer) { + // 删除旧的,添加新的 + [self.mj_trailer removeFromSuperview]; + if (mj_trailer) { + [self insertSubview:mj_trailer atIndex:0]; + } + // 存储新的 + objc_setAssociatedObject(self, &MJRefreshTrailerKey, + mj_trailer, OBJC_ASSOCIATION_RETAIN); + } +} + +- (MJRefreshTrailer *)mj_trailer { + return objc_getAssociatedObject(self, &MJRefreshTrailerKey); +} + +#pragma mark - 过期 +- (void)setFooter:(MJRefreshFooter *)footer +{ + self.mj_footer = footer; +} + +- (MJRefreshFooter *)footer +{ + return self.mj_footer; +} + +- (void)setHeader:(MJRefreshHeader *)header +{ + self.mj_header = header; +} + +- (MJRefreshHeader *)header +{ + return self.mj_header; +} + +#pragma mark - other +- (NSInteger)mj_totalDataCount +{ + NSInteger totalCount = 0; + if ([self isKindOfClass:[UITableView class]]) { + UITableView *tableView = (UITableView *)self; + + for (NSInteger section = 0; section < tableView.numberOfSections; section++) { + totalCount += [tableView numberOfRowsInSection:section]; + } + } else if ([self isKindOfClass:[UICollectionView class]]) { + UICollectionView *collectionView = (UICollectionView *)self; + + for (NSInteger section = 0; section < collectionView.numberOfSections; section++) { + totalCount += [collectionView numberOfItemsInSection:section]; + } + } + return totalCount; +} + +@end diff --git a/Pods/MJRefresh/MJRefresh/UIView+MJExtension.h b/Pods/MJRefresh/MJRefresh/UIView+MJExtension.h new file mode 100644 index 0000000..0ac0968 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/UIView+MJExtension.h @@ -0,0 +1,22 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// UIView+Extension.h +// MJRefresh +// +// Created by MJ Lee on 14-5-28. +// Copyright (c) 2014年 小码哥. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface UIView (MJExtension) +@property (assign, nonatomic) CGFloat mj_x; +@property (assign, nonatomic) CGFloat mj_y; +@property (assign, nonatomic) CGFloat mj_w; +@property (assign, nonatomic) CGFloat mj_h; +@property (assign, nonatomic) CGSize mj_size; +@property (assign, nonatomic) CGPoint mj_origin; +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/MJRefresh/MJRefresh/UIView+MJExtension.m b/Pods/MJRefresh/MJRefresh/UIView+MJExtension.m new file mode 100644 index 0000000..f4dcf44 --- /dev/null +++ b/Pods/MJRefresh/MJRefresh/UIView+MJExtension.m @@ -0,0 +1,83 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// UIView+Extension.m +// MJRefresh +// +// Created by MJ Lee on 14-5-28. +// Copyright (c) 2014年 小码哥. All rights reserved. +// + +#import "UIView+MJExtension.h" + +@implementation UIView (MJExtension) +- (void)setMj_x:(CGFloat)mj_x +{ + CGRect frame = self.frame; + frame.origin.x = mj_x; + self.frame = frame; +} + +- (CGFloat)mj_x +{ + return self.frame.origin.x; +} + +- (void)setMj_y:(CGFloat)mj_y +{ + CGRect frame = self.frame; + frame.origin.y = mj_y; + self.frame = frame; +} + +- (CGFloat)mj_y +{ + return self.frame.origin.y; +} + +- (void)setMj_w:(CGFloat)mj_w +{ + CGRect frame = self.frame; + frame.size.width = mj_w; + self.frame = frame; +} + +- (CGFloat)mj_w +{ + return self.frame.size.width; +} + +- (void)setMj_h:(CGFloat)mj_h +{ + CGRect frame = self.frame; + frame.size.height = mj_h; + self.frame = frame; +} + +- (CGFloat)mj_h +{ + return self.frame.size.height; +} + +- (void)setMj_size:(CGSize)mj_size +{ + CGRect frame = self.frame; + frame.size = mj_size; + self.frame = frame; +} + +- (CGSize)mj_size +{ + return self.frame.size; +} + +- (void)setMj_origin:(CGPoint)mj_origin +{ + CGRect frame = self.frame; + frame.origin = mj_origin; + self.frame = frame; +} + +- (CGPoint)mj_origin +{ + return self.frame.origin; +} +@end diff --git a/Pods/MJRefresh/README.md b/Pods/MJRefresh/README.md new file mode 100644 index 0000000..0746fbe --- /dev/null +++ b/Pods/MJRefresh/README.md @@ -0,0 +1,457 @@ +## MJRefresh +[![SPM supported](https://img.shields.io/badge/SPM-supported-4BC51D.svg?style=flat)](https://github.com/apple/swift-package-manager) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) +[![podversion](https://img.shields.io/cocoapods/v/MJRefresh.svg)](https://cocoapods.org/pods/MJRefresh) + +* An easy way to use pull-to-refresh + +[📜✍🏻**Release Notes**: more details](https://github.com/CoderMJLee/MJRefresh/releases) + +## Contents + +- New Features + - [Dynamic i18n Switching](#dynamic_i18n_switching) + - [SPM Supported](#spm_supported) + - [Swift Chaining Grammar Supported](#swift_chaining_grammar_supported) + +* Getting Started + * [Features【Support what kinds of controls to refresh】](#Support_what_kinds_of_controls_to_refresh) + * [Installation【How to use MJRefresh】](#How_to_use_MJRefresh) + * [Who's using【More than hundreds of Apps are using MJRefresh】](#More_than_hundreds_of_Apps_are_using_MJRefresh) + * [Classes【The Class Structure Chart of MJRefresh】](#The_Class_Structure_Chart_of_MJRefresh) +* Comment API + * [MJRefreshComponent.h](#MJRefreshComponent.h) + * [MJRefreshHeader.h](#MJRefreshHeader.h) + * [MJRefreshFooter.h](#MJRefreshFooter.h) + * [MJRefreshAutoFooter.h](#MJRefreshAutoFooter.h) + * [MJRefreshTrailer.h](#MJRefreshTrailer.h) +* Examples + * [Reference](#Reference) + * [The drop-down refresh 01-Default](#The_drop-down_refresh_01-Default) + * [The drop-down refresh 02-Animation image](#The_drop-down_refresh_02-Animation_image) + * [The drop-down refresh 03-Hide the time](#The_drop-down_refresh_03-Hide_the_time) + * [The drop-down refresh 04-Hide status and time](#The_drop-down_refresh_04-Hide_status_and_time) + * [The drop-down refresh 05-DIY title](#The_drop-down_refresh_05-DIY_title) + * [The drop-down refresh 06-DIY the control of refresh](#The_drop-down_refresh_06-DIY_the_control_of_refresh) + * [The pull to refresh 01-Default](#The_pull_to_refresh_01-Default) + * [The pull to refresh 02-Animation image](#The_pull_to_refresh_02-Animation_image) + * [The pull to refresh 03-Hide the title of refresh status](#The_pull_to_refresh_03-Hide_the_title_of_refresh_status) + * [The pull to refresh 04-All loaded](#The_pull_to_refresh_04-All_loaded) + * [The pull to refresh 05-DIY title](#The_pull_to_refresh_05-DIY_title) + * [The pull to refresh 06-Hidden After loaded](#The_pull_to_refresh_06-Hidden_After_loaded) + * [The pull to refresh 07-Automatic back of the pull01](#The_pull_to_refresh_07-Automatic_back_of_the_pull01) + * [The pull to refresh 08-Automatic back of the pull02](#The_pull_to_refresh_08-Automatic_back_of_the_pull02) + * [The pull to refresh 09-DIY the control of refresh(Automatic refresh)](#The_pull_to_refresh_09-DIY_the_control_of_refresh(Automatic_refresh)) + * [The pull to refresh 10-DIY the control of refresh(Automatic back)](#The_pull_to_refresh_10-DIY_the_control_of_refresh(Automatic_back)) + * [UICollectionView01-The pull and drop-down refresh](#UICollectionView01-The_pull_and_drop-down_refresh) + * [UICollectionView02-The trailer refresh](#UICollectionView02-The_trailer_refresh) + * [WKWebView01-The drop-down refresh](#WKWebView01-The_drop-down_refresh) +* [Hope](#Hope) + +## New Features +### Dynamic i18n Switching + +Now `MJRefresh components` will be rerendered automatically with `MJRefreshConfig.default.language` setting. + +#### Example + +Go `i18n` folder and see lots of cases. Simulator example is behind `i18n tab` in right-top corner. + +#### Setting language + +```swift +MJRefreshConfig.default.language = "zh-hans" +``` + +#### Setting i18n file name + +```swift +MJRefreshConfig.default.i18nFilename = "i18n File Name(not include type<.strings>)" +``` + +#### Setting i18n language bundle + +```swift +MJRefreshConfig.default.i18nBundle = +``` + +#### Adopting the feature in your DIY component + +1. Just override `i18nDidChange` function and reset texts. + +```swift +// must use this localization methods +Bundle.mj_localizedString(forKey: "") +// or +Bundle.mj_localizedString(forKey: "", value:"") + +override func i18nDidChange() { + // Reset texts function + setupTexts() + // Make sure to call super after resetting texts. It will call placeSubViews for applying new layout. + super.i18nDidChange() +} +``` + +2. Receiving `MJRefreshDidChangeLanguageNotification` notification. + +### SPM Supported + +Released from [`3.7.1`](https://github.com/CoderMJLee/MJRefresh/releases/tag/3.7.1) + +### Swift Chaining Grammar Supported + +```swift + // Example as MJRefreshNormalHeader + func addRefreshHeader() { + MJRefreshNormalHeader { [weak self] in + // load some data + }.autoChangeTransparency(true) + .link(to: tableView) + } +``` + +## Support what kinds of controls to refresh + +* `UIScrollView`、`UITableView`、`UICollectionView`、`WKWebView` + +## How to use MJRefresh +* Installation with CocoaPods:`pod 'MJRefresh'` +* Installation with [Carthage](https://github.com/Carthage/Carthage):`github "CoderMJLee/MJRefresh"` +* Manual import: + * Drag All files in the `MJRefresh` folder to project + * Import the main file:`#import "MJRefresh.h"` + +```objc +Base Custom +MJRefresh.bundle MJRefresh.h +MJRefreshConst.h MJRefreshConst.m +UIScrollView+MJExtension.h UIScrollView+MJExtension.m +UIScrollView+MJRefresh.h UIScrollView+MJRefresh.m +UIView+MJExtension.h UIView+MJExtension.m +``` + +## More than hundreds of Apps are using MJRefresh + +* More information of App can focus on:[M了个J-博客园](http://www.cnblogs.com/mjios/p/4409853.html) + +## The Class Structure Chart of MJRefresh +![](http://images0.cnblogs.com/blog2015/497279/201506/132232456139177.png) +- `The class of red text` in the chart:You can use them directly + - The drop-down refresh control types + - Normal:`MJRefreshNormalHeader` + - Gif:`MJRefreshGifHeader` + - The pull to refresh control types + - Auto refresh + - Normal:`MJRefreshAutoNormalFooter` + - Gif:`MJRefreshAutoGifFooter` + - Auto Back + - Normal:`MJRefreshBackNormalFooter` + - Gif:`MJRefreshBackGifFooter` + +- `The class of non-red text` in the chart:For inheritance,to use DIY the control of refresh + +- About how to DIY the control of refresh,You can refer the Class in below Chart
+ + + +## MJRefreshComponent.h +```objc +/** The Base Class of refresh control */ +@interface MJRefreshComponent : UIView +#pragma mark - Control the state of Refresh + +/** BeginRefreshing */ +- (void)beginRefreshing; +/** EndRefreshing */ +- (void)endRefreshing; +/** IsRefreshing */ +- (BOOL)isRefreshing; + +#pragma mark - Other +/** According to the drag ratio to change alpha automatically */ +@property (assign, nonatomic, getter=isAutomaticallyChangeAlpha) BOOL automaticallyChangeAlpha; +@end +``` + +## MJRefreshHeader.h +```objc +@interface MJRefreshHeader : MJRefreshComponent +/** Creat header */ ++ (instancetype)headerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock; +/** Creat header */ ++ (instancetype)headerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; + +/** This key is used to storage the time that the last time of drown-down successfully */ +@property (copy, nonatomic) NSString *lastUpdatedTimeKey; +/** The last time of drown-down successfully */ +@property (strong, nonatomic, readonly) NSDate *lastUpdatedTime; + +/** Ignored scrollView contentInset top */ +@property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetTop; +@end +``` + +## MJRefreshFooter.h +```objc +@interface MJRefreshFooter : MJRefreshComponent +/** Creat footer */ ++ (instancetype)footerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock; +/** Creat footer */ ++ (instancetype)footerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; + +/** NoticeNoMoreData */ +- (void)noticeNoMoreData; +/** ResetNoMoreData(Clear the status of NoMoreData ) */ +- (void)resetNoMoreData; + +/** Ignored scrollView contentInset bottom */ +@property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetBottom; +@end +``` + +## MJRefreshAutoFooter.h +```objc +@interface MJRefreshAutoFooter : MJRefreshFooter +/** Is Automatically Refresh(Default is Yes) */ +@property (assign, nonatomic, getter=isAutomaticallyRefresh) BOOL automaticallyRefresh; + +/** When there is much at the bottom of the control is automatically refresh(Default is 1.0,Is at the bottom of the control appears in full, will refresh automatically) */ +@property (assign, nonatomic) CGFloat triggerAutomaticallyRefreshPercent; +@end +``` + +## MJRefreshTrailer.h +```objc +@interface MJRefreshTrailer : MJRefreshComponent + +/** 创建trailer */ ++ (instancetype)trailerWithRefreshingBlock:(MJRefreshComponentAction)refreshingBlock; +/** 创建trailer */ ++ (instancetype)trailerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; + +/** 忽略多少scrollView的contentInset的right */ +@property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetRight; + +@end +``` + +## Reference +```objc +* Due to there are more functions of this framework,Don't write specific text describe its usage +* You can directly reference examples MJTableViewController、MJCollectionViewController、MJWebViewController,More intuitive and fast. +``` + + +## The drop-down refresh 01-Default + +```objc +self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ + //Call this Block When enter the refresh status automatically +}]; +或 +// Set the callback(Once you enter the refresh status,then call the action of target,that is call [self loadNewData]) +self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; + +// Enter the refresh status immediately +[self.tableView.mj_header beginRefreshing]; +``` +![(下拉刷新01-普通)](http://images0.cnblogs.com/blog2015/497279/201506/141204343486151.gif) + +## The drop-down refresh 02-Animation image +```objc +// Set the callback(一Once you enter the refresh status,then call the action of target,that is call [self loadNewData]) +MJRefreshGifHeader *header = [MJRefreshGifHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; +// Set the ordinary state of animated images +[header setImages:idleImages forState:MJRefreshStateIdle]; +// Set the pulling state of animated images(Enter the status of refreshing as soon as loosen) +[header setImages:pullingImages forState:MJRefreshStatePulling]; +// Set the refreshing state of animated images +[header setImages:refreshingImages forState:MJRefreshStateRefreshing]; +// Set header +self.tableView.mj_header = header; +``` +![(下拉刷新02-动画图片)](http://images0.cnblogs.com/blog2015/497279/201506/141204402238389.gif) + +## The drop-down refresh 03-Hide the time +```objc +// Hide the time +header.lastUpdatedTimeLabel.hidden = YES; +``` +![(下拉刷新03-隐藏时间)](http://images0.cnblogs.com/blog2015/497279/201506/141204456132944.gif) + +## The drop-down refresh 04-Hide status and time +```objc +// Hide the time +header.lastUpdatedTimeLabel.hidden = YES; + +// Hide the status +header.stateLabel.hidden = YES; +``` +![(下拉刷新04-隐藏状态和时间0)](http://images0.cnblogs.com/blog2015/497279/201506/141204508639539.gif) + +## The drop-down refresh 05-DIY title +```objc +// Set title +[header setTitle:@"Pull down to refresh" forState:MJRefreshStateIdle]; +[header setTitle:@"Release to refresh" forState:MJRefreshStatePulling]; +[header setTitle:@"Loading ..." forState:MJRefreshStateRefreshing]; + +// Set font +header.stateLabel.font = [UIFont systemFontOfSize:15]; +header.lastUpdatedTimeLabel.font = [UIFont systemFontOfSize:14]; + +// Set textColor +header.stateLabel.textColor = [UIColor redColor]; +header.lastUpdatedTimeLabel.textColor = [UIColor blueColor]; +``` +![(下拉刷新05-自定义文字)](http://images0.cnblogs.com/blog2015/497279/201506/141204563633593.gif) + +## The drop-down refresh 06-DIY the control of refresh +```objc +self.tableView.mj_header = [MJDIYHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; +// Implementation reference to MJDIYHeader.h和MJDIYHeader.m +``` +![(下拉刷新06-自定义刷新控件)](http://images0.cnblogs.com/blog2015/497279/201506/141205019261159.gif) + +## The pull to refresh 01-Default +```objc +self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{ + //Call this Block When enter the refresh status automatically +}]; +或 +// Set the callback(Once you enter the refresh status,then call the action of target,that is call [self loadMoreData]) +self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; +``` +![(上拉刷新01-默认)](http://images0.cnblogs.com/blog2015/497279/201506/141205090047696.gif) + +## The pull to refresh 02-Animation image +```objc +// Set the callback(Once you enter the refresh status,then call the action of target,that is call [self loadMoreData]) +MJRefreshAutoGifFooter *footer = [MJRefreshAutoGifFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; + +// Set the refresh image +[footer setImages:refreshingImages forState:MJRefreshStateRefreshing]; + +// Set footer +self.tableView.mj_footer = footer; +``` +![(上拉刷新02-动画图片)](http://images0.cnblogs.com/blog2015/497279/201506/141205141445793.gif) + +## The pull to refresh 03-Hide the title of refresh status +```objc +// Hide the title of refresh status +footer.refreshingTitleHidden = YES; +// If does have not above method,then use footer.stateLabel.hidden = YES; +``` +![(上拉刷新03-隐藏刷新状态的文字)](http://images0.cnblogs.com/blog2015/497279/201506/141205200985774.gif) + +## The pull to refresh 04-All loaded +```objc +//Become the status of NoMoreData +[footer noticeNoMoreData]; +``` +![(上拉刷新04-全部加载完毕)](http://images0.cnblogs.com/blog2015/497279/201506/141205248634686.gif) + +## The pull to refresh 05-DIY title +```objc +// Set title +[footer setTitle:@"Click or drag up to refresh" forState:MJRefreshStateIdle]; +[footer setTitle:@"Loading more ..." forState:MJRefreshStateRefreshing]; +[footer setTitle:@"No more data" forState:MJRefreshStateNoMoreData]; + +// Set font +footer.stateLabel.font = [UIFont systemFontOfSize:17]; + +// Set textColor +footer.stateLabel.textColor = [UIColor blueColor]; +``` +![(上拉刷新05-自定义文字)](http://images0.cnblogs.com/blog2015/497279/201506/141205295511153.gif) + +## The pull to refresh 06-Hidden After loaded +```objc +//Hidden current control of the pull to refresh +self.tableView.mj_footer.hidden = YES; +``` +![(上拉刷新06-加载后隐藏)](http://images0.cnblogs.com/blog2015/497279/201506/141205343481821.gif) + +## The pull to refresh 07-Automatic back of the pull01 +```objc +self.tableView.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; +``` +![(上拉刷新07-自动回弹的上拉01)](http://images0.cnblogs.com/blog2015/497279/201506/141205392239231.gif) + +## The pull to refresh 08-Automatic back of the pull02 +```objc +MJRefreshBackGifFooter *footer = [MJRefreshBackGifFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; + +// Set the normal state of the animated image +[footer setImages:idleImages forState:MJRefreshStateIdle]; +// Set the pulling state of animated images(Enter the status of refreshing as soon as loosen) +[footer setImages:pullingImages forState:MJRefreshStatePulling]; +// Set the refreshing state of animated images +[footer setImages:refreshingImages forState:MJRefreshStateRefreshing]; + +// Set footer +self.tableView.mj_footer = footer; +``` +![(上拉刷新07-自动回弹的上拉02)](http://images0.cnblogs.com/blog2015/497279/201506/141205441443628.gif) + +## The pull to refresh 09-DIY the control of refresh(Automatic refresh) +```objc +self.tableView.mj_footer = [MJDIYAutoFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; +// Implementation reference to MJDIYAutoFooter.h和MJDIYAutoFooter.m +``` +![(上拉刷新09-自定义刷新控件(自动刷新))](http://images0.cnblogs.com/blog2015/497279/201506/141205500195866.gif) + +## The pull to refresh 10-DIY the control of refresh(Automatic back) +```objc +self.tableView.mj_footer = [MJDIYBackFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; +// Implementation reference to MJDIYBackFooter.h和MJDIYBackFooter.m +``` +![(上拉刷新10-自定义刷新控件(自动回弹))](http://images0.cnblogs.com/blog2015/497279/201506/141205560666819.gif) + +## UICollectionView01-The pull and drop-down refresh +```objc +// The drop-down refresh +self.collectionView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ + //Call this Block When enter the refresh status automatically +}]; + +// The pull to refresh +self.collectionView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{ + //Call this Block When enter the refresh status automatically +}]; +``` +![(UICollectionView01-上下拉刷新)](http://images0.cnblogs.com/blog2015/497279/201506/141206021603758.gif) + +## UICollectionView02-The trailer refresh +```objc +// The trailer refresh +self.collectionView.mj_trailer = [MJRefreshNormalTrailer trailerWithRefreshingBlock:^{ + //Call this Block When enter the refresh status automatically +}]; + +``` +![(UICollectionView02-左拉刷新)](Gif/trailer_refresh.gif) + +## WKWebView01-The drop-down refresh +```objc +//Add the control of The drop-down refresh +self.webView.scrollView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ + //Call this Block When enter the refresh status automatically +}]; +``` +![(UICollectionView01-上下拉刷新)](http://images0.cnblogs.com/blog2015/497279/201506/141206080514524.gif) + +## Remind +* ARC +* iOS>=9.0 +* iPhone \ iPad screen anyway + +## 寻求志同道合的小伙伴 + +- 因本人工作忙,没有太多时间去维护MJRefresh,在此向广大框架使用者说声:非常抱歉!😞 +- 现寻求志同道合的小伙伴一起维护此框架,有兴趣的小伙伴可以[发邮件](mailto:richermj123go@vip.qq.com)给我,非常感谢😊 +- 如果一切OK,我将开放框架维护权限(github、pod等) +- 目前已经找到3位小伙伴(^-^)V diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index e913de3..3302729 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -1,11 +1,14 @@ PODS: - Alamofire (5.9.1) - - IQKeyboardManagerSwift (6.5.13) + - IQKeyboardManagerSwift (6.5.16) - JXPagingView/Paging (2.1.3) - JXSegmentedView (1.3.3) - Kingfisher (7.11.0) - - SnapKit (5.6.0) - - SVProgressHUD (2.2.5) + - MJRefresh (3.7.9) + - SnapKit (5.7.1) + - SVProgressHUD (2.3.1): + - SVProgressHUD/Core (= 2.3.1) + - SVProgressHUD/Core (2.3.1) - SwiftDate (6.3.1) DEPENDENCIES: @@ -14,6 +17,7 @@ DEPENDENCIES: - JXPagingView/Paging - JXSegmentedView - Kingfisher + - MJRefresh - SnapKit - SVProgressHUD - SwiftDate @@ -25,20 +29,22 @@ SPEC REPOS: - JXPagingView - JXSegmentedView - Kingfisher + - MJRefresh - SnapKit - SVProgressHUD - SwiftDate SPEC CHECKSUMS: Alamofire: f36a35757af4587d8e4f4bfa223ad10be2422b8c - IQKeyboardManagerSwift: 69b5fb9960edff37263d45c44fd97427e1f8c22b + IQKeyboardManagerSwift: 12d89768845bb77b55cc092ecc2b1f9370f06b76 JXPagingView: afdd2e9af09c90160dd232b970d603cc6e7ddd0e JXSegmentedView: 651b60fcf705258ba9395edd53876dbd2853fb68 Kingfisher: b9c985d864d43515f404f1ef4a8ce7d802ace3ac - SnapKit: e01d52ebb8ddbc333eefe2132acf85c8227d9c25 - SVProgressHUD: 1428aafac632c1f86f62aa4243ec12008d7a51d6 + MJRefresh: ff9e531227924c84ce459338414550a05d2aea78 + SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a + SVProgressHUD: 4837c74bdfe2e51e8821c397825996a8d7de6e22 SwiftDate: 72d28954e8e1c6c1c0f917ccc8005e4f83c7d4b2 -PODFILE CHECKSUM: c0bbca53cdc7c53ea7a9dbc8d75b7ae964a1dbc2 +PODFILE CHECKSUM: ba88795291c32ea83d380e5384537ca7f5568cd7 COCOAPODS: 1.15.2 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index 82da0ab..0080b76 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -7,755 +7,908 @@ objects = { /* Begin PBXBuildFile section */ - 00A2749F46C967ED4725A32357E3FB1B /* ConstraintLayoutSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ECAA08258069FFA67EFC17C35C656B7 /* ConstraintLayoutSupport.swift */; }; - 018E14B621F0A041F5109C9B4028DAA7 /* JXSegmentedIndicatorGradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F9C80933FC230A20E8DB141B42D78B /* JXSegmentedIndicatorGradientView.swift */; }; - 0361F2B5CB823772710AB366D00D3F0E /* Formatter+Protocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28279C39A331FDBCCB4726BA6CC681C6 /* Formatter+Protocols.swift */; }; - 04637C70546B34F93C3A1D79C3F78B37 /* ConstraintDirectionalInsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14B2FD7F1C5BA01262CA8DA89FC19A86 /* ConstraintDirectionalInsetTarget.swift */; }; - 0493E66044259CA8F47711626563E29C /* RelativeFormatterLanguage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 684339D85749BA476348D011AAF940F8 /* RelativeFormatterLanguage.swift */; }; - 057C34276F1C858071F1372C68540A5E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 828F1C480D9959D94E2868CE1084677F /* CoreGraphics.framework */; }; - 0591132B5EA1BE4DDA268D8A9C3D0421 /* LayoutConstraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = E14C41F18595A29151A31E735A1B7692 /* LayoutConstraint.swift */; }; - 05B82D21BB4500108A38518E64D25A6E /* CPListItem+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = D60E4FF19874657631F19D84E77C0FCD /* CPListItem+Kingfisher.swift */; }; - 06E43B4751069B47B3BD4AFD936A57E3 /* ConstraintPriority.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51AAE5F7671D63A1A83A5E003572F18C /* ConstraintPriority.swift */; }; - 080B0A6E64DD22DBD5BF269AA6A556FB /* KFAnimatedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D27856B2E2A4B0DFBC9C847E272AF9E /* KFAnimatedImage.swift */; }; - 0833E66E7F19849322305D67777B77DB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4B8063291033C95A8B2A24FA2AD7A79 /* Foundation.framework */; }; - 08593ACC3F8955B57D3865FBE5940230 /* JXPagingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 086CE1250364E2AA597A5C1956BE37AB /* JXPagingView.swift */; }; - 09871A1E8CE997DD91E7ACE2A0A273BF /* Zones.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8480154D84F74BD3E0CB4C5D9AEA2A2A /* Zones.swift */; }; - 0B994CDC79B1AD3A7BE62490D27C60C8 /* ConstraintAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 773370F5C5F8C1A1ED9DA49D4CFA08B8 /* ConstraintAttributes.swift */; }; - 0CC41A7F3CDAAF90C1825DCF4FB71B9B /* DateRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1C800A89115F306E7099713F917565C /* DateRepresentable.swift */; }; - 0F1D68554CA1AC595168E8FB4E1A6E63 /* CachedResponseHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 007D1989958B519F880D7E7993017377 /* CachedResponseHandler.swift */; }; - 1102439674F0EB249240589D2607B9EF /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A7EBDEB55449170B0A5AA76B77186C0 /* Result.swift */; }; - 11F2B1DF419EC68AD10D2A1D1176B082 /* SwiftDate-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 17E2B3692AE65F40EC23C3140816F5E2 /* SwiftDate-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 12EC6890A8A59536867A18E8F83C8BB7 /* JXPagingView-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B75E4A5B88AB2E12901FD79392108078 /* JXPagingView-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1336E9B0D82E5DE4E4DA4DAD898489BC /* DateInRegion+Create.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A4F3875045D1DB4D796129111609B9D /* DateInRegion+Create.swift */; }; - 146999B1FCD6D467CC69DB8F6B0A4E79 /* IQKeyboardManagerSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F1211F5D08477CCC9FD2CE425EDC276 /* IQKeyboardManagerSwift-dummy.m */; }; - 15CC896E2126D6A47D03C01964D74776 /* JXSegmentedIndicatorGradientLineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4238031501C063D51EF5A23B8F8B99A1 /* JXSegmentedIndicatorGradientLineView.swift */; }; - 162B358A9CC48A414D6744BAF8562D93 /* JXSegmentedTitleDynamicConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4650F81AED57651885068C4F1EAA4836 /* JXSegmentedTitleDynamicConfiguration.swift */; }; - 183D8B3E057B885EA7DF9A8CDCCE9029 /* ConstraintMakerRelatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03CB6A229CF84BA1622B096CE234952C /* ConstraintMakerRelatable.swift */; }; - 1A56A2E0BE0367DDB6BE95E537D43314 /* Commons.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE12AE6B4D59FD7310447B92B7B2B83C /* Commons.swift */; }; - 1D325CFE11FE13A075C835E922BE1017 /* SVRadialGradientLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EE1A2A286DF3C313266DAA14C61273E /* SVRadialGradientLayer.m */; }; - 1F4A13FD6675FCFCD9C19DF350348899 /* SVProgressAnimatedView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ADE20627987FA4EA010036CDEE47000 /* SVProgressAnimatedView.m */; }; - 1FF54BA1EA87ACD81339325012E2537B /* JXSegmentedTitleGradientCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09203F4D31B935FBE7056B3EEBF52D09 /* JXSegmentedTitleGradientCell.swift */; }; - 220D6AC9B1B1EC8EFFB204F9C1EAC842 /* ConstraintMakerEditable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97B043B3414EEE6CE9FB38F6C8C4E938 /* ConstraintMakerEditable.swift */; }; - 222B9B50C37D319BBACE8E15B8A40348 /* JXSegmentedNumberDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEC77FF989202A953833F6020DC1B1B0 /* JXSegmentedNumberDataSource.swift */; }; - 22FAFA41450EC40132CF4B0EEE7E6788 /* ParameterEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4146F3303D77A54D70EFCE400FA4336 /* ParameterEncoder.swift */; }; - 23277D4B1F4E8335DDCAB69A2AD75C9F /* JXSegmentedTitleOrImageDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2470434CB358730731625103150715B2 /* JXSegmentedTitleOrImageDataSource.swift */; }; - 2480B116D9A738E79212C0E0DD41872D /* GIFAnimatedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD4404E7BA0E07C8EDABCE9734F9BBC9 /* GIFAnimatedImage.swift */; }; - 256558233B40ACA6818F143BBC5B8017 /* ConstraintViewDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FEB76C2B6C718226251B5CBDA7A3540 /* ConstraintViewDSL.swift */; }; - 25E88D4079655A5E49799B0B559DD42A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C07BEF0CE5DECC5BDCAC8625BF2FFA4B /* QuartzCore.framework */; }; - 26541C9BEC53081C7AD9BB9819D71B41 /* JXSegmentedNumberCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89DB2376678936DD230CBCCDD11F0A5B /* JXSegmentedNumberCell.swift */; }; - 274E0D56AEB27C391FC58EBED912F19A /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = C950C7B6D82094FBAA31EA39107D9934 /* Image.swift */; }; - 28212776FD42960CDE96CE78D98F5A43 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 02BF3CA1A4DE19EBC809FFFBC30556D9 /* PrivacyInfo.xcprivacy */; }; - 2887D1CB726611AE4AF5918318B36712 /* IQKeyboardManager+Toolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30EF94D6856E6C7203AF8C170322CB4A /* IQKeyboardManager+Toolbar.swift */; }; - 29378021941FBC3A89E5EC565110180C /* IQKeyboardManagerConstantsInternal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C3D488F6F9118C5795E86C32D405E5C /* IQKeyboardManagerConstantsInternal.swift */; }; - 2AE3EFDE302E34CF498E6A693ACC9D06 /* ImageDataProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE6F6DA791EBF42B686DEEAE637C154D /* ImageDataProcessor.swift */; }; - 2B1AAA73D9231A2A7BA89DD1FF01C273 /* JXSegmentedTitleImageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03AFFBAA3AD566778A561F1FB11DD0AE /* JXSegmentedTitleImageCell.swift */; }; - 2B230B24827053BA3E9DA0C78A796BC2 /* ResponseSerialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = F27DE7E6CC48EBD987659B78F5B0E68C /* ResponseSerialization.swift */; }; - 2B42D035AFF52D62722161A7772C6C08 /* HTTPHeaders.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA7CF9C41BA9CA940652D4EC49B99A2D /* HTTPHeaders.swift */; }; - 2C4C08BB733A2101D945E8C37256F78F /* UploadRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 067DAF837200693933CD063D222B31FC /* UploadRequest.swift */; }; - 2DD965DE434BE3B5A0C6EC1FC47AE81D /* String+Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FA988EC253BB0E37DA9DCBEE6C99E9E /* String+Parser.swift */; }; - 2E572B53624BB2ED444BC9747A9F1781 /* ImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88D9E5016D9005153DC1BF421EB97D45 /* ImageDownloader.swift */; }; - 2F1EF2B296BBE6BB2B25C16FE4454444 /* IQKeyboardManager+OrientationNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 410484E6026824E3DC6B14FC5E7A7F80 /* IQKeyboardManager+OrientationNotification.swift */; }; + 018E14B621F0A041F5109C9B4028DAA7 /* JXSegmentedIndicatorGradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 135384F59FC764376A1E1806D1B43835 /* JXSegmentedIndicatorGradientView.swift */; }; + 02298A4639A27A1808AA3188B7A566E9 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = E90BED91E412505AF7055D21B806502E /* PrivacyInfo.xcprivacy */; }; + 0335018FAC1AD7BC453F8F9A68CDABC4 /* SVProgressAnimatedView.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAB28B6A1A5AA4CC4A0EEB258D9DC57 /* SVProgressAnimatedView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0361F2B5CB823772710AB366D00D3F0E /* Formatter+Protocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EF651FECE01069367CDE0054F13249F /* Formatter+Protocols.swift */; }; + 0493E66044259CA8F47711626563E29C /* RelativeFormatterLanguage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 418EE8CAF2C7190F191FC7554EAE20D3 /* RelativeFormatterLanguage.swift */; }; + 05B82D21BB4500108A38518E64D25A6E /* CPListItem+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDCF0C8D768EFB2E7C6A48EB2256867E /* CPListItem+Kingfisher.swift */; }; + 07F83DE63FB5CC8015F48F7B9B800B6F /* IQPreviousNextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FF0E1D3C22D93C0C7B2C51A16E17913 /* IQPreviousNextView.swift */; }; + 07FD274BC01F578C7B37989F79350C1E /* IQToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AA5BD68BC8AE62D30B207A9A089DBE2 /* IQToolbar.swift */; }; + 080B0A6E64DD22DBD5BF269AA6A556FB /* KFAnimatedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D15BEF86A67CAF30B602BB5A260F77B /* KFAnimatedImage.swift */; }; + 081815B67871C182C0D337274DEDCE69 /* MJRefreshBackStateFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = E770B62A86FAE28308923E8266E15451 /* MJRefreshBackStateFooter.m */; }; + 08593ACC3F8955B57D3865FBE5940230 /* JXPagingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4C866B997568C25289AC4481D960976 /* JXPagingView.swift */; }; + 0874E6176184E3A1C3E8AB158AE5E98B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 828F1C480D9959D94E2868CE1084677F /* CoreGraphics.framework */; }; + 09871A1E8CE997DD91E7ACE2A0A273BF /* Zones.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55E9A15EC42E241A39E5CABDB5E0D428 /* Zones.swift */; }; + 0A5C290276F7453D9471E25BEA655842 /* ConstraintLayoutGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1384016DEBC0AD27C484B338B4FBEDB5 /* ConstraintLayoutGuide.swift */; }; + 0AD7A0DA8FF5880E3D8599062129AB12 /* ConstraintMakerEditable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F088EAD83DD6725075FBD8403594C429 /* ConstraintMakerEditable.swift */; }; + 0CC41A7F3CDAAF90C1825DCF4FB71B9B /* DateRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0917B962F89415FDAAA876040A72E83 /* DateRepresentable.swift */; }; + 0D665B6767B345D8C70D7E029A2A48D8 /* ConstraintViewDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CC5E0E6473324DB3F517B54470CBE6C /* ConstraintViewDSL.swift */; }; + 0DA9A9D2F8960818017E26DA480FA143 /* ConstraintLayoutGuideDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 482206CB35A8E05C272FA37C0A8BF762 /* ConstraintLayoutGuideDSL.swift */; }; + 0F1D68554CA1AC595168E8FB4E1A6E63 /* CachedResponseHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28BCEACC594F9EA2E10117D26B3DA759 /* CachedResponseHandler.swift */; }; + 0FBCA5C01FA487754C6D0B1690FC9CDA /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = F796615F5FF6E91238484B197D6CF227 /* PrivacyInfo.xcprivacy */; }; + 1093AAD9CB7394BDBDD0E287103515F6 /* MJRefreshNormalTrailer.h in Headers */ = {isa = PBXBuildFile; fileRef = D18ABD1C495B7F72F0284AAC613A93F2 /* MJRefreshNormalTrailer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1102439674F0EB249240589D2607B9EF /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF651BDF14D5A324318BC3F8C317F57A /* Result.swift */; }; + 11F2B1DF419EC68AD10D2A1D1176B082 /* SwiftDate-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 207F4383A0CAE6E946319D62026A82F0 /* SwiftDate-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 12EC6890A8A59536867A18E8F83C8BB7 /* JXPagingView-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EFEBDB3A2CB8EFD1E1BB0C882FC6500 /* JXPagingView-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1336E9B0D82E5DE4E4DA4DAD898489BC /* DateInRegion+Create.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C51E9357636F513F9828759A831069 /* DateInRegion+Create.swift */; }; + 13CC0CFB1C56F23BBC872801F983C1A3 /* ConstraintLayoutSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AFFBD2618F9F069B2DFFC4829E58831 /* ConstraintLayoutSupport.swift */; }; + 15CC896E2126D6A47D03C01964D74776 /* JXSegmentedIndicatorGradientLineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AC9CFB040D783BBBD3E787C142BFF2A /* JXSegmentedIndicatorGradientLineView.swift */; }; + 15F68E09ADCDB843B938C490059485BD /* ConstraintMakerRelatable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ABF6319E31E3E401B63195B3374007D /* ConstraintMakerRelatable+Extensions.swift */; }; + 162B358A9CC48A414D6744BAF8562D93 /* JXSegmentedTitleDynamicConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225AEBA0EC32A3D5A52ECA46DBBED7F3 /* JXSegmentedTitleDynamicConfiguration.swift */; }; + 16E5F9C7FE2C499D21F3E7AF1FFC2FA7 /* IQKeyboardManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2E886364CE3D1DE31930B53C67EFBEB /* IQKeyboardManager.swift */; }; + 170E0C2556FD00466C155473B428F792 /* MJRefreshBackFooter.h in Headers */ = {isa = PBXBuildFile; fileRef = D5A9B7775663040A8BD50618EDF84298 /* MJRefreshBackFooter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 172D6F4BDBFD921ABF3F4936747C7B5F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4B8063291033C95A8B2A24FA2AD7A79 /* Foundation.framework */; }; + 18B137C1708A9B9DC45BBB1ECF1CE4A8 /* MJRefreshHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 612886EAB1AE5139D8545245115B7EC8 /* MJRefreshHeader.m */; }; + 19C5CA44D4D4D5B711D33A73525D453F /* IQUIView+IQKeyboardToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC81E237B242F0601E0FC35F98708DC4 /* IQUIView+IQKeyboardToolbar.swift */; }; + 19FE9BC7F25FF5D48B6B2B3B520D4D47 /* SVProgressHUD.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C589304DE45B301793ACB48B3D74C25 /* SVProgressHUD.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1A39B80A5083C84CF22A0D9FBB27761E /* UICollectionViewLayout+MJRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DA3BDF290E39DAB4D1F114C808EB725 /* UICollectionViewLayout+MJRefresh.m */; }; + 1A56A2E0BE0367DDB6BE95E537D43314 /* Commons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E619DA6F3D601658833035BDA0E167C /* Commons.swift */; }; + 1AEABE21257723E2AEE836117F3A8B12 /* MJRefreshFooter.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A99AB9AED98C1B656C310507C966514 /* MJRefreshFooter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1B4B180E84924CF99663817A2AFFAA92 /* IQKeyboardManager+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = E17C586A0C27A8F810C609FC78419447 /* IQKeyboardManager+Debug.swift */; }; + 1E7E37C51375285EA22294CD2ADB3159 /* Debugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88C5C3FE92321767662E35C421964B3 /* Debugging.swift */; }; + 1FF54BA1EA87ACD81339325012E2537B /* JXSegmentedTitleGradientCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2820DA7141C1E36BCF6D4D5D96802EAF /* JXSegmentedTitleGradientCell.swift */; }; + 218C0927BB7605141B611529DD6F65B4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4B8063291033C95A8B2A24FA2AD7A79 /* Foundation.framework */; }; + 222B9B50C37D319BBACE8E15B8A40348 /* JXSegmentedNumberDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EC6A17326897FCD562597FF862EFB28 /* JXSegmentedNumberDataSource.swift */; }; + 22FAFA41450EC40132CF4B0EEE7E6788 /* ParameterEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AC28BE75055A99E1BD5B4B8D07E3C1B /* ParameterEncoder.swift */; }; + 23277D4B1F4E8335DDCAB69A2AD75C9F /* JXSegmentedTitleOrImageDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCD84A7AB4756552C1E55E266165ACA /* JXSegmentedTitleOrImageDataSource.swift */; }; + 23B1B9EA25E2C943FCE5EC6D4EE19D6A /* MJRefreshGifHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 70D291797444B210FC11B05604380747 /* MJRefreshGifHeader.m */; }; + 23EE2A5A9ADF9A6B9A3515CA85E382ED /* UIView+MJExtension.h in Headers */ = {isa = PBXBuildFile; fileRef = 810BB8FC42B516FF79349CC6C8C13E4C /* UIView+MJExtension.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 244119912087C6ECC078CB0E740833EB /* UIScrollView+MJRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = D38764AB52ACD239BAD933070283AA4F /* UIScrollView+MJRefresh.m */; }; + 2480B116D9A738E79212C0E0DD41872D /* GIFAnimatedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D394AD7BFA59E7271EC623CF17FBDD30 /* GIFAnimatedImage.swift */; }; + 26541C9BEC53081C7AD9BB9819D71B41 /* JXSegmentedNumberCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFFBC6D1E5E46588B6AAB4F0711B9D5E /* JXSegmentedNumberCell.swift */; }; + 274E0D56AEB27C391FC58EBED912F19A /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D613FC602AD1B3823E553095A17BB58 /* Image.swift */; }; + 279E3C4211663A097FFE575249B19BC3 /* SVProgressAnimatedView.m in Sources */ = {isa = PBXBuildFile; fileRef = BD1BE557E2AE4A84F2515EB14ABAF97B /* SVProgressAnimatedView.m */; }; + 2927AE446998C11370D49E4A2CFD17AC /* MJRefreshNormalHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F1162C00BCBB4CECFD5CA05ED5667F3 /* MJRefreshNormalHeader.m */; }; + 2AE3EFDE302E34CF498E6A693ACC9D06 /* ImageDataProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9B6DF66CC0D9538F8F45AB7F7F82FB3 /* ImageDataProcessor.swift */; }; + 2B1AAA73D9231A2A7BA89DD1FF01C273 /* JXSegmentedTitleImageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55914F40E7C5BD463245E2016A8906BC /* JXSegmentedTitleImageCell.swift */; }; + 2B230B24827053BA3E9DA0C78A796BC2 /* ResponseSerialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88F8FEC13A3A1DB04F7186FA15AE1CB /* ResponseSerialization.swift */; }; + 2B42D035AFF52D62722161A7772C6C08 /* HTTPHeaders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5699EE5AE55BF8C2FE30604FAED64A7C /* HTTPHeaders.swift */; }; + 2C1014EEE6B2404C98A9F7AA534B534C /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = C50C61572CB504F3A1B27F44B20F385F /* PrivacyInfo.xcprivacy */; }; + 2C4C08BB733A2101D945E8C37256F78F /* UploadRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B4EE5D13ED112C5C84DB3A6ADE8E7E0 /* UploadRequest.swift */; }; + 2C94C305900E95BDB9296A7EFCF3C940 /* MJRefreshConst.h in Headers */ = {isa = PBXBuildFile; fileRef = 03538AE63A9932FE6DD18C82468E190F /* MJRefreshConst.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2DD965DE434BE3B5A0C6EC1FC47AE81D /* String+Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DF245C6F43F9612AD56BC7D2ADB123 /* String+Parser.swift */; }; + 2E572B53624BB2ED444BC9747A9F1781 /* ImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA1E44B32910D0CD9054692D4F938398 /* ImageDownloader.swift */; }; + 2E84CD435150EDA1356EE23EAB3CE5E7 /* SVRadialGradientLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = F6D3AF216BBC3443539D5BAD7BE5DEDF /* SVRadialGradientLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3013EFF5D3DB5F626FB63C96A690082A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4B8063291033C95A8B2A24FA2AD7A79 /* Foundation.framework */; }; - 3031C92E9CB81AD378483755A4DA6F79 /* KingfisherManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4AA0EBFFFCAE79E4DD76DB28D399121 /* KingfisherManager.swift */; }; - 32AD6316A2024235B39F19FC97C0B6BF /* ImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05E103BDBB854A87B92514983DFE7F29 /* ImageDataProvider.swift */; }; - 32E0490E336AF2371589D77723F8AA69 /* IQKeyboardReturnKeyHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0805789482CC6182F98FE7236D8D83BE /* IQKeyboardReturnKeyHandler.swift */; }; - 34966E12C60EA5E3295F91618492D76C /* IQBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23C5673EA0CD0D48D9B6124BE63E96C3 /* IQBarButtonItem.swift */; }; - 360F2B06AC4C38F3994965AA69FF0AC7 /* Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3219E80F1D4ABFEBA0A158FD5D5F5591 /* Kingfisher.swift */; }; - 3660B4F629053ABC3C1DF69366770289 /* ConstraintConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EF8045540E68DD0F0CB57EA73DC4DE1 /* ConstraintConfig.swift */; }; - 36C78069A72BECAEB66B31FF794A09ED /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = A426DD55A10EB28F224B77DD61B2BF00 /* Request.swift */; }; - 37289CBB73D25EA3424BF2ADFBB898AC /* TimePeriodProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 169771C1499556CFFC8826DA446C2612 /* TimePeriodProtocol.swift */; }; - 37D302D5A81F84194396C4A7C871F1DA /* langs in Resources */ = {isa = PBXBuildFile; fileRef = 53A154F0773A1007FDE314D65058E654 /* langs */; }; - 38B9D58E94D9C1CECD7E381C64A2329D /* UILayoutSupport+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1BC0AA48F6B64CE90390DE5DBE67EFD /* UILayoutSupport+Extensions.swift */; }; - 39EAB37ED329E6CE7C691B9EAF731446 /* JXSegmentedDotDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C3F23EBC877B0289008C16C4981B784 /* JXSegmentedDotDataSource.swift */; }; - 3B573F7FAA3A12BA7BF2CC874A31DEAB /* DateInRegion+Components.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B17D99233F4B43D0CE24E0142AAA24A /* DateInRegion+Components.swift */; }; + 3031C92E9CB81AD378483755A4DA6F79 /* KingfisherManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8DAC31F0F6FE66D2C8AF5489F272CEA /* KingfisherManager.swift */; }; + 3035E05E0216ED11647680F9C2127B01 /* MJRefresh.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 84FCB0C95F94873F8D87374CE1ACA147 /* MJRefresh.bundle */; }; + 30DBC87A501715FE2328B9FF011F1BB9 /* MJRefreshStateHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 82CD43FF64DC36B945840368DAC1706E /* MJRefreshStateHeader.m */; }; + 32AD6316A2024235B39F19FC97C0B6BF /* ImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = C408D0CD682A652982659893260F5EA4 /* ImageDataProvider.swift */; }; + 3360B725B480679D59E44B812DD8D116 /* MJRefresh-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 82E922355D2129F96245BA8E4E5FFF67 /* MJRefresh-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 346855A32221981DE16BBB5C1E636BA4 /* MJRefreshAutoStateFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = BE8BB5A012C6C501F12A4876ABF49101 /* MJRefreshAutoStateFooter.m */; }; + 34DE07309F7BF7F614A480667602D079 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 832AF59B8B94B734BFA5598CF822D2E8 /* PrivacyInfo.xcprivacy */; }; + 360F2B06AC4C38F3994965AA69FF0AC7 /* Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83C7B6631D6A0479168A89D25B68A47C /* Kingfisher.swift */; }; + 36C78069A72BECAEB66B31FF794A09ED /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB8D6628308EE28230C57E4CE1063A31 /* Request.swift */; }; + 37289CBB73D25EA3424BF2ADFBB898AC /* TimePeriodProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513DEC141FDDFD1CDAA8ED56A66AF623 /* TimePeriodProtocol.swift */; }; + 373502D50A1B2266D86409E19EC46DDB /* IQTitleBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81D659C29A42861AC5A4EF3B9D26DC0B /* IQTitleBarButtonItem.swift */; }; + 37D302D5A81F84194396C4A7C871F1DA /* langs in Resources */ = {isa = PBXBuildFile; fileRef = B5819E5E132D7A725A5CF03163E7796D /* langs */; }; + 39EAB37ED329E6CE7C691B9EAF731446 /* JXSegmentedDotDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 344A8E805D9E365E5FDF94223860238E /* JXSegmentedDotDataSource.swift */; }; + 3B573F7FAA3A12BA7BF2CC874A31DEAB /* DateInRegion+Components.swift in Sources */ = {isa = PBXBuildFile; fileRef = E48EF69AA55D5B91B47D8C1EB4BA4691 /* DateInRegion+Components.swift */; }; 3B901DF82C6576019330391D0F470B31 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A2A128F3FAE37601751167FDC47182A /* CFNetwork.framework */; }; - 3BC51136C1F65D6962C6727889AA942E /* String+MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E756CE2D8BBBFBD61C705DCB85928FC /* String+MD5.swift */; }; - 3C425FEE22F5E6EE82500F6107EAE8F4 /* JXSegmentedIndicatorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE645C9DF881DC086EE8AD29F9834E09 /* JXSegmentedIndicatorProtocol.swift */; }; - 3DFF965F16137F3DA3AA3835B328EFB4 /* IQKeyboardManager+UITextFieldViewNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A05EFFD6130413819CBE3401EB499CF /* IQKeyboardManager+UITextFieldViewNotification.swift */; }; - 417EAFB7648F1C35B8F7ADC203A96315 /* JXSegmentedBaseItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79E5B2D4D893485EE03EBC446DCDC057 /* JXSegmentedBaseItemModel.swift */; }; - 419464E3F898FD98316E39355FF35B0C /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 86D63DBB9B2A913FBA9303BF4AEA2AFE /* PrivacyInfo.xcprivacy */; }; - 42B43A15ADA9F66F4E2AD66666943F26 /* SwiftDate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3D25104232F456441BF20779E54737 /* SwiftDate.swift */; }; - 42B6ACFCF650183030867CB3EF345E95 /* ConstraintMakerFinalizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FCAF7C1E0C7EF57EDC617DCE77194E5 /* ConstraintMakerFinalizable.swift */; }; - 4337931D8B8E3F3BA03C77C1B496BEAD /* HTTPMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B6B02E550BBA54CD9271600724D14D /* HTTPMethod.swift */; }; - 440C0830E1410552E2ED0A1647CC4209 /* JXPagingListRefreshView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24EC295179204A13C2E78DB844ABF4AC /* JXPagingListRefreshView.swift */; }; - 4413F602F8263A6E3EE93517916F2EDF /* SwiftDate-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 3B97DDE49382A64974F6385E6313AD53 /* SwiftDate-dummy.m */; }; - 45D1C5B966D0BE59EF67F8A839AED2F4 /* JXSegmentedViewTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD1A206A2C1CBD7E676E9B6169ECDF72 /* JXSegmentedViewTool.swift */; }; - 4653D1D4B40D19F203638552FC8CE1BB /* IQUITextFieldView+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2015AFD9107C9946CA35C41D72E9B5D /* IQUITextFieldView+Additions.swift */; }; - 47B7A22D43797E42FCDCD96028823BFF /* KFImageProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18E3BBCE92E077B287C988B88A527154 /* KFImageProtocol.swift */; }; - 4803DFE6BE7D9A926811385567288A8C /* TimePeriodGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AC2B39FA1F6CBF8CD4718489EA8F09E /* TimePeriodGroup.swift */; }; - 4AADD25AAE104D5F72CDC039E82D9BB6 /* RedirectHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F1F4699C3C4B6DC02C6B5A89D1AC4A /* RedirectHandler.swift */; }; - 4B6EA5410A2C492D91A141426FD81588 /* WKInterfaceImage+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5672FA74F6AF0085E780C6D735D8918B /* WKInterfaceImage+Kingfisher.swift */; }; - 4BAD99B7394E225CEDBF94B8100BCC7F /* ConstraintRelation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97840F079FDCC2C242D262A194809427 /* ConstraintRelation.swift */; }; - 4C1CC731DAB49793158DB4EA0982137C /* ImageBinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AC1EA3AB5460CAF71C28DE23506948D /* ImageBinder.swift */; }; - 4D77099177C62FCD622E0BB73237386E /* CacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C5BB459268D5535E82BA01CD4B7E5F2 /* CacheSerializer.swift */; }; - 4DA72FD7F1FB2C0449EDEF4B8A579807 /* ConstraintPriorityTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB180FDD1F9AAD170DE5179EBA67AFE2 /* ConstraintPriorityTarget.swift */; }; - 4DC032894868226AE220360BADB2C237 /* SVProgressHUD-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = E6052A6B485A84163CBF2D1FC6D30DB7 /* SVProgressHUD-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4F2F7AFD7C593DAE210F77E7F8BC2403 /* JXSegmentedIndicatorTriangleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF379AB14D224D349C2E17BAE5136840 /* JXSegmentedIndicatorTriangleView.swift */; }; + 3BC51136C1F65D6962C6727889AA942E /* String+MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7143F3A6986BF2AB2828E2DC37C9C09D /* String+MD5.swift */; }; + 3C425FEE22F5E6EE82500F6107EAE8F4 /* JXSegmentedIndicatorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89FE60E3816FD1A788423E90F6E28D8D /* JXSegmentedIndicatorProtocol.swift */; }; + 3DAFEDCDC5094007E329D71FE84FF704 /* SnapKit-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = A933F95E4E12D348E925A9E3B27750CB /* SnapKit-dummy.m */; }; + 417EAFB7648F1C35B8F7ADC203A96315 /* JXSegmentedBaseItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A207FA0764909F90D1FCCDE191F924 /* JXSegmentedBaseItemModel.swift */; }; + 41A536E6CE1C85116A756B710B2C660B /* IQKeyboardManagerConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A89AE3F00FA615DB614031B7510C78F /* IQKeyboardManagerConstants.swift */; }; + 42B43A15ADA9F66F4E2AD66666943F26 /* SwiftDate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B832310B3844FB85DE10E60B45F44A3 /* SwiftDate.swift */; }; + 4337931D8B8E3F3BA03C77C1B496BEAD /* HTTPMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D3E36D2866A136708CF5F602D268BD7 /* HTTPMethod.swift */; }; + 43ED71634C98518E6B0749001ED89C43 /* MJRefreshAutoNormalFooter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C5F4CF175A8588A2773B4AF89EA51EC /* MJRefreshAutoNormalFooter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 440C0830E1410552E2ED0A1647CC4209 /* JXPagingListRefreshView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89FA1854F15DFB5CA5EAC2BF88823143 /* JXPagingListRefreshView.swift */; }; + 4413F602F8263A6E3EE93517916F2EDF /* SwiftDate-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 43FF45102B67E91CC3D79928C2717E40 /* SwiftDate-dummy.m */; }; + 45131830DC22C22B4A21C4A54A147947 /* MJRefreshNormalTrailer.m in Sources */ = {isa = PBXBuildFile; fileRef = 280637DA318DC5D912D98194C6844751 /* MJRefreshNormalTrailer.m */; }; + 45D1C5B966D0BE59EF67F8A839AED2F4 /* JXSegmentedViewTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EB8A3AF649521A0ED645B8858FB4DDF /* JXSegmentedViewTool.swift */; }; + 47B7A22D43797E42FCDCD96028823BFF /* KFImageProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F79F3D31F68D650253E6399BB7549D1 /* KFImageProtocol.swift */; }; + 4803DFE6BE7D9A926811385567288A8C /* TimePeriodGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = F44F0D93CFD9BB7C99C0FFCD686FF4E3 /* TimePeriodGroup.swift */; }; + 48E83D4BC4A5C3542CB0560A1E82A2F4 /* MJRefresh.h in Headers */ = {isa = PBXBuildFile; fileRef = 1434E2DF42114AA07FFC65F0AF74B738 /* MJRefresh.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 498FFEC31A02476F4F719EF645AC1562 /* MJRefreshHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 8124055AC9E04813E53A3EE6EDD5E1DE /* MJRefreshHeader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4AADD25AAE104D5F72CDC039E82D9BB6 /* RedirectHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A78C7902D8016F72AC215D2E28422F6 /* RedirectHandler.swift */; }; + 4B6EA5410A2C492D91A141426FD81588 /* WKInterfaceImage+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2893522A05B1339D4388FD46FF52C52A /* WKInterfaceImage+Kingfisher.swift */; }; + 4C1CC731DAB49793158DB4EA0982137C /* ImageBinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE5DD88C594D20A1F18F99828A3FEB64 /* ImageBinder.swift */; }; + 4D77099177C62FCD622E0BB73237386E /* CacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 268D0497BC989AF2355C7E9712755278 /* CacheSerializer.swift */; }; + 4F2F7AFD7C593DAE210F77E7F8BC2403 /* JXSegmentedIndicatorTriangleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09B2FF8925A3677E79E08183E04491D1 /* JXSegmentedIndicatorTriangleView.swift */; }; 4F4B9DFA352D9958C7494D7BC24631D8 /* Alamofire-Alamofire in Resources */ = {isa = PBXBuildFile; fileRef = 085DBCE7DD98588B2ED103B1C1F36026 /* Alamofire-Alamofire */; }; - 4FE35DBCEE3E9B3AE786452DCCD1B66C /* JXSegmentedBaseDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 896D7A2849ACF34D2EA1166731A5D332 /* JXSegmentedBaseDataSource.swift */; }; - 5075DC82A63A9807DFC390B4CE8046CD /* Session.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF3E7152220EF9221D3638B93DAE5EAD /* Session.swift */; }; - 51E5E4EC9A8AF80C7BEAF1BBED48FCF3 /* IQPreviousNextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FBE965ECA32AF1AF759DCA0E41A904C /* IQPreviousNextView.swift */; }; - 52BCC3B2F8AE7F59556925DEC603C634 /* SVIndefiniteAnimatedView.m in Sources */ = {isa = PBXBuildFile; fileRef = 44E1D50EA152F2FA29542A017C52B34A /* SVIndefiniteAnimatedView.m */; }; - 52CA20D0D7072BA85F22361EAD5C41F6 /* IQKeyboardManager+Internal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 814DE9B814D4E171655394905E30304A /* IQKeyboardManager+Internal.swift */; }; - 530FC2CFAAF9C09C0B75CF5CF6DF0B65 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 905F41A1A4BC05366108CBB7D774CB63 /* Storage.swift */; }; - 5380454C48A12A6E376122ABD8096968 /* ConstraintDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0457F1A1D877D4B914DE716739D328E1 /* ConstraintDescription.swift */; }; - 539E9EED5FBF53E3ECF2652ECFA4A2FD /* MemoryStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20485D884C20E59FFC1CE9922C547D5 /* MemoryStorage.swift */; }; - 53BECA6AA55F80D63F104475EE6524CA /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C07BEF0CE5DECC5BDCAC8625BF2FFA4B /* QuartzCore.framework */; }; - 55E51F45F1E157D3B4942BA7252C277E /* ConstraintRelatableTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = C254E57BBEAA35B8CE7E6626A38511AF /* ConstraintRelatableTarget.swift */; }; - 56987A745C2D39979A167EBF45B8D073 /* JXPagingSmoothView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A27DAE3B348C14EA5A36CFA7BF8804 /* JXPagingSmoothView.swift */; }; - 56A72F6D13D930C4A2568F24DEA33C8D /* ConstraintLayoutSupportDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B7F7B98523171E533048422B5C3CDC /* ConstraintLayoutSupportDSL.swift */; }; - 56AC6DC6459AE47E7BC4AF06E5B148D2 /* ConstraintDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DFEF57B19765C495039E698F1C7679F /* ConstraintDSL.swift */; }; - 56E561C1A8960D630D418FF931D36FBA /* JXSegmentedTitleItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A76DF775AC63A1EDDD3E18D271B4C926 /* JXSegmentedTitleItemModel.swift */; }; - 571142A2747CD90165F631A8AE980A0A /* Alamofire-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 54D73AFB747FAE30C1BB44E19677DBDD /* Alamofire-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 574450219BF9DBA9113E31EBC80BAEF2 /* JXSegmentedTitleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A41FA1D67A369D0AF9F089B2E949C60E /* JXSegmentedTitleCell.swift */; }; - 578833D3ED755D5D1F1577005AEADBAE /* TimeStructures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00B510B9BAFAF4B6D74A60254B99F26E /* TimeStructures.swift */; }; - 5830C6260CA2B7CD6DC74054FB29CDD1 /* DownloadRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 706A08832B908FA228085663A3B07DB9 /* DownloadRequest.swift */; }; - 5896E7040BD3FBD6C57C9727F706407A /* GraphicsContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02B20B40A566E7F7A9D3CA9FD8FE353B /* GraphicsContext.swift */; }; - 58E936B1E7E42C0BFC119D428B70F1D8 /* Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F9310A68A7C4ADA421B3156B5403F7E /* Alamofire.swift */; }; - 5AD4E5B4118A1DC7D639F611044B4159 /* DataRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A662353E669242D628CA325F3A11119 /* DataRequest.swift */; }; - 5C041C0F3BBC8ED3017D03D1A00BFEDF /* DisplayLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AE736393524312D73608EA88A6743E6 /* DisplayLink.swift */; }; - 5D2F784CAC2EEE09B332245A61D3687D /* AssociatedValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45E2E40D8E912E8E28DCD35E76FA3425 /* AssociatedValues.swift */; }; - 5D36B99F3CAB1FC7337082D9581FECA6 /* Debugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 278F6659C16FB8FEFA7A2B0F4CCB19AC /* Debugging.swift */; }; - 5D90B0097BBDAB6B90F35314BBC37554 /* Date+Create.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6532F8DAD6AD80487996CDEC5B376D30 /* Date+Create.swift */; }; + 4F80144C5D33EFDAC14379838CF9720E /* MJRefreshBackFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 136FDCF413CE3C1DC00030DAFFF9A94F /* MJRefreshBackFooter.m */; }; + 4FE35DBCEE3E9B3AE786452DCCD1B66C /* JXSegmentedBaseDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 460F21D69A6B1F9493AACA08A2F865B9 /* JXSegmentedBaseDataSource.swift */; }; + 506C1EE2968687F178BB2DFA34D185CE /* IQKeyboardReturnKeyHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDCBF5F15899BDBF63D3CC736990E1A5 /* IQKeyboardReturnKeyHandler.swift */; }; + 5075DC82A63A9807DFC390B4CE8046CD /* Session.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A9A6B3FF123B6733156B839AB90A488 /* Session.swift */; }; + 50E4E24710A4C5A77BE6594A10DFE773 /* ConstraintMultiplierTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1294C0C419D6967DAAFC5C21609CAAAF /* ConstraintMultiplierTarget.swift */; }; + 514A19E702520E6E336D77E2615D17CF /* NSBundle+MJRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 76BE0C86A979CEA47E0B7AD2EE15D888 /* NSBundle+MJRefresh.m */; }; + 530FC2CFAAF9C09C0B75CF5CF6DF0B65 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 321C97AD92F4D32E4E33BB5B77FFE0FC /* Storage.swift */; }; + 539E9EED5FBF53E3ECF2652ECFA4A2FD /* MemoryStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BF75314341E15EAF5EC8A5095F2878D /* MemoryStorage.swift */; }; + 56987A745C2D39979A167EBF45B8D073 /* JXPagingSmoothView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 142F33BE61F0E752B876C5145BE8D812 /* JXPagingSmoothView.swift */; }; + 56CD198002D3D45274F6719725B983CF /* ConstraintOffsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65E17F9E27F1D47AFFD1AE176DFE1657 /* ConstraintOffsetTarget.swift */; }; + 56E561C1A8960D630D418FF931D36FBA /* JXSegmentedTitleItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBF28FA874E18F2693E3B035356382F0 /* JXSegmentedTitleItemModel.swift */; }; + 571142A2747CD90165F631A8AE980A0A /* Alamofire-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 56263B06F3EAEC382F6F91F1599D4E74 /* Alamofire-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 574450219BF9DBA9113E31EBC80BAEF2 /* JXSegmentedTitleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F86EAA1D247756258692097BEA95A21 /* JXSegmentedTitleCell.swift */; }; + 578833D3ED755D5D1F1577005AEADBAE /* TimeStructures.swift in Sources */ = {isa = PBXBuildFile; fileRef = C468581B4214846A9CA4FFED32F836D8 /* TimeStructures.swift */; }; + 5830C6260CA2B7CD6DC74054FB29CDD1 /* DownloadRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4316C38FD6E88F2FFBBB3BC6DF2C26FF /* DownloadRequest.swift */; }; + 5896E7040BD3FBD6C57C9727F706407A /* GraphicsContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F0A7FCD71890676CE08D3ADDB7CA7B4 /* GraphicsContext.swift */; }; + 58E936B1E7E42C0BFC119D428B70F1D8 /* Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5347F4D40BA296B41A792189CB1331E9 /* Alamofire.swift */; }; + 5AD4E5B4118A1DC7D639F611044B4159 /* DataRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6E279BCC1C2C3A2FA64E3E7F3FD5335 /* DataRequest.swift */; }; + 5C041C0F3BBC8ED3017D03D1A00BFEDF /* DisplayLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7694CB3A399B0E568F03F27D28868B95 /* DisplayLink.swift */; }; + 5D2F784CAC2EEE09B332245A61D3687D /* AssociatedValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475A4FB59CFB3BBA7FAC2F058F91F6E3 /* AssociatedValues.swift */; }; + 5D4490556ADDD36F5100CF5D9F68ABF9 /* Pods-MusicPlayer-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 1BBB6DE3AF0E150160FD2FA346CC6CD6 /* Pods-MusicPlayer-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5D90B0097BBDAB6B90F35314BBC37554 /* Date+Create.swift in Sources */ = {isa = PBXBuildFile; fileRef = 594D2794764B5796C8A422C4401A7E2F /* Date+Create.swift */; }; 5E858AD3F64F096EE17F34759F017DC3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1199E580C5F19AFD1010FE20258DADBD /* UIKit.framework */; }; - 5E977209B51A440181A31A4CA27CA677 /* ImageContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B710B049CD54BF711CB18566657FE6E /* ImageContext.swift */; }; - 5F52D18FE8736028A8FB4B4B61B49111 /* JXSegmentedView-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = BB4408CC7D50AB78010F283775082F2E /* JXSegmentedView-dummy.m */; }; - 5FE04B779A038EBDFE268D19297F0FA5 /* RelativeFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B60AE218D04ECB2F352996F87D62ABA4 /* RelativeFormatter.swift */; }; - 604D3C93C17978C23600EC415949AB64 /* ConstraintInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39F93B4F6F36C41FDDD2C63E96361841 /* ConstraintInsets.swift */; }; - 6084CC72921FA7260B8FA2A07F49AE96 /* JXSegmentedTitleAttributeItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C81299D08C14E0F9FD7DEF40D51B331F /* JXSegmentedTitleAttributeItemModel.swift */; }; - 60CD99E8F32FD54F599DECFB768863A0 /* JXSegmentedIndicatorImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3929FB15B816836DB3935DDE677205 /* JXSegmentedIndicatorImageView.swift */; }; - 611CEF7FF1EF9EA1BCEF6C73EEE3ACCF /* ConstraintLayoutGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9127C21D70BA07B74F31B569E2887C5F /* ConstraintLayoutGuide.swift */; }; - 612AE0ABB9BCD3AF0E1D29B4C063CA62 /* StringEncoding+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 149557C3AB89BD20814904E291880583 /* StringEncoding+Alamofire.swift */; }; - 6142372CEE4D251A94EA4BE2630F27E7 /* Date+Components.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3EE8956158B369D9D59C65C4D96EA3 /* Date+Components.swift */; }; - 62B187638CAD57515889A98D90ED3860 /* IQUIView+IQKeyboardToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 611229333DB8EA6474A5F49BD282ABF9 /* IQUIView+IQKeyboardToolbar.swift */; }; - 632239BD2DF58FF13D9E4D1C4327F528 /* JXSegmentedTitleDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E21BA4A95E9124E56A3ABDC946ED751 /* JXSegmentedTitleDataSource.swift */; }; - 638A729C295B6267093699D505B8589D /* KFImageRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B829BB92CE7C61E3EF4CAEA14D3264FE /* KFImageRenderer.swift */; }; - 6584A733B2610DAFBB1CEF8E90635EC9 /* TimePeriodCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A21A5D82E7614E60D1FBD7885945FCE /* TimePeriodCollection.swift */; }; - 65D2E717EEAEBB4658708CD9C8991C93 /* CallbackQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = F05B27A0A6364144E57B02027A6A91F2 /* CallbackQueue.swift */; }; - 65F1A046F742E910CE0EE30BE2600DDD /* JXSegmentedDotItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6744A18229EA48CA16F54DFC8F3C6A3C /* JXSegmentedDotItemModel.swift */; }; - 6628BE82C4F27A39F94CBEA02BB498EF /* DateInRegion+Compare.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0F9FC31B8F636F7E4D3A505B5FCEA48 /* DateInRegion+Compare.swift */; }; - 6654CDCA10823EA080976DF72D8729B2 /* AVAssetImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6E3FB0EAE53F7E9EEF4A4D9EB32372 /* AVAssetImageDataProvider.swift */; }; - 67942FD70EE19BA957045141036FD49E /* RequestModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BA376AE75DD6C89F006B5ABBAD1A00 /* RequestModifier.swift */; }; - 68238227D42B2511FA6A26BF71E92520 /* Alamofire-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C473B98F873BE78A2F86D02402284B3D /* Alamofire-dummy.m */; }; - 68241B77CB3EE81665BBB4275AC19679 /* JXSegmentedListContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E8F31E23CB0B4C162D0624DB465C98A /* JXSegmentedListContainerView.swift */; }; - 68995B28EE5B539CEA5A1133E4623927 /* MultipartFormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A8250492A7EB690EF84D025A6F171D /* MultipartFormData.swift */; }; - 68A74F13F8FEBAA7E0EA9344DED0458B /* OperationQueue+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EBA3469B966D049CF9C6584ADCE1420 /* OperationQueue+Alamofire.swift */; }; - 68DCF4550B3B72228D5D8B4E25A341F2 /* Box.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28FE2901B317396EE489A6D5CA08C3FA /* Box.swift */; }; - 69261B5D3B53EBF7109D5E1DA3768CAC /* AuthenticationInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8112989320F97673E4EB82A275CAE0C /* AuthenticationInterceptor.swift */; }; - 69DE75BA185BBAB5FDAA28321F3C849F /* ConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7347F615A018CDE56878D17CCECC138 /* ConstraintItem.swift */; }; - 6AC1B881BB319C89AD023A02CDC8FC3D /* ConstraintLayoutGuide+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD9B444681135CCF6E363CC0A67B6651 /* ConstraintLayoutGuide+Extensions.swift */; }; - 6C2A8D78B7E5B02974B212599B28AD77 /* Indicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B207E1FC13165182A34EDC2DB916D27 /* Indicator.swift */; }; - 6C4BCC8C2D31263360E2697776A9E80D /* JXSegmentedIndicatorBaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0C110EA1EFE725C53F87FB7D4FD59B7 /* JXSegmentedIndicatorBaseView.swift */; }; - 6CC7E7C00730B1BF42A28B2E23CA01D6 /* URLSessionConfiguration+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E59570FEEE578BB8DA85857824B7375 /* URLSessionConfiguration+Alamofire.swift */; }; - 6D1E33469FB8FBE812956B0076A7B28F /* SVRadialGradientLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25700C90519D6E5662DBD6E110F3AAB9 /* SVRadialGradientLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6E4DEB1A81739DE58C64997251DAA87C /* ISOFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 551F872E8F0FDAAED3407034F590B022 /* ISOFormatter.swift */; }; - 6EAC8B6FA2D115DE708A58C601DD25E1 /* Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C763B3088899119C0227AA4D0ECD4F7 /* Constraint.swift */; }; - 6F2E0DC7D8598283D088A989FDB8E5F6 /* ParameterEncoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCE24B18F4CDA56F48417247341E3F76 /* ParameterEncoding.swift */; }; - 7073BBB5FB012B196E1111C4EA4B0B90 /* IQKeyboardManagerSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F26DAEAF14BD22F7BA131A68C794F8E /* IQKeyboardManagerSwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 70B890CA221D229ABF2346A7245654C5 /* Int+DateComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F6B30053062472A32F7652BD0C4B138 /* Int+DateComponents.swift */; }; - 70DA8965F2816B1992A48342A90953BE /* IQNSArray+Sort.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC9A4AF661D951099E57AB12E84B84E0 /* IQNSArray+Sort.swift */; }; - 714D5F4F9165ED6BF3CFA9FEA7DB9FF5 /* Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12EAC48C11B1824841992EFCD031F4CF /* Placeholder.swift */; }; - 71655F70079826C7494ABF198F9F563A /* RelativeFormatter+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E17EC9F5615EFDD36A5372D376D7353 /* RelativeFormatter+Style.swift */; }; - 71B32D2CE27370DCC6032569FEE5C8DC /* Date+Math.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F1AFA1CC231FD02BDF99D7579908AC /* Date+Math.swift */; }; - 72C19C762FADC82517C344E9F47D7E50 /* AlamofireExtended.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1005A1E92368A5F7B5C869FAF2E1E7 /* AlamofireExtended.swift */; }; - 72D0CDE3B34D718422CFD4F85ADEFB04 /* RetryStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25037E4FB7BC7534B013D62B4131021F /* RetryStrategy.swift */; }; - 735B99CA4190FBE5FE23DA796402D447 /* DateInRegion.swift in Sources */ = {isa = PBXBuildFile; fileRef = E72A243B166894EB9748892B7E08CE91 /* DateInRegion.swift */; }; + 5E8E9469BF126E918EADF79EC4BB5CA2 /* IQUIView+Hierarchy.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9045FA6D60732F49E7765B398DDC46B /* IQUIView+Hierarchy.swift */; }; + 5E977209B51A440181A31A4CA27CA677 /* ImageContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = D061CC1A5FB61D63B44C75541D898A36 /* ImageContext.swift */; }; + 5F52D18FE8736028A8FB4B4B61B49111 /* JXSegmentedView-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 356BE641A77A6E56A217190DD89D8259 /* JXSegmentedView-dummy.m */; }; + 5FE04B779A038EBDFE268D19297F0FA5 /* RelativeFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 728D0FC1713F8BD85AD5D78DF7CC3E06 /* RelativeFormatter.swift */; }; + 6084CC72921FA7260B8FA2A07F49AE96 /* JXSegmentedTitleAttributeItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FDEAE488C153F23CC530F9FC7878CE4 /* JXSegmentedTitleAttributeItemModel.swift */; }; + 60CD99E8F32FD54F599DECFB768863A0 /* JXSegmentedIndicatorImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11E47356E556750015100B2119302E53 /* JXSegmentedIndicatorImageView.swift */; }; + 60CE1AC69D95F0F7C6637C601A84C069 /* MJRefresh-MJRefresh.Privacy in Resources */ = {isa = PBXBuildFile; fileRef = 7E3097CFEFDA621E9FB0E62009FF87FC /* MJRefresh-MJRefresh.Privacy */; }; + 612AE0ABB9BCD3AF0E1D29B4C063CA62 /* StringEncoding+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = E681F9A4BFBE0245493029CEB1B8A1C8 /* StringEncoding+Alamofire.swift */; }; + 6142372CEE4D251A94EA4BE2630F27E7 /* Date+Components.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14C0D566F3A17E2E2DBDE4098F711125 /* Date+Components.swift */; }; + 632239BD2DF58FF13D9E4D1C4327F528 /* JXSegmentedTitleDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = E652FB17C57B0AF0273621B2B037A0C7 /* JXSegmentedTitleDataSource.swift */; }; + 638A729C295B6267093699D505B8589D /* KFImageRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B43CFD3981B70FD7D609A5839B6A9218 /* KFImageRenderer.swift */; }; + 63BCE3414C785046BB317537B8120B5D /* MJRefreshAutoFooter.h in Headers */ = {isa = PBXBuildFile; fileRef = 94F9116CE6A49B5AFFA19B16D5346243 /* MJRefreshAutoFooter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6431218578A566C5EBF5FD166F164059 /* ConstraintMakerExtendable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EC53E7C517308EABC44AEFB75F5C064 /* ConstraintMakerExtendable.swift */; }; + 647D16586EBBE25158E3FD684541A1DD /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4B8063291033C95A8B2A24FA2AD7A79 /* Foundation.framework */; }; + 64B7C1BD8191B0963F3897F64977A7AA /* Pods-MusicPlayer-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 137651D4B8A2CAB9ADEE7E77FCB50B0C /* Pods-MusicPlayer-dummy.m */; }; + 6584A733B2610DAFBB1CEF8E90635EC9 /* TimePeriodCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AB27763B449AF051985734B3773B4ED /* TimePeriodCollection.swift */; }; + 65D2E717EEAEBB4658708CD9C8991C93 /* CallbackQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E1CCD164ECD3A398893DB0C3F224494 /* CallbackQueue.swift */; }; + 65F1A046F742E910CE0EE30BE2600DDD /* JXSegmentedDotItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CFAC3CD688A5BEB743550BA40C464FF /* JXSegmentedDotItemModel.swift */; }; + 6628BE82C4F27A39F94CBEA02BB498EF /* DateInRegion+Compare.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B33B085086724D9914992FFDEF83E0B /* DateInRegion+Compare.swift */; }; + 6654CDCA10823EA080976DF72D8729B2 /* AVAssetImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43F88826BD8118C95446B4D9D4F416F /* AVAssetImageDataProvider.swift */; }; + 6735E4B11C64D20B4E05A92811F5A721 /* IQKeyboardManager+Internal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 773DD03EC2EC00F685DE0E46779320CC /* IQKeyboardManager+Internal.swift */; }; + 67942FD70EE19BA957045141036FD49E /* RequestModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035EB38FC9B73D3AFE4C25920C1A1C32 /* RequestModifier.swift */; }; + 68238227D42B2511FA6A26BF71E92520 /* Alamofire-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = AA35F74EEBAD4E0CB28C015AD5D6EECF /* Alamofire-dummy.m */; }; + 68241B77CB3EE81665BBB4275AC19679 /* JXSegmentedListContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA90CEFF373663026D2F06371A3D4E9A /* JXSegmentedListContainerView.swift */; }; + 686ABAEBCE5C0EA6644AA80F9B4B3687 /* MJRefreshNormalHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = E4678D7C77B6546A4205C194E9F275EB /* MJRefreshNormalHeader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 68995B28EE5B539CEA5A1133E4623927 /* MultipartFormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB03A8FE1983F5F495EC9ADC0D6E7E6B /* MultipartFormData.swift */; }; + 68A74F13F8FEBAA7E0EA9344DED0458B /* OperationQueue+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB50AF41FD17FD4D634D6CB5152810D /* OperationQueue+Alamofire.swift */; }; + 68DCF4550B3B72228D5D8B4E25A341F2 /* Box.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56CF6C9E5C4416011FAC32CEB31AA525 /* Box.swift */; }; + 69261B5D3B53EBF7109D5E1DA3768CAC /* AuthenticationInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7052242B5B59DCEC7125EE873BC0202A /* AuthenticationInterceptor.swift */; }; + 6C2A8D78B7E5B02974B212599B28AD77 /* Indicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02D1EC547B26205284A72A9F9473EB73 /* Indicator.swift */; }; + 6C4BCC8C2D31263360E2697776A9E80D /* JXSegmentedIndicatorBaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E81980AF59D081E0E8A9761D1C422BF /* JXSegmentedIndicatorBaseView.swift */; }; + 6CC7E7C00730B1BF42A28B2E23CA01D6 /* URLSessionConfiguration+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12A6ED7989C6F4843507D223BD102CC5 /* URLSessionConfiguration+Alamofire.swift */; }; + 6D389E4D5F97798BE1AEEB8C317852D7 /* SnapKit-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 31126E0DD1B56D3713965A56F0B05AC8 /* SnapKit-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6D4A08865846C0F0DB9A05C617C2A947 /* MJRefreshStateTrailer.h in Headers */ = {isa = PBXBuildFile; fileRef = B764532F7A465FF640FDA97A850A103D /* MJRefreshStateTrailer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6E2884B29CD49EE91C48C725105F295A /* LayoutConstraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEE5906F519651F94E70B28F42C4C70B /* LayoutConstraint.swift */; }; + 6E4DEB1A81739DE58C64997251DAA87C /* ISOFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F56A78070D28571910937BC0EE5894B8 /* ISOFormatter.swift */; }; + 6F271B6EA85E0BDDA7DD1CC621EDC4F9 /* MJRefreshGifHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 536595B34971D58E93F91CEFFBA20A22 /* MJRefreshGifHeader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6F2E0DC7D8598283D088A989FDB8E5F6 /* ParameterEncoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 368AFBDCEBBA20270829ACA09283D127 /* ParameterEncoding.swift */; }; + 7052944C657F270E47777446D0E10E1C /* ConstraintInsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 234A9BD48AA1E6813E36334F22C346D4 /* ConstraintInsetTarget.swift */; }; + 70B890CA221D229ABF2346A7245654C5 /* Int+DateComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD56DAD13E1185FD74DB7A8649E746CE /* Int+DateComponents.swift */; }; + 714D5F4F9165ED6BF3CFA9FEA7DB9FF5 /* Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 774F6E017AC64D4F20E0DA360CA3FECF /* Placeholder.swift */; }; + 71655F70079826C7494ABF198F9F563A /* RelativeFormatter+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30D9FC3ABDA982F6CA82384628D6F165 /* RelativeFormatter+Style.swift */; }; + 71B32D2CE27370DCC6032569FEE5C8DC /* Date+Math.swift in Sources */ = {isa = PBXBuildFile; fileRef = DED1174C630E86B387EC34B8B1DD2DA3 /* Date+Math.swift */; }; + 72C19C762FADC82517C344E9F47D7E50 /* AlamofireExtended.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A8F4312D81FC10BD8029BE851C76498 /* AlamofireExtended.swift */; }; + 72D0CDE3B34D718422CFD4F85ADEFB04 /* RetryStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8AC6801BE5A7B67B8032757817BE51 /* RetryStrategy.swift */; }; + 735B99CA4190FBE5FE23DA796402D447 /* DateInRegion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 951E048B27AEAC006B779E585701262E /* DateInRegion.swift */; }; + 73F8AC99A58E5837924C056E89543B97 /* Typealiases.swift in Sources */ = {isa = PBXBuildFile; fileRef = 440D319A1267C894C2AFFDA3362EBE9E /* Typealiases.swift */; }; 74145F14ACD710C1D165C5F9B3F0D7ED /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4B8063291033C95A8B2A24FA2AD7A79 /* Foundation.framework */; }; + 74BF3CC58474F118E0E3953ADBBD233F /* MJRefreshComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CBB6593899E987A5B4300FC21B80983 /* MJRefreshComponent.m */; }; 74DBD7BAE1B62FA323770957159589E1 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA39C6D2448DC5A9AD18DDA3C96A1A0F /* Accelerate.framework */; }; - 76F871A99E11BE8B63BF2FB2A30068A7 /* IQKeyboardManager+Position.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13F50E8CD9EED0FF95C7743EBA58ECB4 /* IQKeyboardManager+Position.swift */; }; - 78CA17524C270C0E381677E3D4C77B6B /* ImageDownloaderDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AE2AF696125AD0E1121BF86AAE5046 /* ImageDownloaderDelegate.swift */; }; - 78D414CF02F5ED61DAB995221C459C22 /* JXSegmentedIndicatorDoubleLineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E3F83A4B256E06D67FBC054152710B2 /* JXSegmentedIndicatorDoubleLineView.swift */; }; - 794FC38D15336AB502B73B012005E9BD /* Validation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82A068C4EC672799ADB247B155675358 /* Validation.swift */; }; - 795681285B4E2B121B5CD420131168F8 /* MultipartUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2767F08F182AD8A9B1774BEFAD31FCE /* MultipartUpload.swift */; }; - 798FA71F8CAE44D05016FFF767100375 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4B8063291033C95A8B2A24FA2AD7A79 /* Foundation.framework */; }; - 7A9A6B9B17AACD040A4A99E5DE07B428 /* IQUIViewController+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03494EF27E38F8E4F8F6A831E3C45FE7 /* IQUIViewController+Additions.swift */; }; - 7AD0E5A1A45CE95B2C7A8078B2F19073 /* TimeInterval+Formatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A778C04C8D2699D2DED1B1600517215 /* TimeInterval+Formatter.swift */; }; - 7AE2E0B382A14D58BE7DAA0C852DCD02 /* ServerTrustEvaluation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CFDD319BC3DFC1F0C2B65AEB2C7B04F /* ServerTrustEvaluation.swift */; }; - 7BC03DCFF31FDA534EB7B100209D1718 /* Calendars.swift in Sources */ = {isa = PBXBuildFile; fileRef = C29313259EB03457900A0146BD10C25F /* Calendars.swift */; }; - 7CC5E76223E1EB7B09FBC03EA07E3DB3 /* JXSegmentedIndicatorBackgroundView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F7A731F70FE21FD4DE8310D869C90DD /* JXSegmentedIndicatorBackgroundView.swift */; }; + 77A016AB014A21D60BBFAB9F7134D38B /* MJRefreshTrailer.h in Headers */ = {isa = PBXBuildFile; fileRef = A56C8749F94C4894BDE28709B22BC8EC /* MJRefreshTrailer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 77D782DE125D322922466676E2FFA289 /* ConstraintPriorityTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 667B5BDDACE02078C87EFED6AAB723C2 /* ConstraintPriorityTarget.swift */; }; + 78CA17524C270C0E381677E3D4C77B6B /* ImageDownloaderDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D36A80F29E20B609E647BAFB548A270 /* ImageDownloaderDelegate.swift */; }; + 78D414CF02F5ED61DAB995221C459C22 /* JXSegmentedIndicatorDoubleLineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 835F2888E352852912F4709F5E54512B /* JXSegmentedIndicatorDoubleLineView.swift */; }; + 794FC38D15336AB502B73B012005E9BD /* Validation.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA42DDB21EAB3527641F275C3D22E4D0 /* Validation.swift */; }; + 795681285B4E2B121B5CD420131168F8 /* MultipartUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94A8D6D5B3A24A5E000AF4DBE9434CF /* MultipartUpload.swift */; }; + 7A19CD0F168E8C66757012114767A36B /* UIScrollView+MJExtension.h in Headers */ = {isa = PBXBuildFile; fileRef = F0CF839DB998A3AA0D5D01C635E92AB8 /* UIScrollView+MJExtension.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7AD0E5A1A45CE95B2C7A8078B2F19073 /* TimeInterval+Formatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2998944D54451B52A0996B2A9FDDD7DB /* TimeInterval+Formatter.swift */; }; + 7AE2E0B382A14D58BE7DAA0C852DCD02 /* ServerTrustEvaluation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAAC3162B7531D025AB197602FE75F31 /* ServerTrustEvaluation.swift */; }; + 7BC03DCFF31FDA534EB7B100209D1718 /* Calendars.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1968FDA9F67DC3333951BED4268CA52 /* Calendars.swift */; }; + 7CC5E76223E1EB7B09FBC03EA07E3DB3 /* JXSegmentedIndicatorBackgroundView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E31B1C576F8187B6B1A1F160B90D6081 /* JXSegmentedIndicatorBackgroundView.swift */; }; + 7E59ABF8A1AC8F61FEFB9B8C72EFB9E5 /* IQKeyboardManager+Position.swift in Sources */ = {isa = PBXBuildFile; fileRef = 988FB962B33EFE0451CB5B6094DEAA75 /* IQKeyboardManager+Position.swift */; }; 7E7F1EE3B8C0BB721181929B686FEC17 /* Kingfisher-Kingfisher in Resources */ = {isa = PBXBuildFile; fileRef = C298ABB78D9B05529B89D8322DB2E7B0 /* Kingfisher-Kingfisher */; }; - 7F60A80731DCB0EB26C7D01DCCA932E4 /* ISOParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17AA6D7827F1E01C2A8379EA8543ED13 /* ISOParser.swift */; }; - 80244605FFB26BF165B3C6E3CFA83A3C /* JXSegmentedTitleImageItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC849766E84C3D70F4A1EC1D8B8B1E23 /* JXSegmentedTitleImageItemModel.swift */; }; - 8072251E5FFDC1AB89E7558218C41D24 /* KingfisherError.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDF1EA36F77390C08F5F803AC6C25B26 /* KingfisherError.swift */; }; - 81202C96DE677B10C9F8F8CE7E8F483E /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 5FC69CA124430885BBDD652A5966AE29 /* PrivacyInfo.xcprivacy */; }; - 81DAB282980A3BB8EB7796B61934E4F4 /* KFImageOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 665D66E791DE2DF5733AC7C3555A21F4 /* KFImageOptions.swift */; }; - 830535E48AA507D7C15359F2A5B72DD1 /* ImageProgressive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85475E21904923ACC16877FB7BA6C30B /* ImageProgressive.swift */; }; - 83DBC0F86AD7C6EFB6947E0F3616467E /* JXPagingListContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 728B87873E161AD29B02B004B8C0F675 /* JXPagingListContainerView.swift */; }; - 8423D60239269F191A47A3E2D82E1EF7 /* ImageTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5DFFE16768F14458BE38939F340F1B /* ImageTransition.swift */; }; + 7F60A80731DCB0EB26C7D01DCCA932E4 /* ISOParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86134D091916FFC476610F2EBFE771E2 /* ISOParser.swift */; }; + 80244605FFB26BF165B3C6E3CFA83A3C /* JXSegmentedTitleImageItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65D6A9EE341D83823E03C122A72A5C1 /* JXSegmentedTitleImageItemModel.swift */; }; + 8072251E5FFDC1AB89E7558218C41D24 /* KingfisherError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 864DAEC4F579E88712B7F5B447424FFC /* KingfisherError.swift */; }; + 81DAB282980A3BB8EB7796B61934E4F4 /* KFImageOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CDB52D83D152A96E4E9CD244CA95DEA /* KFImageOptions.swift */; }; + 82FE3B046FEA46F2BDFE7FB0E9D7CBAD /* SVProgressHUD-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = C68BBA48149EB58E146B969600FB99B8 /* SVProgressHUD-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 830535E48AA507D7C15359F2A5B72DD1 /* ImageProgressive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4897326E2C8838615713B47EBE1FAD3D /* ImageProgressive.swift */; }; + 83DBC0F86AD7C6EFB6947E0F3616467E /* JXPagingListContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2DC9D938B1784B3E0E8FFC9851FCAEA /* JXPagingListContainerView.swift */; }; + 8423D60239269F191A47A3E2D82E1EF7 /* ImageTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E33A2601884DE73A47BD1A2690B14F /* ImageTransition.swift */; }; 84BEB9E439780B1E0DEF56459E3D3352 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4B8063291033C95A8B2A24FA2AD7A79 /* Foundation.framework */; }; - 868D4A456CBC3255A772F7FEA2F63BE0 /* JXSegmentedIndicatorParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF4F6584F8A39930FEF6F95DB825779 /* JXSegmentedIndicatorParams.swift */; }; - 8775BC8B188C38085646E9580CE231BA /* Kingfisher-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 11E5886F19EFFF862FFFA5B536854A3C /* Kingfisher-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 887DB52C63E52FBD3B88F42DD8CFB421 /* RequestCompression.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC849700AF2A2CAC32974D17E4B461D2 /* RequestCompression.swift */; }; - 893B6A268524ABD700BE29D240AD0458 /* IQKeyboardManager+UIKeyboardNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46359F9ADB38A9DAE1A1B6214177702D /* IQKeyboardManager+UIKeyboardNotification.swift */; }; - 89DF2D9C5EFB02A72EC0CE2138B77F35 /* SVProgressHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = FEDF29E375EBE13E620E486941023E18 /* SVProgressHUD.m */; }; - 8CEABAE06B171EA941EB497A2F4A6917 /* Runtime.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7778F9E9BCCA019BA4450E1ED18BB74 /* Runtime.swift */; }; - 8D18198290C6F15504358DD49F0C505F /* JXSegmentedTitleOrImageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C07796D011ECD3006D3BA479CD6C93C /* JXSegmentedTitleOrImageCell.swift */; }; - 8DD0EA5259D87AA915FC266D43CD08D6 /* JXSegmentedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB998DCE982EFC41FF337EC72362789A /* JXSegmentedView.swift */; }; - 8DD46EE7FB9503E7634E929DDE1CBA31 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65C3C5A1B404B17346AE855FFF4BDDA1 /* Notifications.swift */; }; - 90D847B19214926EDE5210D44A08F3C7 /* RequestTaskMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FA5B49E1B796D739442A55E81329C1C /* RequestTaskMap.swift */; }; - 9136355471B1C08A16DA36B0A2E536B8 /* NSButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98668AA82D39D5CB2E405768140C5404 /* NSButton+Kingfisher.swift */; }; - 9189CD495B78CBC65B25DED32A881426 /* KFOptionsSetter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6805397BC4354ED2D75A5B7AAE174E86 /* KFOptionsSetter.swift */; }; - 92138A77DFEB4F76FCB582E97633896D /* URLRequest+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CD193641BF411C264722678C735CFC4 /* URLRequest+Alamofire.swift */; }; - 9255A2BCECEB0006DAAF985CA00E2D15 /* JXSegmentedTitleGradientItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88EBA936D76416362096C319D61B9AE0 /* JXSegmentedTitleGradientItemModel.swift */; }; - 92592305D7EDCC7D117E563F9CB09B4A /* IQUIView+Hierarchy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E9F891E8CCB8860AE7419A69AC9327 /* IQUIView+Hierarchy.swift */; }; - 932470342D7352EEC18C00E52B37A5AE /* DotNetParserFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8C007F792870EEA4EC7B19A0FACC384 /* DotNetParserFormatter.swift */; }; - 9378157945D7B405C862A05B0D6B971B /* Result+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0F5BDD0C9E9E0CA159C3D2940A73FAD /* Result+Alamofire.swift */; }; - 943B0A1B436BAF4D419574466EF70FB3 /* SVProgressHUD.bundle in Resources */ = {isa = PBXBuildFile; fileRef = F8560E583BCEFEFC4455CDA8AE15D746 /* SVProgressHUD.bundle */; }; - 94E00674FACB3ED40684E8DAA40BCC84 /* KF.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DF2560B7559A05BA6EF1E5162CB2E28 /* KF.swift */; }; - 95E194A3AABB5407231E898B6686F73E /* ConstraintMakerRelatable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC679D42513109DC163A916172A01E41 /* ConstraintMakerRelatable+Extensions.swift */; }; - 97D7D91FC818805D8344C373CC098C32 /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF2199462536623489EFF7EDEF57722F /* SessionDelegate.swift */; }; - 98A6234F16C6C27B7618386B842E6D64 /* IQTitleBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F56A43D0608BE9C9E5E018F488A70CD4 /* IQTitleBarButtonItem.swift */; }; - 98F570DA48370453D648BD526FDAAEAA /* LayoutConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 540940F677A9EFC1CF5FD25315DE5F5A /* LayoutConstraintItem.swift */; }; - 99F2413E51A57A17AF0B52EE43D448D3 /* Resource.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCFB2567FE9BD5DDD79D4D4E176FE079 /* Resource.swift */; }; - 99FB2910921988A9BCC5533A1EA70E59 /* Region.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC1A24F4E1851F5E5FF43741ED5ADCD /* Region.swift */; }; - 9B93846DEFDF34EC2E881F65938B3F17 /* JXSegmentedTitleOrImageItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F1C6EFDCC0D193444D079AD48016EF8 /* JXSegmentedTitleOrImageItemModel.swift */; }; - 9C7D314BE45AB79E96B260656C36BAEC /* RedirectHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = F37D9853994687118DD881E59106C758 /* RedirectHandler.swift */; }; - 9C9548E8B4675954566202F7B87FF0E6 /* ConstraintConstantTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3BE4EB2A04A4F30656E0864B64A6A88 /* ConstraintConstantTarget.swift */; }; - 9D5654F75F726E0B176684741CA9A1C6 /* IQKeyboardManager+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2540A9293E8ADAB4B67AF923E8AFC51F /* IQKeyboardManager+Debug.swift */; }; - 9D8BED7F3F86BB39E7C0923D92E73F8B /* Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C64660111FD6606664A3951D1C9E793 /* Combine.swift */; }; - 9E02CFFEFE1BEC978B512286F03D31DA /* ConstraintInsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E89ECD9194EDFD568A9EF6F17101045 /* ConstraintInsetTarget.swift */; }; - 9F8F5BCE4DAD6C16F3A8AA2A2F783D01 /* FormatIndicatedCacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E33C97B5283CD7B31E6C56118C99CB3 /* FormatIndicatedCacheSerializer.swift */; }; - A03FDA8BC5741880B1EF11AFD248EF48 /* ConstraintOffsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = C570C2B10208E17D82B7BE0255BD166E /* ConstraintOffsetTarget.swift */; }; - A1506893FF52AA466B130E8B05FBE868 /* NetworkReachabilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CECF59F44BE476A62417A1367B020FF4 /* NetworkReachabilityManager.swift */; }; - A1A93726CD533C8ACD4755250E46E48D /* Delegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AED5BF44EC43B565CFB49DC523A2FE6 /* Delegate.swift */; }; - A22A2ACF53FDC243AAAFB009005A710F /* Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7CF26B5F28E33AB65201BFB9772E94 /* Concurrency.swift */; }; - A393340CB069126B0A3D781C174E6E49 /* JXSegmentedNumberItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 126C50DAB71E48A6A012ECFB4420D997 /* JXSegmentedNumberItemModel.swift */; }; - A3E3AB7C765C21AE17B1E6EE6560040C /* SnapKit-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 258A1691BC25E6887D2399F3FA414308 /* SnapKit-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A3FD52DF5584364FFD56965394C36CF2 /* URLConvertible+URLRequestConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9CC3B5B9CB0EEA62534F2B47807C815 /* URLConvertible+URLRequestConvertible.swift */; }; - A5A8BF973BFE9C9304372A26C9F2E35B /* ConstraintMakerExtendable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A6A3FAA6F0F3F494BB498919493C5ED /* ConstraintMakerExtendable.swift */; }; - A70C6EBC13661A0FC4023236B350AEA1 /* AuthenticationChallengeResponsable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F7058BED0353F5D41333BF24E48B67 /* AuthenticationChallengeResponsable.swift */; }; - A86A28FC358F0AFE453C2EBD1D035751 /* JXSegmentedTitleGradientDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 487654BCA0B02C5A6F1A496C85CDFC36 /* JXSegmentedTitleGradientDataSource.swift */; }; - AA602A49B1DC7FDED565CAD8BB89EAC1 /* AFError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B162065ADCC62F8E5918B4FA00D73B81 /* AFError.swift */; }; - AA99A5B65FF84BABBAADA73755A1128E /* TimePeriodChain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BBCE430AE205EC78BD6A9993B59A91F /* TimePeriodChain.swift */; }; - AA9BF7A395D928D03794FCF7063056DB /* IQTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59A6EEB5900F7A2EFF2E4353A16CFB10 /* IQTextView.swift */; }; - AB3FB3A4F52F88797D743DB4324DFD16 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4B8063291033C95A8B2A24FA2AD7A79 /* Foundation.framework */; }; - B03B5579590D528CBA6D11FF638BC2AF /* Typealiases.swift in Sources */ = {isa = PBXBuildFile; fileRef = E329FD7AFE7914B19431A5027E14E2E3 /* Typealiases.swift */; }; - B155E9B44BDC68C87FCC13B10F1D5532 /* ImageFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123F9D355B6FA77F1C0BBFDFB7DCEFC2 /* ImageFormat.swift */; }; - B1E4796F3830DE510675DEE45E7FB648 /* JXSegmentedTitleImageDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDFACB4345054B019481CEDCD494F54E /* JXSegmentedTitleImageDataSource.swift */; }; - B2E03E67465612F21A685BC97EE7F947 /* KFImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B3AB6B42435ED2BB97F0E60A022953 /* KFImage.swift */; }; - B3048DDF53B358B345D8FC23A4D7D1AB /* JXSegmentedIndicatorRainbowLineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 379DC6E350D05131719D9E95995D51D1 /* JXSegmentedIndicatorRainbowLineView.swift */; }; - B43017FEC99D227D4CDD81DD2C27D9D9 /* ConstraintMakerPrioritizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73D95693DF679081C2166C4C7F9A2F66 /* ConstraintMakerPrioritizable.swift */; }; - B462CD14FCF8FA2EF578F76C63AB9FFB /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1199E580C5F19AFD1010FE20258DADBD /* UIKit.framework */; }; - B4F5A298E60CC038619FC7685C3D50C3 /* Date+Compare.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349DDAFE2B858FF1C77548AEB5A9024F /* Date+Compare.swift */; }; - B5C66B48EB624FEC4D2F64A50F143716 /* DataStreamRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AE0D04C04D9D2C94118025EAB921A25 /* DataStreamRequest.swift */; }; - B5E3B2C7AE25969552E18A5083E73D08 /* IQKeyboardManagerConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBCD2385297C11F5F3C9C95418952EF1 /* IQKeyboardManagerConstants.swift */; }; - B6E953695C48D2FDCE8D86321DE7D474 /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC9CD67D400913EBE69B43B5CD49163E /* ImageCache.swift */; }; - B752F7C4BECB65894B1F49421049CE5F /* ConstraintView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A43A96448C1937678DB79A129BB6F2C2 /* ConstraintView.swift */; }; - B784C1E8FB583A4AA328D89038D2DC5B /* TimePeriod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56E1C515E167FC148720369572DA2FB8 /* TimePeriod.swift */; }; - B85354283CB89C658911748A7C5AF891 /* JXSegmentedAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BE57309210A754C8C684F298E14077B /* JXSegmentedAnimator.swift */; }; - B97D95F7C0C87105C015BCCAE634B8DC /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA7D8134BAFA04D2B580073EE31DACA /* Filter.swift */; }; - B9DCCFD9F7800B172476EE7F2D90354B /* JXSegmentedTitleAttributeDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2D0518832B22B12029C5C922BB7D8 /* JXSegmentedTitleAttributeDataSource.swift */; }; - BAF334D6167CAED8479849147C7F6858 /* TVMonogramView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C789A86A2E73450B8364125FF6DF392B /* TVMonogramView+Kingfisher.swift */; }; - BB84B6AC5338AF7AD3B82B1C012386F8 /* JXSegmentedDotCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE72EF69BD801D8C5E4AFBF5B3338955 /* JXSegmentedDotCell.swift */; }; - BBC9585C538DD5B68FF7E7E32F714023 /* JXSegmentedCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1790A81F081026839A33E7AA4A3172 /* JXSegmentedCollectionView.swift */; }; - BC0A0C473B63B817926F4D58611281BB /* URLEncodedFormEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C47E79C3926F155B6C7EC94D87F0C5B /* URLEncodedFormEncoder.swift */; }; - BD47CB74CD9B2B4D2D942C9B65748DFB /* SnapKit-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9FF5D58E8072CFF7D8524E5423ABF567 /* SnapKit-dummy.m */; }; - BDEF755484EB2BA591FBF48752FBAEEC /* NSTextAttachment+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4763CB38C57143759CBF3728786434 /* NSTextAttachment+Kingfisher.swift */; }; - C15B3F89E6F83DC9CCB14903FC5D80C5 /* SVProgressHUD.h in Headers */ = {isa = PBXBuildFile; fileRef = 384CCE46006CEC00E0ADA0DB1232170E /* SVProgressHUD.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C28B9E7727B5131A76E454A52F32FFC2 /* IQUIScrollView+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7FA6A81D452D73024CD59E468AADA68 /* IQUIScrollView+Additions.swift */; }; - C52630B4D59C7A2757A8E7508F37D1B7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4B8063291033C95A8B2A24FA2AD7A79 /* Foundation.framework */; }; + 8640829049AE9907FE93825E5510C33D /* ConstraintMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50DD91D5AAEBFBFB4776365998B843B7 /* ConstraintMaker.swift */; }; + 868D4A456CBC3255A772F7FEA2F63BE0 /* JXSegmentedIndicatorParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEC00130945EBD53372EFBC22FB8119E /* JXSegmentedIndicatorParams.swift */; }; + 8775BC8B188C38085646E9580CE231BA /* Kingfisher-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 814205A97B8158339AF6DCF93609360F /* Kingfisher-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 87996D11DC92EE19EAF9305DAEA4ACF2 /* ConstraintMakerPrioritizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24091B247B320B28B53B7DB2A0EB996B /* ConstraintMakerPrioritizable.swift */; }; + 8868BA37E3CE7C58D26123806D543F3F /* ConstraintView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FBC7116157221928733CE2DB074EB86 /* ConstraintView.swift */; }; + 887DB52C63E52FBD3B88F42DD8CFB421 /* RequestCompression.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E6DA59208C9C680C1A08AB6B751A05E /* RequestCompression.swift */; }; + 891D1BF14C8881C74262EE9DBE5D67A9 /* UILayoutSupport+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A16ABD25AB8AAB13E0072CADE42E65 /* UILayoutSupport+Extensions.swift */; }; + 8C077A05101B84731A302657381218CB /* MJRefreshStateHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 86545830194573BF57878FC631A90181 /* MJRefreshStateHeader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8CEABAE06B171EA941EB497A2F4A6917 /* Runtime.swift in Sources */ = {isa = PBXBuildFile; fileRef = E75F2A56E77879A823734237F7B0D90B /* Runtime.swift */; }; + 8D18198290C6F15504358DD49F0C505F /* JXSegmentedTitleOrImageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A8B5D1A6CBAD8FC5DA5D3D0DA7512BE /* JXSegmentedTitleOrImageCell.swift */; }; + 8DD0EA5259D87AA915FC266D43CD08D6 /* JXSegmentedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67318C8CDF97D3763D84C0B08910AD54 /* JXSegmentedView.swift */; }; + 8DD46EE7FB9503E7634E929DDE1CBA31 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6B66846BA638DCD6F5ABB338C4AA41 /* Notifications.swift */; }; + 90441CBC43993A5E4E0F5CD5BECC2DDE /* MJRefreshBackNormalFooter.h in Headers */ = {isa = PBXBuildFile; fileRef = F15F5BABB5166FF00A9E43E67C060454 /* MJRefreshBackNormalFooter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 906EF891E58A035281766993F82373E3 /* ConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58092F279DEDF69EA7576C313DC62F89 /* ConstraintItem.swift */; }; + 90D847B19214926EDE5210D44A08F3C7 /* RequestTaskMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C1665911416D598AAD937FC0E0D42E4 /* RequestTaskMap.swift */; }; + 9136355471B1C08A16DA36B0A2E536B8 /* NSButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B843EC8B993674D3288F87AEA9D122 /* NSButton+Kingfisher.swift */; }; + 9189CD495B78CBC65B25DED32A881426 /* KFOptionsSetter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A26B70DABA1CBACD8166FC00D07C081 /* KFOptionsSetter.swift */; }; + 92138A77DFEB4F76FCB582E97633896D /* URLRequest+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA5D2A634B9432EA862513BDE2A5ED4 /* URLRequest+Alamofire.swift */; }; + 9255A2BCECEB0006DAAF985CA00E2D15 /* JXSegmentedTitleGradientItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E39692FF9A73D5EC6D4AE2DE35E3C0C /* JXSegmentedTitleGradientItemModel.swift */; }; + 92A81311D8592CB3D907E9DA59023E38 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 2C9B6C74D874F93335EDA5FBAC20675C /* PrivacyInfo.xcprivacy */; }; + 930B495B7A3197730A016E2339A4CBA7 /* IQKeyboardManagerSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = E1176C58859CF5334183B7786DAC8E87 /* IQKeyboardManagerSwift-dummy.m */; }; + 932470342D7352EEC18C00E52B37A5AE /* DotNetParserFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 000257BCD6570C4B0371D660CCF8D3E1 /* DotNetParserFormatter.swift */; }; + 9378157945D7B405C862A05B0D6B971B /* Result+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB0F440BD5C5987BBAD5992F1CC0CCAA /* Result+Alamofire.swift */; }; + 938CFF5F6DE6E7E8CE94373E51F3E07A /* ConstraintLayoutGuide+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B4DCC2536CD7F8BD55F0BAA08F110C7 /* ConstraintLayoutGuide+Extensions.swift */; }; + 94E00674FACB3ED40684E8DAA40BCC84 /* KF.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE633CEBF91C6D351A438EB13D3F4E1F /* KF.swift */; }; + 950B809760A8CE4375DCE1016FB9859F /* ConstraintMakerRelatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86EE2D4250A56EE1BB39FFEB834371D /* ConstraintMakerRelatable.swift */; }; + 9779D52AD8CDA703D6EEE1C6D38E019F /* ConstraintAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD0AE0ACE265AEC714180F643F48C621 /* ConstraintAttributes.swift */; }; + 97D7D91FC818805D8344C373CC098C32 /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65BAE3F45733F6EB3DAE2F48599D8CAB /* SessionDelegate.swift */; }; + 97EA46DA072EC4FD4D831606095B92C1 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1199E580C5F19AFD1010FE20258DADBD /* UIKit.framework */; }; + 98455F4176C861F9E33D36892A932684 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4B8063291033C95A8B2A24FA2AD7A79 /* Foundation.framework */; }; + 99F2413E51A57A17AF0B52EE43D448D3 /* Resource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49B4649E1D11EB9D32BD3E212382EF1D /* Resource.swift */; }; + 99FB2910921988A9BCC5533A1EA70E59 /* Region.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA38A01E090C908AE5886021034EE11D /* Region.swift */; }; + 9A07F0B734748735A80119550AC32104 /* SVIndefiniteAnimatedView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DE3D079E059E37BB8233A28ECEF0FC7 /* SVIndefiniteAnimatedView.m */; }; + 9AF14E4B1C52E5AD4C38021C4EC17974 /* UIScrollView+MJRefresh.h in Headers */ = {isa = PBXBuildFile; fileRef = 96222B976672EC3736CB9B53FC49C92E /* UIScrollView+MJRefresh.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9AF53260DACD3DE030C97AA110DAD22E /* MJRefreshComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 0082002FD60B11229524482ADA592954 /* MJRefreshComponent.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9B93846DEFDF34EC2E881F65938B3F17 /* JXSegmentedTitleOrImageItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDD5BF7F25804ED6AC6B15D6801FE4AD /* JXSegmentedTitleOrImageItemModel.swift */; }; + 9C2584A9CCF8CA6C9DF2AD79DB831E70 /* IQKeyboardManager+UIKeyboardNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA467CC8E830A4407AEEA9E195B5572 /* IQKeyboardManager+UIKeyboardNotification.swift */; }; + 9C292E2C761CB97ACD00F95FA4D60E85 /* IQKeyboardManager+OrientationNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52CB2CCAA127ADA834B4CCF4686ECE60 /* IQKeyboardManager+OrientationNotification.swift */; }; + 9C7D314BE45AB79E96B260656C36BAEC /* RedirectHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6855310DB35D41B1E466E5EFFAF771BE /* RedirectHandler.swift */; }; + 9D8BED7F3F86BB39E7C0923D92E73F8B /* Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05A41A0B8D148A4BA10DC25292FA63E6 /* Combine.swift */; }; + 9E4E278A3C1543798E1912699886023E /* IQKeyboardManager+UITextFieldViewNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07490687930290E2CF12D183E94326BF /* IQKeyboardManager+UITextFieldViewNotification.swift */; }; + 9F8F5BCE4DAD6C16F3A8AA2A2F783D01 /* FormatIndicatedCacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC741E10FE2F276DD3C474545224A00 /* FormatIndicatedCacheSerializer.swift */; }; + A0371DF7D93D9B86BD50474D4B9294FD /* ConstraintInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7682AD6DBFD519C9BA5ECCAC483C0CF4 /* ConstraintInsets.swift */; }; + A051999781E1280746F7743BDEEA6C49 /* ConstraintDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5E05285408F9AA5B005A82CEFDA99 /* ConstraintDescription.swift */; }; + A1506893FF52AA466B130E8B05FBE868 /* NetworkReachabilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88647C8377C8FB3AE854C55C7B81559E /* NetworkReachabilityManager.swift */; }; + A1A93726CD533C8ACD4755250E46E48D /* Delegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D49B5FF4D24E46BB7F695E22A9907317 /* Delegate.swift */; }; + A22A2ACF53FDC243AAAFB009005A710F /* Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9B7826E0EF5E37E1704D27E7C361C78 /* Concurrency.swift */; }; + A35877DE0C3D6B4CF2A10E666EF5F490 /* LayoutConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7B2E649574AA0FAECB00E9B883C49A6 /* LayoutConstraintItem.swift */; }; + A393340CB069126B0A3D781C174E6E49 /* JXSegmentedNumberItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A704FDB2D535D699FD2D53CC6DFFC70 /* JXSegmentedNumberItemModel.swift */; }; + A3FD52DF5584364FFD56965394C36CF2 /* URLConvertible+URLRequestConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAD5CEA5D178799C659489E705F0BDE8 /* URLConvertible+URLRequestConvertible.swift */; }; + A50A72FCD270217D99ECA1D2700CFAD4 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EFE78C092A2B391D6411B2D75E0897C5 /* PrivacyInfo.xcprivacy */; }; + A70C6EBC13661A0FC4023236B350AEA1 /* AuthenticationChallengeResponsable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E5CD298A2F13E3902AAA3510FE5C9FD /* AuthenticationChallengeResponsable.swift */; }; + A7AE58053194FA1CEA420D995AF17B85 /* MJRefreshAutoStateFooter.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B9379FA3746B5215A31DE8D1CD26166 /* MJRefreshAutoStateFooter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A86A28FC358F0AFE453C2EBD1D035751 /* JXSegmentedTitleGradientDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 695AA5A7D6BF0B59DFBF71ABC3F3FECE /* JXSegmentedTitleGradientDataSource.swift */; }; + A8C0CBBC63C39A8C10083CBCA172F7CF /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C07BEF0CE5DECC5BDCAC8625BF2FFA4B /* QuartzCore.framework */; }; + A8DD3F39B4D1F0C7B11866484A03336E /* IQInvocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCA08BA243343C7A9EAEE567CC5F4318 /* IQInvocation.swift */; }; + AA602A49B1DC7FDED565CAD8BB89EAC1 /* AFError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B98A705AFD36170CD85E492121E37403 /* AFError.swift */; }; + AA99A5B65FF84BABBAADA73755A1128E /* TimePeriodChain.swift in Sources */ = {isa = PBXBuildFile; fileRef = D19D1617C2FB2FC864606303AF174A6D /* TimePeriodChain.swift */; }; + AAC2529A1B4F4832A052B348C5093018 /* IQUIScrollView+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C54C3E1777728F805F3EFCB27BB703BC /* IQUIScrollView+Additions.swift */; }; + AB651DB3A97A623234B6544AD030406A /* IQNSArray+Sort.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C1E1CFDA9E2D6AECCA91F210C0B6064 /* IQNSArray+Sort.swift */; }; + AC46B7DF5115A19C887EDDC9C226B66E /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 84E085540B9A46FE188C3ED65522C329 /* PrivacyInfo.xcprivacy */; }; + ACDFC76B3486D1E62FD11EFAA88678ED /* SVProgressHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B189CE2110C0A21199EB8FB87FCEB6D /* SVProgressHUD.m */; }; + AD3CE903FA2BEE3EFA153E7FA7C9610E /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = F86ED01EB7CC70315E585984B7CEADA2 /* PrivacyInfo.xcprivacy */; }; + B0CB5FB63262E1A67317045B8960F363 /* IQBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B860B422FB58A9842214FE11A933BBD4 /* IQBarButtonItem.swift */; }; + B133BB9C9B03481C7F1D221F35A617F2 /* Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = A26DF092CAB68C5202C9271E71C8F750 /* Constraint.swift */; }; + B155E9B44BDC68C87FCC13B10F1D5532 /* ImageFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CEA2AD00C187BA485EFF154E41EF587 /* ImageFormat.swift */; }; + B1E4796F3830DE510675DEE45E7FB648 /* JXSegmentedTitleImageDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1194040926B2C7D711B859F8AE4312 /* JXSegmentedTitleImageDataSource.swift */; }; + B2E03E67465612F21A685BC97EE7F947 /* KFImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3EEB78584831D0B242BDCAA90CED58E /* KFImage.swift */; }; + B3048DDF53B358B345D8FC23A4D7D1AB /* JXSegmentedIndicatorRainbowLineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71DCFBED49883055AA94888206F221A9 /* JXSegmentedIndicatorRainbowLineView.swift */; }; + B3F75D115D5150C258F5E68404751010 /* ConstraintConstantTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EB8A72B411C5E90471A44666337E7D2 /* ConstraintConstantTarget.swift */; }; + B46A36CA19ED6C09341D8E4031F66D5C /* IQUIViewController+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40E3CE126BEDA57D7DA923F7BBC49D32 /* IQUIViewController+Additions.swift */; }; + B4F5A298E60CC038619FC7685C3D50C3 /* Date+Compare.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E6EB2C04F247D9F4D15B77F830EDF54 /* Date+Compare.swift */; }; + B4F9C9EC1B3F1689AE56BB719AE5439C /* ConstraintDirectionalInsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 570B90AE83D4F878D222EF7D7B7A18F9 /* ConstraintDirectionalInsetTarget.swift */; }; + B5C66B48EB624FEC4D2F64A50F143716 /* DataStreamRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8C8C3813F3BA6EEC658167AE65D9419 /* DataStreamRequest.swift */; }; + B6E953695C48D2FDCE8D86321DE7D474 /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CF9BAB200D238346E29ED2DBA085B17 /* ImageCache.swift */; }; + B784C1E8FB583A4AA328D89038D2DC5B /* TimePeriod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECC357045F3ADF02DFCA0E0F6D4DEE0 /* TimePeriod.swift */; }; + B85354283CB89C658911748A7C5AF891 /* JXSegmentedAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDE736DCB96A4842E66D08021E34D36C /* JXSegmentedAnimator.swift */; }; + B962ED35C37063794B7D8468FB007AD5 /* MJRefresh-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DD688DF2ADF79B72ECC735C35F05F41 /* MJRefresh-dummy.m */; }; + B97D95F7C0C87105C015BCCAE634B8DC /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AAF19FA9EB514B2794ECCAD1BB7FA2E /* Filter.swift */; }; + B99F90601D5EED64587743374BBC44F6 /* MJRefreshStateTrailer.m in Sources */ = {isa = PBXBuildFile; fileRef = E0E418BB3B470DAB2533C31BAD7884C0 /* MJRefreshStateTrailer.m */; }; + B9A56C1C079CE609AD4404964A95A170 /* MJRefreshTrailer.m in Sources */ = {isa = PBXBuildFile; fileRef = 13184921F92E5D84095DD92314A9A4EA /* MJRefreshTrailer.m */; }; + B9DCCFD9F7800B172476EE7F2D90354B /* JXSegmentedTitleAttributeDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B28820A2229C358F6F00F9A6EE1A659 /* JXSegmentedTitleAttributeDataSource.swift */; }; + BAF334D6167CAED8479849147C7F6858 /* TVMonogramView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67675B8E7AD45A266A61E66355512D15 /* TVMonogramView+Kingfisher.swift */; }; + BB84B6AC5338AF7AD3B82B1C012386F8 /* JXSegmentedDotCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2215909E83BE0517F84079C1593E4E85 /* JXSegmentedDotCell.swift */; }; + BBC9585C538DD5B68FF7E7E32F714023 /* JXSegmentedCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F1FB2699EA33ABD4EDB7F856D39296F /* JXSegmentedCollectionView.swift */; }; + BC0A0C473B63B817926F4D58611281BB /* URLEncodedFormEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08E28C2D9A6137B156647AC16D95A15E /* URLEncodedFormEncoder.swift */; }; + BDAD667B60A9D9981738646851C825A0 /* IQKeyboardManager+Toolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB34508FC3184D3482A1002BEBC16654 /* IQKeyboardManager+Toolbar.swift */; }; + BDEF755484EB2BA591FBF48752FBAEEC /* NSTextAttachment+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F69248BB24307C449A27A28477BAF56 /* NSTextAttachment+Kingfisher.swift */; }; + BE355F69F84788D334FDAC7D1CD9B8C4 /* ConstraintDirectionalInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14052CB3D5057DCF4593BD1E77D90942 /* ConstraintDirectionalInsets.swift */; }; + BE60EC19FCBB8F301081E9C31BB85F3E /* IQUITextFieldView+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56E8C8A30A6C29843067AEFDBDB0DD5E /* IQUITextFieldView+Additions.swift */; }; + BF567AEFDD52DC43AC75122734D571E2 /* ConstraintMakerFinalizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5545219DAAC101FE50450F293367D8C9 /* ConstraintMakerFinalizable.swift */; }; + C04DBE6AE13FC5CFD01D363A351EF76A /* ConstraintView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C19F89F8FC7DDEB64DB778A90CC2BC /* ConstraintView+Extensions.swift */; }; + C09A286120D64335EA18D7689720B773 /* NSBundle+MJRefresh.h in Headers */ = {isa = PBXBuildFile; fileRef = B4111D05E2FD45B47E3E6AD830625F74 /* NSBundle+MJRefresh.h */; settings = {ATTRIBUTES = (Public, ); }; }; C5C4137EA46E97E717E83EF0ACEBC695 /* JXSegmentedView-JXSegmentedView in Resources */ = {isa = PBXBuildFile; fileRef = 92B0EC788EDA1B0CFA48DFFCB3DDAECD /* JXSegmentedView-JXSegmentedView */; }; - C6675F7517783A748EEF6AF441B187EB /* DiskStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 156E359C7D79A3E1C10A8B625DB45E59 /* DiskStorage.swift */; }; - C97C4259FD08F4E7519F858AA06B1A3B /* JXSegmentedRTLLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8868D3E0EEBED6EEE631D6CBDB9C0E01 /* JXSegmentedRTLLayout.swift */; }; - CA2820BE946964DCBC8E68604B34FD10 /* SizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2571304BB906066EBA3D52C58187895 /* SizeExtensions.swift */; }; - CBC1AE6750CA581BF0EBB5857C119552 /* IQInvocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78EEE8A477A369C06D750C1ED88021A2 /* IQInvocation.swift */; }; + C6675F7517783A748EEF6AF441B187EB /* DiskStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D65D8CBF9D74AB85CB305B6D9B87509 /* DiskStorage.swift */; }; + C7E343559158D03F717C616F79FAA006 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4B8063291033C95A8B2A24FA2AD7A79 /* Foundation.framework */; }; + C97C4259FD08F4E7519F858AA06B1A3B /* JXSegmentedRTLLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB0205A7B7089CE3AA7AF45ACDE3629A /* JXSegmentedRTLLayout.swift */; }; + C9D65759B4F36BDD6F29F0D4EA18AEFF /* SVProgressHUD.bundle in Resources */ = {isa = PBXBuildFile; fileRef = A206F578A0BA9FC1C6B8B6078EFF6B9A /* SVProgressHUD.bundle */; }; + CA2820BE946964DCBC8E68604B34FD10 /* SizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C0F797B07A4C95A5F90FB6C7E6A296 /* SizeExtensions.swift */; }; CCD6784611A32AE82D759F673AD23B47 /* JXPagingView-JXPagingView in Resources */ = {isa = PBXBuildFile; fileRef = 7EB20B4E68CCB69F85E7D08B7F8463D6 /* JXPagingView-JXPagingView */; }; - CDCA01B605A086576DBB75F8C3A24337 /* RetryPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89AE4C34F9A0CCC31019F7C0115A0BB7 /* RetryPolicy.swift */; }; - D06D49E07A6416A2A6E41B7B7B0D66F2 /* ImagePrefetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 924CF8F11C00458CC225420E918BA09B /* ImagePrefetcher.swift */; }; - D219C90C04F199356B9E9356693A3D59 /* Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36893E4F6E35B5AF8060ABB0AAA6C6BF /* Date.swift */; }; - D21E59C63A36A71A0B639350BA49E1A5 /* JXSegmentedView-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = DC3193C7C92FBD37C24C5E36096576D6 /* JXSegmentedView-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D313FF15F05623E5026892D032C08A30 /* JXSegmentedIndicatorLineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 342970F609D91209A7F339DC270C0C20 /* JXSegmentedIndicatorLineView.swift */; }; - D46A095C95DE691323E1D470F9DA1A39 /* KingfisherOptionsInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B6C0753CD229018B31E3685E1F4B7FC /* KingfisherOptionsInfo.swift */; }; - D5CDB942C402656138596C179E5A64EB /* ImageModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CF9C49F0627CE4DC176C8910520DD1A /* ImageModifier.swift */; }; - D6C6BF7DF334ECB734DF0F1AC176184B /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAE668ECEAF7AAFCDEEDD1F0D9C0B3F1 /* SessionDelegate.swift */; }; - D786D7CA6B8CE037FE8376A1DD390506 /* JXSegmentedBaseCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD71D3CDC6450CFD5A6E4F493768310F /* JXSegmentedBaseCell.swift */; }; - DAA39F07C362D3F2DB232609D93CDF6B /* ImageDrawing.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B0B70AF11FE76174D9E1B20575FAAB /* ImageDrawing.swift */; }; - DCE8DA2810BF13609E3F4281AA773569 /* Pods-MusicPlayer-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 1BBB6DE3AF0E150160FD2FA346CC6CD6 /* Pods-MusicPlayer-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DE896085DFDD686BDBDEFB776F0D683A /* DispatchQueue+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B4E6F9C722A37921CB299D06E531578 /* DispatchQueue+Alamofire.swift */; }; - DE8F5B68839128A005EE3549A1149B09 /* RequestInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEF1F46153EB848293C59AAA92FFCE28 /* RequestInterceptor.swift */; }; - E1C7B6DB080AC2293002CC3C12B136AD /* UIButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = F954C218AC5D88CE4C61680D652F9306 /* UIButton+Kingfisher.swift */; }; - E2112B22B6B162AE91C23934B3F5C481 /* Source.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9CE7D5D62E97450A0DF267A8A799F0B /* Source.swift */; }; - E27BD12C9CBA52D3E501FB2AE769B135 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 99DACD800F6BC071C09C771CFA780B2D /* PrivacyInfo.xcprivacy */; }; - E34DBE5BF2885EB48F3F0B8E6FE703AB /* IQKeyboardManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70EE242B119207B6DE78061ABCD5426 /* IQKeyboardManager.swift */; }; - E521F6DAB5E30920772B66F0C67C7028 /* Pods-MusicPlayer-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 137651D4B8A2CAB9ADEE7E77FCB50B0C /* Pods-MusicPlayer-dummy.m */; }; - E598C1E3C7A57F92401D607E5675ADD3 /* JXSegmentedIndicatorDotLineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA2B7CB6D3C5BF9E8732BD8ED85BC022 /* JXSegmentedIndicatorDotLineView.swift */; }; - E6ED06AC318A34F7744B32CEC759CDA9 /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E208F65C34D21FBC484B3D0337F1008 /* Response.swift */; }; - E70EBA16751054574A227A6432CCE4B0 /* SVIndefiniteAnimatedView.h in Headers */ = {isa = PBXBuildFile; fileRef = 699CF3DF23FE505906183E16A8B215AD /* SVIndefiniteAnimatedView.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E718E500074E8D6B011D53571B27BC0D /* Kingfisher-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F57F780799948B0298A107CA1DAF860C /* Kingfisher-dummy.m */; }; - E7E74B56BBD14101D9D391410FCAD323 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 13F72F1929EF4D62E0B78F56864FF024 /* PrivacyInfo.xcprivacy */; }; + CDCA01B605A086576DBB75F8C3A24337 /* RetryPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10D7C8D9A8EFE21347CF640AE5AFCD9 /* RetryPolicy.swift */; }; + CE453C62D0DA474AEE306AF3DF6DDAF1 /* MJRefreshConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 813F5F884BA0F0F6C062E545B4CA81EC /* MJRefreshConfig.m */; }; + D06D49E07A6416A2A6E41B7B7B0D66F2 /* ImagePrefetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36730D770821B0E94A45B2817FC4E2FD /* ImagePrefetcher.swift */; }; + D091D9EA20CEB92609BF1E622E8CA348 /* SnapKit-SnapKit_Privacy in Resources */ = {isa = PBXBuildFile; fileRef = B9DCB5EC0B1CDADD221717CADDF62359 /* SnapKit-SnapKit_Privacy */; }; + D0DF994786BCEC54939BC8216B42FBC4 /* IQTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E16F379BC5CA8C2B21212962C6FA430 /* IQTextView.swift */; }; + D191F3F5F0841B63F1F54A430608830E /* MJRefreshFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = C76A1ABBD38622E820640903E4A979AD /* MJRefreshFooter.m */; }; + D219C90C04F199356B9E9356693A3D59 /* Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0422DB62B6B3C1A201A2762EBBB5A97 /* Date.swift */; }; + D21E59C63A36A71A0B639350BA49E1A5 /* JXSegmentedView-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 37C1098A010D1C8E4E069D976A8D8DFD /* JXSegmentedView-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D313FF15F05623E5026892D032C08A30 /* JXSegmentedIndicatorLineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F125D521A9DA47CB8D38C8C03AEF68A0 /* JXSegmentedIndicatorLineView.swift */; }; + D32F246A21567182179C39B12D534191 /* MJRefreshBackGifFooter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F08C4884167A8DF12652D4ADA87DC8E /* MJRefreshBackGifFooter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D46A095C95DE691323E1D470F9DA1A39 /* KingfisherOptionsInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = A47365FDDB9CB0AC423AD6C3AF49AD21 /* KingfisherOptionsInfo.swift */; }; + D496B7637BE491EE925D965EC64A46E8 /* MJRefreshBackStateFooter.h in Headers */ = {isa = PBXBuildFile; fileRef = 67853DE27314756744C79CE55FBAA9A4 /* MJRefreshBackStateFooter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D4A9338A969C1416E3C79CECCB97D514 /* SVIndefiniteAnimatedView.h in Headers */ = {isa = PBXBuildFile; fileRef = 282ACC9FB46C251345FC5EB3AEF1B9CE /* SVIndefiniteAnimatedView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D4C21761CC592857F35B99ACDD62ADAB /* MJRefreshAutoNormalFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = A04C1CC2D7176FD20CE057E555EFC2CB /* MJRefreshAutoNormalFooter.m */; }; + D4E2EAD773A30B252B6AD6B99A7490F4 /* IQKeyboardManagerSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 98D0F4FF0A3E2660BE566528FDF31D03 /* IQKeyboardManagerSwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D5CDB942C402656138596C179E5A64EB /* ImageModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = D776B0C4D357F0B0466B42C8BF6495D5 /* ImageModifier.swift */; }; + D6A1AB77D9F4C84779521FAF5E469343 /* MJRefreshAutoFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 7A43EE3F113EE7EB81E5065DB5FDD3F2 /* MJRefreshAutoFooter.m */; }; + D6C6BF7DF334ECB734DF0F1AC176184B /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E1F7BD2E4AFF6989C1387F2558185ED /* SessionDelegate.swift */; }; + D6D4AB4590700B3706919889BF614D26 /* SVRadialGradientLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = AE5B1F68CF04B5EBB405EA5A612234B6 /* SVRadialGradientLayer.m */; }; + D786D7CA6B8CE037FE8376A1DD390506 /* JXSegmentedBaseCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA08845BC3434B44AF0A3C8AFC111D93 /* JXSegmentedBaseCell.swift */; }; + D92AEF78B87F929D88D5C876ABBAD79A /* ConstraintLayoutSupportDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6ADEBF08B3C1426137C7A2ED9E5E54D8 /* ConstraintLayoutSupportDSL.swift */; }; + DAA39F07C362D3F2DB232609D93CDF6B /* ImageDrawing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08D053BD683C26F73E7D5BAADC8A4FEF /* ImageDrawing.swift */; }; + DE896085DFDD686BDBDEFB776F0D683A /* DispatchQueue+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11AF900AC1C5B4CD4047B709266568E5 /* DispatchQueue+Alamofire.swift */; }; + DE8F5B68839128A005EE3549A1149B09 /* RequestInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D89E20D36B74F4A890688A090C311698 /* RequestInterceptor.swift */; }; + E06C5FBFE7D88C3630BA1FD51F7AF1E7 /* SVProgressHUD-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EC583B42A01E6257C74C1DCD53164A8 /* SVProgressHUD-dummy.m */; }; + E1C7B6DB080AC2293002CC3C12B136AD /* UIButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66CFC994F45F4A9A50C54C16724D763 /* UIButton+Kingfisher.swift */; }; + E2112B22B6B162AE91C23934B3F5C481 /* Source.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68A219042E44DB63D69EE3B79763130C /* Source.swift */; }; + E55E592D62CAE3D0B2960146E3D15CC6 /* UIView+MJExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = E3C11DA33AB8B0E9203520516067EC23 /* UIView+MJExtension.m */; }; + E598C1E3C7A57F92401D607E5675ADD3 /* JXSegmentedIndicatorDotLineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0CE74EB3DE207E3CAE98CDE17280DBA /* JXSegmentedIndicatorDotLineView.swift */; }; + E6ED06AC318A34F7744B32CEC759CDA9 /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1383471ECB9F37892C9CC3EF67CA0375 /* Response.swift */; }; + E702D99CA55B52C306544C4DDF9083DA /* MJRefreshBackGifFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 50DD20A7091C1AF20BBDAE8FF40C638E /* MJRefreshBackGifFooter.m */; }; + E718E500074E8D6B011D53571B27BC0D /* Kingfisher-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 33033614BAFA0628A44D6CE5D2EDBB09 /* Kingfisher-dummy.m */; }; E818AF38E910251104A9A8AFC9227C3C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4B8063291033C95A8B2A24FA2AD7A79 /* Foundation.framework */; }; - E98DC8FB2578E76A812E0C94BA10E1B1 /* ConstraintDirectionalInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01AD1A13BBD29E50BAC17596D47EED9B /* ConstraintDirectionalInsets.swift */; }; - ED3AF010A8D34BC50D7C0D7BE3D2E890 /* JXPagingView-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D0F0E865FFAB434485335DA1629A1388 /* JXPagingView-dummy.m */; }; - EF21586EC3DFF6097A58EEC87376A0C1 /* ConstraintLayoutGuideDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = FABEEC9AF2516E3B746E77F84AD1BD3F /* ConstraintLayoutGuideDSL.swift */; }; - F04A9832815B9EF600EF7387C6882D3D /* DateInRegion+Math.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FD2369502A9924937B397068E453724 /* DateInRegion+Math.swift */; }; - F0AB498412A415474D6105F398614F74 /* JXSegmentedComponetGradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F780BDE3AA3E75F9B115272AAFD28A9E /* JXSegmentedComponetGradientView.swift */; }; - F0DF27608B184B348B3127233761F4BA /* ExtensionHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8E1418AF8EB9AC57EA5BDC745EE7216 /* ExtensionHelpers.swift */; }; - F3B5353C1CDE6C2DD2E80F32D3637750 /* SessionDataTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4E70BC82C57A65822AE2D5EB9D6201 /* SessionDataTask.swift */; }; - F3EC0ED4BED8DD2C3222C7DCAC2452D2 /* JXSegmentedTitleAttributeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB0F871541AF0A23961743411FF66100 /* JXSegmentedTitleAttributeCell.swift */; }; - F404BFA0E5F2CFF051688C90B319AC85 /* AnimatedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D7A0F2127AEF6AA887F6668525FA08 /* AnimatedImageView.swift */; }; - F4DD0AD58DDD5641BDEAEA6CF44FF0ED /* Protected.swift in Sources */ = {isa = PBXBuildFile; fileRef = 267268BCAAF578FB1C90F6F623ABCFF2 /* Protected.swift */; }; - F4E0886D3A9B4FC44D50099AD867A839 /* IQToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD54F4811AE511D52253868A482B0282 /* IQToolbar.swift */; }; - F69925E3D8812AAFC099940721D12AEC /* Locales.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B3C33514BEE5D1F1405B8A6BB47511D /* Locales.swift */; }; - F77280E74EB91678AA294E66DD6070E2 /* SVProgressAnimatedView.h in Headers */ = {isa = PBXBuildFile; fileRef = E9EBABB97D904EE628416E05BCE58900 /* SVProgressAnimatedView.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F7C0960CEEB8F0C18F4503B405EAC08F /* ConstraintMultiplierTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFF930183A98B76DFC6E381963A1F56A /* ConstraintMultiplierTarget.swift */; }; - F7E576E007A81E0EFD2E0849CB17878D /* WebSocketRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B714CDE211483876F8D71E98D218A3 /* WebSocketRequest.swift */; }; - F953AA9104BFE0C2DAD639EA60104A75 /* ConstraintView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D98B938C502BAD501835A48A8F2DCC2 /* ConstraintView+Extensions.swift */; }; + E8AD52B68BDE7B679B358601CCAB3F2D /* UICollectionViewLayout+MJRefresh.h in Headers */ = {isa = PBXBuildFile; fileRef = A418AA4ADA9598EFD690FF4427F182A5 /* UICollectionViewLayout+MJRefresh.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E94B31DCAF75D93405D3BAE188604EB2 /* ConstraintConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0837DA8FB2DF8148CEE1EA57A72EE570 /* ConstraintConfig.swift */; }; + EB126B698D642942058D9B676EC1E32B /* MJRefreshConst.m in Sources */ = {isa = PBXBuildFile; fileRef = 27798DCE9459ACACF37012755F087DB9 /* MJRefreshConst.m */; }; + ECAA15FA3C4560E3287F2226EC8C1ECF /* IQKeyboardManagerConstantsInternal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398152B547C8B96AD8C376F10BEB5701 /* IQKeyboardManagerConstantsInternal.swift */; }; + ED3AF010A8D34BC50D7C0D7BE3D2E890 /* JXPagingView-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 04446B3B53853AB15AE3B7B85CF9343D /* JXPagingView-dummy.m */; }; + EF9B92EF4A0412D775FA55E4D1CB7A45 /* MJRefreshConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = BB17A1319D51982E2F7A99EFC3D11F38 /* MJRefreshConfig.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EFC90283F9AB43BB6FF377812BD3673F /* ConstraintPriority.swift in Sources */ = {isa = PBXBuildFile; fileRef = A78C6D5D45F26A283595741E6566040D /* ConstraintPriority.swift */; }; + F00E48AB2D923607D9B91DC61DBDEB8F /* MJRefreshAutoGifFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = A10B7F476AA2BC85DA32CDCA695E94CF /* MJRefreshAutoGifFooter.m */; }; + F04A9832815B9EF600EF7387C6882D3D /* DateInRegion+Math.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C554CE5C82E098DD3FF24BA75EE7490 /* DateInRegion+Math.swift */; }; + F0AB498412A415474D6105F398614F74 /* JXSegmentedComponetGradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36E3BC01C35A4242976E6B95431C9F17 /* JXSegmentedComponetGradientView.swift */; }; + F0DF27608B184B348B3127233761F4BA /* ExtensionHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFCB35EFBB8A545F2F8352A7D27D5B2A /* ExtensionHelpers.swift */; }; + F2E9C9068E8434E9FC9B60755A354FA8 /* MJRefreshBackNormalFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1C8F4284CBAD963633A64783E4CFB37D /* MJRefreshBackNormalFooter.m */; }; + F366D04DEA0EBBCA9CA4F1F4E29695E8 /* ConstraintDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A92A995C2CF52A57109B1F08F9E6044 /* ConstraintDSL.swift */; }; + F3B5353C1CDE6C2DD2E80F32D3637750 /* SessionDataTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61585200C65A159F5B6731050D64BA59 /* SessionDataTask.swift */; }; + F3EC0ED4BED8DD2C3222C7DCAC2452D2 /* JXSegmentedTitleAttributeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E95438C214C29A3893A1B32DE8B1898F /* JXSegmentedTitleAttributeCell.swift */; }; + F404BFA0E5F2CFF051688C90B319AC85 /* AnimatedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8138B9E4A2A6AA8C683562DF69844549 /* AnimatedImageView.swift */; }; + F47587932A67D8E3820DAFD9A0E1995E /* IQPlaceholderable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC2D820ED623D3C956582179E970607 /* IQPlaceholderable.swift */; }; + F4DD0AD58DDD5641BDEAEA6CF44FF0ED /* Protected.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DB30FE6997717CE3E7589C60A9C7A9E /* Protected.swift */; }; + F69925E3D8812AAFC099940721D12AEC /* Locales.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2752DAD78FD744FDF40B54ADB0708E81 /* Locales.swift */; }; + F7E576E007A81E0EFD2E0849CB17878D /* WebSocketRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = A793885CE536998701B9632A60B45781 /* WebSocketRequest.swift */; }; + F94703ED86C58DDBE5A2503D148CD040 /* ConstraintRelation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7477826A60436064D61A5EFA564B9D6F /* ConstraintRelation.swift */; }; FA1E35E6DE6EC8A9E5E2B12A414E1B70 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A2A128F3FAE37601751167FDC47182A /* CFNetwork.framework */; }; - FAB03959C2357E325B19E08BC4775DAB /* ConstraintMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 014C66675810A411BF2633383898D51D /* ConstraintMaker.swift */; }; - FB2EEA5AF5278F76CD7366B23CC66815 /* ImageView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7746FB2D26EF54C07CCBA2B580E80230 /* ImageView+Kingfisher.swift */; }; - FCE62086E1AB54A4F61EBCDBA15C1510 /* EventMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F1F2DD34925CE8FB29B1319F19DEE3 /* EventMonitor.swift */; }; - FCEB3C1A7FCD1518AF8985822E2E14AA /* ImageProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0601225BD77C06D730B494562E9F9229 /* ImageProcessor.swift */; }; - FDEB8D2D369F9FEBF8FC3D822E5C96C6 /* JXPagingMainTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C8A901F12C600B3F5FF1554147E17FE /* JXPagingMainTableView.swift */; }; + FB2EEA5AF5278F76CD7366B23CC66815 /* ImageView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A296F41C13699333333D3C630E92F80 /* ImageView+Kingfisher.swift */; }; + FC524E181A75784881A12562BDB00CC6 /* MJRefreshAutoGifFooter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1624F448C0756E91DC913FD781A9A9EC /* MJRefreshAutoGifFooter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FC745954D9A2704BCACCB3A03336976E /* UIScrollView+MJExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 3B4DD5E3C3843A80F1882655B380DCDA /* UIScrollView+MJExtension.m */; }; + FCE62086E1AB54A4F61EBCDBA15C1510 /* EventMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393CAB07C81E1F3ACA4DDB1CAB615E1B /* EventMonitor.swift */; }; + FCEB3C1A7FCD1518AF8985822E2E14AA /* ImageProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 662BA990AF2EEE7892AF8EA530C1AE31 /* ImageProcessor.swift */; }; + FDEB8D2D369F9FEBF8FC3D822E5C96C6 /* JXPagingMainTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB420F181A7222985A450867020EFB2C /* JXPagingMainTableView.swift */; }; FE8F4A5C40BA40C835CA301C92AED5E0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4B8063291033C95A8B2A24FA2AD7A79 /* Foundation.framework */; }; - FEC85148AFF458241FDD707C5BA8CD40 /* TimePeriod+Support.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1989579A81204690482F69CF91196CC1 /* TimePeriod+Support.swift */; }; - FEDB5503231B230FDA7C7A25EAB38318 /* DateComponents+Extras.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F5CAE7EE7E6C725618BA82F8F9711D0 /* DateComponents+Extras.swift */; }; - FFD43D91BF1FA4ADF714D56E7A10B2A8 /* SVProgressHUD-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C63097B44D599B12E8CEF1425112BEA1 /* SVProgressHUD-dummy.m */; }; + FEC85148AFF458241FDD707C5BA8CD40 /* TimePeriod+Support.swift in Sources */ = {isa = PBXBuildFile; fileRef = 725764D6EDA104D9902913F6D02AB7FF /* TimePeriod+Support.swift */; }; + FEDB5503231B230FDA7C7A25EAB38318 /* DateComponents+Extras.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF512DBF4BC4483F9F306E2B3A5CDB70 /* DateComponents+Extras.swift */; }; + FF886124915FEF2A6FBB663CA621B4FC /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C07BEF0CE5DECC5BDCAC8625BF2FFA4B /* QuartzCore.framework */; }; + FFD7E1B8FA0F3960BE24DA2D20647332 /* ConstraintRelatableTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = C483D88FC9B266C71FB54AA488C58BBD /* ConstraintRelatableTarget.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 14CFBBAAE542CF39A18203BDB5B9BFF8 /* PBXContainerItemProxy */ = { + 04009532C9602DFA4571AF336AFB7C5C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = E863A9A96F52A35F47491E7B41ECEF9A; - remoteInfo = JXSegmentedView; + remoteGlobalIDString = B26054DF1DEA11585A231AF6D1D80D5E; + remoteInfo = "MJRefresh-MJRefresh.Privacy"; }; - 337E73A4312787E508FB5683B01CA08C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 19622742EBA51E823D6DAE3F8CDBFAD4; - remoteInfo = SnapKit; - }; - 3BFEE7E797791F14CB73632777FC7E0A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B2B2AD5303610D8EBEA025B2660C8EC5; - remoteInfo = "JXPagingView-JXPagingView"; - }; - 4B054C05A7B4D35DAC66F62602DBBBA8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = C4E1020AF425614337737213AA26DBD5; - remoteInfo = JXPagingView; - }; - 641D58C69E949A855265B8A2A3DF416D /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 976126A1CE06DC6E162563800E1BDF14; - remoteInfo = "Alamofire-Alamofire"; - }; - 86E184579D2A3A2E9E152CB03CD170CA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = EAAA1AD3A8A1B59AB91319EE40752C6D; - remoteInfo = Alamofire; - }; - 8E906C346976DD165C3801A68B69CA36 /* PBXContainerItemProxy */ = { + 0A0E1A8C5689F0474D3549298F7E19CB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = 9828BBC09E9FB1238624113D7456E59E; remoteInfo = "Kingfisher-Kingfisher"; }; - 9E0BC0EAEF34022CBA17D9D2C31CA096 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 52F43AC38D9FF80196C69FB03AEEFDDA; - remoteInfo = "JXSegmentedView-JXSegmentedView"; - }; - D286B63CF5B76BA9E11E563F7C46E005 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = E8022D22FAA6690B5E1C379C1BCE1491; - remoteInfo = Kingfisher; - }; - E5CF03012635B743F552559DE12FB67B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 6038CE6006EFBE9D905454CF01909C42; - remoteInfo = SwiftDate; - }; - FC6F7551C370BC1C321567C80999546D /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B490E7485944099E16C9CBD79119D1D4; - remoteInfo = IQKeyboardManagerSwift; - }; - FFFD2037F7EB41815943CEB089778B47 /* PBXContainerItemProxy */ = { + 142BCA0E13C05E1A83FB4666F22A1552 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = 1C8D67D8B72D6BA42CCEDB648537A340; remoteInfo = SVProgressHUD; }; + 201623F455C6F19F61031B03545147D2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6868056D761E163D10FDAF8CF1C4D9B8; + remoteInfo = MJRefresh; + }; + 2799C4D2D7768534EDE92F178DE24D47 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B490E7485944099E16C9CBD79119D1D4; + remoteInfo = IQKeyboardManagerSwift; + }; + 2C2690B3E48F2A7DAC7365AE33F00B17 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B2B2AD5303610D8EBEA025B2660C8EC5; + remoteInfo = "JXPagingView-JXPagingView"; + }; + 2D57819E56EE60F3DF2C6E678E7D3569 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E863A9A96F52A35F47491E7B41ECEF9A; + remoteInfo = JXSegmentedView; + }; + 30FFF29F3A02744304E52EE68F953BF3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EAAA1AD3A8A1B59AB91319EE40752C6D; + remoteInfo = Alamofire; + }; + 44996704F085A77FFFD3669AD2AD3058 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 52F43AC38D9FF80196C69FB03AEEFDDA; + remoteInfo = "JXSegmentedView-JXSegmentedView"; + }; + 4679EE8967F1A89961ECB2793E44547B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8A8DB685241263AFDF5E6B20FE67B93A; + remoteInfo = "SnapKit-SnapKit_Privacy"; + }; + 668AF990E71B0FD610A0100A739B125C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C4E1020AF425614337737213AA26DBD5; + remoteInfo = JXPagingView; + }; + 7912D6332CD6248A05C5E894EA0DE591 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 19622742EBA51E823D6DAE3F8CDBFAD4; + remoteInfo = SnapKit; + }; + A7BFC44123CBC428C300871C2A5C0B39 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6038CE6006EFBE9D905454CF01909C42; + remoteInfo = SwiftDate; + }; + D80071531B55B03F9F25899249DEDFC3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 976126A1CE06DC6E162563800E1BDF14; + remoteInfo = "Alamofire-Alamofire"; + }; + E34EB63D4E4B105244F3DA6DA3F80E0D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E8022D22FAA6690B5E1C379C1BCE1491; + remoteInfo = Kingfisher; + }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 007D1989958B519F880D7E7993017377 /* CachedResponseHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CachedResponseHandler.swift; path = Source/Features/CachedResponseHandler.swift; sourceTree = ""; }; - 00B510B9BAFAF4B6D74A60254B99F26E /* TimeStructures.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TimeStructures.swift; path = Sources/SwiftDate/Supports/TimeStructures.swift; sourceTree = ""; }; - 014C66675810A411BF2633383898D51D /* ConstraintMaker.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMaker.swift; path = Sources/ConstraintMaker.swift; sourceTree = ""; }; - 01AD1A13BBD29E50BAC17596D47EED9B /* ConstraintDirectionalInsets.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDirectionalInsets.swift; path = Sources/ConstraintDirectionalInsets.swift; sourceTree = ""; }; - 02B20B40A566E7F7A9D3CA9FD8FE353B /* GraphicsContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GraphicsContext.swift; path = Sources/Image/GraphicsContext.swift; sourceTree = ""; }; - 02BF3CA1A4DE19EBC809FFFBC30556D9 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Sources/PrivacyInfo.xcprivacy; sourceTree = ""; }; - 03494EF27E38F8E4F8F6A831E3C45FE7 /* IQUIViewController+Additions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIViewController+Additions.swift"; path = "IQKeyboardManagerSwift/Categories/IQUIViewController+Additions.swift"; sourceTree = ""; }; - 03AFFBAA3AD566778A561F1FB11DD0AE /* JXSegmentedTitleImageCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleImageCell.swift; path = Sources/TitleImage/JXSegmentedTitleImageCell.swift; sourceTree = ""; }; - 03CB6A229CF84BA1622B096CE234952C /* ConstraintMakerRelatable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerRelatable.swift; path = Sources/ConstraintMakerRelatable.swift; sourceTree = ""; }; - 03F1AFA1CC231FD02BDF99D7579908AC /* Date+Math.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Date+Math.swift"; path = "Sources/SwiftDate/Date/Date+Math.swift"; sourceTree = ""; }; - 0457F1A1D877D4B914DE716739D328E1 /* ConstraintDescription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDescription.swift; path = Sources/ConstraintDescription.swift; sourceTree = ""; }; - 05E103BDBB854A87B92514983DFE7F29 /* ImageDataProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDataProvider.swift; path = Sources/General/ImageSource/ImageDataProvider.swift; sourceTree = ""; }; - 0601225BD77C06D730B494562E9F9229 /* ImageProcessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageProcessor.swift; path = Sources/Image/ImageProcessor.swift; sourceTree = ""; }; - 067DAF837200693933CD063D222B31FC /* UploadRequest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UploadRequest.swift; path = Source/Core/UploadRequest.swift; sourceTree = ""; }; + 000257BCD6570C4B0371D660CCF8D3E1 /* DotNetParserFormatter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DotNetParserFormatter.swift; path = Sources/SwiftDate/Formatters/DotNetParserFormatter.swift; sourceTree = ""; }; + 0082002FD60B11229524482ADA592954 /* MJRefreshComponent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshComponent.h; path = MJRefresh/Base/MJRefreshComponent.h; sourceTree = ""; }; + 02D1EC547B26205284A72A9F9473EB73 /* Indicator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Indicator.swift; path = Sources/Views/Indicator.swift; sourceTree = ""; }; + 03538AE63A9932FE6DD18C82468E190F /* MJRefreshConst.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshConst.h; path = MJRefresh/MJRefreshConst.h; sourceTree = ""; }; + 035EB38FC9B73D3AFE4C25920C1A1C32 /* RequestModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestModifier.swift; path = Sources/Networking/RequestModifier.swift; sourceTree = ""; }; + 04446B3B53853AB15AE3B7B85CF9343D /* JXPagingView-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "JXPagingView-dummy.m"; sourceTree = ""; }; + 05A41A0B8D148A4BA10DC25292FA63E6 /* Combine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Combine.swift; path = Source/Features/Combine.swift; sourceTree = ""; }; + 07490687930290E2CF12D183E94326BF /* IQKeyboardManager+UITextFieldViewNotification.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+UITextFieldViewNotification.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+UITextFieldViewNotification.swift"; sourceTree = ""; }; 07928762D9A8551470DAAD7C1E1F53A5 /* JXSegmentedView */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = JXSegmentedView; path = JXSegmentedView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 0805789482CC6182F98FE7236D8D83BE /* IQKeyboardReturnKeyHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardReturnKeyHandler.swift; path = IQKeyboardManagerSwift/IQKeyboardReturnKeyHandler.swift; sourceTree = ""; }; + 0837DA8FB2DF8148CEE1EA57A72EE570 /* ConstraintConfig.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintConfig.swift; path = Sources/ConstraintConfig.swift; sourceTree = ""; }; 085DBCE7DD98588B2ED103B1C1F36026 /* Alamofire-Alamofire */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "Alamofire-Alamofire"; path = Alamofire.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; - 086CE1250364E2AA597A5C1956BE37AB /* JXPagingView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXPagingView.swift; path = Sources/JXPagingView/JXPagingView.swift; sourceTree = ""; }; - 09203F4D31B935FBE7056B3EEBF52D09 /* JXSegmentedTitleGradientCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleGradientCell.swift; path = Sources/TitleGradient/JXSegmentedTitleGradientCell.swift; sourceTree = ""; }; - 0C763B3088899119C0227AA4D0ECD4F7 /* Constraint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Constraint.swift; path = Sources/Constraint.swift; sourceTree = ""; }; - 0E33C97B5283CD7B31E6C56118C99CB3 /* FormatIndicatedCacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FormatIndicatedCacheSerializer.swift; path = Sources/Cache/FormatIndicatedCacheSerializer.swift; sourceTree = ""; }; - 0E59570FEEE578BB8DA85857824B7375 /* URLSessionConfiguration+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLSessionConfiguration+Alamofire.swift"; path = "Source/Extensions/URLSessionConfiguration+Alamofire.swift"; sourceTree = ""; }; + 08D053BD683C26F73E7D5BAADC8A4FEF /* ImageDrawing.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDrawing.swift; path = Sources/Image/ImageDrawing.swift; sourceTree = ""; }; + 08E28C2D9A6137B156647AC16D95A15E /* URLEncodedFormEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = URLEncodedFormEncoder.swift; path = Source/Features/URLEncodedFormEncoder.swift; sourceTree = ""; }; + 09B2FF8925A3677E79E08183E04491D1 /* JXSegmentedIndicatorTriangleView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorTriangleView.swift; path = Sources/Indicator/JXSegmentedIndicatorTriangleView.swift; sourceTree = ""; }; + 0A704FDB2D535D699FD2D53CC6DFFC70 /* JXSegmentedNumberItemModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedNumberItemModel.swift; path = Sources/Number/JXSegmentedNumberItemModel.swift; sourceTree = ""; }; + 0A8B5D1A6CBAD8FC5DA5D3D0DA7512BE /* JXSegmentedTitleOrImageCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleOrImageCell.swift; path = Sources/TitleOrImage/JXSegmentedTitleOrImageCell.swift; sourceTree = ""; }; + 0AB50AF41FD17FD4D634D6CB5152810D /* OperationQueue+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "OperationQueue+Alamofire.swift"; path = "Source/Extensions/OperationQueue+Alamofire.swift"; sourceTree = ""; }; + 0DB2B3B9A91393821FCD01D47CB39B40 /* JXSegmentedView.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = JXSegmentedView.debug.xcconfig; sourceTree = ""; }; + 0DB30FE6997717CE3E7589C60A9C7A9E /* Protected.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Protected.swift; path = Source/Core/Protected.swift; sourceTree = ""; }; + 0E81980AF59D081E0E8A9761D1C422BF /* JXSegmentedIndicatorBaseView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorBaseView.swift; path = Sources/Indicator/JXSegmentedIndicatorBaseView.swift; sourceTree = ""; }; + 0EA5D2A634B9432EA862513BDE2A5ED4 /* URLRequest+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLRequest+Alamofire.swift"; path = "Source/Extensions/URLRequest+Alamofire.swift"; sourceTree = ""; }; + 0EC583B42A01E6257C74C1DCD53164A8 /* SVProgressHUD-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SVProgressHUD-dummy.m"; sourceTree = ""; }; 0EE185594AC917D6AC98B5601D843EDA /* Pods-MusicPlayer-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-MusicPlayer-frameworks.sh"; sourceTree = ""; }; - 0FA5B49E1B796D739442A55E81329C1C /* RequestTaskMap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestTaskMap.swift; path = Source/Core/RequestTaskMap.swift; sourceTree = ""; }; - 0FEB76C2B6C718226251B5CBDA7A3540 /* ConstraintViewDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintViewDSL.swift; path = Sources/ConstraintViewDSL.swift; sourceTree = ""; }; 1199E580C5F19AFD1010FE20258DADBD /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; - 11E5886F19EFFF862FFFA5B536854A3C /* Kingfisher-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-umbrella.h"; sourceTree = ""; }; - 123F9D355B6FA77F1C0BBFDFB7DCEFC2 /* ImageFormat.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageFormat.swift; path = Sources/Image/ImageFormat.swift; sourceTree = ""; }; - 126C50DAB71E48A6A012ECFB4420D997 /* JXSegmentedNumberItemModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedNumberItemModel.swift; path = Sources/Number/JXSegmentedNumberItemModel.swift; sourceTree = ""; }; - 12B322F6069250C5291A6856F3F5F19B /* JXSegmentedView-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "JXSegmentedView-prefix.pch"; sourceTree = ""; }; - 12EAC48C11B1824841992EFCD031F4CF /* Placeholder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Placeholder.swift; path = Sources/Image/Placeholder.swift; sourceTree = ""; }; + 11AF900AC1C5B4CD4047B709266568E5 /* DispatchQueue+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DispatchQueue+Alamofire.swift"; path = "Source/Extensions/DispatchQueue+Alamofire.swift"; sourceTree = ""; }; + 11E47356E556750015100B2119302E53 /* JXSegmentedIndicatorImageView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorImageView.swift; path = Sources/Indicator/JXSegmentedIndicatorImageView.swift; sourceTree = ""; }; + 1294C0C419D6967DAAFC5C21609CAAAF /* ConstraintMultiplierTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMultiplierTarget.swift; path = Sources/ConstraintMultiplierTarget.swift; sourceTree = ""; }; + 12A6ED7989C6F4843507D223BD102CC5 /* URLSessionConfiguration+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLSessionConfiguration+Alamofire.swift"; path = "Source/Extensions/URLSessionConfiguration+Alamofire.swift"; sourceTree = ""; }; + 13184921F92E5D84095DD92314A9A4EA /* MJRefreshTrailer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshTrailer.m; path = MJRefresh/Base/MJRefreshTrailer.m; sourceTree = ""; }; + 135384F59FC764376A1E1806D1B43835 /* JXSegmentedIndicatorGradientView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorGradientView.swift; path = Sources/Indicator/JXSegmentedIndicatorGradientView.swift; sourceTree = ""; }; + 136FDCF413CE3C1DC00030DAFFF9A94F /* MJRefreshBackFooter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshBackFooter.m; path = MJRefresh/Base/MJRefreshBackFooter.m; sourceTree = ""; }; 137651D4B8A2CAB9ADEE7E77FCB50B0C /* Pods-MusicPlayer-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-MusicPlayer-dummy.m"; sourceTree = ""; }; - 13F50E8CD9EED0FF95C7743EBA58ECB4 /* IQKeyboardManager+Position.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+Position.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+Position.swift"; sourceTree = ""; }; - 13F72F1929EF4D62E0B78F56864FF024 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Sources/PrivacyInfo.xcprivacy; sourceTree = ""; }; - 1420FB96B25110EF4B6D376EFD05F3D8 /* JXPagingView.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = JXPagingView.modulemap; sourceTree = ""; }; - 149557C3AB89BD20814904E291880583 /* StringEncoding+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "StringEncoding+Alamofire.swift"; path = "Source/Extensions/StringEncoding+Alamofire.swift"; sourceTree = ""; }; - 14B2FD7F1C5BA01262CA8DA89FC19A86 /* ConstraintDirectionalInsetTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDirectionalInsetTarget.swift; path = Sources/ConstraintDirectionalInsetTarget.swift; sourceTree = ""; }; - 156E359C7D79A3E1C10A8B625DB45E59 /* DiskStorage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DiskStorage.swift; path = Sources/Cache/DiskStorage.swift; sourceTree = ""; }; + 1383471ECB9F37892C9CC3EF67CA0375 /* Response.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Response.swift; path = Source/Core/Response.swift; sourceTree = ""; }; + 1384016DEBC0AD27C484B338B4FBEDB5 /* ConstraintLayoutGuide.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutGuide.swift; path = Sources/ConstraintLayoutGuide.swift; sourceTree = ""; }; + 13AB468987C8A41B4D5D6B895F8B9A6F /* JXSegmentedView.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = JXSegmentedView.modulemap; sourceTree = ""; }; + 14052CB3D5057DCF4593BD1E77D90942 /* ConstraintDirectionalInsets.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDirectionalInsets.swift; path = Sources/ConstraintDirectionalInsets.swift; sourceTree = ""; }; + 142F33BE61F0E752B876C5145BE8D812 /* JXPagingSmoothView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXPagingSmoothView.swift; path = Sources/JXPagingView/JXPagingSmoothView.swift; sourceTree = ""; }; + 1434E2DF42114AA07FFC65F0AF74B738 /* MJRefresh.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefresh.h; path = MJRefresh/MJRefresh.h; sourceTree = ""; }; + 14C0D566F3A17E2E2DBDE4098F711125 /* Date+Components.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Date+Components.swift"; path = "Sources/SwiftDate/Date/Date+Components.swift"; sourceTree = ""; }; 15E14083D6A2AB230F81705892CB4520 /* Pods-MusicPlayer.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-MusicPlayer.modulemap"; sourceTree = ""; }; - 169771C1499556CFFC8826DA446C2612 /* TimePeriodProtocol.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TimePeriodProtocol.swift; path = Sources/SwiftDate/TimePeriod/TimePeriodProtocol.swift; sourceTree = ""; }; - 17AA6D7827F1E01C2A8379EA8543ED13 /* ISOParser.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ISOParser.swift; path = Sources/SwiftDate/Formatters/ISOParser.swift; sourceTree = ""; }; - 17E2B3692AE65F40EC23C3140816F5E2 /* SwiftDate-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftDate-umbrella.h"; sourceTree = ""; }; - 18E3BBCE92E077B287C988B88A527154 /* KFImageProtocol.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFImageProtocol.swift; path = Sources/SwiftUI/KFImageProtocol.swift; sourceTree = ""; }; - 1989579A81204690482F69CF91196CC1 /* TimePeriod+Support.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "TimePeriod+Support.swift"; path = "Sources/SwiftDate/TimePeriod/TimePeriod+Support.swift"; sourceTree = ""; }; - 19A8250492A7EB690EF84D025A6F171D /* MultipartFormData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultipartFormData.swift; path = Source/Features/MultipartFormData.swift; sourceTree = ""; }; - 1A778C04C8D2699D2DED1B1600517215 /* TimeInterval+Formatter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "TimeInterval+Formatter.swift"; path = "Sources/SwiftDate/Foundation+Extras/TimeInterval+Formatter.swift"; sourceTree = ""; }; - 1AC2B39FA1F6CBF8CD4718489EA8F09E /* TimePeriodGroup.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TimePeriodGroup.swift; path = Sources/SwiftDate/TimePeriod/Groups/TimePeriodGroup.swift; sourceTree = ""; }; - 1B4E6F9C722A37921CB299D06E531578 /* DispatchQueue+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DispatchQueue+Alamofire.swift"; path = "Source/Extensions/DispatchQueue+Alamofire.swift"; sourceTree = ""; }; + 1624F448C0756E91DC913FD781A9A9EC /* MJRefreshAutoGifFooter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshAutoGifFooter.h; path = MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.h; sourceTree = ""; }; + 1A26B70DABA1CBACD8166FC00D07C081 /* KFOptionsSetter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFOptionsSetter.swift; path = Sources/General/KFOptionsSetter.swift; sourceTree = ""; }; + 1A8F4312D81FC10BD8029BE851C76498 /* AlamofireExtended.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AlamofireExtended.swift; path = Source/Features/AlamofireExtended.swift; sourceTree = ""; }; + 1AAB28B6A1A5AA4CC4A0EEB258D9DC57 /* SVProgressAnimatedView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SVProgressAnimatedView.h; path = SVProgressHUD/SVProgressAnimatedView.h; sourceTree = ""; }; 1BBB6DE3AF0E150160FD2FA346CC6CD6 /* Pods-MusicPlayer-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-MusicPlayer-umbrella.h"; sourceTree = ""; }; - 1C07796D011ECD3006D3BA479CD6C93C /* JXSegmentedTitleOrImageCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleOrImageCell.swift; path = Sources/TitleOrImage/JXSegmentedTitleOrImageCell.swift; sourceTree = ""; }; - 1C47E79C3926F155B6C7EC94D87F0C5B /* URLEncodedFormEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = URLEncodedFormEncoder.swift; path = Source/Features/URLEncodedFormEncoder.swift; sourceTree = ""; }; - 1E1C7FC14F4B42EDC20FE49A9E3D581F /* IQKeyboardManagerSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "IQKeyboardManagerSwift-prefix.pch"; sourceTree = ""; }; - 1E4763CB38C57143759CBF3728786434 /* NSTextAttachment+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSTextAttachment+Kingfisher.swift"; path = "Sources/Extensions/NSTextAttachment+Kingfisher.swift"; sourceTree = ""; }; - 1EE1A2A286DF3C313266DAA14C61273E /* SVRadialGradientLayer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SVRadialGradientLayer.m; path = SVProgressHUD/SVRadialGradientLayer.m; sourceTree = ""; }; - 1EF8045540E68DD0F0CB57EA73DC4DE1 /* ConstraintConfig.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintConfig.swift; path = Sources/ConstraintConfig.swift; sourceTree = ""; }; - 1F5CAE7EE7E6C725618BA82F8F9711D0 /* DateComponents+Extras.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DateComponents+Extras.swift"; path = "Sources/SwiftDate/Foundation+Extras/DateComponents+Extras.swift"; sourceTree = ""; }; - 237F6B26512B98501CC693A53DCB92AB /* SwiftDate.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftDate.debug.xcconfig; sourceTree = ""; }; - 23C5673EA0CD0D48D9B6124BE63E96C3 /* IQBarButtonItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQBarButtonItem.swift; path = IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift; sourceTree = ""; }; - 2470434CB358730731625103150715B2 /* JXSegmentedTitleOrImageDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleOrImageDataSource.swift; path = Sources/TitleOrImage/JXSegmentedTitleOrImageDataSource.swift; sourceTree = ""; }; - 24EC295179204A13C2E78DB844ABF4AC /* JXPagingListRefreshView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXPagingListRefreshView.swift; path = Sources/JXPagingView/JXPagingListRefreshView.swift; sourceTree = ""; }; - 25037E4FB7BC7534B013D62B4131021F /* RetryStrategy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RetryStrategy.swift; path = Sources/Networking/RetryStrategy.swift; sourceTree = ""; }; - 2540A9293E8ADAB4B67AF923E8AFC51F /* IQKeyboardManager+Debug.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+Debug.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+Debug.swift"; sourceTree = ""; }; - 25700C90519D6E5662DBD6E110F3AAB9 /* SVRadialGradientLayer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SVRadialGradientLayer.h; path = SVProgressHUD/SVRadialGradientLayer.h; sourceTree = ""; }; - 258A1691BC25E6887D2399F3FA414308 /* SnapKit-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SnapKit-umbrella.h"; sourceTree = ""; }; - 25F1F4699C3C4B6DC02C6B5A89D1AC4A /* RedirectHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RedirectHandler.swift; path = Sources/Networking/RedirectHandler.swift; sourceTree = ""; }; - 25F3DD0AF63950115410158C85035041 /* Alamofire.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Alamofire.modulemap; sourceTree = ""; }; - 267268BCAAF578FB1C90F6F623ABCFF2 /* Protected.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Protected.swift; path = Source/Core/Protected.swift; sourceTree = ""; }; - 278F6659C16FB8FEFA7A2B0F4CCB19AC /* Debugging.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Debugging.swift; path = Sources/Debugging.swift; sourceTree = ""; }; - 28279C39A331FDBCCB4726BA6CC681C6 /* Formatter+Protocols.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Formatter+Protocols.swift"; path = "Sources/SwiftDate/Formatters/Formatter+Protocols.swift"; sourceTree = ""; }; - 28A27DAE3B348C14EA5A36CFA7BF8804 /* JXPagingSmoothView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXPagingSmoothView.swift; path = Sources/JXPagingView/JXPagingSmoothView.swift; sourceTree = ""; }; - 28FE2901B317396EE489A6D5CA08C3FA /* Box.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Box.swift; path = Sources/Utility/Box.swift; sourceTree = ""; }; - 2A05EFFD6130413819CBE3401EB499CF /* IQKeyboardManager+UITextFieldViewNotification.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+UITextFieldViewNotification.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+UITextFieldViewNotification.swift"; sourceTree = ""; }; - 2A3929FB15B816836DB3935DDE677205 /* JXSegmentedIndicatorImageView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorImageView.swift; path = Sources/Indicator/JXSegmentedIndicatorImageView.swift; sourceTree = ""; }; - 2B207E1FC13165182A34EDC2DB916D27 /* Indicator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Indicator.swift; path = Sources/Views/Indicator.swift; sourceTree = ""; }; - 2C39947ECE9F9309B3ED71BEFD21C4BC /* SVProgressHUD.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SVProgressHUD.release.xcconfig; sourceTree = ""; }; - 2D98B938C502BAD501835A48A8F2DCC2 /* ConstraintView+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ConstraintView+Extensions.swift"; path = "Sources/ConstraintView+Extensions.swift"; sourceTree = ""; }; + 1C8C49DCED4EC3826245D19DFC7FA7E9 /* ResourceBundle-JXSegmentedView-JXSegmentedView-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-JXSegmentedView-JXSegmentedView-Info.plist"; sourceTree = ""; }; + 1C8F4284CBAD963633A64783E4CFB37D /* MJRefreshBackNormalFooter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshBackNormalFooter.m; path = MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.m; sourceTree = ""; }; + 1DA3BDF290E39DAB4D1F114C808EB725 /* UICollectionViewLayout+MJRefresh.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UICollectionViewLayout+MJRefresh.m"; path = "MJRefresh/UICollectionViewLayout+MJRefresh.m"; sourceTree = ""; }; + 1DE3D079E059E37BB8233A28ECEF0FC7 /* SVIndefiniteAnimatedView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SVIndefiniteAnimatedView.m; path = SVProgressHUD/SVIndefiniteAnimatedView.m; sourceTree = ""; }; + 1E5CD298A2F13E3902AAA3510FE5C9FD /* AuthenticationChallengeResponsable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AuthenticationChallengeResponsable.swift; path = Sources/Networking/AuthenticationChallengeResponsable.swift; sourceTree = ""; }; + 1EC6A17326897FCD562597FF862EFB28 /* JXSegmentedNumberDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedNumberDataSource.swift; path = Sources/Number/JXSegmentedNumberDataSource.swift; sourceTree = ""; }; + 1F08C4884167A8DF12652D4ADA87DC8E /* MJRefreshBackGifFooter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshBackGifFooter.h; path = MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.h; sourceTree = ""; }; + 1F0A7FCD71890676CE08D3ADDB7CA7B4 /* GraphicsContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GraphicsContext.swift; path = Sources/Image/GraphicsContext.swift; sourceTree = ""; }; + 1F79F3D31F68D650253E6399BB7549D1 /* KFImageProtocol.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFImageProtocol.swift; path = Sources/SwiftUI/KFImageProtocol.swift; sourceTree = ""; }; + 1FF0E1D3C22D93C0C7B2C51A16E17913 /* IQPreviousNextView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQPreviousNextView.swift; path = IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift; sourceTree = ""; }; + 207F4383A0CAE6E946319D62026A82F0 /* SwiftDate-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftDate-umbrella.h"; sourceTree = ""; }; + 2215909E83BE0517F84079C1593E4E85 /* JXSegmentedDotCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedDotCell.swift; path = Sources/Dot/JXSegmentedDotCell.swift; sourceTree = ""; }; + 225AEBA0EC32A3D5A52ECA46DBBED7F3 /* JXSegmentedTitleDynamicConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleDynamicConfiguration.swift; path = Sources/Title/JXSegmentedTitleDynamicConfiguration.swift; sourceTree = ""; }; + 234A9BD48AA1E6813E36334F22C346D4 /* ConstraintInsetTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintInsetTarget.swift; path = Sources/ConstraintInsetTarget.swift; sourceTree = ""; }; + 24091B247B320B28B53B7DB2A0EB996B /* ConstraintMakerPrioritizable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerPrioritizable.swift; path = Sources/ConstraintMakerPrioritizable.swift; sourceTree = ""; }; + 268D0497BC989AF2355C7E9712755278 /* CacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CacheSerializer.swift; path = Sources/Cache/CacheSerializer.swift; sourceTree = ""; }; + 26E33A2601884DE73A47BD1A2690B14F /* ImageTransition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageTransition.swift; path = Sources/Image/ImageTransition.swift; sourceTree = ""; }; + 2752DAD78FD744FDF40B54ADB0708E81 /* Locales.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Locales.swift; path = Sources/SwiftDate/Supports/Locales.swift; sourceTree = ""; }; + 27798DCE9459ACACF37012755F087DB9 /* MJRefreshConst.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshConst.m; path = MJRefresh/MJRefreshConst.m; sourceTree = ""; }; + 280637DA318DC5D912D98194C6844751 /* MJRefreshNormalTrailer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshNormalTrailer.m; path = MJRefresh/Custom/Trailer/MJRefreshNormalTrailer.m; sourceTree = ""; }; + 2820DA7141C1E36BCF6D4D5D96802EAF /* JXSegmentedTitleGradientCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleGradientCell.swift; path = Sources/TitleGradient/JXSegmentedTitleGradientCell.swift; sourceTree = ""; }; + 282ACC9FB46C251345FC5EB3AEF1B9CE /* SVIndefiniteAnimatedView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SVIndefiniteAnimatedView.h; path = SVProgressHUD/SVIndefiniteAnimatedView.h; sourceTree = ""; }; + 2893522A05B1339D4388FD46FF52C52A /* WKInterfaceImage+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "WKInterfaceImage+Kingfisher.swift"; path = "Sources/Extensions/WKInterfaceImage+Kingfisher.swift"; sourceTree = ""; }; + 28BCEACC594F9EA2E10117D26B3DA759 /* CachedResponseHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CachedResponseHandler.swift; path = Source/Features/CachedResponseHandler.swift; sourceTree = ""; }; + 2998944D54451B52A0996B2A9FDDD7DB /* TimeInterval+Formatter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "TimeInterval+Formatter.swift"; path = "Sources/SwiftDate/Foundation+Extras/TimeInterval+Formatter.swift"; sourceTree = ""; }; + 2C9B6C74D874F93335EDA5FBAC20675C /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = SVProgressHUD/PrivacyInfo.xcprivacy; sourceTree = ""; }; + 2E39692FF9A73D5EC6D4AE2DE35E3C0C /* JXSegmentedTitleGradientItemModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleGradientItemModel.swift; path = Sources/TitleGradient/JXSegmentedTitleGradientItemModel.swift; sourceTree = ""; }; + 2E89132366DFF0DC6A319EF946DF4CEA /* JXPagingView-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "JXPagingView-Info.plist"; sourceTree = ""; }; + 2EB8A72B411C5E90471A44666337E7D2 /* ConstraintConstantTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintConstantTarget.swift; path = Sources/ConstraintConstantTarget.swift; sourceTree = ""; }; 2F4A1CCB21DB7EA5A2ACEB11E374FBCA /* JXPagingView */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = JXPagingView; path = JXPagingView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 2F7A731F70FE21FD4DE8310D869C90DD /* JXSegmentedIndicatorBackgroundView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorBackgroundView.swift; path = Sources/Indicator/JXSegmentedIndicatorBackgroundView.swift; sourceTree = ""; }; - 2FA988EC253BB0E37DA9DCBEE6C99E9E /* String+Parser.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+Parser.swift"; path = "Sources/SwiftDate/Foundation+Extras/String+Parser.swift"; sourceTree = ""; }; - 2FD2369502A9924937B397068E453724 /* DateInRegion+Math.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DateInRegion+Math.swift"; path = "Sources/SwiftDate/DateInRegion/DateInRegion+Math.swift"; sourceTree = ""; }; - 2FD30818E5615E1D5255CA94386719F2 /* IQKeyboardManagerSwift-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "IQKeyboardManagerSwift-Info.plist"; sourceTree = ""; }; - 30EF94D6856E6C7203AF8C170322CB4A /* IQKeyboardManager+Toolbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+Toolbar.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+Toolbar.swift"; sourceTree = ""; }; - 3219E80F1D4ABFEBA0A158FD5D5F5591 /* Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Kingfisher.swift; path = Sources/General/Kingfisher.swift; sourceTree = ""; }; - 342970F609D91209A7F339DC270C0C20 /* JXSegmentedIndicatorLineView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorLineView.swift; path = Sources/Indicator/JXSegmentedIndicatorLineView.swift; sourceTree = ""; }; - 349DDAFE2B858FF1C77548AEB5A9024F /* Date+Compare.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Date+Compare.swift"; path = "Sources/SwiftDate/Date/Date+Compare.swift"; sourceTree = ""; }; - 36893E4F6E35B5AF8060ABB0AAA6C6BF /* Date.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Date.swift; path = Sources/SwiftDate/Date/Date.swift; sourceTree = ""; }; - 379DC6E350D05131719D9E95995D51D1 /* JXSegmentedIndicatorRainbowLineView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorRainbowLineView.swift; path = Sources/Indicator/JXSegmentedIndicatorRainbowLineView.swift; sourceTree = ""; }; - 37B75E2E8CD6D8FBCEEA2C814BD288E2 /* Alamofire.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Alamofire.debug.xcconfig; sourceTree = ""; }; - 384CCE46006CEC00E0ADA0DB1232170E /* SVProgressHUD.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SVProgressHUD.h; path = SVProgressHUD/SVProgressHUD.h; sourceTree = ""; }; - 39F93B4F6F36C41FDDD2C63E96361841 /* ConstraintInsets.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintInsets.swift; path = Sources/ConstraintInsets.swift; sourceTree = ""; }; - 3A21A5D82E7614E60D1FBD7885945FCE /* TimePeriodCollection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TimePeriodCollection.swift; path = Sources/SwiftDate/TimePeriod/Groups/TimePeriodCollection.swift; sourceTree = ""; }; - 3B3C33514BEE5D1F1405B8A6BB47511D /* Locales.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Locales.swift; path = Sources/SwiftDate/Supports/Locales.swift; sourceTree = ""; }; - 3B97DDE49382A64974F6385E6313AD53 /* SwiftDate-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftDate-dummy.m"; sourceTree = ""; }; - 3BB776688BCCFEAA2C9D7ADDE83D4CA3 /* SnapKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SnapKit.release.xcconfig; sourceTree = ""; }; - 3BE3F2A07329201502F823489AF74A99 /* JXPagingView-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "JXPagingView-Info.plist"; sourceTree = ""; }; - 3C78B7DBAF5BC78F4AB22534D3664BF5 /* ResourceBundle-Kingfisher-Kingfisher-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-Kingfisher-Kingfisher-Info.plist"; sourceTree = ""; }; - 3CFDD319BC3DFC1F0C2B65AEB2C7B04F /* ServerTrustEvaluation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerTrustEvaluation.swift; path = Source/Features/ServerTrustEvaluation.swift; sourceTree = ""; }; - 3DFEF57B19765C495039E698F1C7679F /* ConstraintDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDSL.swift; path = Sources/ConstraintDSL.swift; sourceTree = ""; }; - 3E89ECD9194EDFD568A9EF6F17101045 /* ConstraintInsetTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintInsetTarget.swift; path = Sources/ConstraintInsetTarget.swift; sourceTree = ""; }; - 3ECAA08258069FFA67EFC17C35C656B7 /* ConstraintLayoutSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutSupport.swift; path = Sources/ConstraintLayoutSupport.swift; sourceTree = ""; }; - 3F26DAEAF14BD22F7BA131A68C794F8E /* IQKeyboardManagerSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "IQKeyboardManagerSwift-umbrella.h"; sourceTree = ""; }; - 3F7D2073948007C3D9C254DB4DFBBAB8 /* SVProgressHUD.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SVProgressHUD.debug.xcconfig; sourceTree = ""; }; - 3F9310A68A7C4ADA421B3156B5403F7E /* Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Alamofire.swift; path = Source/Alamofire.swift; sourceTree = ""; }; - 3FBE965ECA32AF1AF759DCA0E41A904C /* IQPreviousNextView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQPreviousNextView.swift; path = IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift; sourceTree = ""; }; - 410484E6026824E3DC6B14FC5E7A7F80 /* IQKeyboardManager+OrientationNotification.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+OrientationNotification.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+OrientationNotification.swift"; sourceTree = ""; }; - 4238031501C063D51EF5A23B8F8B99A1 /* JXSegmentedIndicatorGradientLineView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorGradientLineView.swift; path = Sources/Indicator/JXSegmentedIndicatorGradientLineView.swift; sourceTree = ""; }; - 44E1D50EA152F2FA29542A017C52B34A /* SVIndefiniteAnimatedView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SVIndefiniteAnimatedView.m; path = SVProgressHUD/SVIndefiniteAnimatedView.m; sourceTree = ""; }; - 45E2E40D8E912E8E28DCD35E76FA3425 /* AssociatedValues.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AssociatedValues.swift; path = Sources/SwiftDate/Supports/AssociatedValues.swift; sourceTree = ""; }; - 46359F9ADB38A9DAE1A1B6214177702D /* IQKeyboardManager+UIKeyboardNotification.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+UIKeyboardNotification.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+UIKeyboardNotification.swift"; sourceTree = ""; }; - 4650F81AED57651885068C4F1EAA4836 /* JXSegmentedTitleDynamicConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleDynamicConfiguration.swift; path = Sources/Title/JXSegmentedTitleDynamicConfiguration.swift; sourceTree = ""; }; - 487654BCA0B02C5A6F1A496C85CDFC36 /* JXSegmentedTitleGradientDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleGradientDataSource.swift; path = Sources/TitleGradient/JXSegmentedTitleGradientDataSource.swift; sourceTree = ""; }; - 49D7A0F2127AEF6AA887F6668525FA08 /* AnimatedImageView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnimatedImageView.swift; path = Sources/Views/AnimatedImageView.swift; sourceTree = ""; }; - 4A662353E669242D628CA325F3A11119 /* DataRequest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DataRequest.swift; path = Source/Core/DataRequest.swift; sourceTree = ""; }; - 4AC1EA3AB5460CAF71C28DE23506948D /* ImageBinder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageBinder.swift; path = Sources/SwiftUI/ImageBinder.swift; sourceTree = ""; }; - 4ADE20627987FA4EA010036CDEE47000 /* SVProgressAnimatedView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SVProgressAnimatedView.m; path = SVProgressHUD/SVProgressAnimatedView.m; sourceTree = ""; }; - 4AE0D04C04D9D2C94118025EAB921A25 /* DataStreamRequest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DataStreamRequest.swift; path = Source/Core/DataStreamRequest.swift; sourceTree = ""; }; - 4B3EE8956158B369D9D59C65C4D96EA3 /* Date+Components.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Date+Components.swift"; path = "Sources/SwiftDate/Date/Date+Components.swift"; sourceTree = ""; }; - 4B4E70BC82C57A65822AE2D5EB9D6201 /* SessionDataTask.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDataTask.swift; path = Sources/Networking/SessionDataTask.swift; sourceTree = ""; }; - 4B6C0753CD229018B31E3685E1F4B7FC /* KingfisherOptionsInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherOptionsInfo.swift; path = Sources/General/KingfisherOptionsInfo.swift; sourceTree = ""; }; - 4B7CF26B5F28E33AB65201BFB9772E94 /* Concurrency.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Concurrency.swift; path = Source/Features/Concurrency.swift; sourceTree = ""; }; - 4E8F31E23CB0B4C162D0624DB465C98A /* JXSegmentedListContainerView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedListContainerView.swift; path = Sources/Common/JXSegmentedListContainerView.swift; sourceTree = ""; }; - 4EBA3469B966D049CF9C6584ADCE1420 /* OperationQueue+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "OperationQueue+Alamofire.swift"; path = "Source/Extensions/OperationQueue+Alamofire.swift"; sourceTree = ""; }; - 4F1C6EFDCC0D193444D079AD48016EF8 /* JXSegmentedTitleOrImageItemModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleOrImageItemModel.swift; path = Sources/TitleOrImage/JXSegmentedTitleOrImageItemModel.swift; sourceTree = ""; }; - 51AAE5F7671D63A1A83A5E003572F18C /* ConstraintPriority.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintPriority.swift; path = Sources/ConstraintPriority.swift; sourceTree = ""; }; - 53A154F0773A1007FDE314D65058E654 /* langs */ = {isa = PBXFileReference; includeInIndex = 1; name = langs; path = Sources/SwiftDate/Formatters/RelativeFormatter/langs; sourceTree = ""; }; - 53AD73B43463C9D32A0BF66D80A09BFB /* JXSegmentedView.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = JXSegmentedView.release.xcconfig; sourceTree = ""; }; - 540940F677A9EFC1CF5FD25315DE5F5A /* LayoutConstraintItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LayoutConstraintItem.swift; path = Sources/LayoutConstraintItem.swift; sourceTree = ""; }; - 54D73AFB747FAE30C1BB44E19677DBDD /* Alamofire-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-umbrella.h"; sourceTree = ""; }; - 551F872E8F0FDAAED3407034F590B022 /* ISOFormatter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ISOFormatter.swift; path = Sources/SwiftDate/Formatters/ISOFormatter.swift; sourceTree = ""; }; - 5672FA74F6AF0085E780C6D735D8918B /* WKInterfaceImage+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "WKInterfaceImage+Kingfisher.swift"; path = "Sources/Extensions/WKInterfaceImage+Kingfisher.swift"; sourceTree = ""; }; - 56B3AB6B42435ED2BB97F0E60A022953 /* KFImage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFImage.swift; path = Sources/SwiftUI/KFImage.swift; sourceTree = ""; }; - 56E1C515E167FC148720369572DA2FB8 /* TimePeriod.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TimePeriod.swift; path = Sources/SwiftDate/TimePeriod/TimePeriod.swift; sourceTree = ""; }; + 2FBE5C3E144BF69BC982850AFCE42CDB /* IQKeyboardManagerSwift-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "IQKeyboardManagerSwift-Info.plist"; sourceTree = ""; }; + 3050C5DBB1E4F1DF9FD1B33611FDBDAD /* SVProgressHUD.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SVProgressHUD.modulemap; sourceTree = ""; }; + 30D9FC3ABDA982F6CA82384628D6F165 /* RelativeFormatter+Style.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "RelativeFormatter+Style.swift"; path = "Sources/SwiftDate/Formatters/RelativeFormatter/RelativeFormatter+Style.swift"; sourceTree = ""; }; + 31126E0DD1B56D3713965A56F0B05AC8 /* SnapKit-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SnapKit-umbrella.h"; sourceTree = ""; }; + 321C97AD92F4D32E4E33BB5B77FFE0FC /* Storage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Storage.swift; path = Sources/Cache/Storage.swift; sourceTree = ""; }; + 33033614BAFA0628A44D6CE5D2EDBB09 /* Kingfisher-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Kingfisher-dummy.m"; sourceTree = ""; }; + 344A8E805D9E365E5FDF94223860238E /* JXSegmentedDotDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedDotDataSource.swift; path = Sources/Dot/JXSegmentedDotDataSource.swift; sourceTree = ""; }; + 356BE641A77A6E56A217190DD89D8259 /* JXSegmentedView-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "JXSegmentedView-dummy.m"; sourceTree = ""; }; + 36730D770821B0E94A45B2817FC4E2FD /* ImagePrefetcher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImagePrefetcher.swift; path = Sources/Networking/ImagePrefetcher.swift; sourceTree = ""; }; + 368AFBDCEBBA20270829ACA09283D127 /* ParameterEncoding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ParameterEncoding.swift; path = Source/Core/ParameterEncoding.swift; sourceTree = ""; }; + 36E3BC01C35A4242976E6B95431C9F17 /* JXSegmentedComponetGradientView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedComponetGradientView.swift; path = Sources/Indicator/JXSegmentedComponetGradientView.swift; sourceTree = ""; }; + 37C1098A010D1C8E4E069D976A8D8DFD /* JXSegmentedView-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "JXSegmentedView-umbrella.h"; sourceTree = ""; }; + 393CAB07C81E1F3ACA4DDB1CAB615E1B /* EventMonitor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EventMonitor.swift; path = Source/Features/EventMonitor.swift; sourceTree = ""; }; + 398152B547C8B96AD8C376F10BEB5701 /* IQKeyboardManagerConstantsInternal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardManagerConstantsInternal.swift; path = IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstantsInternal.swift; sourceTree = ""; }; + 3A92A995C2CF52A57109B1F08F9E6044 /* ConstraintDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDSL.swift; path = Sources/ConstraintDSL.swift; sourceTree = ""; }; + 3A99AB9AED98C1B656C310507C966514 /* MJRefreshFooter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshFooter.h; path = MJRefresh/Base/MJRefreshFooter.h; sourceTree = ""; }; + 3AB6A380647126E36416E4610575F354 /* JXSegmentedView-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "JXSegmentedView-prefix.pch"; sourceTree = ""; }; + 3AE4A701F7BAB983ED11B504E6487F76 /* MJRefresh.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MJRefresh.debug.xcconfig; sourceTree = ""; }; + 3B4DD5E3C3843A80F1882655B380DCDA /* UIScrollView+MJExtension.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIScrollView+MJExtension.m"; path = "MJRefresh/UIScrollView+MJExtension.m"; sourceTree = ""; }; + 3CF9BAB200D238346E29ED2DBA085B17 /* ImageCache.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageCache.swift; path = Sources/Cache/ImageCache.swift; sourceTree = ""; }; + 3D613FC602AD1B3823E553095A17BB58 /* Image.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Image.swift; path = Sources/Image/Image.swift; sourceTree = ""; }; + 3EF5F786A9CD8F2E78E95733362FE187 /* JXPagingView.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = JXPagingView.debug.xcconfig; sourceTree = ""; }; + 3EFEBDB3A2CB8EFD1E1BB0C882FC6500 /* JXPagingView-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "JXPagingView-umbrella.h"; sourceTree = ""; }; + 3F8AC6801BE5A7B67B8032757817BE51 /* RetryStrategy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RetryStrategy.swift; path = Sources/Networking/RetryStrategy.swift; sourceTree = ""; }; + 40E3CE126BEDA57D7DA923F7BBC49D32 /* IQUIViewController+Additions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIViewController+Additions.swift"; path = "IQKeyboardManagerSwift/Categories/IQUIViewController+Additions.swift"; sourceTree = ""; }; + 418EE8CAF2C7190F191FC7554EAE20D3 /* RelativeFormatterLanguage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RelativeFormatterLanguage.swift; path = Sources/SwiftDate/Formatters/RelativeFormatter/RelativeFormatterLanguage.swift; sourceTree = ""; }; + 4316C38FD6E88F2FFBBB3BC6DF2C26FF /* DownloadRequest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DownloadRequest.swift; path = Source/Core/DownloadRequest.swift; sourceTree = ""; }; + 43FF45102B67E91CC3D79928C2717E40 /* SwiftDate-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftDate-dummy.m"; sourceTree = ""; }; + 440D319A1267C894C2AFFDA3362EBE9E /* Typealiases.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Typealiases.swift; path = Sources/Typealiases.swift; sourceTree = ""; }; + 451FEDBFD2A922230CA33D46534CD7F7 /* JXSegmentedView.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = JXSegmentedView.release.xcconfig; sourceTree = ""; }; + 460F21D69A6B1F9493AACA08A2F865B9 /* JXSegmentedBaseDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedBaseDataSource.swift; path = Sources/Core/JXSegmentedBaseDataSource.swift; sourceTree = ""; }; + 475A4FB59CFB3BBA7FAC2F058F91F6E3 /* AssociatedValues.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AssociatedValues.swift; path = Sources/SwiftDate/Supports/AssociatedValues.swift; sourceTree = ""; }; + 482206CB35A8E05C272FA37C0A8BF762 /* ConstraintLayoutGuideDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutGuideDSL.swift; path = Sources/ConstraintLayoutGuideDSL.swift; sourceTree = ""; }; + 4897326E2C8838615713B47EBE1FAD3D /* ImageProgressive.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageProgressive.swift; path = Sources/Image/ImageProgressive.swift; sourceTree = ""; }; + 49B4649E1D11EB9D32BD3E212382EF1D /* Resource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Resource.swift; path = Sources/General/ImageSource/Resource.swift; sourceTree = ""; }; + 4BE5E05285408F9AA5B005A82CEFDA99 /* ConstraintDescription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDescription.swift; path = Sources/ConstraintDescription.swift; sourceTree = ""; }; + 4C1194040926B2C7D711B859F8AE4312 /* JXSegmentedTitleImageDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleImageDataSource.swift; path = Sources/TitleImage/JXSegmentedTitleImageDataSource.swift; sourceTree = ""; }; + 4C554CE5C82E098DD3FF24BA75EE7490 /* DateInRegion+Math.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DateInRegion+Math.swift"; path = "Sources/SwiftDate/DateInRegion/DateInRegion+Math.swift"; sourceTree = ""; }; + 4CBB6593899E987A5B4300FC21B80983 /* MJRefreshComponent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshComponent.m; path = MJRefresh/Base/MJRefreshComponent.m; sourceTree = ""; }; + 4CDB52D83D152A96E4E9CD244CA95DEA /* KFImageOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFImageOptions.swift; path = Sources/SwiftUI/KFImageOptions.swift; sourceTree = ""; }; + 4DE64A8F508B88F991A85594504A5076 /* ResourceBundle-MJRefresh.Privacy-MJRefresh-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-MJRefresh.Privacy-MJRefresh-Info.plist"; sourceTree = ""; }; + 4E16F379BC5CA8C2B21212962C6FA430 /* IQTextView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQTextView.swift; path = IQKeyboardManagerSwift/IQTextView/IQTextView.swift; sourceTree = ""; }; + 4F1FB2699EA33ABD4EDB7F856D39296F /* JXSegmentedCollectionView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedCollectionView.swift; path = Sources/Core/JXSegmentedCollectionView.swift; sourceTree = ""; }; + 4FDEAE488C153F23CC530F9FC7878CE4 /* JXSegmentedTitleAttributeItemModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleAttributeItemModel.swift; path = Sources/AttributeTitle/JXSegmentedTitleAttributeItemModel.swift; sourceTree = ""; }; + 50DD20A7091C1AF20BBDAE8FF40C638E /* MJRefreshBackGifFooter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshBackGifFooter.m; path = MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.m; sourceTree = ""; }; + 50DD91D5AAEBFBFB4776365998B843B7 /* ConstraintMaker.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMaker.swift; path = Sources/ConstraintMaker.swift; sourceTree = ""; }; + 513DEC141FDDFD1CDAA8ED56A66AF623 /* TimePeriodProtocol.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TimePeriodProtocol.swift; path = Sources/SwiftDate/TimePeriod/TimePeriodProtocol.swift; sourceTree = ""; }; + 51A207FA0764909F90D1FCCDE191F924 /* JXSegmentedBaseItemModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedBaseItemModel.swift; path = Sources/Core/JXSegmentedBaseItemModel.swift; sourceTree = ""; }; + 52C0154703620B58E000A12A7DD03B58 /* IQKeyboardManagerSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "IQKeyboardManagerSwift-prefix.pch"; sourceTree = ""; }; + 52CB2CCAA127ADA834B4CCF4686ECE60 /* IQKeyboardManager+OrientationNotification.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+OrientationNotification.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+OrientationNotification.swift"; sourceTree = ""; }; + 5347F4D40BA296B41A792189CB1331E9 /* Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Alamofire.swift; path = Source/Alamofire.swift; sourceTree = ""; }; + 536595B34971D58E93F91CEFFBA20A22 /* MJRefreshGifHeader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshGifHeader.h; path = MJRefresh/Custom/Header/MJRefreshGifHeader.h; sourceTree = ""; }; + 54B843EC8B993674D3288F87AEA9D122 /* NSButton+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSButton+Kingfisher.swift"; path = "Sources/Extensions/NSButton+Kingfisher.swift"; sourceTree = ""; }; + 5545219DAAC101FE50450F293367D8C9 /* ConstraintMakerFinalizable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerFinalizable.swift; path = Sources/ConstraintMakerFinalizable.swift; sourceTree = ""; }; + 55914F40E7C5BD463245E2016A8906BC /* JXSegmentedTitleImageCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleImageCell.swift; path = Sources/TitleImage/JXSegmentedTitleImageCell.swift; sourceTree = ""; }; + 55E9A15EC42E241A39E5CABDB5E0D428 /* Zones.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Zones.swift; path = Sources/SwiftDate/Supports/Zones.swift; sourceTree = ""; }; + 56263B06F3EAEC382F6F91F1599D4E74 /* Alamofire-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-umbrella.h"; sourceTree = ""; }; + 5699EE5AE55BF8C2FE30604FAED64A7C /* HTTPHeaders.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTPHeaders.swift; path = Source/Core/HTTPHeaders.swift; sourceTree = ""; }; + 56CF6C9E5C4416011FAC32CEB31AA525 /* Box.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Box.swift; path = Sources/Utility/Box.swift; sourceTree = ""; }; + 56E8C8A30A6C29843067AEFDBDB0DD5E /* IQUITextFieldView+Additions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUITextFieldView+Additions.swift"; path = "IQKeyboardManagerSwift/Categories/IQUITextFieldView+Additions.swift"; sourceTree = ""; }; + 570B90AE83D4F878D222EF7D7B7A18F9 /* ConstraintDirectionalInsetTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDirectionalInsetTarget.swift; path = Sources/ConstraintDirectionalInsetTarget.swift; sourceTree = ""; }; + 58092F279DEDF69EA7576C313DC62F89 /* ConstraintItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintItem.swift; path = Sources/ConstraintItem.swift; sourceTree = ""; }; 58AE0544E0C381DDBD09356C357EC82B /* SwiftDate */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftDate; path = SwiftDate.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 59A6EEB5900F7A2EFF2E4353A16CFB10 /* IQTextView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQTextView.swift; path = IQKeyboardManagerSwift/IQTextView/IQTextView.swift; sourceTree = ""; }; - 5A7EBDEB55449170B0A5AA76B77186C0 /* Result.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Result.swift; path = Sources/Utility/Result.swift; sourceTree = ""; }; - 5C3D488F6F9118C5795E86C32D405E5C /* IQKeyboardManagerConstantsInternal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardManagerConstantsInternal.swift; path = IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstantsInternal.swift; sourceTree = ""; }; - 5CF9C49F0627CE4DC176C8910520DD1A /* ImageModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageModifier.swift; path = Sources/Networking/ImageModifier.swift; sourceTree = ""; }; + 594D2794764B5796C8A422C4401A7E2F /* Date+Create.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Date+Create.swift"; path = "Sources/SwiftDate/Date/Date+Create.swift"; sourceTree = ""; }; + 5AA5BD68BC8AE62D30B207A9A089DBE2 /* IQToolbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQToolbar.swift; path = IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift; sourceTree = ""; }; + 5AAF19FA9EB514B2794ECCAD1BB7FA2E /* Filter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Filter.swift; path = Sources/Image/Filter.swift; sourceTree = ""; }; + 5AB27763B449AF051985734B3773B4ED /* TimePeriodCollection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TimePeriodCollection.swift; path = Sources/SwiftDate/TimePeriod/Groups/TimePeriodCollection.swift; sourceTree = ""; }; + 5AEFD27CAFBA0B3BB80B6F22588271D1 /* MJRefresh-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "MJRefresh-Info.plist"; sourceTree = ""; }; + 5B832310B3844FB85DE10E60B45F44A3 /* SwiftDate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwiftDate.swift; path = Sources/SwiftDate/SwiftDate.swift; sourceTree = ""; }; + 5CEFF5B6E9210A0DDADD6C198F0BC68C /* Alamofire.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Alamofire.modulemap; sourceTree = ""; }; + 5D15BEF86A67CAF30B602BB5A260F77B /* KFAnimatedImage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFAnimatedImage.swift; path = Sources/SwiftUI/KFAnimatedImage.swift; sourceTree = ""; }; + 5D36A80F29E20B609E647BAFB548A270 /* ImageDownloaderDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDownloaderDelegate.swift; path = Sources/Networking/ImageDownloaderDelegate.swift; sourceTree = ""; }; 5D797E9A5C5782CE845840781FA1CC81 /* Alamofire */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Alamofire; path = Alamofire.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 5F1211F5D08477CCC9FD2CE425EDC276 /* IQKeyboardManagerSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "IQKeyboardManagerSwift-dummy.m"; sourceTree = ""; }; - 5FC69CA124430885BBDD652A5966AE29 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Sources/PrivacyInfo.xcprivacy; sourceTree = ""; }; - 611229333DB8EA6474A5F49BD282ABF9 /* IQUIView+IQKeyboardToolbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIView+IQKeyboardToolbar.swift"; path = "IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift"; sourceTree = ""; }; - 62CA51FDCDCF824E7E2811F5A29E5FC9 /* SnapKit-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SnapKit-Info.plist"; sourceTree = ""; }; - 6532F8DAD6AD80487996CDEC5B376D30 /* Date+Create.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Date+Create.swift"; path = "Sources/SwiftDate/Date/Date+Create.swift"; sourceTree = ""; }; - 65C3C5A1B404B17346AE855FFF4BDDA1 /* Notifications.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Notifications.swift; path = Source/Core/Notifications.swift; sourceTree = ""; }; - 665D66E791DE2DF5733AC7C3555A21F4 /* KFImageOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFImageOptions.swift; path = Sources/SwiftUI/KFImageOptions.swift; sourceTree = ""; }; - 6744A18229EA48CA16F54DFC8F3C6A3C /* JXSegmentedDotItemModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedDotItemModel.swift; path = Sources/Dot/JXSegmentedDotItemModel.swift; sourceTree = ""; }; - 67CE46015CE4475FDA0178EC41D8A5F8 /* SVProgressHUD-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SVProgressHUD-prefix.pch"; sourceTree = ""; }; - 6805397BC4354ED2D75A5B7AAE174E86 /* KFOptionsSetter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFOptionsSetter.swift; path = Sources/General/KFOptionsSetter.swift; sourceTree = ""; }; - 684339D85749BA476348D011AAF940F8 /* RelativeFormatterLanguage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RelativeFormatterLanguage.swift; path = Sources/SwiftDate/Formatters/RelativeFormatter/RelativeFormatterLanguage.swift; sourceTree = ""; }; - 699CF3DF23FE505906183E16A8B215AD /* SVIndefiniteAnimatedView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SVIndefiniteAnimatedView.h; path = SVProgressHUD/SVIndefiniteAnimatedView.h; sourceTree = ""; }; - 6A4F3875045D1DB4D796129111609B9D /* DateInRegion+Create.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DateInRegion+Create.swift"; path = "Sources/SwiftDate/DateInRegion/DateInRegion+Create.swift"; sourceTree = ""; }; - 6A6A3FAA6F0F3F494BB498919493C5ED /* ConstraintMakerExtendable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerExtendable.swift; path = Sources/ConstraintMakerExtendable.swift; sourceTree = ""; }; - 6BBCE430AE205EC78BD6A9993B59A91F /* TimePeriodChain.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TimePeriodChain.swift; path = Sources/SwiftDate/TimePeriod/Groups/TimePeriodChain.swift; sourceTree = ""; }; - 6BE57309210A754C8C684F298E14077B /* JXSegmentedAnimator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedAnimator.swift; path = Sources/Common/JXSegmentedAnimator.swift; sourceTree = ""; }; - 6C5BB459268D5535E82BA01CD4B7E5F2 /* CacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CacheSerializer.swift; path = Sources/Cache/CacheSerializer.swift; sourceTree = ""; }; - 6D136815A9B53EFB45552F7FF30A357F /* Kingfisher-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-prefix.pch"; sourceTree = ""; }; - 6DC1A24F4E1851F5E5FF43741ED5ADCD /* Region.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Region.swift; path = Sources/SwiftDate/DateInRegion/Region.swift; sourceTree = ""; }; - 6E17EC9F5615EFDD36A5372D376D7353 /* RelativeFormatter+Style.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "RelativeFormatter+Style.swift"; path = "Sources/SwiftDate/Formatters/RelativeFormatter/RelativeFormatter+Style.swift"; sourceTree = ""; }; - 6E208F65C34D21FBC484B3D0337F1008 /* Response.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Response.swift; path = Source/Core/Response.swift; sourceTree = ""; }; - 706A08832B908FA228085663A3B07DB9 /* DownloadRequest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DownloadRequest.swift; path = Source/Core/DownloadRequest.swift; sourceTree = ""; }; - 728B87873E161AD29B02B004B8C0F675 /* JXPagingListContainerView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXPagingListContainerView.swift; path = Sources/JXPagingView/JXPagingListContainerView.swift; sourceTree = ""; }; - 73D95693DF679081C2166C4C7F9A2F66 /* ConstraintMakerPrioritizable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerPrioritizable.swift; path = Sources/ConstraintMakerPrioritizable.swift; sourceTree = ""; }; - 76515B292B0F99B23C35557C81C52120 /* SVProgressHUD.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SVProgressHUD.modulemap; sourceTree = ""; }; - 773370F5C5F8C1A1ED9DA49D4CFA08B8 /* ConstraintAttributes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintAttributes.swift; path = Sources/ConstraintAttributes.swift; sourceTree = ""; }; - 7746FB2D26EF54C07CCBA2B580E80230 /* ImageView+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ImageView+Kingfisher.swift"; path = "Sources/Extensions/ImageView+Kingfisher.swift"; sourceTree = ""; }; - 78E2FF8B1C1A44452421E9A481603C3B /* JXSegmentedView-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "JXSegmentedView-Info.plist"; sourceTree = ""; }; - 78EEE8A477A369C06D750C1ED88021A2 /* IQInvocation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQInvocation.swift; path = IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift; sourceTree = ""; }; - 79E5B2D4D893485EE03EBC446DCDC057 /* JXSegmentedBaseItemModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedBaseItemModel.swift; path = Sources/Core/JXSegmentedBaseItemModel.swift; sourceTree = ""; }; - 7AED5BF44EC43B565CFB49DC523A2FE6 /* Delegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Delegate.swift; path = Sources/Utility/Delegate.swift; sourceTree = ""; }; - 7B710B049CD54BF711CB18566657FE6E /* ImageContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageContext.swift; path = Sources/SwiftUI/ImageContext.swift; sourceTree = ""; }; - 7DAC46988C621826DE9C8B685C307E5B /* SwiftDate.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftDate.release.xcconfig; sourceTree = ""; }; - 7DF2560B7559A05BA6EF1E5162CB2E28 /* KF.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KF.swift; path = Sources/General/KF.swift; sourceTree = ""; }; + 5DD688DF2ADF79B72ECC735C35F05F41 /* MJRefresh-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "MJRefresh-dummy.m"; sourceTree = ""; }; + 5EBCD15895605FBBBCD96B9C8E928D3B /* Alamofire.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Alamofire.debug.xcconfig; sourceTree = ""; }; + 612886EAB1AE5139D8545245115B7EC8 /* MJRefreshHeader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshHeader.m; path = MJRefresh/Base/MJRefreshHeader.m; sourceTree = ""; }; + 61585200C65A159F5B6731050D64BA59 /* SessionDataTask.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDataTask.swift; path = Sources/Networking/SessionDataTask.swift; sourceTree = ""; }; + 65BAE3F45733F6EB3DAE2F48599D8CAB /* SessionDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDelegate.swift; path = Source/Core/SessionDelegate.swift; sourceTree = ""; }; + 65E17F9E27F1D47AFFD1AE176DFE1657 /* ConstraintOffsetTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintOffsetTarget.swift; path = Sources/ConstraintOffsetTarget.swift; sourceTree = ""; }; + 662BA990AF2EEE7892AF8EA530C1AE31 /* ImageProcessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageProcessor.swift; path = Sources/Image/ImageProcessor.swift; sourceTree = ""; }; + 667B5BDDACE02078C87EFED6AAB723C2 /* ConstraintPriorityTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintPriorityTarget.swift; path = Sources/ConstraintPriorityTarget.swift; sourceTree = ""; }; + 67318C8CDF97D3763D84C0B08910AD54 /* JXSegmentedView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedView.swift; path = Sources/Core/JXSegmentedView.swift; sourceTree = ""; }; + 67675B8E7AD45A266A61E66355512D15 /* TVMonogramView+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "TVMonogramView+Kingfisher.swift"; path = "Sources/Extensions/TVMonogramView+Kingfisher.swift"; sourceTree = ""; }; + 67853DE27314756744C79CE55FBAA9A4 /* MJRefreshBackStateFooter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshBackStateFooter.h; path = MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.h; sourceTree = ""; }; + 6855310DB35D41B1E466E5EFFAF771BE /* RedirectHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RedirectHandler.swift; path = Source/Features/RedirectHandler.swift; sourceTree = ""; }; + 68A219042E44DB63D69EE3B79763130C /* Source.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Source.swift; path = Sources/General/ImageSource/Source.swift; sourceTree = ""; }; + 695AA5A7D6BF0B59DFBF71ABC3F3FECE /* JXSegmentedTitleGradientDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleGradientDataSource.swift; path = Sources/TitleGradient/JXSegmentedTitleGradientDataSource.swift; sourceTree = ""; }; + 6AC9CFB040D783BBBD3E787C142BFF2A /* JXSegmentedIndicatorGradientLineView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorGradientLineView.swift; path = Sources/Indicator/JXSegmentedIndicatorGradientLineView.swift; sourceTree = ""; }; + 6ADEBF08B3C1426137C7A2ED9E5E54D8 /* ConstraintLayoutSupportDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutSupportDSL.swift; path = Sources/ConstraintLayoutSupportDSL.swift; sourceTree = ""; }; + 6AFFBD2618F9F069B2DFFC4829E58831 /* ConstraintLayoutSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutSupport.swift; path = Sources/ConstraintLayoutSupport.swift; sourceTree = ""; }; + 6B28820A2229C358F6F00F9A6EE1A659 /* JXSegmentedTitleAttributeDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleAttributeDataSource.swift; path = Sources/AttributeTitle/JXSegmentedTitleAttributeDataSource.swift; sourceTree = ""; }; + 6B4DCC2536CD7F8BD55F0BAA08F110C7 /* ConstraintLayoutGuide+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ConstraintLayoutGuide+Extensions.swift"; path = "Sources/ConstraintLayoutGuide+Extensions.swift"; sourceTree = ""; }; + 6B82834CA67E7FF1B8610BF181E51004 /* SVProgressHUD.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SVProgressHUD.release.xcconfig; sourceTree = ""; }; + 6BF75314341E15EAF5EC8A5095F2878D /* MemoryStorage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MemoryStorage.swift; path = Sources/Cache/MemoryStorage.swift; sourceTree = ""; }; + 6C5F4CF175A8588A2773B4AF89EA51EC /* MJRefreshAutoNormalFooter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshAutoNormalFooter.h; path = MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.h; sourceTree = ""; }; + 6CEA2AD00C187BA485EFF154E41EF587 /* ImageFormat.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageFormat.swift; path = Sources/Image/ImageFormat.swift; sourceTree = ""; }; + 6D3E36D2866A136708CF5F602D268BD7 /* HTTPMethod.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTPMethod.swift; path = Source/Core/HTTPMethod.swift; sourceTree = ""; }; + 6D65D8CBF9D74AB85CB305B6D9B87509 /* DiskStorage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DiskStorage.swift; path = Sources/Cache/DiskStorage.swift; sourceTree = ""; }; + 6E1CCD164ECD3A398893DB0C3F224494 /* CallbackQueue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CallbackQueue.swift; path = Sources/Utility/CallbackQueue.swift; sourceTree = ""; }; + 6E619DA6F3D601658833035BDA0E167C /* Commons.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Commons.swift; path = Sources/SwiftDate/Supports/Commons.swift; sourceTree = ""; }; + 6E6DA59208C9C680C1A08AB6B751A05E /* RequestCompression.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestCompression.swift; path = Source/Features/RequestCompression.swift; sourceTree = ""; }; + 6EF651FECE01069367CDE0054F13249F /* Formatter+Protocols.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Formatter+Protocols.swift"; path = "Sources/SwiftDate/Formatters/Formatter+Protocols.swift"; sourceTree = ""; }; + 6F69248BB24307C449A27A28477BAF56 /* NSTextAttachment+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSTextAttachment+Kingfisher.swift"; path = "Sources/Extensions/NSTextAttachment+Kingfisher.swift"; sourceTree = ""; }; + 6F86EAA1D247756258692097BEA95A21 /* JXSegmentedTitleCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleCell.swift; path = Sources/Title/JXSegmentedTitleCell.swift; sourceTree = ""; }; + 7052242B5B59DCEC7125EE873BC0202A /* AuthenticationInterceptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AuthenticationInterceptor.swift; path = Source/Features/AuthenticationInterceptor.swift; sourceTree = ""; }; + 70D291797444B210FC11B05604380747 /* MJRefreshGifHeader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshGifHeader.m; path = MJRefresh/Custom/Header/MJRefreshGifHeader.m; sourceTree = ""; }; + 7143F3A6986BF2AB2828E2DC37C9C09D /* String+MD5.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+MD5.swift"; path = "Sources/Utility/String+MD5.swift"; sourceTree = ""; }; + 71DCFBED49883055AA94888206F221A9 /* JXSegmentedIndicatorRainbowLineView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorRainbowLineView.swift; path = Sources/Indicator/JXSegmentedIndicatorRainbowLineView.swift; sourceTree = ""; }; + 725764D6EDA104D9902913F6D02AB7FF /* TimePeriod+Support.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "TimePeriod+Support.swift"; path = "Sources/SwiftDate/TimePeriod/TimePeriod+Support.swift"; sourceTree = ""; }; + 728D0FC1713F8BD85AD5D78DF7CC3E06 /* RelativeFormatter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RelativeFormatter.swift; path = Sources/SwiftDate/Formatters/RelativeFormatter/RelativeFormatter.swift; sourceTree = ""; }; + 7477826A60436064D61A5EFA564B9D6F /* ConstraintRelation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintRelation.swift; path = Sources/ConstraintRelation.swift; sourceTree = ""; }; + 7682AD6DBFD519C9BA5ECCAC483C0CF4 /* ConstraintInsets.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintInsets.swift; path = Sources/ConstraintInsets.swift; sourceTree = ""; }; + 7694CB3A399B0E568F03F27D28868B95 /* DisplayLink.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DisplayLink.swift; path = Sources/Utility/DisplayLink.swift; sourceTree = ""; }; + 76BE0C86A979CEA47E0B7AD2EE15D888 /* NSBundle+MJRefresh.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSBundle+MJRefresh.m"; path = "MJRefresh/NSBundle+MJRefresh.m"; sourceTree = ""; }; + 773DD03EC2EC00F685DE0E46779320CC /* IQKeyboardManager+Internal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+Internal.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+Internal.swift"; sourceTree = ""; }; + 774F6E017AC64D4F20E0DA360CA3FECF /* Placeholder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Placeholder.swift; path = Sources/Image/Placeholder.swift; sourceTree = ""; }; + 77AF4A7E7C61F4843CEE9608EFB1F2A8 /* SnapKit-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SnapKit-prefix.pch"; sourceTree = ""; }; + 7A43EE3F113EE7EB81E5065DB5FDD3F2 /* MJRefreshAutoFooter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshAutoFooter.m; path = MJRefresh/Base/MJRefreshAutoFooter.m; sourceTree = ""; }; + 7A78C7902D8016F72AC215D2E28422F6 /* RedirectHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RedirectHandler.swift; path = Sources/Networking/RedirectHandler.swift; sourceTree = ""; }; + 7B24959E1B5D6E0DB944451D77D9BEEF /* JXSegmentedView-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "JXSegmentedView-Info.plist"; sourceTree = ""; }; + 7B9379FA3746B5215A31DE8D1CD26166 /* MJRefreshAutoStateFooter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshAutoStateFooter.h; path = MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.h; sourceTree = ""; }; + 7BD8D5C9444C4C58CF152CD4CC8DB0A3 /* Alamofire.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Alamofire.release.xcconfig; sourceTree = ""; }; + 7C1665911416D598AAD937FC0E0D42E4 /* RequestTaskMap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestTaskMap.swift; path = Source/Core/RequestTaskMap.swift; sourceTree = ""; }; + 7C1E1CFDA9E2D6AECCA91F210C0B6064 /* IQNSArray+Sort.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQNSArray+Sort.swift"; path = "IQKeyboardManagerSwift/Categories/IQNSArray+Sort.swift"; sourceTree = ""; }; + 7C589304DE45B301793ACB48B3D74C25 /* SVProgressHUD.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SVProgressHUD.h; path = SVProgressHUD/SVProgressHUD.h; sourceTree = ""; }; + 7E3097CFEFDA621E9FB0E62009FF87FC /* MJRefresh-MJRefresh.Privacy */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "MJRefresh-MJRefresh.Privacy"; path = MJRefresh.Privacy.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 7EB20B4E68CCB69F85E7D08B7F8463D6 /* JXPagingView-JXPagingView */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "JXPagingView-JXPagingView"; path = JXPagingView.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; - 7F6B30053062472A32F7652BD0C4B138 /* Int+DateComponents.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Int+DateComponents.swift"; path = "Sources/SwiftDate/Foundation+Extras/Int+DateComponents.swift"; sourceTree = ""; }; - 7FCAF7C1E0C7EF57EDC617DCE77194E5 /* ConstraintMakerFinalizable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerFinalizable.swift; path = Sources/ConstraintMakerFinalizable.swift; sourceTree = ""; }; - 814DE9B814D4E171655394905E30304A /* IQKeyboardManager+Internal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+Internal.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+Internal.swift"; sourceTree = ""; }; + 7EB8A3AF649521A0ED645B8858FB4DDF /* JXSegmentedViewTool.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedViewTool.swift; path = Sources/Common/JXSegmentedViewTool.swift; sourceTree = ""; }; + 7EC53E7C517308EABC44AEFB75F5C064 /* ConstraintMakerExtendable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerExtendable.swift; path = Sources/ConstraintMakerExtendable.swift; sourceTree = ""; }; + 7ECC357045F3ADF02DFCA0E0F6D4DEE0 /* TimePeriod.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TimePeriod.swift; path = Sources/SwiftDate/TimePeriod/TimePeriod.swift; sourceTree = ""; }; + 7FBC7116157221928733CE2DB074EB86 /* ConstraintView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintView.swift; path = Sources/ConstraintView.swift; sourceTree = ""; }; + 810BB8FC42B516FF79349CC6C8C13E4C /* UIView+MJExtension.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIView+MJExtension.h"; path = "MJRefresh/UIView+MJExtension.h"; sourceTree = ""; }; + 8124055AC9E04813E53A3EE6EDD5E1DE /* MJRefreshHeader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshHeader.h; path = MJRefresh/Base/MJRefreshHeader.h; sourceTree = ""; }; + 8138B9E4A2A6AA8C683562DF69844549 /* AnimatedImageView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnimatedImageView.swift; path = Sources/Views/AnimatedImageView.swift; sourceTree = ""; }; + 813F5F884BA0F0F6C062E545B4CA81EC /* MJRefreshConfig.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshConfig.m; path = MJRefresh/MJRefreshConfig.m; sourceTree = ""; }; + 814205A97B8158339AF6DCF93609360F /* Kingfisher-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-umbrella.h"; sourceTree = ""; }; + 81D659C29A42861AC5A4EF3B9D26DC0B /* IQTitleBarButtonItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQTitleBarButtonItem.swift; path = IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift; sourceTree = ""; }; 828F1C480D9959D94E2868CE1084677F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; }; - 82A068C4EC672799ADB247B155675358 /* Validation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Validation.swift; path = Source/Features/Validation.swift; sourceTree = ""; }; - 8480154D84F74BD3E0CB4C5D9AEA2A2A /* Zones.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Zones.swift; path = Sources/SwiftDate/Supports/Zones.swift; sourceTree = ""; }; - 84B7F7B98523171E533048422B5C3CDC /* ConstraintLayoutSupportDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutSupportDSL.swift; path = Sources/ConstraintLayoutSupportDSL.swift; sourceTree = ""; }; - 85475E21904923ACC16877FB7BA6C30B /* ImageProgressive.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageProgressive.swift; path = Sources/Image/ImageProgressive.swift; sourceTree = ""; }; - 85BA376AE75DD6C89F006B5ABBAD1A00 /* RequestModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestModifier.swift; path = Sources/Networking/RequestModifier.swift; sourceTree = ""; }; - 86D63DBB9B2A913FBA9303BF4AEA2AFE /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = IQKeyboardManagerSwift/PrivacyInfo.xcprivacy; sourceTree = ""; }; - 8868D3E0EEBED6EEE631D6CBDB9C0E01 /* JXSegmentedRTLLayout.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedRTLLayout.swift; path = Sources/Common/JXSegmentedRTLLayout.swift; sourceTree = ""; }; - 88D9E5016D9005153DC1BF421EB97D45 /* ImageDownloader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDownloader.swift; path = Sources/Networking/ImageDownloader.swift; sourceTree = ""; }; - 88EBA936D76416362096C319D61B9AE0 /* JXSegmentedTitleGradientItemModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleGradientItemModel.swift; path = Sources/TitleGradient/JXSegmentedTitleGradientItemModel.swift; sourceTree = ""; }; - 890F8EEE5DAE16274422CC38E258B8D1 /* Kingfisher.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.release.xcconfig; sourceTree = ""; }; + 82CD43FF64DC36B945840368DAC1706E /* MJRefreshStateHeader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshStateHeader.m; path = MJRefresh/Custom/Header/MJRefreshStateHeader.m; sourceTree = ""; }; + 82E922355D2129F96245BA8E4E5FFF67 /* MJRefresh-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MJRefresh-umbrella.h"; sourceTree = ""; }; + 832AF59B8B94B734BFA5598CF822D2E8 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Source/PrivacyInfo.xcprivacy; sourceTree = ""; }; + 835F2888E352852912F4709F5E54512B /* JXSegmentedIndicatorDoubleLineView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorDoubleLineView.swift; path = Sources/Indicator/JXSegmentedIndicatorDoubleLineView.swift; sourceTree = ""; }; + 83C7B6631D6A0479168A89D25B68A47C /* Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Kingfisher.swift; path = Sources/General/Kingfisher.swift; sourceTree = ""; }; + 84C0F797B07A4C95A5F90FB6C7E6A296 /* SizeExtensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SizeExtensions.swift; path = Sources/Utility/SizeExtensions.swift; sourceTree = ""; }; + 84C32F4F34E89EC16281BE7CB8022B54 /* Alamofire-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-prefix.pch"; sourceTree = ""; }; + 84DF245C6F43F9612AD56BC7D2ADB123 /* String+Parser.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+Parser.swift"; path = "Sources/SwiftDate/Foundation+Extras/String+Parser.swift"; sourceTree = ""; }; + 84E085540B9A46FE188C3ED65522C329 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Sources/PrivacyInfo.xcprivacy; sourceTree = ""; }; + 84FCB0C95F94873F8D87374CE1ACA147 /* MJRefresh.bundle */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "wrapper.plug-in"; name = MJRefresh.bundle; path = MJRefresh/MJRefresh.bundle; sourceTree = ""; }; + 86134D091916FFC476610F2EBFE771E2 /* ISOParser.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ISOParser.swift; path = Sources/SwiftDate/Formatters/ISOParser.swift; sourceTree = ""; }; + 864DAEC4F579E88712B7F5B447424FFC /* KingfisherError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherError.swift; path = Sources/General/KingfisherError.swift; sourceTree = ""; }; + 86545830194573BF57878FC631A90181 /* MJRefreshStateHeader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshStateHeader.h; path = MJRefresh/Custom/Header/MJRefreshStateHeader.h; sourceTree = ""; }; + 86D05EEFA439B19ACFEC22979C2BBF4D /* SnapKit.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SnapKit.modulemap; sourceTree = ""; }; + 88647C8377C8FB3AE854C55C7B81559E /* NetworkReachabilityManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NetworkReachabilityManager.swift; path = Source/Features/NetworkReachabilityManager.swift; sourceTree = ""; }; 8927A418B90BECD52B8D147258EB4781 /* Pods-MusicPlayer-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-MusicPlayer-acknowledgements.plist"; sourceTree = ""; }; - 896D7A2849ACF34D2EA1166731A5D332 /* JXSegmentedBaseDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedBaseDataSource.swift; path = Sources/Core/JXSegmentedBaseDataSource.swift; sourceTree = ""; }; - 8976C2EEB49511E14ED3D66C2CAEF73F /* SVProgressHUD-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SVProgressHUD-Info.plist"; sourceTree = ""; }; - 89AE4C34F9A0CCC31019F7C0115A0BB7 /* RetryPolicy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RetryPolicy.swift; path = Source/Features/RetryPolicy.swift; sourceTree = ""; }; - 89DB2376678936DD230CBCCDD11F0A5B /* JXSegmentedNumberCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedNumberCell.swift; path = Sources/Number/JXSegmentedNumberCell.swift; sourceTree = ""; }; + 89FA1854F15DFB5CA5EAC2BF88823143 /* JXPagingListRefreshView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXPagingListRefreshView.swift; path = Sources/JXPagingView/JXPagingListRefreshView.swift; sourceTree = ""; }; + 89FE60E3816FD1A788423E90F6E28D8D /* JXSegmentedIndicatorProtocol.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorProtocol.swift; path = Sources/Indicator/JXSegmentedIndicatorProtocol.swift; sourceTree = ""; }; + 8A296F41C13699333333D3C630E92F80 /* ImageView+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ImageView+Kingfisher.swift"; path = "Sources/Extensions/ImageView+Kingfisher.swift"; sourceTree = ""; }; 8A2A128F3FAE37601751167FDC47182A /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/CFNetwork.framework; sourceTree = DEVELOPER_DIR; }; - 8B17D99233F4B43D0CE24E0142AAA24A /* DateInRegion+Components.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DateInRegion+Components.swift"; path = "Sources/SwiftDate/DateInRegion/DateInRegion+Components.swift"; sourceTree = ""; }; - 8C3F23EBC877B0289008C16C4981B784 /* JXSegmentedDotDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedDotDataSource.swift; path = Sources/Dot/JXSegmentedDotDataSource.swift; sourceTree = ""; }; - 8C64660111FD6606664A3951D1C9E793 /* Combine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Combine.swift; path = Source/Features/Combine.swift; sourceTree = ""; }; - 8CD193641BF411C264722678C735CFC4 /* URLRequest+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLRequest+Alamofire.swift"; path = "Source/Extensions/URLRequest+Alamofire.swift"; sourceTree = ""; }; - 8D27856B2E2A4B0DFBC9C847E272AF9E /* KFAnimatedImage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFAnimatedImage.swift; path = Sources/SwiftUI/KFAnimatedImage.swift; sourceTree = ""; }; - 8E21BA4A95E9124E56A3ABDC946ED751 /* JXSegmentedTitleDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleDataSource.swift; path = Sources/Title/JXSegmentedTitleDataSource.swift; sourceTree = ""; }; - 8E3F83A4B256E06D67FBC054152710B2 /* JXSegmentedIndicatorDoubleLineView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorDoubleLineView.swift; path = Sources/Indicator/JXSegmentedIndicatorDoubleLineView.swift; sourceTree = ""; }; - 905F41A1A4BC05366108CBB7D774CB63 /* Storage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Storage.swift; path = Sources/Cache/Storage.swift; sourceTree = ""; }; - 90B6B02E550BBA54CD9271600724D14D /* HTTPMethod.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTPMethod.swift; path = Source/Core/HTTPMethod.swift; sourceTree = ""; }; - 9127C21D70BA07B74F31B569E2887C5F /* ConstraintLayoutGuide.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutGuide.swift; path = Sources/ConstraintLayoutGuide.swift; sourceTree = ""; }; - 924CF8F11C00458CC225420E918BA09B /* ImagePrefetcher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImagePrefetcher.swift; path = Sources/Networking/ImagePrefetcher.swift; sourceTree = ""; }; + 8A9A6B3FF123B6733156B839AB90A488 /* Session.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Session.swift; path = Source/Core/Session.swift; sourceTree = ""; }; + 8B4EE5D13ED112C5C84DB3A6ADE8E7E0 /* UploadRequest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UploadRequest.swift; path = Source/Core/UploadRequest.swift; sourceTree = ""; }; + 8CFAC3CD688A5BEB743550BA40C464FF /* JXSegmentedDotItemModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedDotItemModel.swift; path = Sources/Dot/JXSegmentedDotItemModel.swift; sourceTree = ""; }; + 8E6EB2C04F247D9F4D15B77F830EDF54 /* Date+Compare.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Date+Compare.swift"; path = "Sources/SwiftDate/Date/Date+Compare.swift"; sourceTree = ""; }; + 8F1162C00BCBB4CECFD5CA05ED5667F3 /* MJRefreshNormalHeader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshNormalHeader.m; path = MJRefresh/Custom/Header/MJRefreshNormalHeader.m; sourceTree = ""; }; 92B0EC788EDA1B0CFA48DFFCB3DDAECD /* JXSegmentedView-JXSegmentedView */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "JXSegmentedView-JXSegmentedView"; path = JXSegmentedView.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; - 947DA5BA2E9A379BFEC2E827244B0CE0 /* IQKeyboardManagerSwift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = IQKeyboardManagerSwift.debug.xcconfig; sourceTree = ""; }; - 97840F079FDCC2C242D262A194809427 /* ConstraintRelation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintRelation.swift; path = Sources/ConstraintRelation.swift; sourceTree = ""; }; + 94F9116CE6A49B5AFFA19B16D5346243 /* MJRefreshAutoFooter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshAutoFooter.h; path = MJRefresh/Base/MJRefreshAutoFooter.h; sourceTree = ""; }; + 951E048B27AEAC006B779E585701262E /* DateInRegion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DateInRegion.swift; path = Sources/SwiftDate/DateInRegion/DateInRegion.swift; sourceTree = ""; }; + 96222B976672EC3736CB9B53FC49C92E /* UIScrollView+MJRefresh.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIScrollView+MJRefresh.h"; path = "MJRefresh/UIScrollView+MJRefresh.h"; sourceTree = ""; }; 979486118B3E90C08386079D57962701 /* SnapKit */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SnapKit; path = SnapKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 97B043B3414EEE6CE9FB38F6C8C4E938 /* ConstraintMakerEditable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerEditable.swift; path = Sources/ConstraintMakerEditable.swift; sourceTree = ""; }; - 98668AA82D39D5CB2E405768140C5404 /* NSButton+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSButton+Kingfisher.swift"; path = "Sources/Extensions/NSButton+Kingfisher.swift"; sourceTree = ""; }; - 999C15F4A94DD7E4875ED8928BAE4925 /* JXPagingView.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = JXPagingView.debug.xcconfig; sourceTree = ""; }; - 99DACD800F6BC071C09C771CFA780B2D /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Source/PrivacyInfo.xcprivacy; sourceTree = ""; }; - 9AE736393524312D73608EA88A6743E6 /* DisplayLink.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DisplayLink.swift; path = Sources/Utility/DisplayLink.swift; sourceTree = ""; }; - 9C8A901F12C600B3F5FF1554147E17FE /* JXPagingMainTableView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXPagingMainTableView.swift; path = Sources/JXPagingView/JXPagingMainTableView.swift; sourceTree = ""; }; - 9CCAAC7200ED63CA697D32D99781785A /* ResourceBundle-Alamofire-Alamofire-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-Alamofire-Alamofire-Info.plist"; sourceTree = ""; }; + 988FB962B33EFE0451CB5B6094DEAA75 /* IQKeyboardManager+Position.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+Position.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+Position.swift"; sourceTree = ""; }; + 98D0F4FF0A3E2660BE566528FDF31D03 /* IQKeyboardManagerSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "IQKeyboardManagerSwift-umbrella.h"; sourceTree = ""; }; + 9A89AE3F00FA615DB614031B7510C78F /* IQKeyboardManagerConstants.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardManagerConstants.swift; path = IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstants.swift; sourceTree = ""; }; + 9ABF6319E31E3E401B63195B3374007D /* ConstraintMakerRelatable+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ConstraintMakerRelatable+Extensions.swift"; path = "Sources/ConstraintMakerRelatable+Extensions.swift"; sourceTree = ""; }; + 9AC28BE75055A99E1BD5B4B8D07E3C1B /* ParameterEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ParameterEncoder.swift; path = Source/Core/ParameterEncoder.swift; sourceTree = ""; }; + 9B189CE2110C0A21199EB8FB87FCEB6D /* SVProgressHUD.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SVProgressHUD.m; path = SVProgressHUD/SVProgressHUD.m; sourceTree = ""; }; + 9B33B085086724D9914992FFDEF83E0B /* DateInRegion+Compare.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DateInRegion+Compare.swift"; path = "Sources/SwiftDate/DateInRegion/DateInRegion+Compare.swift"; sourceTree = ""; }; + 9CC5E0E6473324DB3F517B54470CBE6C /* ConstraintViewDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintViewDSL.swift; path = Sources/ConstraintViewDSL.swift; sourceTree = ""; }; 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - 9E6E3FB0EAE53F7E9EEF4A4D9EB32372 /* AVAssetImageDataProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AVAssetImageDataProvider.swift; path = Sources/General/ImageSource/AVAssetImageDataProvider.swift; sourceTree = ""; }; - 9E756CE2D8BBBFBD61C705DCB85928FC /* String+MD5.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+MD5.swift"; path = "Sources/Utility/String+MD5.swift"; sourceTree = ""; }; - 9FF5D58E8072CFF7D8524E5423ABF567 /* SnapKit-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SnapKit-dummy.m"; sourceTree = ""; }; - A2767F08F182AD8A9B1774BEFAD31FCE /* MultipartUpload.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultipartUpload.swift; path = Source/Features/MultipartUpload.swift; sourceTree = ""; }; - A4146F3303D77A54D70EFCE400FA4336 /* ParameterEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ParameterEncoder.swift; path = Source/Core/ParameterEncoder.swift; sourceTree = ""; }; - A41FA1D67A369D0AF9F089B2E949C60E /* JXSegmentedTitleCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleCell.swift; path = Sources/Title/JXSegmentedTitleCell.swift; sourceTree = ""; }; - A426DD55A10EB28F224B77DD61B2BF00 /* Request.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Request.swift; path = Source/Core/Request.swift; sourceTree = ""; }; - A43A96448C1937678DB79A129BB6F2C2 /* ConstraintView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintView.swift; path = Sources/ConstraintView.swift; sourceTree = ""; }; + 9DB02FC7AC88AE54321E64548CBFD1FF /* SnapKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SnapKit.release.xcconfig; sourceTree = ""; }; + 9E1F7BD2E4AFF6989C1387F2558185ED /* SessionDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDelegate.swift; path = Sources/Networking/SessionDelegate.swift; sourceTree = ""; }; + A0422DB62B6B3C1A201A2762EBBB5A97 /* Date.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Date.swift; path = Sources/SwiftDate/Date/Date.swift; sourceTree = ""; }; + A04C1CC2D7176FD20CE057E555EFC2CB /* MJRefreshAutoNormalFooter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshAutoNormalFooter.m; path = MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.m; sourceTree = ""; }; + A10B7F476AA2BC85DA32CDCA695E94CF /* MJRefreshAutoGifFooter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshAutoGifFooter.m; path = MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.m; sourceTree = ""; }; + A206F578A0BA9FC1C6B8B6078EFF6B9A /* SVProgressHUD.bundle */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "wrapper.plug-in"; name = SVProgressHUD.bundle; path = SVProgressHUD/SVProgressHUD.bundle; sourceTree = ""; }; + A26DF092CAB68C5202C9271E71C8F750 /* Constraint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Constraint.swift; path = Sources/Constraint.swift; sourceTree = ""; }; + A3841A0A7F5A5EABE2100147A429E0C6 /* IQKeyboardManagerSwift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = IQKeyboardManagerSwift.debug.xcconfig; sourceTree = ""; }; + A418AA4ADA9598EFD690FF4427F182A5 /* UICollectionViewLayout+MJRefresh.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UICollectionViewLayout+MJRefresh.h"; path = "MJRefresh/UICollectionViewLayout+MJRefresh.h"; sourceTree = ""; }; A46268EC24FA52F2CB5649EC2E7A996C /* Pods-MusicPlayer-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-MusicPlayer-acknowledgements.markdown"; sourceTree = ""; }; - A4AA0EBFFFCAE79E4DD76DB28D399121 /* KingfisherManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherManager.swift; path = Sources/General/KingfisherManager.swift; sourceTree = ""; }; - A76DF775AC63A1EDDD3E18D271B4C926 /* JXSegmentedTitleItemModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleItemModel.swift; path = Sources/Title/JXSegmentedTitleItemModel.swift; sourceTree = ""; }; - A7767A0D4F0D3EBD1C8E13F6F05FB25B /* JXPagingView.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = JXPagingView.release.xcconfig; sourceTree = ""; }; + A47365FDDB9CB0AC423AD6C3AF49AD21 /* KingfisherOptionsInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherOptionsInfo.swift; path = Sources/General/KingfisherOptionsInfo.swift; sourceTree = ""; }; + A56C8749F94C4894BDE28709B22BC8EC /* MJRefreshTrailer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshTrailer.h; path = MJRefresh/Base/MJRefreshTrailer.h; sourceTree = ""; }; + A690FBA7765087019C4F3AFEDD3E2CB0 /* ResourceBundle-JXPagingView-JXPagingView-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-JXPagingView-JXPagingView-Info.plist"; sourceTree = ""; }; + A78C6D5D45F26A283595741E6566040D /* ConstraintPriority.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintPriority.swift; path = Sources/ConstraintPriority.swift; sourceTree = ""; }; + A793885CE536998701B9632A60B45781 /* WebSocketRequest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WebSocketRequest.swift; path = Source/Core/WebSocketRequest.swift; sourceTree = ""; }; + A7AF9A69BFF4975345B92D217643792D /* Kingfisher.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Kingfisher.modulemap; sourceTree = ""; }; A8E950A16D00F649C54FFB30F81D7842 /* IQKeyboardManagerSwift */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = IQKeyboardManagerSwift; path = IQKeyboardManagerSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A933F95E4E12D348E925A9E3B27750CB /* SnapKit-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SnapKit-dummy.m"; sourceTree = ""; }; + AA2205F6575D1182446627195A2B2D7D /* SwiftDate.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftDate.release.xcconfig; sourceTree = ""; }; + AA35F74EEBAD4E0CB28C015AD5D6EECF /* Alamofire-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Alamofire-dummy.m"; sourceTree = ""; }; AA39C6D2448DC5A9AD18DDA3C96A1A0F /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Accelerate.framework; sourceTree = DEVELOPER_DIR; }; - AD4404E7BA0E07C8EDABCE9734F9BBC9 /* GIFAnimatedImage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GIFAnimatedImage.swift; path = Sources/Image/GIFAnimatedImage.swift; sourceTree = ""; }; - AD54F4811AE511D52253868A482B0282 /* IQToolbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQToolbar.swift; path = IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift; sourceTree = ""; }; - AD71D3CDC6450CFD5A6E4F493768310F /* JXSegmentedBaseCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedBaseCell.swift; path = Sources/Core/JXSegmentedBaseCell.swift; sourceTree = ""; }; - AEC77FF989202A953833F6020DC1B1B0 /* JXSegmentedNumberDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedNumberDataSource.swift; path = Sources/Number/JXSegmentedNumberDataSource.swift; sourceTree = ""; }; - AF2199462536623489EFF7EDEF57722F /* SessionDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDelegate.swift; path = Source/Core/SessionDelegate.swift; sourceTree = ""; }; - AF379AB14D224D349C2E17BAE5136840 /* JXSegmentedIndicatorTriangleView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorTriangleView.swift; path = Sources/Indicator/JXSegmentedIndicatorTriangleView.swift; sourceTree = ""; }; - AFA7D8134BAFA04D2B580073EE31DACA /* Filter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Filter.swift; path = Sources/Image/Filter.swift; sourceTree = ""; }; - B162065ADCC62F8E5918B4FA00D73B81 /* AFError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AFError.swift; path = Source/Core/AFError.swift; sourceTree = ""; }; - B3BE4EB2A04A4F30656E0864B64A6A88 /* ConstraintConstantTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintConstantTarget.swift; path = Sources/ConstraintConstantTarget.swift; sourceTree = ""; }; + AAA467CC8E830A4407AEEA9E195B5572 /* IQKeyboardManager+UIKeyboardNotification.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+UIKeyboardNotification.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+UIKeyboardNotification.swift"; sourceTree = ""; }; + AB0205A7B7089CE3AA7AF45ACDE3629A /* JXSegmentedRTLLayout.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedRTLLayout.swift; path = Sources/Common/JXSegmentedRTLLayout.swift; sourceTree = ""; }; + AB089815F261E66CDE44D5F4DE72EE32 /* IQKeyboardManagerSwift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = IQKeyboardManagerSwift.release.xcconfig; sourceTree = ""; }; + AC5E8113942F4B6D5C87580AA549D92C /* MJRefresh.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MJRefresh.release.xcconfig; sourceTree = ""; }; + ADD37EAEC18687AE8ED7C2EED0B1463A /* MJRefresh-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MJRefresh-prefix.pch"; sourceTree = ""; }; + AE5B1F68CF04B5EBB405EA5A612234B6 /* SVRadialGradientLayer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SVRadialGradientLayer.m; path = SVProgressHUD/SVRadialGradientLayer.m; sourceTree = ""; }; + AE8FD0EA90E35589FF45377FFE6445D6 /* IQKeyboardManagerSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = IQKeyboardManagerSwift.modulemap; sourceTree = ""; }; + AFCD84A7AB4756552C1E55E266165ACA /* JXSegmentedTitleOrImageDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleOrImageDataSource.swift; path = Sources/TitleOrImage/JXSegmentedTitleOrImageDataSource.swift; sourceTree = ""; }; + AFFBC6D1E5E46588B6AAB4F0711B9D5E /* JXSegmentedNumberCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedNumberCell.swift; path = Sources/Number/JXSegmentedNumberCell.swift; sourceTree = ""; }; + B06108CF75D8C3024C894159C039AF1C /* SVProgressHUD.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SVProgressHUD.debug.xcconfig; sourceTree = ""; }; + B0CE74EB3DE207E3CAE98CDE17280DBA /* JXSegmentedIndicatorDotLineView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorDotLineView.swift; path = Sources/Indicator/JXSegmentedIndicatorDotLineView.swift; sourceTree = ""; }; + B10D7C8D9A8EFE21347CF640AE5AFCD9 /* RetryPolicy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RetryPolicy.swift; path = Source/Features/RetryPolicy.swift; sourceTree = ""; }; + B2E886364CE3D1DE31930B53C67EFBEB /* IQKeyboardManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardManager.swift; path = IQKeyboardManagerSwift/IQKeyboardManager.swift; sourceTree = ""; }; + B4111D05E2FD45B47E3E6AD830625F74 /* NSBundle+MJRefresh.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSBundle+MJRefresh.h"; path = "MJRefresh/NSBundle+MJRefresh.h"; sourceTree = ""; }; + B43CFD3981B70FD7D609A5839B6A9218 /* KFImageRenderer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFImageRenderer.swift; path = Sources/SwiftUI/KFImageRenderer.swift; sourceTree = ""; }; B4B8063291033C95A8B2A24FA2AD7A79 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; - B60AE218D04ECB2F352996F87D62ABA4 /* RelativeFormatter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RelativeFormatter.swift; path = Sources/SwiftDate/Formatters/RelativeFormatter/RelativeFormatter.swift; sourceTree = ""; }; - B6AE2AF696125AD0E1121BF86AAE5046 /* ImageDownloaderDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDownloaderDelegate.swift; path = Sources/Networking/ImageDownloaderDelegate.swift; sourceTree = ""; }; - B6F9C80933FC230A20E8DB141B42D78B /* JXSegmentedIndicatorGradientView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorGradientView.swift; path = Sources/Indicator/JXSegmentedIndicatorGradientView.swift; sourceTree = ""; }; - B75E4A5B88AB2E12901FD79392108078 /* JXPagingView-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "JXPagingView-umbrella.h"; sourceTree = ""; }; - B829BB92CE7C61E3EF4CAEA14D3264FE /* KFImageRenderer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFImageRenderer.swift; path = Sources/SwiftUI/KFImageRenderer.swift; sourceTree = ""; }; - B88842C93039689D079B0F4AA14852C6 /* Kingfisher.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.debug.xcconfig; sourceTree = ""; }; - B942DFB5FFD9E8DA9A4C3E8B8FC26306 /* Alamofire.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Alamofire.release.xcconfig; sourceTree = ""; }; - B9CC3B5B9CB0EEA62534F2B47807C815 /* URLConvertible+URLRequestConvertible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLConvertible+URLRequestConvertible.swift"; path = "Source/Core/URLConvertible+URLRequestConvertible.swift"; sourceTree = ""; }; - BB0F871541AF0A23961743411FF66100 /* JXSegmentedTitleAttributeCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleAttributeCell.swift; path = Sources/AttributeTitle/JXSegmentedTitleAttributeCell.swift; sourceTree = ""; }; - BB180FDD1F9AAD170DE5179EBA67AFE2 /* ConstraintPriorityTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintPriorityTarget.swift; path = Sources/ConstraintPriorityTarget.swift; sourceTree = ""; }; - BB3D25104232F456441BF20779E54737 /* SwiftDate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwiftDate.swift; path = Sources/SwiftDate/SwiftDate.swift; sourceTree = ""; }; - BB4408CC7D50AB78010F283775082F2E /* JXSegmentedView-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "JXSegmentedView-dummy.m"; sourceTree = ""; }; - BB998DCE982EFC41FF337EC72362789A /* JXSegmentedView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedView.swift; path = Sources/Core/JXSegmentedView.swift; sourceTree = ""; }; - BBCD2385297C11F5F3C9C95418952EF1 /* IQKeyboardManagerConstants.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardManagerConstants.swift; path = IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstants.swift; sourceTree = ""; }; - BCE24B18F4CDA56F48417247341E3F76 /* ParameterEncoding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ParameterEncoding.swift; path = Source/Core/ParameterEncoding.swift; sourceTree = ""; }; - BD9B444681135CCF6E363CC0A67B6651 /* ConstraintLayoutGuide+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ConstraintLayoutGuide+Extensions.swift"; path = "Sources/ConstraintLayoutGuide+Extensions.swift"; sourceTree = ""; }; - BDFACB4345054B019481CEDCD494F54E /* JXSegmentedTitleImageDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleImageDataSource.swift; path = Sources/TitleImage/JXSegmentedTitleImageDataSource.swift; sourceTree = ""; }; - BF082BF0DDC572A9715FBE1F68360401 /* SnapKit-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SnapKit-prefix.pch"; sourceTree = ""; }; + B5819E5E132D7A725A5CF03163E7796D /* langs */ = {isa = PBXFileReference; includeInIndex = 1; name = langs; path = Sources/SwiftDate/Formatters/RelativeFormatter/langs; sourceTree = ""; }; + B65D6A9EE341D83823E03C122A72A5C1 /* JXSegmentedTitleImageItemModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleImageItemModel.swift; path = Sources/TitleImage/JXSegmentedTitleImageItemModel.swift; sourceTree = ""; }; + B66FA26ED5139D4710E18EA56AEC64BE /* Kingfisher-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-prefix.pch"; sourceTree = ""; }; + B764532F7A465FF640FDA97A850A103D /* MJRefreshStateTrailer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshStateTrailer.h; path = MJRefresh/Custom/Trailer/MJRefreshStateTrailer.h; sourceTree = ""; }; + B860B422FB58A9842214FE11A933BBD4 /* IQBarButtonItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQBarButtonItem.swift; path = IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift; sourceTree = ""; }; + B86EE2D4250A56EE1BB39FFEB834371D /* ConstraintMakerRelatable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerRelatable.swift; path = Sources/ConstraintMakerRelatable.swift; sourceTree = ""; }; + B98A705AFD36170CD85E492121E37403 /* AFError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AFError.swift; path = Source/Core/AFError.swift; sourceTree = ""; }; + B9DCB5EC0B1CDADD221717CADDF62359 /* SnapKit-SnapKit_Privacy */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "SnapKit-SnapKit_Privacy"; path = SnapKit_Privacy.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + BA90CEFF373663026D2F06371A3D4E9A /* JXSegmentedListContainerView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedListContainerView.swift; path = Sources/Common/JXSegmentedListContainerView.swift; sourceTree = ""; }; + BAAC3162B7531D025AB197602FE75F31 /* ServerTrustEvaluation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerTrustEvaluation.swift; path = Source/Features/ServerTrustEvaluation.swift; sourceTree = ""; }; + BB17A1319D51982E2F7A99EFC3D11F38 /* MJRefreshConfig.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshConfig.h; path = MJRefresh/MJRefreshConfig.h; sourceTree = ""; }; + BB420F181A7222985A450867020EFB2C /* JXPagingMainTableView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXPagingMainTableView.swift; path = Sources/JXPagingView/JXPagingMainTableView.swift; sourceTree = ""; }; + BB993F1FCBAA91D44D43B0587DB633FB /* SnapKit-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SnapKit-Info.plist"; sourceTree = ""; }; + BC90E0F634A75E57580CB83CB0B039E4 /* SnapKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SnapKit.debug.xcconfig; sourceTree = ""; }; + BD1BE557E2AE4A84F2515EB14ABAF97B /* SVProgressAnimatedView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SVProgressAnimatedView.m; path = SVProgressHUD/SVProgressAnimatedView.m; sourceTree = ""; }; + BD56DAD13E1185FD74DB7A8649E746CE /* Int+DateComponents.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Int+DateComponents.swift"; path = "Sources/SwiftDate/Foundation+Extras/Int+DateComponents.swift"; sourceTree = ""; }; + BDCF0C8D768EFB2E7C6A48EB2256867E /* CPListItem+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "CPListItem+Kingfisher.swift"; path = "Sources/Extensions/CPListItem+Kingfisher.swift"; sourceTree = ""; }; + BE0D9928CC4ABC217232D13CC2A41C53 /* SwiftDate.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftDate.debug.xcconfig; sourceTree = ""; }; + BE633CEBF91C6D351A438EB13D3F4E1F /* KF.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KF.swift; path = Sources/General/KF.swift; sourceTree = ""; }; + BE8BB5A012C6C501F12A4876ABF49101 /* MJRefreshAutoStateFooter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshAutoStateFooter.m; path = MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.m; sourceTree = ""; }; + BF6B66846BA638DCD6F5ABB338C4AA41 /* Notifications.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Notifications.swift; path = Source/Core/Notifications.swift; sourceTree = ""; }; C07BEF0CE5DECC5BDCAC8625BF2FFA4B /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; }; - C0F9FC31B8F636F7E4D3A505B5FCEA48 /* DateInRegion+Compare.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DateInRegion+Compare.swift"; path = "Sources/SwiftDate/DateInRegion/DateInRegion+Compare.swift"; sourceTree = ""; }; - C254E57BBEAA35B8CE7E6626A38511AF /* ConstraintRelatableTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintRelatableTarget.swift; path = Sources/ConstraintRelatableTarget.swift; sourceTree = ""; }; - C29313259EB03457900A0146BD10C25F /* Calendars.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Calendars.swift; path = Sources/SwiftDate/Supports/Calendars.swift; sourceTree = ""; }; C298ABB78D9B05529B89D8322DB2E7B0 /* Kingfisher-Kingfisher */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "Kingfisher-Kingfisher"; path = Kingfisher.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; - C2C597CA08FD78204DA81232B06ECD56 /* Kingfisher.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Kingfisher.modulemap; sourceTree = ""; }; + C2DC9D938B1784B3E0E8FFC9851FCAEA /* JXPagingListContainerView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXPagingListContainerView.swift; path = Sources/JXPagingView/JXPagingListContainerView.swift; sourceTree = ""; }; + C33A744358DA725C9E769351AB40C521 /* SwiftDate-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftDate-prefix.pch"; sourceTree = ""; }; C3F44C782D64D7EB20B61CE3844EBFAD /* Kingfisher */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Kingfisher; path = Kingfisher.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C434D6410430E92943DEAD104FCC27BE /* JXSegmentedView.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = JXSegmentedView.debug.xcconfig; sourceTree = ""; }; - C473B98F873BE78A2F86D02402284B3D /* Alamofire-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Alamofire-dummy.m"; sourceTree = ""; }; - C4B0B70AF11FE76174D9E1B20575FAAB /* ImageDrawing.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDrawing.swift; path = Sources/Image/ImageDrawing.swift; sourceTree = ""; }; - C5133FAC5521041D7059BD29ED6BD54E /* SwiftDate-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftDate-prefix.pch"; sourceTree = ""; }; - C570C2B10208E17D82B7BE0255BD166E /* ConstraintOffsetTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintOffsetTarget.swift; path = Sources/ConstraintOffsetTarget.swift; sourceTree = ""; }; - C63097B44D599B12E8CEF1425112BEA1 /* SVProgressHUD-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SVProgressHUD-dummy.m"; sourceTree = ""; }; - C7347F615A018CDE56878D17CCECC138 /* ConstraintItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintItem.swift; path = Sources/ConstraintItem.swift; sourceTree = ""; }; - C7778F9E9BCCA019BA4450E1ED18BB74 /* Runtime.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Runtime.swift; path = Sources/Utility/Runtime.swift; sourceTree = ""; }; - C789A86A2E73450B8364125FF6DF392B /* TVMonogramView+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "TVMonogramView+Kingfisher.swift"; path = "Sources/Extensions/TVMonogramView+Kingfisher.swift"; sourceTree = ""; }; - C81299D08C14E0F9FD7DEF40D51B331F /* JXSegmentedTitleAttributeItemModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleAttributeItemModel.swift; path = Sources/AttributeTitle/JXSegmentedTitleAttributeItemModel.swift; sourceTree = ""; }; - C950C7B6D82094FBAA31EA39107D9934 /* Image.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Image.swift; path = Sources/Image/Image.swift; sourceTree = ""; }; - CA7CF9C41BA9CA940652D4EC49B99A2D /* HTTPHeaders.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTPHeaders.swift; path = Source/Core/HTTPHeaders.swift; sourceTree = ""; }; - CC59DEE17997F5A0F4B91B06798B4CE9 /* IQKeyboardManagerSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = IQKeyboardManagerSwift.modulemap; sourceTree = ""; }; - CCAFDE558FB2154AF814B4EDA40CD48A /* SwiftDate-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftDate-Info.plist"; sourceTree = ""; }; - CD5DFFE16768F14458BE38939F340F1B /* ImageTransition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageTransition.swift; path = Sources/Image/ImageTransition.swift; sourceTree = ""; }; - CD8451E73468081EE9470C36E27AA3D8 /* SnapKit.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SnapKit.modulemap; sourceTree = ""; }; - CDF1EA36F77390C08F5F803AC6C25B26 /* KingfisherError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherError.swift; path = Sources/General/KingfisherError.swift; sourceTree = ""; }; - CECF59F44BE476A62417A1367B020FF4 /* NetworkReachabilityManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NetworkReachabilityManager.swift; path = Source/Features/NetworkReachabilityManager.swift; sourceTree = ""; }; - D0F0E865FFAB434485335DA1629A1388 /* JXPagingView-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "JXPagingView-dummy.m"; sourceTree = ""; }; - D1B714CDE211483876F8D71E98D218A3 /* WebSocketRequest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WebSocketRequest.swift; path = Source/Core/WebSocketRequest.swift; sourceTree = ""; }; - D1BC0AA48F6B64CE90390DE5DBE67EFD /* UILayoutSupport+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UILayoutSupport+Extensions.swift"; path = "Sources/UILayoutSupport+Extensions.swift"; sourceTree = ""; }; - D1D5E0DBAC440FA8BD16F3D87B5D36B6 /* JXSegmentedView.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = JXSegmentedView.modulemap; sourceTree = ""; }; - D1D71E0DF282F4F1A0C83021CB0B5E10 /* Alamofire-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Alamofire-Info.plist"; sourceTree = ""; }; - D20485D884C20E59FFC1CE9922C547D5 /* MemoryStorage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MemoryStorage.swift; path = Sources/Cache/MemoryStorage.swift; sourceTree = ""; }; - D2CE45575AF714BC629EF55E552BAC8E /* ResourceBundle-JXSegmentedView-JXSegmentedView-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-JXSegmentedView-JXSegmentedView-Info.plist"; sourceTree = ""; }; - D33E49B3F1AC34C95B187A51D1AC0D17 /* ResourceBundle-JXPagingView-JXPagingView-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-JXPagingView-JXPagingView-Info.plist"; sourceTree = ""; }; - D378275D09B96773C488D7591063EC86 /* IQKeyboardManagerSwift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = IQKeyboardManagerSwift.release.xcconfig; sourceTree = ""; }; - D45E015988EDAE0D78F39EE421B58283 /* JXPagingView-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "JXPagingView-prefix.pch"; sourceTree = ""; }; - D60E4FF19874657631F19D84E77C0FCD /* CPListItem+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "CPListItem+Kingfisher.swift"; path = "Sources/Extensions/CPListItem+Kingfisher.swift"; sourceTree = ""; }; - D6A9EFEFEBACC5355C9CC03D88A5F10D /* Alamofire-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-prefix.pch"; sourceTree = ""; }; - D7E9F891E8CCB8860AE7419A69AC9327 /* IQUIView+Hierarchy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIView+Hierarchy.swift"; path = "IQKeyboardManagerSwift/Categories/IQUIView+Hierarchy.swift"; sourceTree = ""; }; - D7F7058BED0353F5D41333BF24E48B67 /* AuthenticationChallengeResponsable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AuthenticationChallengeResponsable.swift; path = Sources/Networking/AuthenticationChallengeResponsable.swift; sourceTree = ""; }; - D8E1418AF8EB9AC57EA5BDC745EE7216 /* ExtensionHelpers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExtensionHelpers.swift; path = Sources/Utility/ExtensionHelpers.swift; sourceTree = ""; }; - DBF19CEB43F8643CAD55D7742AC0970A /* SwiftDate.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftDate.modulemap; sourceTree = ""; }; - DC3193C7C92FBD37C24C5E36096576D6 /* JXSegmentedView-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "JXSegmentedView-umbrella.h"; sourceTree = ""; }; - DC679D42513109DC163A916172A01E41 /* ConstraintMakerRelatable+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ConstraintMakerRelatable+Extensions.swift"; path = "Sources/ConstraintMakerRelatable+Extensions.swift"; sourceTree = ""; }; - DDC2D0518832B22B12029C5C922BB7D8 /* JXSegmentedTitleAttributeDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleAttributeDataSource.swift; path = Sources/AttributeTitle/JXSegmentedTitleAttributeDataSource.swift; sourceTree = ""; }; - E14C41F18595A29151A31E735A1B7692 /* LayoutConstraint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LayoutConstraint.swift; path = Sources/LayoutConstraint.swift; sourceTree = ""; }; - E2571304BB906066EBA3D52C58187895 /* SizeExtensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SizeExtensions.swift; path = Sources/Utility/SizeExtensions.swift; sourceTree = ""; }; - E329FD7AFE7914B19431A5027E14E2E3 /* Typealiases.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Typealiases.swift; path = Sources/Typealiases.swift; sourceTree = ""; }; - E4F1F2DD34925CE8FB29B1319F19DEE3 /* EventMonitor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EventMonitor.swift; path = Source/Features/EventMonitor.swift; sourceTree = ""; }; - E6052A6B485A84163CBF2D1FC6D30DB7 /* SVProgressHUD-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SVProgressHUD-umbrella.h"; sourceTree = ""; }; + C408D0CD682A652982659893260F5EA4 /* ImageDataProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDataProvider.swift; path = Sources/General/ImageSource/ImageDataProvider.swift; sourceTree = ""; }; + C468581B4214846A9CA4FFED32F836D8 /* TimeStructures.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TimeStructures.swift; path = Sources/SwiftDate/Supports/TimeStructures.swift; sourceTree = ""; }; + C483D88FC9B266C71FB54AA488C58BBD /* ConstraintRelatableTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintRelatableTarget.swift; path = Sources/ConstraintRelatableTarget.swift; sourceTree = ""; }; + C4A16ABD25AB8AAB13E0072CADE42E65 /* UILayoutSupport+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UILayoutSupport+Extensions.swift"; path = "Sources/UILayoutSupport+Extensions.swift"; sourceTree = ""; }; + C4C51E9357636F513F9828759A831069 /* DateInRegion+Create.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DateInRegion+Create.swift"; path = "Sources/SwiftDate/DateInRegion/DateInRegion+Create.swift"; sourceTree = ""; }; + C50C61572CB504F3A1B27F44B20F385F /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Sources/PrivacyInfo.xcprivacy; sourceTree = ""; }; + C521434F700F146BC7EEBBE2C6735ABF /* JXPagingView.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = JXPagingView.modulemap; sourceTree = ""; }; + C54C3E1777728F805F3EFCB27BB703BC /* IQUIScrollView+Additions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIScrollView+Additions.swift"; path = "IQKeyboardManagerSwift/Categories/IQUIScrollView+Additions.swift"; sourceTree = ""; }; + C68BBA48149EB58E146B969600FB99B8 /* SVProgressHUD-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SVProgressHUD-umbrella.h"; sourceTree = ""; }; + C76A1ABBD38622E820640903E4A979AD /* MJRefreshFooter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshFooter.m; path = MJRefresh/Base/MJRefreshFooter.m; sourceTree = ""; }; + C94A8D6D5B3A24A5E000AF4DBE9434CF /* MultipartUpload.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultipartUpload.swift; path = Source/Features/MultipartUpload.swift; sourceTree = ""; }; + CA08845BC3434B44AF0A3C8AFC111D93 /* JXSegmentedBaseCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedBaseCell.swift; path = Sources/Core/JXSegmentedBaseCell.swift; sourceTree = ""; }; + CA42DDB21EAB3527641F275C3D22E4D0 /* Validation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Validation.swift; path = Source/Features/Validation.swift; sourceTree = ""; }; + CA5885E0EE3717A1437053591B37EAD8 /* SwiftDate-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftDate-Info.plist"; sourceTree = ""; }; + CB03A8FE1983F5F495EC9ADC0D6E7E6B /* MultipartFormData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultipartFormData.swift; path = Source/Features/MultipartFormData.swift; sourceTree = ""; }; + CB0F440BD5C5987BBAD5992F1CC0CCAA /* Result+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Result+Alamofire.swift"; path = "Source/Extensions/Result+Alamofire.swift"; sourceTree = ""; }; + CB34508FC3184D3482A1002BEBC16654 /* IQKeyboardManager+Toolbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+Toolbar.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+Toolbar.swift"; sourceTree = ""; }; + CDC741E10FE2F276DD3C474545224A00 /* FormatIndicatedCacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FormatIndicatedCacheSerializer.swift; path = Sources/Cache/FormatIndicatedCacheSerializer.swift; sourceTree = ""; }; + CDCBF5F15899BDBF63D3CC736990E1A5 /* IQKeyboardReturnKeyHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardReturnKeyHandler.swift; path = IQKeyboardManagerSwift/IQKeyboardReturnKeyHandler.swift; sourceTree = ""; }; + CE14F9280BCE30360011E5C9806D2516 /* ResourceBundle-Alamofire-Alamofire-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-Alamofire-Alamofire-Info.plist"; sourceTree = ""; }; + CF14834E63FED3D59E4631FEEA9514CD /* MJRefresh.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = MJRefresh.modulemap; sourceTree = ""; }; + CFCB35EFBB8A545F2F8352A7D27D5B2A /* ExtensionHelpers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExtensionHelpers.swift; path = Sources/Utility/ExtensionHelpers.swift; sourceTree = ""; }; + D061CC1A5FB61D63B44C75541D898A36 /* ImageContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageContext.swift; path = Sources/SwiftUI/ImageContext.swift; sourceTree = ""; }; + D18ABD1C495B7F72F0284AAC613A93F2 /* MJRefreshNormalTrailer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshNormalTrailer.h; path = MJRefresh/Custom/Trailer/MJRefreshNormalTrailer.h; sourceTree = ""; }; + D1968FDA9F67DC3333951BED4268CA52 /* Calendars.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Calendars.swift; path = Sources/SwiftDate/Supports/Calendars.swift; sourceTree = ""; }; + D19D1617C2FB2FC864606303AF174A6D /* TimePeriodChain.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TimePeriodChain.swift; path = Sources/SwiftDate/TimePeriod/Groups/TimePeriodChain.swift; sourceTree = ""; }; + D38764AB52ACD239BAD933070283AA4F /* UIScrollView+MJRefresh.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIScrollView+MJRefresh.m"; path = "MJRefresh/UIScrollView+MJRefresh.m"; sourceTree = ""; }; + D394AD7BFA59E7271EC623CF17FBDD30 /* GIFAnimatedImage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GIFAnimatedImage.swift; path = Sources/Image/GIFAnimatedImage.swift; sourceTree = ""; }; + D44F4C1AC6C2A207BC560F616003B1B3 /* SVProgressHUD-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SVProgressHUD-prefix.pch"; sourceTree = ""; }; + D473476568C2D2300CCBAE8BAC883DCE /* JXPagingView.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = JXPagingView.release.xcconfig; sourceTree = ""; }; + D49B5FF4D24E46BB7F695E22A9907317 /* Delegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Delegate.swift; path = Sources/Utility/Delegate.swift; sourceTree = ""; }; + D5A9B7775663040A8BD50618EDF84298 /* MJRefreshBackFooter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshBackFooter.h; path = MJRefresh/Base/MJRefreshBackFooter.h; sourceTree = ""; }; + D66CFC994F45F4A9A50C54C16724D763 /* UIButton+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIButton+Kingfisher.swift"; path = "Sources/Extensions/UIButton+Kingfisher.swift"; sourceTree = ""; }; + D776B0C4D357F0B0466B42C8BF6495D5 /* ImageModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageModifier.swift; path = Sources/Networking/ImageModifier.swift; sourceTree = ""; }; + D88F8FEC13A3A1DB04F7186FA15AE1CB /* ResponseSerialization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ResponseSerialization.swift; path = Source/Features/ResponseSerialization.swift; sourceTree = ""; }; + D89E20D36B74F4A890688A090C311698 /* RequestInterceptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestInterceptor.swift; path = Source/Features/RequestInterceptor.swift; sourceTree = ""; }; + D96D6359D0BE44C30CD6EE91D83FA37B /* SVProgressHUD-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SVProgressHUD-Info.plist"; sourceTree = ""; }; + DA1E44B32910D0CD9054692D4F938398 /* ImageDownloader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDownloader.swift; path = Sources/Networking/ImageDownloader.swift; sourceTree = ""; }; + DBF28FA874E18F2693E3B035356382F0 /* JXSegmentedTitleItemModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleItemModel.swift; path = Sources/Title/JXSegmentedTitleItemModel.swift; sourceTree = ""; }; + DC81E237B242F0601E0FC35F98708DC4 /* IQUIView+IQKeyboardToolbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIView+IQKeyboardToolbar.swift"; path = "IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift"; sourceTree = ""; }; + DED1174C630E86B387EC34B8B1DD2DA3 /* Date+Math.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Date+Math.swift"; path = "Sources/SwiftDate/Date/Date+Math.swift"; sourceTree = ""; }; + DF2C075BA691343B5759F4F639FA08A6 /* Kingfisher.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.debug.xcconfig; sourceTree = ""; }; + E0E418BB3B470DAB2533C31BAD7884C0 /* MJRefreshStateTrailer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshStateTrailer.m; path = MJRefresh/Custom/Trailer/MJRefreshStateTrailer.m; sourceTree = ""; }; + E1176C58859CF5334183B7786DAC8E87 /* IQKeyboardManagerSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "IQKeyboardManagerSwift-dummy.m"; sourceTree = ""; }; + E17C586A0C27A8F810C609FC78419447 /* IQKeyboardManager+Debug.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+Debug.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+Debug.swift"; sourceTree = ""; }; + E18618FEAC0ECEE393834FA4EEDDD337 /* Kingfisher.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.release.xcconfig; sourceTree = ""; }; + E31B1C576F8187B6B1A1F160B90D6081 /* JXSegmentedIndicatorBackgroundView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorBackgroundView.swift; path = Sources/Indicator/JXSegmentedIndicatorBackgroundView.swift; sourceTree = ""; }; + E3C11DA33AB8B0E9203520516067EC23 /* UIView+MJExtension.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIView+MJExtension.m"; path = "MJRefresh/UIView+MJExtension.m"; sourceTree = ""; }; + E4678D7C77B6546A4205C194E9F275EB /* MJRefreshNormalHeader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshNormalHeader.h; path = MJRefresh/Custom/Header/MJRefreshNormalHeader.h; sourceTree = ""; }; + E48EF69AA55D5B91B47D8C1EB4BA4691 /* DateInRegion+Components.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DateInRegion+Components.swift"; path = "Sources/SwiftDate/DateInRegion/DateInRegion+Components.swift"; sourceTree = ""; }; + E49D6D248DD1CEE584E6776B9164A1B2 /* MJRefresh */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = MJRefresh; path = MJRefresh.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E623870FC6E557F7D90E41BF1892B184 /* Pods-MusicPlayer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-MusicPlayer.debug.xcconfig"; sourceTree = ""; }; - E72A243B166894EB9748892B7E08CE91 /* DateInRegion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DateInRegion.swift; path = Sources/SwiftDate/DateInRegion/DateInRegion.swift; sourceTree = ""; }; - E7FA6A81D452D73024CD59E468AADA68 /* IQUIScrollView+Additions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIScrollView+Additions.swift"; path = "IQKeyboardManagerSwift/Categories/IQUIScrollView+Additions.swift"; sourceTree = ""; }; - E8112989320F97673E4EB82A275CAE0C /* AuthenticationInterceptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AuthenticationInterceptor.swift; path = Source/Features/AuthenticationInterceptor.swift; sourceTree = ""; }; + E652FB17C57B0AF0273621B2B037A0C7 /* JXSegmentedTitleDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleDataSource.swift; path = Sources/Title/JXSegmentedTitleDataSource.swift; sourceTree = ""; }; + E681F9A4BFBE0245493029CEB1B8A1C8 /* StringEncoding+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "StringEncoding+Alamofire.swift"; path = "Source/Extensions/StringEncoding+Alamofire.swift"; sourceTree = ""; }; + E6E279BCC1C2C3A2FA64E3E7F3FD5335 /* DataRequest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DataRequest.swift; path = Source/Core/DataRequest.swift; sourceTree = ""; }; + E75F2A56E77879A823734237F7B0D90B /* Runtime.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Runtime.swift; path = Sources/Utility/Runtime.swift; sourceTree = ""; }; + E770B62A86FAE28308923E8266E15451 /* MJRefreshBackStateFooter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJRefreshBackStateFooter.m; path = MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.m; sourceTree = ""; }; + E88C5C3FE92321767662E35C421964B3 /* Debugging.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Debugging.swift; path = Sources/Debugging.swift; sourceTree = ""; }; + E8DAC31F0F6FE66D2C8AF5489F272CEA /* KingfisherManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherManager.swift; path = Sources/General/KingfisherManager.swift; sourceTree = ""; }; + E9045FA6D60732F49E7765B398DDC46B /* IQUIView+Hierarchy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIView+Hierarchy.swift"; path = "IQKeyboardManagerSwift/Categories/IQUIView+Hierarchy.swift"; sourceTree = ""; }; + E90BED91E412505AF7055D21B806502E /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = MJRefresh/PrivacyInfo.xcprivacy; sourceTree = ""; }; + E95438C214C29A3893A1B32DE8B1898F /* JXSegmentedTitleAttributeCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleAttributeCell.swift; path = Sources/AttributeTitle/JXSegmentedTitleAttributeCell.swift; sourceTree = ""; }; E97D43C46A45EE515A4DA3AF94398441 /* SVProgressHUD */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SVProgressHUD; path = SVProgressHUD.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - E9CE7D5D62E97450A0DF267A8A799F0B /* Source.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Source.swift; path = Sources/General/ImageSource/Source.swift; sourceTree = ""; }; - E9EBABB97D904EE628416E05BCE58900 /* SVProgressAnimatedView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SVProgressAnimatedView.h; path = SVProgressHUD/SVProgressAnimatedView.h; sourceTree = ""; }; - EA2B7CB6D3C5BF9E8732BD8ED85BC022 /* JXSegmentedIndicatorDotLineView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorDotLineView.swift; path = Sources/Indicator/JXSegmentedIndicatorDotLineView.swift; sourceTree = ""; }; - EAF4F6584F8A39930FEF6F95DB825779 /* JXSegmentedIndicatorParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorParams.swift; path = Sources/Indicator/JXSegmentedIndicatorParams.swift; sourceTree = ""; }; - EB1005A1E92368A5F7B5C869FAF2E1E7 /* AlamofireExtended.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AlamofireExtended.swift; path = Source/Features/AlamofireExtended.swift; sourceTree = ""; }; - EC849766E84C3D70F4A1EC1D8B8B1E23 /* JXSegmentedTitleImageItemModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleImageItemModel.swift; path = Sources/TitleImage/JXSegmentedTitleImageItemModel.swift; sourceTree = ""; }; - EC9CD67D400913EBE69B43B5CD49163E /* ImageCache.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageCache.swift; path = Sources/Cache/ImageCache.swift; sourceTree = ""; }; + E9B6DF66CC0D9538F8F45AB7F7F82FB3 /* ImageDataProcessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDataProcessor.swift; path = Sources/Networking/ImageDataProcessor.swift; sourceTree = ""; }; + E9B7826E0EF5E37E1704D27E7C361C78 /* Concurrency.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Concurrency.swift; path = Source/Features/Concurrency.swift; sourceTree = ""; }; + E9C19F89F8FC7DDEB64DB778A90CC2BC /* ConstraintView+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ConstraintView+Extensions.swift"; path = "Sources/ConstraintView+Extensions.swift"; sourceTree = ""; }; + E9C22A64A41E73EF4590DC6552E80DE8 /* JXPagingView-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "JXPagingView-prefix.pch"; sourceTree = ""; }; + E9CA1CB30F953F8E32CCE0D206E0DFE5 /* ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist"; sourceTree = ""; }; + EAD5CEA5D178799C659489E705F0BDE8 /* URLConvertible+URLRequestConvertible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLConvertible+URLRequestConvertible.swift"; path = "Source/Core/URLConvertible+URLRequestConvertible.swift"; sourceTree = ""; }; + EB8D6628308EE28230C57E4CE1063A31 /* Request.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Request.swift; path = Source/Core/Request.swift; sourceTree = ""; }; + EC02376976FBCAAD8506234104E8BAA5 /* Alamofire-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Alamofire-Info.plist"; sourceTree = ""; }; EDBCA147FB2F16410EABF574FBB6C2EB /* Pods-MusicPlayer-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-MusicPlayer-Info.plist"; sourceTree = ""; }; - EE645C9DF881DC086EE8AD29F9834E09 /* JXSegmentedIndicatorProtocol.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorProtocol.swift; path = Sources/Indicator/JXSegmentedIndicatorProtocol.swift; sourceTree = ""; }; - EE72EF69BD801D8C5E4AFBF5B3338955 /* JXSegmentedDotCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedDotCell.swift; path = Sources/Dot/JXSegmentedDotCell.swift; sourceTree = ""; }; - EF3E7152220EF9221D3638B93DAE5EAD /* Session.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Session.swift; path = Source/Core/Session.swift; sourceTree = ""; }; - F05B27A0A6364144E57B02027A6A91F2 /* CallbackQueue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CallbackQueue.swift; path = Sources/Utility/CallbackQueue.swift; sourceTree = ""; }; - F0C110EA1EFE725C53F87FB7D4FD59B7 /* JXSegmentedIndicatorBaseView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorBaseView.swift; path = Sources/Indicator/JXSegmentedIndicatorBaseView.swift; sourceTree = ""; }; + EEC2D820ED623D3C956582179E970607 /* IQPlaceholderable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQPlaceholderable.swift; path = IQKeyboardManagerSwift/IQTextView/IQPlaceholderable.swift; sourceTree = ""; }; + EF651BDF14D5A324318BC3F8C317F57A /* Result.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Result.swift; path = Sources/Utility/Result.swift; sourceTree = ""; }; + EFE78C092A2B391D6411B2D75E0897C5 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = IQKeyboardManagerSwift/PrivacyInfo.xcprivacy; sourceTree = ""; }; + F088EAD83DD6725075FBD8403594C429 /* ConstraintMakerEditable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerEditable.swift; path = Sources/ConstraintMakerEditable.swift; sourceTree = ""; }; + F0917B962F89415FDAAA876040A72E83 /* DateRepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DateRepresentable.swift; path = Sources/SwiftDate/DateRepresentable.swift; sourceTree = ""; }; + F0CF839DB998A3AA0D5D01C635E92AB8 /* UIScrollView+MJExtension.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIScrollView+MJExtension.h"; path = "MJRefresh/UIScrollView+MJExtension.h"; sourceTree = ""; }; F0F27AFF60F54ECC48396ECBB22D94EC /* Pods-MusicPlayer.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-MusicPlayer.release.xcconfig"; sourceTree = ""; }; - F0F5BDD0C9E9E0CA159C3D2940A73FAD /* Result+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Result+Alamofire.swift"; path = "Source/Extensions/Result+Alamofire.swift"; sourceTree = ""; }; - F16488115126AF3281342B1C0395D41E /* Kingfisher-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Kingfisher-Info.plist"; sourceTree = ""; }; - F1C800A89115F306E7099713F917565C /* DateRepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DateRepresentable.swift; path = Sources/SwiftDate/DateRepresentable.swift; sourceTree = ""; }; - F2015AFD9107C9946CA35C41D72E9B5D /* IQUITextFieldView+Additions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUITextFieldView+Additions.swift"; path = "IQKeyboardManagerSwift/Categories/IQUITextFieldView+Additions.swift"; sourceTree = ""; }; + F125D521A9DA47CB8D38C8C03AEF68A0 /* JXSegmentedIndicatorLineView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorLineView.swift; path = Sources/Indicator/JXSegmentedIndicatorLineView.swift; sourceTree = ""; }; + F15F5BABB5166FF00A9E43E67C060454 /* MJRefreshBackNormalFooter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJRefreshBackNormalFooter.h; path = MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.h; sourceTree = ""; }; F23C669C0B769DC30F5A05CE45FEA445 /* Pods-MusicPlayer */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-MusicPlayer"; path = Pods_MusicPlayer.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - F27DE7E6CC48EBD987659B78F5B0E68C /* ResponseSerialization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ResponseSerialization.swift; path = Source/Features/ResponseSerialization.swift; sourceTree = ""; }; - F37D9853994687118DD881E59106C758 /* RedirectHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RedirectHandler.swift; path = Source/Features/RedirectHandler.swift; sourceTree = ""; }; - F56A43D0608BE9C9E5E018F488A70CD4 /* IQTitleBarButtonItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQTitleBarButtonItem.swift; path = IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift; sourceTree = ""; }; - F57F780799948B0298A107CA1DAF860C /* Kingfisher-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Kingfisher-dummy.m"; sourceTree = ""; }; - F70EE242B119207B6DE78061ABCD5426 /* IQKeyboardManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardManager.swift; path = IQKeyboardManagerSwift/IQKeyboardManager.swift; sourceTree = ""; }; - F780BDE3AA3E75F9B115272AAFD28A9E /* JXSegmentedComponetGradientView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedComponetGradientView.swift; path = Sources/Indicator/JXSegmentedComponetGradientView.swift; sourceTree = ""; }; - F8560E583BCEFEFC4455CDA8AE15D746 /* SVProgressHUD.bundle */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "wrapper.plug-in"; name = SVProgressHUD.bundle; path = SVProgressHUD/SVProgressHUD.bundle; sourceTree = ""; }; - F8765B4E3D1104165E5D1E435F4945D9 /* SnapKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SnapKit.debug.xcconfig; sourceTree = ""; }; - F8C007F792870EEA4EC7B19A0FACC384 /* DotNetParserFormatter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DotNetParserFormatter.swift; path = Sources/SwiftDate/Formatters/DotNetParserFormatter.swift; sourceTree = ""; }; - F954C218AC5D88CE4C61680D652F9306 /* UIButton+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIButton+Kingfisher.swift"; path = "Sources/Extensions/UIButton+Kingfisher.swift"; sourceTree = ""; }; - FA1790A81F081026839A33E7AA4A3172 /* JXSegmentedCollectionView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedCollectionView.swift; path = Sources/Core/JXSegmentedCollectionView.swift; sourceTree = ""; }; - FABEEC9AF2516E3B746E77F84AD1BD3F /* ConstraintLayoutGuideDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutGuideDSL.swift; path = Sources/ConstraintLayoutGuideDSL.swift; sourceTree = ""; }; - FAE668ECEAF7AAFCDEEDD1F0D9C0B3F1 /* SessionDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDelegate.swift; path = Sources/Networking/SessionDelegate.swift; sourceTree = ""; }; - FC849700AF2A2CAC32974D17E4B461D2 /* RequestCompression.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestCompression.swift; path = Source/Features/RequestCompression.swift; sourceTree = ""; }; - FC9A4AF661D951099E57AB12E84B84E0 /* IQNSArray+Sort.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQNSArray+Sort.swift"; path = "IQKeyboardManagerSwift/Categories/IQNSArray+Sort.swift"; sourceTree = ""; }; - FCFB2567FE9BD5DDD79D4D4E176FE079 /* Resource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Resource.swift; path = Sources/General/ImageSource/Resource.swift; sourceTree = ""; }; - FD1A206A2C1CBD7E676E9B6169ECDF72 /* JXSegmentedViewTool.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedViewTool.swift; path = Sources/Common/JXSegmentedViewTool.swift; sourceTree = ""; }; - FE12AE6B4D59FD7310447B92B7B2B83C /* Commons.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Commons.swift; path = Sources/SwiftDate/Supports/Commons.swift; sourceTree = ""; }; - FE6F6DA791EBF42B686DEEAE637C154D /* ImageDataProcessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDataProcessor.swift; path = Sources/Networking/ImageDataProcessor.swift; sourceTree = ""; }; - FEDF29E375EBE13E620E486941023E18 /* SVProgressHUD.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SVProgressHUD.m; path = SVProgressHUD/SVProgressHUD.m; sourceTree = ""; }; - FEF1F46153EB848293C59AAA92FFCE28 /* RequestInterceptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestInterceptor.swift; path = Source/Features/RequestInterceptor.swift; sourceTree = ""; }; - FFF930183A98B76DFC6E381963A1F56A /* ConstraintMultiplierTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMultiplierTarget.swift; path = Sources/ConstraintMultiplierTarget.swift; sourceTree = ""; }; + F3AC7EE5F91C56B1C96124A3C58154A5 /* ResourceBundle-Kingfisher-Kingfisher-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-Kingfisher-Kingfisher-Info.plist"; sourceTree = ""; }; + F3EEB78584831D0B242BDCAA90CED58E /* KFImage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KFImage.swift; path = Sources/SwiftUI/KFImage.swift; sourceTree = ""; }; + F43F88826BD8118C95446B4D9D4F416F /* AVAssetImageDataProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AVAssetImageDataProvider.swift; path = Sources/General/ImageSource/AVAssetImageDataProvider.swift; sourceTree = ""; }; + F44F0D93CFD9BB7C99C0FFCD686FF4E3 /* TimePeriodGroup.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TimePeriodGroup.swift; path = Sources/SwiftDate/TimePeriod/Groups/TimePeriodGroup.swift; sourceTree = ""; }; + F4C866B997568C25289AC4481D960976 /* JXPagingView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXPagingView.swift; path = Sources/JXPagingView/JXPagingView.swift; sourceTree = ""; }; + F4ED2B675426F9C1C129D85C5356428E /* SwiftDate.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftDate.modulemap; sourceTree = ""; }; + F56A78070D28571910937BC0EE5894B8 /* ISOFormatter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ISOFormatter.swift; path = Sources/SwiftDate/Formatters/ISOFormatter.swift; sourceTree = ""; }; + F62422400EE70C424F8B9090F58835FC /* Kingfisher-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Kingfisher-Info.plist"; sourceTree = ""; }; + F6D3AF216BBC3443539D5BAD7BE5DEDF /* SVRadialGradientLayer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SVRadialGradientLayer.h; path = SVProgressHUD/SVRadialGradientLayer.h; sourceTree = ""; }; + F796615F5FF6E91238484B197D6CF227 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Sources/PrivacyInfo.xcprivacy; sourceTree = ""; }; + F7B2E649574AA0FAECB00E9B883C49A6 /* LayoutConstraintItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LayoutConstraintItem.swift; path = Sources/LayoutConstraintItem.swift; sourceTree = ""; }; + F86ED01EB7CC70315E585984B7CEADA2 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Sources/PrivacyInfo.xcprivacy; sourceTree = ""; }; + F8C8C3813F3BA6EEC658167AE65D9419 /* DataStreamRequest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DataStreamRequest.swift; path = Source/Core/DataStreamRequest.swift; sourceTree = ""; }; + FA38A01E090C908AE5886021034EE11D /* Region.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Region.swift; path = Sources/SwiftDate/DateInRegion/Region.swift; sourceTree = ""; }; + FCA08BA243343C7A9EAEE567CC5F4318 /* IQInvocation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQInvocation.swift; path = IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift; sourceTree = ""; }; + FD0AE0ACE265AEC714180F643F48C621 /* ConstraintAttributes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintAttributes.swift; path = Sources/ConstraintAttributes.swift; sourceTree = ""; }; + FDD5BF7F25804ED6AC6B15D6801FE4AD /* JXSegmentedTitleOrImageItemModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedTitleOrImageItemModel.swift; path = Sources/TitleOrImage/JXSegmentedTitleOrImageItemModel.swift; sourceTree = ""; }; + FDE736DCB96A4842E66D08021E34D36C /* JXSegmentedAnimator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedAnimator.swift; path = Sources/Common/JXSegmentedAnimator.swift; sourceTree = ""; }; + FE5DD88C594D20A1F18F99828A3FEB64 /* ImageBinder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageBinder.swift; path = Sources/SwiftUI/ImageBinder.swift; sourceTree = ""; }; + FEC00130945EBD53372EFBC22FB8119E /* JXSegmentedIndicatorParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JXSegmentedIndicatorParams.swift; path = Sources/Indicator/JXSegmentedIndicatorParams.swift; sourceTree = ""; }; + FEE5906F519651F94E70B28F42C4C70B /* LayoutConstraint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LayoutConstraint.swift; path = Sources/LayoutConstraint.swift; sourceTree = ""; }; + FF512DBF4BC4483F9F306E2B3A5CDB70 /* DateComponents+Extras.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DateComponents+Extras.swift"; path = "Sources/SwiftDate/Foundation+Extras/DateComponents+Extras.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 067799593B2F15037103C952D8E15BCA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 115EE9484AD8D18887A8175CFF9FEB3C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -774,28 +927,53 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5A29158CAB99F1CFF837C37811A7B6A1 /* Frameworks */ = { + 2560AEF01B4ED19DB7D7B4882A6F90F9 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 98455F4176C861F9E33D36892A932684 /* Foundation.framework in Frameworks */, + FF886124915FEF2A6FBB663CA621B4FC /* QuartzCore.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3FA6BB0E255F3D1C771079154343333B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 172D6F4BDBFD921ABF3F4936747C7B5F /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 402E49A24B937179BD48FB96001CBF9D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 86543E133EC209AA0A53EECE72BFA079 /* Frameworks */ = { + 4B885211E9E65DAB21AAD17EBC56C6F1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 057C34276F1C858071F1372C68540A5E /* CoreGraphics.framework in Frameworks */, - C52630B4D59C7A2757A8E7508F37D1B7 /* Foundation.framework in Frameworks */, - 25E88D4079655A5E49799B0B559DD42A /* QuartzCore.framework in Frameworks */, - B462CD14FCF8FA2EF578F76C63AB9FFB /* UIKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 8C2D9DF369727E237BEC22EF0C9C2AD5 /* Frameworks */ = { + 65BFC75CE1541E38446FFDA8AFF0DBEC /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 0874E6176184E3A1C3E8AB158AE5E98B /* CoreGraphics.framework in Frameworks */, + 647D16586EBBE25158E3FD684541A1DD /* Foundation.framework in Frameworks */, + A8C0CBBC63C39A8C10083CBCA172F7CF /* QuartzCore.framework in Frameworks */, + 97EA46DA072EC4FD4D831606095B92C1 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6F796DCACF7FECDF5C5CEF6AFE7BC0FF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + C7E343559158D03F717C616F79FAA006 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -808,6 +986,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 8CB5E1A5B008E0176BA7B33578DFF0C8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 218C0927BB7605141B611529DD6F65B4 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; A5C342523C3577E7122B4B43929BA8F3 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -817,34 +1003,24 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - CB094C5CC2CE7C14828D233306D629F8 /* Frameworks */ = { + ACBA24352126BCD74C702B7475807D88 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - D1B0699FE073B926EB6BB5C6B177A326 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - AB3FB3A4F52F88797D743DB4324DFD16 /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D76F1A0A75BD4615906466C44D72FDFF /* Frameworks */ = { + E74997FAADCF49681E528FCB21A4D1AA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - E389FF082B036E756B0679583C1BE62E /* Frameworks */ = { + E77A06A0307FF511269865599FB0CBC8 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 798FA71F8CAE44D05016FFF767100375 /* Foundation.framework in Frameworks */, - 53BECA6AA55F80D63F104475EE6524CA /* QuartzCore.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -856,51 +1032,131 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - E8E4E7CE8309D3EF7B7476AC57986BE9 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 0833E66E7F19849322305D67777B77DB /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 066A119AC73825E311A92A10A39576B5 /* SVProgressHUD */ = { + 06AE3DF2432EBA8876A90CEDD3312552 /* Resources */ = { isa = PBXGroup; children = ( - 699CF3DF23FE505906183E16A8B215AD /* SVIndefiniteAnimatedView.h */, - 44E1D50EA152F2FA29542A017C52B34A /* SVIndefiniteAnimatedView.m */, - E9EBABB97D904EE628416E05BCE58900 /* SVProgressAnimatedView.h */, - 4ADE20627987FA4EA010036CDEE47000 /* SVProgressAnimatedView.m */, - 384CCE46006CEC00E0ADA0DB1232170E /* SVProgressHUD.h */, - FEDF29E375EBE13E620E486941023E18 /* SVProgressHUD.m */, - 25700C90519D6E5662DBD6E110F3AAB9 /* SVRadialGradientLayer.h */, - 1EE1A2A286DF3C313266DAA14C61273E /* SVRadialGradientLayer.m */, - C12BA1DD7528D0DB05AC3956322C5CBA /* Resources */, - 4F3E918834B66F0E10BC1AAC77A14542 /* Support Files */, - ); - name = SVProgressHUD; - path = SVProgressHUD; - sourceTree = ""; - }; - 0E5748DA9911AC1A96532641D6F01D71 /* Resources */ = { - isa = PBXGroup; - children = ( - 99DACD800F6BC071C09C771CFA780B2D /* PrivacyInfo.xcprivacy */, + F796615F5FF6E91238484B197D6CF227 /* PrivacyInfo.xcprivacy */, ); name = Resources; sourceTree = ""; }; - 1B4243047EF6606A4809DBC3B992C6F4 /* Resources */ = { + 0D71198B2379509AC4AA8EC9853ED524 /* Support Files */ = { isa = PBXGroup; children = ( - 5FC69CA124430885BBDD652A5966AE29 /* PrivacyInfo.xcprivacy */, + CF14834E63FED3D59E4631FEEA9514CD /* MJRefresh.modulemap */, + 5DD688DF2ADF79B72ECC735C35F05F41 /* MJRefresh-dummy.m */, + 5AEFD27CAFBA0B3BB80B6F22588271D1 /* MJRefresh-Info.plist */, + ADD37EAEC18687AE8ED7C2EED0B1463A /* MJRefresh-prefix.pch */, + 82E922355D2129F96245BA8E4E5FFF67 /* MJRefresh-umbrella.h */, + 3AE4A701F7BAB983ED11B504E6487F76 /* MJRefresh.debug.xcconfig */, + AC5E8113942F4B6D5C87580AA549D92C /* MJRefresh.release.xcconfig */, + 4DE64A8F508B88F991A85594504A5076 /* ResourceBundle-MJRefresh.Privacy-MJRefresh-Info.plist */, + ); + name = "Support Files"; + path = "../Target Support Files/MJRefresh"; + sourceTree = ""; + }; + 124E79470B5BB059B6D2B9C11028C2E3 /* Resources */ = { + isa = PBXGroup; + children = ( + C50C61572CB504F3A1B27F44B20F385F /* PrivacyInfo.xcprivacy */, ); name = Resources; sourceTree = ""; }; + 19C29489FB998EB8E7E019A0A9BE7772 /* Products */ = { + isa = PBXGroup; + children = ( + 5D797E9A5C5782CE845840781FA1CC81 /* Alamofire */, + 085DBCE7DD98588B2ED103B1C1F36026 /* Alamofire-Alamofire */, + A8E950A16D00F649C54FFB30F81D7842 /* IQKeyboardManagerSwift */, + 2F4A1CCB21DB7EA5A2ACEB11E374FBCA /* JXPagingView */, + 7EB20B4E68CCB69F85E7D08B7F8463D6 /* JXPagingView-JXPagingView */, + 07928762D9A8551470DAAD7C1E1F53A5 /* JXSegmentedView */, + 92B0EC788EDA1B0CFA48DFFCB3DDAECD /* JXSegmentedView-JXSegmentedView */, + C3F44C782D64D7EB20B61CE3844EBFAD /* Kingfisher */, + C298ABB78D9B05529B89D8322DB2E7B0 /* Kingfisher-Kingfisher */, + E49D6D248DD1CEE584E6776B9164A1B2 /* MJRefresh */, + 7E3097CFEFDA621E9FB0E62009FF87FC /* MJRefresh-MJRefresh.Privacy */, + F23C669C0B769DC30F5A05CE45FEA445 /* Pods-MusicPlayer */, + 979486118B3E90C08386079D57962701 /* SnapKit */, + B9DCB5EC0B1CDADD221717CADDF62359 /* SnapKit-SnapKit_Privacy */, + E97D43C46A45EE515A4DA3AF94398441 /* SVProgressHUD */, + 58AE0544E0C381DDBD09356C357EC82B /* SwiftDate */, + ); + name = Products; + sourceTree = ""; + }; + 21A960E74EC481373E719394FDBE27EF /* Resources */ = { + isa = PBXGroup; + children = ( + 832AF59B8B94B734BFA5598CF822D2E8 /* PrivacyInfo.xcprivacy */, + ); + name = Resources; + sourceTree = ""; + }; + 22B6388EE2F6A689255DDA896BFF58B8 /* MJRefresh */ = { + isa = PBXGroup; + children = ( + 1434E2DF42114AA07FFC65F0AF74B738 /* MJRefresh.h */, + 94F9116CE6A49B5AFFA19B16D5346243 /* MJRefreshAutoFooter.h */, + 7A43EE3F113EE7EB81E5065DB5FDD3F2 /* MJRefreshAutoFooter.m */, + 1624F448C0756E91DC913FD781A9A9EC /* MJRefreshAutoGifFooter.h */, + A10B7F476AA2BC85DA32CDCA695E94CF /* MJRefreshAutoGifFooter.m */, + 6C5F4CF175A8588A2773B4AF89EA51EC /* MJRefreshAutoNormalFooter.h */, + A04C1CC2D7176FD20CE057E555EFC2CB /* MJRefreshAutoNormalFooter.m */, + 7B9379FA3746B5215A31DE8D1CD26166 /* MJRefreshAutoStateFooter.h */, + BE8BB5A012C6C501F12A4876ABF49101 /* MJRefreshAutoStateFooter.m */, + D5A9B7775663040A8BD50618EDF84298 /* MJRefreshBackFooter.h */, + 136FDCF413CE3C1DC00030DAFFF9A94F /* MJRefreshBackFooter.m */, + 1F08C4884167A8DF12652D4ADA87DC8E /* MJRefreshBackGifFooter.h */, + 50DD20A7091C1AF20BBDAE8FF40C638E /* MJRefreshBackGifFooter.m */, + F15F5BABB5166FF00A9E43E67C060454 /* MJRefreshBackNormalFooter.h */, + 1C8F4284CBAD963633A64783E4CFB37D /* MJRefreshBackNormalFooter.m */, + 67853DE27314756744C79CE55FBAA9A4 /* MJRefreshBackStateFooter.h */, + E770B62A86FAE28308923E8266E15451 /* MJRefreshBackStateFooter.m */, + 0082002FD60B11229524482ADA592954 /* MJRefreshComponent.h */, + 4CBB6593899E987A5B4300FC21B80983 /* MJRefreshComponent.m */, + BB17A1319D51982E2F7A99EFC3D11F38 /* MJRefreshConfig.h */, + 813F5F884BA0F0F6C062E545B4CA81EC /* MJRefreshConfig.m */, + 03538AE63A9932FE6DD18C82468E190F /* MJRefreshConst.h */, + 27798DCE9459ACACF37012755F087DB9 /* MJRefreshConst.m */, + 3A99AB9AED98C1B656C310507C966514 /* MJRefreshFooter.h */, + C76A1ABBD38622E820640903E4A979AD /* MJRefreshFooter.m */, + 536595B34971D58E93F91CEFFBA20A22 /* MJRefreshGifHeader.h */, + 70D291797444B210FC11B05604380747 /* MJRefreshGifHeader.m */, + 8124055AC9E04813E53A3EE6EDD5E1DE /* MJRefreshHeader.h */, + 612886EAB1AE5139D8545245115B7EC8 /* MJRefreshHeader.m */, + E4678D7C77B6546A4205C194E9F275EB /* MJRefreshNormalHeader.h */, + 8F1162C00BCBB4CECFD5CA05ED5667F3 /* MJRefreshNormalHeader.m */, + D18ABD1C495B7F72F0284AAC613A93F2 /* MJRefreshNormalTrailer.h */, + 280637DA318DC5D912D98194C6844751 /* MJRefreshNormalTrailer.m */, + 86545830194573BF57878FC631A90181 /* MJRefreshStateHeader.h */, + 82CD43FF64DC36B945840368DAC1706E /* MJRefreshStateHeader.m */, + B764532F7A465FF640FDA97A850A103D /* MJRefreshStateTrailer.h */, + E0E418BB3B470DAB2533C31BAD7884C0 /* MJRefreshStateTrailer.m */, + A56C8749F94C4894BDE28709B22BC8EC /* MJRefreshTrailer.h */, + 13184921F92E5D84095DD92314A9A4EA /* MJRefreshTrailer.m */, + B4111D05E2FD45B47E3E6AD830625F74 /* NSBundle+MJRefresh.h */, + 76BE0C86A979CEA47E0B7AD2EE15D888 /* NSBundle+MJRefresh.m */, + A418AA4ADA9598EFD690FF4427F182A5 /* UICollectionViewLayout+MJRefresh.h */, + 1DA3BDF290E39DAB4D1F114C808EB725 /* UICollectionViewLayout+MJRefresh.m */, + F0CF839DB998A3AA0D5D01C635E92AB8 /* UIScrollView+MJExtension.h */, + 3B4DD5E3C3843A80F1882655B380DCDA /* UIScrollView+MJExtension.m */, + 96222B976672EC3736CB9B53FC49C92E /* UIScrollView+MJRefresh.h */, + D38764AB52ACD239BAD933070283AA4F /* UIScrollView+MJRefresh.m */, + 810BB8FC42B516FF79349CC6C8C13E4C /* UIView+MJExtension.h */, + E3C11DA33AB8B0E9203520516067EC23 /* UIView+MJExtension.m */, + 8F7DDD383A521C01FAB264F2788D6E86 /* Resources */, + 0D71198B2379509AC4AA8EC9853ED524 /* Support Files */, + ); + name = MJRefresh; + path = MJRefresh; + sourceTree = ""; + }; 2AC81103547C6D86F33FC7D3D692CCAE /* Pods-MusicPlayer */ = { isa = PBXGroup; children = ( @@ -918,89 +1174,30 @@ path = "Target Support Files/Pods-MusicPlayer"; sourceTree = ""; }; - 2C565D57B124DA6CCD25696736A30F00 /* JXSegmentedView */ = { + 385385A8F793C6C811AF2F8236997A1B /* JXPagingView */ = { isa = PBXGroup; children = ( - 6BE57309210A754C8C684F298E14077B /* JXSegmentedAnimator.swift */, - AD71D3CDC6450CFD5A6E4F493768310F /* JXSegmentedBaseCell.swift */, - 896D7A2849ACF34D2EA1166731A5D332 /* JXSegmentedBaseDataSource.swift */, - 79E5B2D4D893485EE03EBC446DCDC057 /* JXSegmentedBaseItemModel.swift */, - FA1790A81F081026839A33E7AA4A3172 /* JXSegmentedCollectionView.swift */, - F780BDE3AA3E75F9B115272AAFD28A9E /* JXSegmentedComponetGradientView.swift */, - EE72EF69BD801D8C5E4AFBF5B3338955 /* JXSegmentedDotCell.swift */, - 8C3F23EBC877B0289008C16C4981B784 /* JXSegmentedDotDataSource.swift */, - 6744A18229EA48CA16F54DFC8F3C6A3C /* JXSegmentedDotItemModel.swift */, - 2F7A731F70FE21FD4DE8310D869C90DD /* JXSegmentedIndicatorBackgroundView.swift */, - F0C110EA1EFE725C53F87FB7D4FD59B7 /* JXSegmentedIndicatorBaseView.swift */, - EA2B7CB6D3C5BF9E8732BD8ED85BC022 /* JXSegmentedIndicatorDotLineView.swift */, - 8E3F83A4B256E06D67FBC054152710B2 /* JXSegmentedIndicatorDoubleLineView.swift */, - 4238031501C063D51EF5A23B8F8B99A1 /* JXSegmentedIndicatorGradientLineView.swift */, - B6F9C80933FC230A20E8DB141B42D78B /* JXSegmentedIndicatorGradientView.swift */, - 2A3929FB15B816836DB3935DDE677205 /* JXSegmentedIndicatorImageView.swift */, - 342970F609D91209A7F339DC270C0C20 /* JXSegmentedIndicatorLineView.swift */, - EAF4F6584F8A39930FEF6F95DB825779 /* JXSegmentedIndicatorParams.swift */, - EE645C9DF881DC086EE8AD29F9834E09 /* JXSegmentedIndicatorProtocol.swift */, - 379DC6E350D05131719D9E95995D51D1 /* JXSegmentedIndicatorRainbowLineView.swift */, - AF379AB14D224D349C2E17BAE5136840 /* JXSegmentedIndicatorTriangleView.swift */, - 4E8F31E23CB0B4C162D0624DB465C98A /* JXSegmentedListContainerView.swift */, - 89DB2376678936DD230CBCCDD11F0A5B /* JXSegmentedNumberCell.swift */, - AEC77FF989202A953833F6020DC1B1B0 /* JXSegmentedNumberDataSource.swift */, - 126C50DAB71E48A6A012ECFB4420D997 /* JXSegmentedNumberItemModel.swift */, - 8868D3E0EEBED6EEE631D6CBDB9C0E01 /* JXSegmentedRTLLayout.swift */, - BB0F871541AF0A23961743411FF66100 /* JXSegmentedTitleAttributeCell.swift */, - DDC2D0518832B22B12029C5C922BB7D8 /* JXSegmentedTitleAttributeDataSource.swift */, - C81299D08C14E0F9FD7DEF40D51B331F /* JXSegmentedTitleAttributeItemModel.swift */, - A41FA1D67A369D0AF9F089B2E949C60E /* JXSegmentedTitleCell.swift */, - 8E21BA4A95E9124E56A3ABDC946ED751 /* JXSegmentedTitleDataSource.swift */, - 4650F81AED57651885068C4F1EAA4836 /* JXSegmentedTitleDynamicConfiguration.swift */, - 09203F4D31B935FBE7056B3EEBF52D09 /* JXSegmentedTitleGradientCell.swift */, - 487654BCA0B02C5A6F1A496C85CDFC36 /* JXSegmentedTitleGradientDataSource.swift */, - 88EBA936D76416362096C319D61B9AE0 /* JXSegmentedTitleGradientItemModel.swift */, - 03AFFBAA3AD566778A561F1FB11DD0AE /* JXSegmentedTitleImageCell.swift */, - BDFACB4345054B019481CEDCD494F54E /* JXSegmentedTitleImageDataSource.swift */, - EC849766E84C3D70F4A1EC1D8B8B1E23 /* JXSegmentedTitleImageItemModel.swift */, - A76DF775AC63A1EDDD3E18D271B4C926 /* JXSegmentedTitleItemModel.swift */, - 1C07796D011ECD3006D3BA479CD6C93C /* JXSegmentedTitleOrImageCell.swift */, - 2470434CB358730731625103150715B2 /* JXSegmentedTitleOrImageDataSource.swift */, - 4F1C6EFDCC0D193444D079AD48016EF8 /* JXSegmentedTitleOrImageItemModel.swift */, - BB998DCE982EFC41FF337EC72362789A /* JXSegmentedView.swift */, - FD1A206A2C1CBD7E676E9B6169ECDF72 /* JXSegmentedViewTool.swift */, - CC6596C895172C9FC5CB51B0BFD497D5 /* Resources */, - 730627CDC6799F1C0BE20429C053D395 /* Support Files */, + 86CA141D7FE28EE45ACB71EA520C1024 /* Paging */, + A7A71010D8CCF5C1D9EF378910670798 /* Support Files */, ); - name = JXSegmentedView; - path = JXSegmentedView; + name = JXPagingView; + path = JXPagingView; sourceTree = ""; }; - 304C52956EB3CFA258215A96CEE0A64A /* Support Files */ = { + 3997AFF09C6B2741C9D946A854C69D26 /* Resources */ = { isa = PBXGroup; children = ( - C2C597CA08FD78204DA81232B06ECD56 /* Kingfisher.modulemap */, - F57F780799948B0298A107CA1DAF860C /* Kingfisher-dummy.m */, - F16488115126AF3281342B1C0395D41E /* Kingfisher-Info.plist */, - 6D136815A9B53EFB45552F7FF30A357F /* Kingfisher-prefix.pch */, - 11E5886F19EFFF862FFFA5B536854A3C /* Kingfisher-umbrella.h */, - B88842C93039689D079B0F4AA14852C6 /* Kingfisher.debug.xcconfig */, - 890F8EEE5DAE16274422CC38E258B8D1 /* Kingfisher.release.xcconfig */, - 3C78B7DBAF5BC78F4AB22534D3664BF5 /* ResourceBundle-Kingfisher-Kingfisher-Info.plist */, + F86ED01EB7CC70315E585984B7CEADA2 /* PrivacyInfo.xcprivacy */, ); - name = "Support Files"; - path = "../Target Support Files/Kingfisher"; + name = Resources; sourceTree = ""; }; - 3D2FE540A13A877B1E1623A9EA421E88 /* Support Files */ = { + 47BE6238B9D2DAEAE874B27AAB7EA08A /* Resources */ = { isa = PBXGroup; children = ( - DBF19CEB43F8643CAD55D7742AC0970A /* SwiftDate.modulemap */, - 3B97DDE49382A64974F6385E6313AD53 /* SwiftDate-dummy.m */, - CCAFDE558FB2154AF814B4EDA40CD48A /* SwiftDate-Info.plist */, - C5133FAC5521041D7059BD29ED6BD54E /* SwiftDate-prefix.pch */, - 17E2B3692AE65F40EC23C3140816F5E2 /* SwiftDate-umbrella.h */, - 237F6B26512B98501CC693A53DCB92AB /* SwiftDate.debug.xcconfig */, - 7DAC46988C621826DE9C8B685C307E5B /* SwiftDate.release.xcconfig */, + B5819E5E132D7A725A5CF03163E7796D /* langs */, ); - name = "Support Files"; - path = "../Target Support Files/SwiftDate"; + name = Resources; sourceTree = ""; }; 4AD22DFAF5934D8E9D83B59C461B799B /* Targets Support Files */ = { @@ -1011,58 +1208,36 @@ name = "Targets Support Files"; sourceTree = ""; }; - 4F3E918834B66F0E10BC1AAC77A14542 /* Support Files */ = { + 4ED80A127B880DDBD359D089C93079AC /* Support Files */ = { isa = PBXGroup; children = ( - 76515B292B0F99B23C35557C81C52120 /* SVProgressHUD.modulemap */, - C63097B44D599B12E8CEF1425112BEA1 /* SVProgressHUD-dummy.m */, - 8976C2EEB49511E14ED3D66C2CAEF73F /* SVProgressHUD-Info.plist */, - 67CE46015CE4475FDA0178EC41D8A5F8 /* SVProgressHUD-prefix.pch */, - E6052A6B485A84163CBF2D1FC6D30DB7 /* SVProgressHUD-umbrella.h */, - 3F7D2073948007C3D9C254DB4DFBBAB8 /* SVProgressHUD.debug.xcconfig */, - 2C39947ECE9F9309B3ED71BEFD21C4BC /* SVProgressHUD.release.xcconfig */, + 13AB468987C8A41B4D5D6B895F8B9A6F /* JXSegmentedView.modulemap */, + 356BE641A77A6E56A217190DD89D8259 /* JXSegmentedView-dummy.m */, + 7B24959E1B5D6E0DB944451D77D9BEEF /* JXSegmentedView-Info.plist */, + 3AB6A380647126E36416E4610575F354 /* JXSegmentedView-prefix.pch */, + 37C1098A010D1C8E4E069D976A8D8DFD /* JXSegmentedView-umbrella.h */, + 0DB2B3B9A91393821FCD01D47CB39B40 /* JXSegmentedView.debug.xcconfig */, + 451FEDBFD2A922230CA33D46534CD7F7 /* JXSegmentedView.release.xcconfig */, + 1C8C49DCED4EC3826245D19DFC7FA7E9 /* ResourceBundle-JXSegmentedView-JXSegmentedView-Info.plist */, ); name = "Support Files"; - path = "../Target Support Files/SVProgressHUD"; + path = "../Target Support Files/JXSegmentedView"; sourceTree = ""; }; - 5270E68FB9F7664AAD60E1D12075B36B /* Resources */ = { + 5B7171C88905EE86E6FB47E5A6F4D2D4 /* Support Files */ = { isa = PBXGroup; children = ( - 86D63DBB9B2A913FBA9303BF4AEA2AFE /* PrivacyInfo.xcprivacy */, + 5CEFF5B6E9210A0DDADD6C198F0BC68C /* Alamofire.modulemap */, + AA35F74EEBAD4E0CB28C015AD5D6EECF /* Alamofire-dummy.m */, + EC02376976FBCAAD8506234104E8BAA5 /* Alamofire-Info.plist */, + 84C32F4F34E89EC16281BE7CB8022B54 /* Alamofire-prefix.pch */, + 56263B06F3EAEC382F6F91F1599D4E74 /* Alamofire-umbrella.h */, + 5EBCD15895605FBBBCD96B9C8E928D3B /* Alamofire.debug.xcconfig */, + 7BD8D5C9444C4C58CF152CD4CC8DB0A3 /* Alamofire.release.xcconfig */, + CE14F9280BCE30360011E5C9806D2516 /* ResourceBundle-Alamofire-Alamofire-Info.plist */, ); - name = Resources; - sourceTree = ""; - }; - 55953622A6566D8D22F47D54DF79DD38 /* Paging */ = { - isa = PBXGroup; - children = ( - 728B87873E161AD29B02B004B8C0F675 /* JXPagingListContainerView.swift */, - 24EC295179204A13C2E78DB844ABF4AC /* JXPagingListRefreshView.swift */, - 9C8A901F12C600B3F5FF1554147E17FE /* JXPagingMainTableView.swift */, - 28A27DAE3B348C14EA5A36CFA7BF8804 /* JXPagingSmoothView.swift */, - 086CE1250364E2AA597A5C1956BE37AB /* JXPagingView.swift */, - 1B4243047EF6606A4809DBC3B992C6F4 /* Resources */, - ); - name = Paging; - sourceTree = ""; - }; - 5F70495B50C1FEEA6D3E99ACFD3F4CC4 /* JXPagingView */ = { - isa = PBXGroup; - children = ( - 55953622A6566D8D22F47D54DF79DD38 /* Paging */, - AA1FE76AC4617EABB21F7658B3A2A98C /* Support Files */, - ); - name = JXPagingView; - path = JXPagingView; - sourceTree = ""; - }; - 63C8FE2C08B105678D415AC0B7FA65BF /* Resources */ = { - isa = PBXGroup; - children = ( - 53A154F0773A1007FDE314D65058E654 /* langs */, - ); - name = Resources; + name = "Support Files"; + path = "../Target Support Files/Alamofire"; sourceTree = ""; }; 6625D72D58B79130D815A3A6D7072BCE /* iOS */ = { @@ -1078,255 +1253,344 @@ name = iOS; sourceTree = ""; }; - 696FF6F0F54FA544AFA3DEDD91AE9EE1 /* Support Files */ = { + 6A4EF31B924CC5861010E154A95CAD31 /* Support Files */ = { isa = PBXGroup; children = ( - CD8451E73468081EE9470C36E27AA3D8 /* SnapKit.modulemap */, - 9FF5D58E8072CFF7D8524E5423ABF567 /* SnapKit-dummy.m */, - 62CA51FDCDCF824E7E2811F5A29E5FC9 /* SnapKit-Info.plist */, - BF082BF0DDC572A9715FBE1F68360401 /* SnapKit-prefix.pch */, - 258A1691BC25E6887D2399F3FA414308 /* SnapKit-umbrella.h */, - F8765B4E3D1104165E5D1E435F4945D9 /* SnapKit.debug.xcconfig */, - 3BB776688BCCFEAA2C9D7ADDE83D4CA3 /* SnapKit.release.xcconfig */, + E9CA1CB30F953F8E32CCE0D206E0DFE5 /* ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist */, + 86D05EEFA439B19ACFEC22979C2BBF4D /* SnapKit.modulemap */, + A933F95E4E12D348E925A9E3B27750CB /* SnapKit-dummy.m */, + BB993F1FCBAA91D44D43B0587DB633FB /* SnapKit-Info.plist */, + 77AF4A7E7C61F4843CEE9608EFB1F2A8 /* SnapKit-prefix.pch */, + 31126E0DD1B56D3713965A56F0B05AC8 /* SnapKit-umbrella.h */, + BC90E0F634A75E57580CB83CB0B039E4 /* SnapKit.debug.xcconfig */, + 9DB02FC7AC88AE54321E64548CBFD1FF /* SnapKit.release.xcconfig */, ); name = "Support Files"; path = "../Target Support Files/SnapKit"; sourceTree = ""; }; - 6FC81FEFE58947E5B476B6EE51473C90 /* Resources */ = { + 86CA141D7FE28EE45ACB71EA520C1024 /* Paging */ = { isa = PBXGroup; children = ( - 02BF3CA1A4DE19EBC809FFFBC30556D9 /* PrivacyInfo.xcprivacy */, + C2DC9D938B1784B3E0E8FFC9851FCAEA /* JXPagingListContainerView.swift */, + 89FA1854F15DFB5CA5EAC2BF88823143 /* JXPagingListRefreshView.swift */, + BB420F181A7222985A450867020EFB2C /* JXPagingMainTableView.swift */, + 142F33BE61F0E752B876C5145BE8D812 /* JXPagingSmoothView.swift */, + F4C866B997568C25289AC4481D960976 /* JXPagingView.swift */, + B6A64081B24DF43D18A38FFA4FCFBDCA /* Resources */, ); - name = Resources; + name = Paging; sourceTree = ""; }; - 730627CDC6799F1C0BE20429C053D395 /* Support Files */ = { + 8B5308B450A10A8C99942BA8C8381883 /* IQKeyboardManagerSwift */ = { isa = PBXGroup; children = ( - D1D5E0DBAC440FA8BD16F3D87B5D36B6 /* JXSegmentedView.modulemap */, - BB4408CC7D50AB78010F283775082F2E /* JXSegmentedView-dummy.m */, - 78E2FF8B1C1A44452421E9A481603C3B /* JXSegmentedView-Info.plist */, - 12B322F6069250C5291A6856F3F5F19B /* JXSegmentedView-prefix.pch */, - DC3193C7C92FBD37C24C5E36096576D6 /* JXSegmentedView-umbrella.h */, - C434D6410430E92943DEAD104FCC27BE /* JXSegmentedView.debug.xcconfig */, - 53AD73B43463C9D32A0BF66D80A09BFB /* JXSegmentedView.release.xcconfig */, - D2CE45575AF714BC629EF55E552BAC8E /* ResourceBundle-JXSegmentedView-JXSegmentedView-Info.plist */, - ); - name = "Support Files"; - path = "../Target Support Files/JXSegmentedView"; - sourceTree = ""; - }; - 7F31BA5B4E973FBB02E82F97957EF6C3 /* Support Files */ = { - isa = PBXGroup; - children = ( - 25F3DD0AF63950115410158C85035041 /* Alamofire.modulemap */, - C473B98F873BE78A2F86D02402284B3D /* Alamofire-dummy.m */, - D1D71E0DF282F4F1A0C83021CB0B5E10 /* Alamofire-Info.plist */, - D6A9EFEFEBACC5355C9CC03D88A5F10D /* Alamofire-prefix.pch */, - 54D73AFB747FAE30C1BB44E19677DBDD /* Alamofire-umbrella.h */, - 37B75E2E8CD6D8FBCEEA2C814BD288E2 /* Alamofire.debug.xcconfig */, - B942DFB5FFD9E8DA9A4C3E8B8FC26306 /* Alamofire.release.xcconfig */, - 9CCAAC7200ED63CA697D32D99781785A /* ResourceBundle-Alamofire-Alamofire-Info.plist */, - ); - name = "Support Files"; - path = "../Target Support Files/Alamofire"; - sourceTree = ""; - }; - 946A5F0D6DD1985A5C02012E944EF9C9 /* Alamofire */ = { - isa = PBXGroup; - children = ( - B162065ADCC62F8E5918B4FA00D73B81 /* AFError.swift */, - 3F9310A68A7C4ADA421B3156B5403F7E /* Alamofire.swift */, - EB1005A1E92368A5F7B5C869FAF2E1E7 /* AlamofireExtended.swift */, - E8112989320F97673E4EB82A275CAE0C /* AuthenticationInterceptor.swift */, - 007D1989958B519F880D7E7993017377 /* CachedResponseHandler.swift */, - 8C64660111FD6606664A3951D1C9E793 /* Combine.swift */, - 4B7CF26B5F28E33AB65201BFB9772E94 /* Concurrency.swift */, - 4A662353E669242D628CA325F3A11119 /* DataRequest.swift */, - 4AE0D04C04D9D2C94118025EAB921A25 /* DataStreamRequest.swift */, - 1B4E6F9C722A37921CB299D06E531578 /* DispatchQueue+Alamofire.swift */, - 706A08832B908FA228085663A3B07DB9 /* DownloadRequest.swift */, - E4F1F2DD34925CE8FB29B1319F19DEE3 /* EventMonitor.swift */, - CA7CF9C41BA9CA940652D4EC49B99A2D /* HTTPHeaders.swift */, - 90B6B02E550BBA54CD9271600724D14D /* HTTPMethod.swift */, - 19A8250492A7EB690EF84D025A6F171D /* MultipartFormData.swift */, - A2767F08F182AD8A9B1774BEFAD31FCE /* MultipartUpload.swift */, - CECF59F44BE476A62417A1367B020FF4 /* NetworkReachabilityManager.swift */, - 65C3C5A1B404B17346AE855FFF4BDDA1 /* Notifications.swift */, - 4EBA3469B966D049CF9C6584ADCE1420 /* OperationQueue+Alamofire.swift */, - A4146F3303D77A54D70EFCE400FA4336 /* ParameterEncoder.swift */, - BCE24B18F4CDA56F48417247341E3F76 /* ParameterEncoding.swift */, - 267268BCAAF578FB1C90F6F623ABCFF2 /* Protected.swift */, - F37D9853994687118DD881E59106C758 /* RedirectHandler.swift */, - A426DD55A10EB28F224B77DD61B2BF00 /* Request.swift */, - FC849700AF2A2CAC32974D17E4B461D2 /* RequestCompression.swift */, - FEF1F46153EB848293C59AAA92FFCE28 /* RequestInterceptor.swift */, - 0FA5B49E1B796D739442A55E81329C1C /* RequestTaskMap.swift */, - 6E208F65C34D21FBC484B3D0337F1008 /* Response.swift */, - F27DE7E6CC48EBD987659B78F5B0E68C /* ResponseSerialization.swift */, - F0F5BDD0C9E9E0CA159C3D2940A73FAD /* Result+Alamofire.swift */, - 89AE4C34F9A0CCC31019F7C0115A0BB7 /* RetryPolicy.swift */, - 3CFDD319BC3DFC1F0C2B65AEB2C7B04F /* ServerTrustEvaluation.swift */, - EF3E7152220EF9221D3638B93DAE5EAD /* Session.swift */, - AF2199462536623489EFF7EDEF57722F /* SessionDelegate.swift */, - 149557C3AB89BD20814904E291880583 /* StringEncoding+Alamofire.swift */, - 067DAF837200693933CD063D222B31FC /* UploadRequest.swift */, - B9CC3B5B9CB0EEA62534F2B47807C815 /* URLConvertible+URLRequestConvertible.swift */, - 1C47E79C3926F155B6C7EC94D87F0C5B /* URLEncodedFormEncoder.swift */, - 8CD193641BF411C264722678C735CFC4 /* URLRequest+Alamofire.swift */, - 0E59570FEEE578BB8DA85857824B7375 /* URLSessionConfiguration+Alamofire.swift */, - 82A068C4EC672799ADB247B155675358 /* Validation.swift */, - D1B714CDE211483876F8D71E98D218A3 /* WebSocketRequest.swift */, - 0E5748DA9911AC1A96532641D6F01D71 /* Resources */, - 7F31BA5B4E973FBB02E82F97957EF6C3 /* Support Files */, - ); - name = Alamofire; - path = Alamofire; - sourceTree = ""; - }; - 9EC42FE8BA9B8FA7438229F51F7FDEAB /* Products */ = { - isa = PBXGroup; - children = ( - 5D797E9A5C5782CE845840781FA1CC81 /* Alamofire */, - 085DBCE7DD98588B2ED103B1C1F36026 /* Alamofire-Alamofire */, - A8E950A16D00F649C54FFB30F81D7842 /* IQKeyboardManagerSwift */, - 2F4A1CCB21DB7EA5A2ACEB11E374FBCA /* JXPagingView */, - 7EB20B4E68CCB69F85E7D08B7F8463D6 /* JXPagingView-JXPagingView */, - 07928762D9A8551470DAAD7C1E1F53A5 /* JXSegmentedView */, - 92B0EC788EDA1B0CFA48DFFCB3DDAECD /* JXSegmentedView-JXSegmentedView */, - C3F44C782D64D7EB20B61CE3844EBFAD /* Kingfisher */, - C298ABB78D9B05529B89D8322DB2E7B0 /* Kingfisher-Kingfisher */, - F23C669C0B769DC30F5A05CE45FEA445 /* Pods-MusicPlayer */, - 979486118B3E90C08386079D57962701 /* SnapKit */, - E97D43C46A45EE515A4DA3AF94398441 /* SVProgressHUD */, - 58AE0544E0C381DDBD09356C357EC82B /* SwiftDate */, - ); - name = Products; - sourceTree = ""; - }; - A1FDC09E1A39070D7A97B3F1A6907209 /* Support Files */ = { - isa = PBXGroup; - children = ( - CC59DEE17997F5A0F4B91B06798B4CE9 /* IQKeyboardManagerSwift.modulemap */, - 5F1211F5D08477CCC9FD2CE425EDC276 /* IQKeyboardManagerSwift-dummy.m */, - 2FD30818E5615E1D5255CA94386719F2 /* IQKeyboardManagerSwift-Info.plist */, - 1E1C7FC14F4B42EDC20FE49A9E3D581F /* IQKeyboardManagerSwift-prefix.pch */, - 3F26DAEAF14BD22F7BA131A68C794F8E /* IQKeyboardManagerSwift-umbrella.h */, - 947DA5BA2E9A379BFEC2E827244B0CE0 /* IQKeyboardManagerSwift.debug.xcconfig */, - D378275D09B96773C488D7591063EC86 /* IQKeyboardManagerSwift.release.xcconfig */, - ); - name = "Support Files"; - path = "../Target Support Files/IQKeyboardManagerSwift"; - sourceTree = ""; - }; - AA1FE76AC4617EABB21F7658B3A2A98C /* Support Files */ = { - isa = PBXGroup; - children = ( - 1420FB96B25110EF4B6D376EFD05F3D8 /* JXPagingView.modulemap */, - D0F0E865FFAB434485335DA1629A1388 /* JXPagingView-dummy.m */, - 3BE3F2A07329201502F823489AF74A99 /* JXPagingView-Info.plist */, - D45E015988EDAE0D78F39EE421B58283 /* JXPagingView-prefix.pch */, - B75E4A5B88AB2E12901FD79392108078 /* JXPagingView-umbrella.h */, - 999C15F4A94DD7E4875ED8928BAE4925 /* JXPagingView.debug.xcconfig */, - A7767A0D4F0D3EBD1C8E13F6F05FB25B /* JXPagingView.release.xcconfig */, - D33E49B3F1AC34C95B187A51D1AC0D17 /* ResourceBundle-JXPagingView-JXPagingView-Info.plist */, - ); - name = "Support Files"; - path = "../Target Support Files/JXPagingView"; - sourceTree = ""; - }; - BE3F0FBA80DAFA8E1837B8FBC4F07BF0 /* IQKeyboardManagerSwift */ = { - isa = PBXGroup; - children = ( - 23C5673EA0CD0D48D9B6124BE63E96C3 /* IQBarButtonItem.swift */, - 78EEE8A477A369C06D750C1ED88021A2 /* IQInvocation.swift */, - F70EE242B119207B6DE78061ABCD5426 /* IQKeyboardManager.swift */, - 2540A9293E8ADAB4B67AF923E8AFC51F /* IQKeyboardManager+Debug.swift */, - 814DE9B814D4E171655394905E30304A /* IQKeyboardManager+Internal.swift */, - 410484E6026824E3DC6B14FC5E7A7F80 /* IQKeyboardManager+OrientationNotification.swift */, - 13F50E8CD9EED0FF95C7743EBA58ECB4 /* IQKeyboardManager+Position.swift */, - 30EF94D6856E6C7203AF8C170322CB4A /* IQKeyboardManager+Toolbar.swift */, - 46359F9ADB38A9DAE1A1B6214177702D /* IQKeyboardManager+UIKeyboardNotification.swift */, - 2A05EFFD6130413819CBE3401EB499CF /* IQKeyboardManager+UITextFieldViewNotification.swift */, - BBCD2385297C11F5F3C9C95418952EF1 /* IQKeyboardManagerConstants.swift */, - 5C3D488F6F9118C5795E86C32D405E5C /* IQKeyboardManagerConstantsInternal.swift */, - 0805789482CC6182F98FE7236D8D83BE /* IQKeyboardReturnKeyHandler.swift */, - FC9A4AF661D951099E57AB12E84B84E0 /* IQNSArray+Sort.swift */, - 3FBE965ECA32AF1AF759DCA0E41A904C /* IQPreviousNextView.swift */, - 59A6EEB5900F7A2EFF2E4353A16CFB10 /* IQTextView.swift */, - F56A43D0608BE9C9E5E018F488A70CD4 /* IQTitleBarButtonItem.swift */, - AD54F4811AE511D52253868A482B0282 /* IQToolbar.swift */, - E7FA6A81D452D73024CD59E468AADA68 /* IQUIScrollView+Additions.swift */, - F2015AFD9107C9946CA35C41D72E9B5D /* IQUITextFieldView+Additions.swift */, - D7E9F891E8CCB8860AE7419A69AC9327 /* IQUIView+Hierarchy.swift */, - 611229333DB8EA6474A5F49BD282ABF9 /* IQUIView+IQKeyboardToolbar.swift */, - 03494EF27E38F8E4F8F6A831E3C45FE7 /* IQUIViewController+Additions.swift */, - 5270E68FB9F7664AAD60E1D12075B36B /* Resources */, - A1FDC09E1A39070D7A97B3F1A6907209 /* Support Files */, + B860B422FB58A9842214FE11A933BBD4 /* IQBarButtonItem.swift */, + FCA08BA243343C7A9EAEE567CC5F4318 /* IQInvocation.swift */, + B2E886364CE3D1DE31930B53C67EFBEB /* IQKeyboardManager.swift */, + E17C586A0C27A8F810C609FC78419447 /* IQKeyboardManager+Debug.swift */, + 773DD03EC2EC00F685DE0E46779320CC /* IQKeyboardManager+Internal.swift */, + 52CB2CCAA127ADA834B4CCF4686ECE60 /* IQKeyboardManager+OrientationNotification.swift */, + 988FB962B33EFE0451CB5B6094DEAA75 /* IQKeyboardManager+Position.swift */, + CB34508FC3184D3482A1002BEBC16654 /* IQKeyboardManager+Toolbar.swift */, + AAA467CC8E830A4407AEEA9E195B5572 /* IQKeyboardManager+UIKeyboardNotification.swift */, + 07490687930290E2CF12D183E94326BF /* IQKeyboardManager+UITextFieldViewNotification.swift */, + 9A89AE3F00FA615DB614031B7510C78F /* IQKeyboardManagerConstants.swift */, + 398152B547C8B96AD8C376F10BEB5701 /* IQKeyboardManagerConstantsInternal.swift */, + CDCBF5F15899BDBF63D3CC736990E1A5 /* IQKeyboardReturnKeyHandler.swift */, + 7C1E1CFDA9E2D6AECCA91F210C0B6064 /* IQNSArray+Sort.swift */, + EEC2D820ED623D3C956582179E970607 /* IQPlaceholderable.swift */, + 1FF0E1D3C22D93C0C7B2C51A16E17913 /* IQPreviousNextView.swift */, + 4E16F379BC5CA8C2B21212962C6FA430 /* IQTextView.swift */, + 81D659C29A42861AC5A4EF3B9D26DC0B /* IQTitleBarButtonItem.swift */, + 5AA5BD68BC8AE62D30B207A9A089DBE2 /* IQToolbar.swift */, + C54C3E1777728F805F3EFCB27BB703BC /* IQUIScrollView+Additions.swift */, + 56E8C8A30A6C29843067AEFDBDB0DD5E /* IQUITextFieldView+Additions.swift */, + E9045FA6D60732F49E7765B398DDC46B /* IQUIView+Hierarchy.swift */, + DC81E237B242F0601E0FC35F98708DC4 /* IQUIView+IQKeyboardToolbar.swift */, + 40E3CE126BEDA57D7DA923F7BBC49D32 /* IQUIViewController+Additions.swift */, + F56AEB416F118ECBB450F18C0A431806 /* Resources */, + E322A4AAC43BD85F10A108F72EC08C4E /* Support Files */, ); name = IQKeyboardManagerSwift; path = IQKeyboardManagerSwift; sourceTree = ""; }; - C12BA1DD7528D0DB05AC3956322C5CBA /* Resources */ = { + 8F7DDD383A521C01FAB264F2788D6E86 /* Resources */ = { isa = PBXGroup; children = ( - F8560E583BCEFEFC4455CDA8AE15D746 /* SVProgressHUD.bundle */, + 84FCB0C95F94873F8D87374CE1ACA147 /* MJRefresh.bundle */, + E90BED91E412505AF7055D21B806502E /* PrivacyInfo.xcprivacy */, ); name = Resources; sourceTree = ""; }; - C2FBD0F076D76C08270A03146678DD28 /* SwiftDate */ = { + A1102946118376B3CF7E47B1B547A7DC /* Kingfisher */ = { isa = PBXGroup; children = ( - 45E2E40D8E912E8E28DCD35E76FA3425 /* AssociatedValues.swift */, - C29313259EB03457900A0146BD10C25F /* Calendars.swift */, - FE12AE6B4D59FD7310447B92B7B2B83C /* Commons.swift */, - 36893E4F6E35B5AF8060ABB0AAA6C6BF /* Date.swift */, - 349DDAFE2B858FF1C77548AEB5A9024F /* Date+Compare.swift */, - 4B3EE8956158B369D9D59C65C4D96EA3 /* Date+Components.swift */, - 6532F8DAD6AD80487996CDEC5B376D30 /* Date+Create.swift */, - 03F1AFA1CC231FD02BDF99D7579908AC /* Date+Math.swift */, - 1F5CAE7EE7E6C725618BA82F8F9711D0 /* DateComponents+Extras.swift */, - E72A243B166894EB9748892B7E08CE91 /* DateInRegion.swift */, - C0F9FC31B8F636F7E4D3A505B5FCEA48 /* DateInRegion+Compare.swift */, - 8B17D99233F4B43D0CE24E0142AAA24A /* DateInRegion+Components.swift */, - 6A4F3875045D1DB4D796129111609B9D /* DateInRegion+Create.swift */, - 2FD2369502A9924937B397068E453724 /* DateInRegion+Math.swift */, - F1C800A89115F306E7099713F917565C /* DateRepresentable.swift */, - F8C007F792870EEA4EC7B19A0FACC384 /* DotNetParserFormatter.swift */, - 28279C39A331FDBCCB4726BA6CC681C6 /* Formatter+Protocols.swift */, - 7F6B30053062472A32F7652BD0C4B138 /* Int+DateComponents.swift */, - 551F872E8F0FDAAED3407034F590B022 /* ISOFormatter.swift */, - 17AA6D7827F1E01C2A8379EA8543ED13 /* ISOParser.swift */, - 3B3C33514BEE5D1F1405B8A6BB47511D /* Locales.swift */, - 6DC1A24F4E1851F5E5FF43741ED5ADCD /* Region.swift */, - B60AE218D04ECB2F352996F87D62ABA4 /* RelativeFormatter.swift */, - 6E17EC9F5615EFDD36A5372D376D7353 /* RelativeFormatter+Style.swift */, - 684339D85749BA476348D011AAF940F8 /* RelativeFormatterLanguage.swift */, - 2FA988EC253BB0E37DA9DCBEE6C99E9E /* String+Parser.swift */, - BB3D25104232F456441BF20779E54737 /* SwiftDate.swift */, - 1A778C04C8D2699D2DED1B1600517215 /* TimeInterval+Formatter.swift */, - 56E1C515E167FC148720369572DA2FB8 /* TimePeriod.swift */, - 1989579A81204690482F69CF91196CC1 /* TimePeriod+Support.swift */, - 6BBCE430AE205EC78BD6A9993B59A91F /* TimePeriodChain.swift */, - 3A21A5D82E7614E60D1FBD7885945FCE /* TimePeriodCollection.swift */, - 1AC2B39FA1F6CBF8CD4718489EA8F09E /* TimePeriodGroup.swift */, - 169771C1499556CFFC8826DA446C2612 /* TimePeriodProtocol.swift */, - 00B510B9BAFAF4B6D74A60254B99F26E /* TimeStructures.swift */, - 8480154D84F74BD3E0CB4C5D9AEA2A2A /* Zones.swift */, - 63C8FE2C08B105678D415AC0B7FA65BF /* Resources */, - 3D2FE540A13A877B1E1623A9EA421E88 /* Support Files */, + 8138B9E4A2A6AA8C683562DF69844549 /* AnimatedImageView.swift */, + 1E5CD298A2F13E3902AAA3510FE5C9FD /* AuthenticationChallengeResponsable.swift */, + F43F88826BD8118C95446B4D9D4F416F /* AVAssetImageDataProvider.swift */, + 56CF6C9E5C4416011FAC32CEB31AA525 /* Box.swift */, + 268D0497BC989AF2355C7E9712755278 /* CacheSerializer.swift */, + 6E1CCD164ECD3A398893DB0C3F224494 /* CallbackQueue.swift */, + BDCF0C8D768EFB2E7C6A48EB2256867E /* CPListItem+Kingfisher.swift */, + D49B5FF4D24E46BB7F695E22A9907317 /* Delegate.swift */, + 6D65D8CBF9D74AB85CB305B6D9B87509 /* DiskStorage.swift */, + 7694CB3A399B0E568F03F27D28868B95 /* DisplayLink.swift */, + CFCB35EFBB8A545F2F8352A7D27D5B2A /* ExtensionHelpers.swift */, + 5AAF19FA9EB514B2794ECCAD1BB7FA2E /* Filter.swift */, + CDC741E10FE2F276DD3C474545224A00 /* FormatIndicatedCacheSerializer.swift */, + D394AD7BFA59E7271EC623CF17FBDD30 /* GIFAnimatedImage.swift */, + 1F0A7FCD71890676CE08D3ADDB7CA7B4 /* GraphicsContext.swift */, + 3D613FC602AD1B3823E553095A17BB58 /* Image.swift */, + FE5DD88C594D20A1F18F99828A3FEB64 /* ImageBinder.swift */, + 3CF9BAB200D238346E29ED2DBA085B17 /* ImageCache.swift */, + D061CC1A5FB61D63B44C75541D898A36 /* ImageContext.swift */, + E9B6DF66CC0D9538F8F45AB7F7F82FB3 /* ImageDataProcessor.swift */, + C408D0CD682A652982659893260F5EA4 /* ImageDataProvider.swift */, + DA1E44B32910D0CD9054692D4F938398 /* ImageDownloader.swift */, + 5D36A80F29E20B609E647BAFB548A270 /* ImageDownloaderDelegate.swift */, + 08D053BD683C26F73E7D5BAADC8A4FEF /* ImageDrawing.swift */, + 6CEA2AD00C187BA485EFF154E41EF587 /* ImageFormat.swift */, + D776B0C4D357F0B0466B42C8BF6495D5 /* ImageModifier.swift */, + 36730D770821B0E94A45B2817FC4E2FD /* ImagePrefetcher.swift */, + 662BA990AF2EEE7892AF8EA530C1AE31 /* ImageProcessor.swift */, + 4897326E2C8838615713B47EBE1FAD3D /* ImageProgressive.swift */, + 26E33A2601884DE73A47BD1A2690B14F /* ImageTransition.swift */, + 8A296F41C13699333333D3C630E92F80 /* ImageView+Kingfisher.swift */, + 02D1EC547B26205284A72A9F9473EB73 /* Indicator.swift */, + BE633CEBF91C6D351A438EB13D3F4E1F /* KF.swift */, + 5D15BEF86A67CAF30B602BB5A260F77B /* KFAnimatedImage.swift */, + F3EEB78584831D0B242BDCAA90CED58E /* KFImage.swift */, + 4CDB52D83D152A96E4E9CD244CA95DEA /* KFImageOptions.swift */, + 1F79F3D31F68D650253E6399BB7549D1 /* KFImageProtocol.swift */, + B43CFD3981B70FD7D609A5839B6A9218 /* KFImageRenderer.swift */, + 1A26B70DABA1CBACD8166FC00D07C081 /* KFOptionsSetter.swift */, + 83C7B6631D6A0479168A89D25B68A47C /* Kingfisher.swift */, + 864DAEC4F579E88712B7F5B447424FFC /* KingfisherError.swift */, + E8DAC31F0F6FE66D2C8AF5489F272CEA /* KingfisherManager.swift */, + A47365FDDB9CB0AC423AD6C3AF49AD21 /* KingfisherOptionsInfo.swift */, + 6BF75314341E15EAF5EC8A5095F2878D /* MemoryStorage.swift */, + 54B843EC8B993674D3288F87AEA9D122 /* NSButton+Kingfisher.swift */, + 6F69248BB24307C449A27A28477BAF56 /* NSTextAttachment+Kingfisher.swift */, + 774F6E017AC64D4F20E0DA360CA3FECF /* Placeholder.swift */, + 7A78C7902D8016F72AC215D2E28422F6 /* RedirectHandler.swift */, + 035EB38FC9B73D3AFE4C25920C1A1C32 /* RequestModifier.swift */, + 49B4649E1D11EB9D32BD3E212382EF1D /* Resource.swift */, + EF651BDF14D5A324318BC3F8C317F57A /* Result.swift */, + 3F8AC6801BE5A7B67B8032757817BE51 /* RetryStrategy.swift */, + E75F2A56E77879A823734237F7B0D90B /* Runtime.swift */, + 61585200C65A159F5B6731050D64BA59 /* SessionDataTask.swift */, + 9E1F7BD2E4AFF6989C1387F2558185ED /* SessionDelegate.swift */, + 84C0F797B07A4C95A5F90FB6C7E6A296 /* SizeExtensions.swift */, + 68A219042E44DB63D69EE3B79763130C /* Source.swift */, + 321C97AD92F4D32E4E33BB5B77FFE0FC /* Storage.swift */, + 7143F3A6986BF2AB2828E2DC37C9C09D /* String+MD5.swift */, + 67675B8E7AD45A266A61E66355512D15 /* TVMonogramView+Kingfisher.swift */, + D66CFC994F45F4A9A50C54C16724D763 /* UIButton+Kingfisher.swift */, + 2893522A05B1339D4388FD46FF52C52A /* WKInterfaceImage+Kingfisher.swift */, + 06AE3DF2432EBA8876A90CEDD3312552 /* Resources */, + DF485347F9CA2BC7B2DDEB48DB96D1CE /* Support Files */, + ); + name = Kingfisher; + path = Kingfisher; + sourceTree = ""; + }; + A2A70AADB5C5F2F057B310201B828389 /* SwiftDate */ = { + isa = PBXGroup; + children = ( + 475A4FB59CFB3BBA7FAC2F058F91F6E3 /* AssociatedValues.swift */, + D1968FDA9F67DC3333951BED4268CA52 /* Calendars.swift */, + 6E619DA6F3D601658833035BDA0E167C /* Commons.swift */, + A0422DB62B6B3C1A201A2762EBBB5A97 /* Date.swift */, + 8E6EB2C04F247D9F4D15B77F830EDF54 /* Date+Compare.swift */, + 14C0D566F3A17E2E2DBDE4098F711125 /* Date+Components.swift */, + 594D2794764B5796C8A422C4401A7E2F /* Date+Create.swift */, + DED1174C630E86B387EC34B8B1DD2DA3 /* Date+Math.swift */, + FF512DBF4BC4483F9F306E2B3A5CDB70 /* DateComponents+Extras.swift */, + 951E048B27AEAC006B779E585701262E /* DateInRegion.swift */, + 9B33B085086724D9914992FFDEF83E0B /* DateInRegion+Compare.swift */, + E48EF69AA55D5B91B47D8C1EB4BA4691 /* DateInRegion+Components.swift */, + C4C51E9357636F513F9828759A831069 /* DateInRegion+Create.swift */, + 4C554CE5C82E098DD3FF24BA75EE7490 /* DateInRegion+Math.swift */, + F0917B962F89415FDAAA876040A72E83 /* DateRepresentable.swift */, + 000257BCD6570C4B0371D660CCF8D3E1 /* DotNetParserFormatter.swift */, + 6EF651FECE01069367CDE0054F13249F /* Formatter+Protocols.swift */, + BD56DAD13E1185FD74DB7A8649E746CE /* Int+DateComponents.swift */, + F56A78070D28571910937BC0EE5894B8 /* ISOFormatter.swift */, + 86134D091916FFC476610F2EBFE771E2 /* ISOParser.swift */, + 2752DAD78FD744FDF40B54ADB0708E81 /* Locales.swift */, + FA38A01E090C908AE5886021034EE11D /* Region.swift */, + 728D0FC1713F8BD85AD5D78DF7CC3E06 /* RelativeFormatter.swift */, + 30D9FC3ABDA982F6CA82384628D6F165 /* RelativeFormatter+Style.swift */, + 418EE8CAF2C7190F191FC7554EAE20D3 /* RelativeFormatterLanguage.swift */, + 84DF245C6F43F9612AD56BC7D2ADB123 /* String+Parser.swift */, + 5B832310B3844FB85DE10E60B45F44A3 /* SwiftDate.swift */, + 2998944D54451B52A0996B2A9FDDD7DB /* TimeInterval+Formatter.swift */, + 7ECC357045F3ADF02DFCA0E0F6D4DEE0 /* TimePeriod.swift */, + 725764D6EDA104D9902913F6D02AB7FF /* TimePeriod+Support.swift */, + D19D1617C2FB2FC864606303AF174A6D /* TimePeriodChain.swift */, + 5AB27763B449AF051985734B3773B4ED /* TimePeriodCollection.swift */, + F44F0D93CFD9BB7C99C0FFCD686FF4E3 /* TimePeriodGroup.swift */, + 513DEC141FDDFD1CDAA8ED56A66AF623 /* TimePeriodProtocol.swift */, + C468581B4214846A9CA4FFED32F836D8 /* TimeStructures.swift */, + 55E9A15EC42E241A39E5CABDB5E0D428 /* Zones.swift */, + 47BE6238B9D2DAEAE874B27AAB7EA08A /* Resources */, + BE411CC01008BC5D5DCC757FE5D2C8D1 /* Support Files */, ); name = SwiftDate; path = SwiftDate; sourceTree = ""; }; - CC6596C895172C9FC5CB51B0BFD497D5 /* Resources */ = { + A7A71010D8CCF5C1D9EF378910670798 /* Support Files */ = { isa = PBXGroup; children = ( - 13F72F1929EF4D62E0B78F56864FF024 /* PrivacyInfo.xcprivacy */, + C521434F700F146BC7EEBBE2C6735ABF /* JXPagingView.modulemap */, + 04446B3B53853AB15AE3B7B85CF9343D /* JXPagingView-dummy.m */, + 2E89132366DFF0DC6A319EF946DF4CEA /* JXPagingView-Info.plist */, + E9C22A64A41E73EF4590DC6552E80DE8 /* JXPagingView-prefix.pch */, + 3EFEBDB3A2CB8EFD1E1BB0C882FC6500 /* JXPagingView-umbrella.h */, + 3EF5F786A9CD8F2E78E95733362FE187 /* JXPagingView.debug.xcconfig */, + D473476568C2D2300CCBAE8BAC883DCE /* JXPagingView.release.xcconfig */, + A690FBA7765087019C4F3AFEDD3E2CB0 /* ResourceBundle-JXPagingView-JXPagingView-Info.plist */, + ); + name = "Support Files"; + path = "../Target Support Files/JXPagingView"; + sourceTree = ""; + }; + B6A64081B24DF43D18A38FFA4FCFBDCA /* Resources */ = { + isa = PBXGroup; + children = ( + 84E085540B9A46FE188C3ED65522C329 /* PrivacyInfo.xcprivacy */, + ); + name = Resources; + sourceTree = ""; + }; + B6AE3338DA076FFE7E0B972538990B7A /* Pods */ = { + isa = PBXGroup; + children = ( + EF77375878C50B61FF2593542685106D /* Alamofire */, + 8B5308B450A10A8C99942BA8C8381883 /* IQKeyboardManagerSwift */, + 385385A8F793C6C811AF2F8236997A1B /* JXPagingView */, + DEA2AF0318429324985ACCA0C980A61F /* JXSegmentedView */, + A1102946118376B3CF7E47B1B547A7DC /* Kingfisher */, + 22B6388EE2F6A689255DDA896BFF58B8 /* MJRefresh */, + C822606ED58A2E9200F4156CDBDC3817 /* SnapKit */, + C5CF704E6D5B3EAE744A297EEFCB6EF0 /* SVProgressHUD */, + A2A70AADB5C5F2F057B310201B828389 /* SwiftDate */, + ); + name = Pods; + sourceTree = ""; + }; + BE411CC01008BC5D5DCC757FE5D2C8D1 /* Support Files */ = { + isa = PBXGroup; + children = ( + F4ED2B675426F9C1C129D85C5356428E /* SwiftDate.modulemap */, + 43FF45102B67E91CC3D79928C2717E40 /* SwiftDate-dummy.m */, + CA5885E0EE3717A1437053591B37EAD8 /* SwiftDate-Info.plist */, + C33A744358DA725C9E769351AB40C521 /* SwiftDate-prefix.pch */, + 207F4383A0CAE6E946319D62026A82F0 /* SwiftDate-umbrella.h */, + BE0D9928CC4ABC217232D13CC2A41C53 /* SwiftDate.debug.xcconfig */, + AA2205F6575D1182446627195A2B2D7D /* SwiftDate.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SwiftDate"; + sourceTree = ""; + }; + C541269A8DAE75B69CA5E2E7AC45959D /* Support Files */ = { + isa = PBXGroup; + children = ( + 3050C5DBB1E4F1DF9FD1B33611FDBDAD /* SVProgressHUD.modulemap */, + 0EC583B42A01E6257C74C1DCD53164A8 /* SVProgressHUD-dummy.m */, + D96D6359D0BE44C30CD6EE91D83FA37B /* SVProgressHUD-Info.plist */, + D44F4C1AC6C2A207BC560F616003B1B3 /* SVProgressHUD-prefix.pch */, + C68BBA48149EB58E146B969600FB99B8 /* SVProgressHUD-umbrella.h */, + B06108CF75D8C3024C894159C039AF1C /* SVProgressHUD.debug.xcconfig */, + 6B82834CA67E7FF1B8610BF181E51004 /* SVProgressHUD.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SVProgressHUD"; + sourceTree = ""; + }; + C5CF704E6D5B3EAE744A297EEFCB6EF0 /* SVProgressHUD */ = { + isa = PBXGroup; + children = ( + CB46B97DF031B3540C8A92C49DECB7F1 /* Core */, + C541269A8DAE75B69CA5E2E7AC45959D /* Support Files */, + ); + name = SVProgressHUD; + path = SVProgressHUD; + sourceTree = ""; + }; + C822606ED58A2E9200F4156CDBDC3817 /* SnapKit */ = { + isa = PBXGroup; + children = ( + A26DF092CAB68C5202C9271E71C8F750 /* Constraint.swift */, + FD0AE0ACE265AEC714180F643F48C621 /* ConstraintAttributes.swift */, + 0837DA8FB2DF8148CEE1EA57A72EE570 /* ConstraintConfig.swift */, + 2EB8A72B411C5E90471A44666337E7D2 /* ConstraintConstantTarget.swift */, + 4BE5E05285408F9AA5B005A82CEFDA99 /* ConstraintDescription.swift */, + 14052CB3D5057DCF4593BD1E77D90942 /* ConstraintDirectionalInsets.swift */, + 570B90AE83D4F878D222EF7D7B7A18F9 /* ConstraintDirectionalInsetTarget.swift */, + 3A92A995C2CF52A57109B1F08F9E6044 /* ConstraintDSL.swift */, + 7682AD6DBFD519C9BA5ECCAC483C0CF4 /* ConstraintInsets.swift */, + 234A9BD48AA1E6813E36334F22C346D4 /* ConstraintInsetTarget.swift */, + 58092F279DEDF69EA7576C313DC62F89 /* ConstraintItem.swift */, + 1384016DEBC0AD27C484B338B4FBEDB5 /* ConstraintLayoutGuide.swift */, + 6B4DCC2536CD7F8BD55F0BAA08F110C7 /* ConstraintLayoutGuide+Extensions.swift */, + 482206CB35A8E05C272FA37C0A8BF762 /* ConstraintLayoutGuideDSL.swift */, + 6AFFBD2618F9F069B2DFFC4829E58831 /* ConstraintLayoutSupport.swift */, + 6ADEBF08B3C1426137C7A2ED9E5E54D8 /* ConstraintLayoutSupportDSL.swift */, + 50DD91D5AAEBFBFB4776365998B843B7 /* ConstraintMaker.swift */, + F088EAD83DD6725075FBD8403594C429 /* ConstraintMakerEditable.swift */, + 7EC53E7C517308EABC44AEFB75F5C064 /* ConstraintMakerExtendable.swift */, + 5545219DAAC101FE50450F293367D8C9 /* ConstraintMakerFinalizable.swift */, + 24091B247B320B28B53B7DB2A0EB996B /* ConstraintMakerPrioritizable.swift */, + B86EE2D4250A56EE1BB39FFEB834371D /* ConstraintMakerRelatable.swift */, + 9ABF6319E31E3E401B63195B3374007D /* ConstraintMakerRelatable+Extensions.swift */, + 1294C0C419D6967DAAFC5C21609CAAAF /* ConstraintMultiplierTarget.swift */, + 65E17F9E27F1D47AFFD1AE176DFE1657 /* ConstraintOffsetTarget.swift */, + A78C6D5D45F26A283595741E6566040D /* ConstraintPriority.swift */, + 667B5BDDACE02078C87EFED6AAB723C2 /* ConstraintPriorityTarget.swift */, + C483D88FC9B266C71FB54AA488C58BBD /* ConstraintRelatableTarget.swift */, + 7477826A60436064D61A5EFA564B9D6F /* ConstraintRelation.swift */, + 7FBC7116157221928733CE2DB074EB86 /* ConstraintView.swift */, + E9C19F89F8FC7DDEB64DB778A90CC2BC /* ConstraintView+Extensions.swift */, + 9CC5E0E6473324DB3F517B54470CBE6C /* ConstraintViewDSL.swift */, + E88C5C3FE92321767662E35C421964B3 /* Debugging.swift */, + FEE5906F519651F94E70B28F42C4C70B /* LayoutConstraint.swift */, + F7B2E649574AA0FAECB00E9B883C49A6 /* LayoutConstraintItem.swift */, + 440D319A1267C894C2AFFDA3362EBE9E /* Typealiases.swift */, + C4A16ABD25AB8AAB13E0072CADE42E65 /* UILayoutSupport+Extensions.swift */, + 124E79470B5BB059B6D2B9C11028C2E3 /* Resources */, + 6A4EF31B924CC5861010E154A95CAD31 /* Support Files */, + ); + name = SnapKit; + path = SnapKit; + sourceTree = ""; + }; + CB46B97DF031B3540C8A92C49DECB7F1 /* Core */ = { + isa = PBXGroup; + children = ( + 282ACC9FB46C251345FC5EB3AEF1B9CE /* SVIndefiniteAnimatedView.h */, + 1DE3D079E059E37BB8233A28ECEF0FC7 /* SVIndefiniteAnimatedView.m */, + 1AAB28B6A1A5AA4CC4A0EEB258D9DC57 /* SVProgressAnimatedView.h */, + BD1BE557E2AE4A84F2515EB14ABAF97B /* SVProgressAnimatedView.m */, + 7C589304DE45B301793ACB48B3D74C25 /* SVProgressHUD.h */, + 9B189CE2110C0A21199EB8FB87FCEB6D /* SVProgressHUD.m */, + F6D3AF216BBC3443539D5BAD7BE5DEDF /* SVRadialGradientLayer.h */, + AE5B1F68CF04B5EBB405EA5A612234B6 /* SVRadialGradientLayer.m */, + CCEE1B7961A9E05DD52CB4CE96EF43CF /* Resources */, + ); + name = Core; + sourceTree = ""; + }; + CCEE1B7961A9E05DD52CB4CE96EF43CF /* Resources */ = { + isa = PBXGroup; + children = ( + 2C9B6C74D874F93335EDA5FBAC20675C /* PrivacyInfo.xcprivacy */, + A206F578A0BA9FC1C6B8B6078EFF6B9A /* SVProgressHUD.bundle */, ); name = Resources; sourceTree = ""; @@ -1336,8 +1600,8 @@ children = ( 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, D68CA58901FBF589D75F5E40F1EAF5BA /* Frameworks */, - D89CEB41E1E0E894A652C2A4A3801B95 /* Pods */, - 9EC42FE8BA9B8FA7438229F51F7FDEAB /* Products */, + B6AE3338DA076FFE7E0B972538990B7A /* Pods */, + 19C29489FB998EB8E7E019A0A9BE7772 /* Products */, 4AD22DFAF5934D8E9D83B59C461B799B /* Targets Support Files */, ); sourceTree = ""; @@ -1350,137 +1614,149 @@ name = Frameworks; sourceTree = ""; }; - D89CEB41E1E0E894A652C2A4A3801B95 /* Pods */ = { + DEA2AF0318429324985ACCA0C980A61F /* JXSegmentedView */ = { isa = PBXGroup; children = ( - 946A5F0D6DD1985A5C02012E944EF9C9 /* Alamofire */, - BE3F0FBA80DAFA8E1837B8FBC4F07BF0 /* IQKeyboardManagerSwift */, - 5F70495B50C1FEEA6D3E99ACFD3F4CC4 /* JXPagingView */, - 2C565D57B124DA6CCD25696736A30F00 /* JXSegmentedView */, - DFA2B1687C41FBD03B49E786597155AE /* Kingfisher */, - E03673E46CA02DA35D8A47DEFDB466DC /* SnapKit */, - 066A119AC73825E311A92A10A39576B5 /* SVProgressHUD */, - C2FBD0F076D76C08270A03146678DD28 /* SwiftDate */, + FDE736DCB96A4842E66D08021E34D36C /* JXSegmentedAnimator.swift */, + CA08845BC3434B44AF0A3C8AFC111D93 /* JXSegmentedBaseCell.swift */, + 460F21D69A6B1F9493AACA08A2F865B9 /* JXSegmentedBaseDataSource.swift */, + 51A207FA0764909F90D1FCCDE191F924 /* JXSegmentedBaseItemModel.swift */, + 4F1FB2699EA33ABD4EDB7F856D39296F /* JXSegmentedCollectionView.swift */, + 36E3BC01C35A4242976E6B95431C9F17 /* JXSegmentedComponetGradientView.swift */, + 2215909E83BE0517F84079C1593E4E85 /* JXSegmentedDotCell.swift */, + 344A8E805D9E365E5FDF94223860238E /* JXSegmentedDotDataSource.swift */, + 8CFAC3CD688A5BEB743550BA40C464FF /* JXSegmentedDotItemModel.swift */, + E31B1C576F8187B6B1A1F160B90D6081 /* JXSegmentedIndicatorBackgroundView.swift */, + 0E81980AF59D081E0E8A9761D1C422BF /* JXSegmentedIndicatorBaseView.swift */, + B0CE74EB3DE207E3CAE98CDE17280DBA /* JXSegmentedIndicatorDotLineView.swift */, + 835F2888E352852912F4709F5E54512B /* JXSegmentedIndicatorDoubleLineView.swift */, + 6AC9CFB040D783BBBD3E787C142BFF2A /* JXSegmentedIndicatorGradientLineView.swift */, + 135384F59FC764376A1E1806D1B43835 /* JXSegmentedIndicatorGradientView.swift */, + 11E47356E556750015100B2119302E53 /* JXSegmentedIndicatorImageView.swift */, + F125D521A9DA47CB8D38C8C03AEF68A0 /* JXSegmentedIndicatorLineView.swift */, + FEC00130945EBD53372EFBC22FB8119E /* JXSegmentedIndicatorParams.swift */, + 89FE60E3816FD1A788423E90F6E28D8D /* JXSegmentedIndicatorProtocol.swift */, + 71DCFBED49883055AA94888206F221A9 /* JXSegmentedIndicatorRainbowLineView.swift */, + 09B2FF8925A3677E79E08183E04491D1 /* JXSegmentedIndicatorTriangleView.swift */, + BA90CEFF373663026D2F06371A3D4E9A /* JXSegmentedListContainerView.swift */, + AFFBC6D1E5E46588B6AAB4F0711B9D5E /* JXSegmentedNumberCell.swift */, + 1EC6A17326897FCD562597FF862EFB28 /* JXSegmentedNumberDataSource.swift */, + 0A704FDB2D535D699FD2D53CC6DFFC70 /* JXSegmentedNumberItemModel.swift */, + AB0205A7B7089CE3AA7AF45ACDE3629A /* JXSegmentedRTLLayout.swift */, + E95438C214C29A3893A1B32DE8B1898F /* JXSegmentedTitleAttributeCell.swift */, + 6B28820A2229C358F6F00F9A6EE1A659 /* JXSegmentedTitleAttributeDataSource.swift */, + 4FDEAE488C153F23CC530F9FC7878CE4 /* JXSegmentedTitleAttributeItemModel.swift */, + 6F86EAA1D247756258692097BEA95A21 /* JXSegmentedTitleCell.swift */, + E652FB17C57B0AF0273621B2B037A0C7 /* JXSegmentedTitleDataSource.swift */, + 225AEBA0EC32A3D5A52ECA46DBBED7F3 /* JXSegmentedTitleDynamicConfiguration.swift */, + 2820DA7141C1E36BCF6D4D5D96802EAF /* JXSegmentedTitleGradientCell.swift */, + 695AA5A7D6BF0B59DFBF71ABC3F3FECE /* JXSegmentedTitleGradientDataSource.swift */, + 2E39692FF9A73D5EC6D4AE2DE35E3C0C /* JXSegmentedTitleGradientItemModel.swift */, + 55914F40E7C5BD463245E2016A8906BC /* JXSegmentedTitleImageCell.swift */, + 4C1194040926B2C7D711B859F8AE4312 /* JXSegmentedTitleImageDataSource.swift */, + B65D6A9EE341D83823E03C122A72A5C1 /* JXSegmentedTitleImageItemModel.swift */, + DBF28FA874E18F2693E3B035356382F0 /* JXSegmentedTitleItemModel.swift */, + 0A8B5D1A6CBAD8FC5DA5D3D0DA7512BE /* JXSegmentedTitleOrImageCell.swift */, + AFCD84A7AB4756552C1E55E266165ACA /* JXSegmentedTitleOrImageDataSource.swift */, + FDD5BF7F25804ED6AC6B15D6801FE4AD /* JXSegmentedTitleOrImageItemModel.swift */, + 67318C8CDF97D3763D84C0B08910AD54 /* JXSegmentedView.swift */, + 7EB8A3AF649521A0ED645B8858FB4DDF /* JXSegmentedViewTool.swift */, + 3997AFF09C6B2741C9D946A854C69D26 /* Resources */, + 4ED80A127B880DDBD359D089C93079AC /* Support Files */, ); - name = Pods; + name = JXSegmentedView; + path = JXSegmentedView; sourceTree = ""; }; - DFA2B1687C41FBD03B49E786597155AE /* Kingfisher */ = { + DF485347F9CA2BC7B2DDEB48DB96D1CE /* Support Files */ = { isa = PBXGroup; children = ( - 49D7A0F2127AEF6AA887F6668525FA08 /* AnimatedImageView.swift */, - D7F7058BED0353F5D41333BF24E48B67 /* AuthenticationChallengeResponsable.swift */, - 9E6E3FB0EAE53F7E9EEF4A4D9EB32372 /* AVAssetImageDataProvider.swift */, - 28FE2901B317396EE489A6D5CA08C3FA /* Box.swift */, - 6C5BB459268D5535E82BA01CD4B7E5F2 /* CacheSerializer.swift */, - F05B27A0A6364144E57B02027A6A91F2 /* CallbackQueue.swift */, - D60E4FF19874657631F19D84E77C0FCD /* CPListItem+Kingfisher.swift */, - 7AED5BF44EC43B565CFB49DC523A2FE6 /* Delegate.swift */, - 156E359C7D79A3E1C10A8B625DB45E59 /* DiskStorage.swift */, - 9AE736393524312D73608EA88A6743E6 /* DisplayLink.swift */, - D8E1418AF8EB9AC57EA5BDC745EE7216 /* ExtensionHelpers.swift */, - AFA7D8134BAFA04D2B580073EE31DACA /* Filter.swift */, - 0E33C97B5283CD7B31E6C56118C99CB3 /* FormatIndicatedCacheSerializer.swift */, - AD4404E7BA0E07C8EDABCE9734F9BBC9 /* GIFAnimatedImage.swift */, - 02B20B40A566E7F7A9D3CA9FD8FE353B /* GraphicsContext.swift */, - C950C7B6D82094FBAA31EA39107D9934 /* Image.swift */, - 4AC1EA3AB5460CAF71C28DE23506948D /* ImageBinder.swift */, - EC9CD67D400913EBE69B43B5CD49163E /* ImageCache.swift */, - 7B710B049CD54BF711CB18566657FE6E /* ImageContext.swift */, - FE6F6DA791EBF42B686DEEAE637C154D /* ImageDataProcessor.swift */, - 05E103BDBB854A87B92514983DFE7F29 /* ImageDataProvider.swift */, - 88D9E5016D9005153DC1BF421EB97D45 /* ImageDownloader.swift */, - B6AE2AF696125AD0E1121BF86AAE5046 /* ImageDownloaderDelegate.swift */, - C4B0B70AF11FE76174D9E1B20575FAAB /* ImageDrawing.swift */, - 123F9D355B6FA77F1C0BBFDFB7DCEFC2 /* ImageFormat.swift */, - 5CF9C49F0627CE4DC176C8910520DD1A /* ImageModifier.swift */, - 924CF8F11C00458CC225420E918BA09B /* ImagePrefetcher.swift */, - 0601225BD77C06D730B494562E9F9229 /* ImageProcessor.swift */, - 85475E21904923ACC16877FB7BA6C30B /* ImageProgressive.swift */, - CD5DFFE16768F14458BE38939F340F1B /* ImageTransition.swift */, - 7746FB2D26EF54C07CCBA2B580E80230 /* ImageView+Kingfisher.swift */, - 2B207E1FC13165182A34EDC2DB916D27 /* Indicator.swift */, - 7DF2560B7559A05BA6EF1E5162CB2E28 /* KF.swift */, - 8D27856B2E2A4B0DFBC9C847E272AF9E /* KFAnimatedImage.swift */, - 56B3AB6B42435ED2BB97F0E60A022953 /* KFImage.swift */, - 665D66E791DE2DF5733AC7C3555A21F4 /* KFImageOptions.swift */, - 18E3BBCE92E077B287C988B88A527154 /* KFImageProtocol.swift */, - B829BB92CE7C61E3EF4CAEA14D3264FE /* KFImageRenderer.swift */, - 6805397BC4354ED2D75A5B7AAE174E86 /* KFOptionsSetter.swift */, - 3219E80F1D4ABFEBA0A158FD5D5F5591 /* Kingfisher.swift */, - CDF1EA36F77390C08F5F803AC6C25B26 /* KingfisherError.swift */, - A4AA0EBFFFCAE79E4DD76DB28D399121 /* KingfisherManager.swift */, - 4B6C0753CD229018B31E3685E1F4B7FC /* KingfisherOptionsInfo.swift */, - D20485D884C20E59FFC1CE9922C547D5 /* MemoryStorage.swift */, - 98668AA82D39D5CB2E405768140C5404 /* NSButton+Kingfisher.swift */, - 1E4763CB38C57143759CBF3728786434 /* NSTextAttachment+Kingfisher.swift */, - 12EAC48C11B1824841992EFCD031F4CF /* Placeholder.swift */, - 25F1F4699C3C4B6DC02C6B5A89D1AC4A /* RedirectHandler.swift */, - 85BA376AE75DD6C89F006B5ABBAD1A00 /* RequestModifier.swift */, - FCFB2567FE9BD5DDD79D4D4E176FE079 /* Resource.swift */, - 5A7EBDEB55449170B0A5AA76B77186C0 /* Result.swift */, - 25037E4FB7BC7534B013D62B4131021F /* RetryStrategy.swift */, - C7778F9E9BCCA019BA4450E1ED18BB74 /* Runtime.swift */, - 4B4E70BC82C57A65822AE2D5EB9D6201 /* SessionDataTask.swift */, - FAE668ECEAF7AAFCDEEDD1F0D9C0B3F1 /* SessionDelegate.swift */, - E2571304BB906066EBA3D52C58187895 /* SizeExtensions.swift */, - E9CE7D5D62E97450A0DF267A8A799F0B /* Source.swift */, - 905F41A1A4BC05366108CBB7D774CB63 /* Storage.swift */, - 9E756CE2D8BBBFBD61C705DCB85928FC /* String+MD5.swift */, - C789A86A2E73450B8364125FF6DF392B /* TVMonogramView+Kingfisher.swift */, - F954C218AC5D88CE4C61680D652F9306 /* UIButton+Kingfisher.swift */, - 5672FA74F6AF0085E780C6D735D8918B /* WKInterfaceImage+Kingfisher.swift */, - 6FC81FEFE58947E5B476B6EE51473C90 /* Resources */, - 304C52956EB3CFA258215A96CEE0A64A /* Support Files */, + A7AF9A69BFF4975345B92D217643792D /* Kingfisher.modulemap */, + 33033614BAFA0628A44D6CE5D2EDBB09 /* Kingfisher-dummy.m */, + F62422400EE70C424F8B9090F58835FC /* Kingfisher-Info.plist */, + B66FA26ED5139D4710E18EA56AEC64BE /* Kingfisher-prefix.pch */, + 814205A97B8158339AF6DCF93609360F /* Kingfisher-umbrella.h */, + DF2C075BA691343B5759F4F639FA08A6 /* Kingfisher.debug.xcconfig */, + E18618FEAC0ECEE393834FA4EEDDD337 /* Kingfisher.release.xcconfig */, + F3AC7EE5F91C56B1C96124A3C58154A5 /* ResourceBundle-Kingfisher-Kingfisher-Info.plist */, ); - name = Kingfisher; - path = Kingfisher; + name = "Support Files"; + path = "../Target Support Files/Kingfisher"; sourceTree = ""; }; - E03673E46CA02DA35D8A47DEFDB466DC /* SnapKit */ = { + E322A4AAC43BD85F10A108F72EC08C4E /* Support Files */ = { isa = PBXGroup; children = ( - 0C763B3088899119C0227AA4D0ECD4F7 /* Constraint.swift */, - 773370F5C5F8C1A1ED9DA49D4CFA08B8 /* ConstraintAttributes.swift */, - 1EF8045540E68DD0F0CB57EA73DC4DE1 /* ConstraintConfig.swift */, - B3BE4EB2A04A4F30656E0864B64A6A88 /* ConstraintConstantTarget.swift */, - 0457F1A1D877D4B914DE716739D328E1 /* ConstraintDescription.swift */, - 01AD1A13BBD29E50BAC17596D47EED9B /* ConstraintDirectionalInsets.swift */, - 14B2FD7F1C5BA01262CA8DA89FC19A86 /* ConstraintDirectionalInsetTarget.swift */, - 3DFEF57B19765C495039E698F1C7679F /* ConstraintDSL.swift */, - 39F93B4F6F36C41FDDD2C63E96361841 /* ConstraintInsets.swift */, - 3E89ECD9194EDFD568A9EF6F17101045 /* ConstraintInsetTarget.swift */, - C7347F615A018CDE56878D17CCECC138 /* ConstraintItem.swift */, - 9127C21D70BA07B74F31B569E2887C5F /* ConstraintLayoutGuide.swift */, - BD9B444681135CCF6E363CC0A67B6651 /* ConstraintLayoutGuide+Extensions.swift */, - FABEEC9AF2516E3B746E77F84AD1BD3F /* ConstraintLayoutGuideDSL.swift */, - 3ECAA08258069FFA67EFC17C35C656B7 /* ConstraintLayoutSupport.swift */, - 84B7F7B98523171E533048422B5C3CDC /* ConstraintLayoutSupportDSL.swift */, - 014C66675810A411BF2633383898D51D /* ConstraintMaker.swift */, - 97B043B3414EEE6CE9FB38F6C8C4E938 /* ConstraintMakerEditable.swift */, - 6A6A3FAA6F0F3F494BB498919493C5ED /* ConstraintMakerExtendable.swift */, - 7FCAF7C1E0C7EF57EDC617DCE77194E5 /* ConstraintMakerFinalizable.swift */, - 73D95693DF679081C2166C4C7F9A2F66 /* ConstraintMakerPrioritizable.swift */, - 03CB6A229CF84BA1622B096CE234952C /* ConstraintMakerRelatable.swift */, - DC679D42513109DC163A916172A01E41 /* ConstraintMakerRelatable+Extensions.swift */, - FFF930183A98B76DFC6E381963A1F56A /* ConstraintMultiplierTarget.swift */, - C570C2B10208E17D82B7BE0255BD166E /* ConstraintOffsetTarget.swift */, - 51AAE5F7671D63A1A83A5E003572F18C /* ConstraintPriority.swift */, - BB180FDD1F9AAD170DE5179EBA67AFE2 /* ConstraintPriorityTarget.swift */, - C254E57BBEAA35B8CE7E6626A38511AF /* ConstraintRelatableTarget.swift */, - 97840F079FDCC2C242D262A194809427 /* ConstraintRelation.swift */, - A43A96448C1937678DB79A129BB6F2C2 /* ConstraintView.swift */, - 2D98B938C502BAD501835A48A8F2DCC2 /* ConstraintView+Extensions.swift */, - 0FEB76C2B6C718226251B5CBDA7A3540 /* ConstraintViewDSL.swift */, - 278F6659C16FB8FEFA7A2B0F4CCB19AC /* Debugging.swift */, - E14C41F18595A29151A31E735A1B7692 /* LayoutConstraint.swift */, - 540940F677A9EFC1CF5FD25315DE5F5A /* LayoutConstraintItem.swift */, - E329FD7AFE7914B19431A5027E14E2E3 /* Typealiases.swift */, - D1BC0AA48F6B64CE90390DE5DBE67EFD /* UILayoutSupport+Extensions.swift */, - 696FF6F0F54FA544AFA3DEDD91AE9EE1 /* Support Files */, + AE8FD0EA90E35589FF45377FFE6445D6 /* IQKeyboardManagerSwift.modulemap */, + E1176C58859CF5334183B7786DAC8E87 /* IQKeyboardManagerSwift-dummy.m */, + 2FBE5C3E144BF69BC982850AFCE42CDB /* IQKeyboardManagerSwift-Info.plist */, + 52C0154703620B58E000A12A7DD03B58 /* IQKeyboardManagerSwift-prefix.pch */, + 98D0F4FF0A3E2660BE566528FDF31D03 /* IQKeyboardManagerSwift-umbrella.h */, + A3841A0A7F5A5EABE2100147A429E0C6 /* IQKeyboardManagerSwift.debug.xcconfig */, + AB089815F261E66CDE44D5F4DE72EE32 /* IQKeyboardManagerSwift.release.xcconfig */, ); - name = SnapKit; - path = SnapKit; + name = "Support Files"; + path = "../Target Support Files/IQKeyboardManagerSwift"; + sourceTree = ""; + }; + EF77375878C50B61FF2593542685106D /* Alamofire */ = { + isa = PBXGroup; + children = ( + B98A705AFD36170CD85E492121E37403 /* AFError.swift */, + 5347F4D40BA296B41A792189CB1331E9 /* Alamofire.swift */, + 1A8F4312D81FC10BD8029BE851C76498 /* AlamofireExtended.swift */, + 7052242B5B59DCEC7125EE873BC0202A /* AuthenticationInterceptor.swift */, + 28BCEACC594F9EA2E10117D26B3DA759 /* CachedResponseHandler.swift */, + 05A41A0B8D148A4BA10DC25292FA63E6 /* Combine.swift */, + E9B7826E0EF5E37E1704D27E7C361C78 /* Concurrency.swift */, + E6E279BCC1C2C3A2FA64E3E7F3FD5335 /* DataRequest.swift */, + F8C8C3813F3BA6EEC658167AE65D9419 /* DataStreamRequest.swift */, + 11AF900AC1C5B4CD4047B709266568E5 /* DispatchQueue+Alamofire.swift */, + 4316C38FD6E88F2FFBBB3BC6DF2C26FF /* DownloadRequest.swift */, + 393CAB07C81E1F3ACA4DDB1CAB615E1B /* EventMonitor.swift */, + 5699EE5AE55BF8C2FE30604FAED64A7C /* HTTPHeaders.swift */, + 6D3E36D2866A136708CF5F602D268BD7 /* HTTPMethod.swift */, + CB03A8FE1983F5F495EC9ADC0D6E7E6B /* MultipartFormData.swift */, + C94A8D6D5B3A24A5E000AF4DBE9434CF /* MultipartUpload.swift */, + 88647C8377C8FB3AE854C55C7B81559E /* NetworkReachabilityManager.swift */, + BF6B66846BA638DCD6F5ABB338C4AA41 /* Notifications.swift */, + 0AB50AF41FD17FD4D634D6CB5152810D /* OperationQueue+Alamofire.swift */, + 9AC28BE75055A99E1BD5B4B8D07E3C1B /* ParameterEncoder.swift */, + 368AFBDCEBBA20270829ACA09283D127 /* ParameterEncoding.swift */, + 0DB30FE6997717CE3E7589C60A9C7A9E /* Protected.swift */, + 6855310DB35D41B1E466E5EFFAF771BE /* RedirectHandler.swift */, + EB8D6628308EE28230C57E4CE1063A31 /* Request.swift */, + 6E6DA59208C9C680C1A08AB6B751A05E /* RequestCompression.swift */, + D89E20D36B74F4A890688A090C311698 /* RequestInterceptor.swift */, + 7C1665911416D598AAD937FC0E0D42E4 /* RequestTaskMap.swift */, + 1383471ECB9F37892C9CC3EF67CA0375 /* Response.swift */, + D88F8FEC13A3A1DB04F7186FA15AE1CB /* ResponseSerialization.swift */, + CB0F440BD5C5987BBAD5992F1CC0CCAA /* Result+Alamofire.swift */, + B10D7C8D9A8EFE21347CF640AE5AFCD9 /* RetryPolicy.swift */, + BAAC3162B7531D025AB197602FE75F31 /* ServerTrustEvaluation.swift */, + 8A9A6B3FF123B6733156B839AB90A488 /* Session.swift */, + 65BAE3F45733F6EB3DAE2F48599D8CAB /* SessionDelegate.swift */, + E681F9A4BFBE0245493029CEB1B8A1C8 /* StringEncoding+Alamofire.swift */, + 8B4EE5D13ED112C5C84DB3A6ADE8E7E0 /* UploadRequest.swift */, + EAD5CEA5D178799C659489E705F0BDE8 /* URLConvertible+URLRequestConvertible.swift */, + 08E28C2D9A6137B156647AC16D95A15E /* URLEncodedFormEncoder.swift */, + 0EA5D2A634B9432EA862513BDE2A5ED4 /* URLRequest+Alamofire.swift */, + 12A6ED7989C6F4843507D223BD102CC5 /* URLSessionConfiguration+Alamofire.swift */, + CA42DDB21EAB3527641F275C3D22E4D0 /* Validation.swift */, + A793885CE536998701B9632A60B45781 /* WebSocketRequest.swift */, + 21A960E74EC481373E719394FDBE27EF /* Resources */, + 5B7171C88905EE86E6FB47E5A6F4D2D4 /* Support Files */, + ); + name = Alamofire; + path = Alamofire; + sourceTree = ""; + }; + F56AEB416F118ECBB450F18C0A431806 /* Resources */ = { + isa = PBXGroup; + children = ( + EFE78C092A2B391D6411B2D75E0897C5 /* PrivacyInfo.xcprivacy */, + ); + name = Resources; sourceTree = ""; }; /* End PBXGroup section */ @@ -1494,31 +1770,36 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 4F6172E8C45AC2744C62C2E3F9AA7566 /* Headers */ = { + 5F56EC88D89E08B670BB19F6457F198C /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 7073BBB5FB012B196E1111C4EA4B0B90 /* IQKeyboardManagerSwift-umbrella.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5FA4790A32ECD84F2CEA55509107BD0A /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - A3E3AB7C765C21AE17B1E6EE6560040C /* SnapKit-umbrella.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 6DE9E7B34EB24769860A549107B4F04C /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - E70EBA16751054574A227A6432CCE4B0 /* SVIndefiniteAnimatedView.h in Headers */, - F77280E74EB91678AA294E66DD6070E2 /* SVProgressAnimatedView.h in Headers */, - C15B3F89E6F83DC9CCB14903FC5D80C5 /* SVProgressHUD.h in Headers */, - 4DC032894868226AE220360BADB2C237 /* SVProgressHUD-umbrella.h in Headers */, - 6D1E33469FB8FBE812956B0076A7B28F /* SVRadialGradientLayer.h in Headers */, + 48E83D4BC4A5C3542CB0560A1E82A2F4 /* MJRefresh.h in Headers */, + 3360B725B480679D59E44B812DD8D116 /* MJRefresh-umbrella.h in Headers */, + 63BCE3414C785046BB317537B8120B5D /* MJRefreshAutoFooter.h in Headers */, + FC524E181A75784881A12562BDB00CC6 /* MJRefreshAutoGifFooter.h in Headers */, + 43ED71634C98518E6B0749001ED89C43 /* MJRefreshAutoNormalFooter.h in Headers */, + A7AE58053194FA1CEA420D995AF17B85 /* MJRefreshAutoStateFooter.h in Headers */, + 170E0C2556FD00466C155473B428F792 /* MJRefreshBackFooter.h in Headers */, + D32F246A21567182179C39B12D534191 /* MJRefreshBackGifFooter.h in Headers */, + 90441CBC43993A5E4E0F5CD5BECC2DDE /* MJRefreshBackNormalFooter.h in Headers */, + D496B7637BE491EE925D965EC64A46E8 /* MJRefreshBackStateFooter.h in Headers */, + 9AF53260DACD3DE030C97AA110DAD22E /* MJRefreshComponent.h in Headers */, + EF9B92EF4A0412D775FA55E4D1CB7A45 /* MJRefreshConfig.h in Headers */, + 2C94C305900E95BDB9296A7EFCF3C940 /* MJRefreshConst.h in Headers */, + 1AEABE21257723E2AEE836117F3A8B12 /* MJRefreshFooter.h in Headers */, + 6F271B6EA85E0BDDA7DD1CC621EDC4F9 /* MJRefreshGifHeader.h in Headers */, + 498FFEC31A02476F4F719EF645AC1562 /* MJRefreshHeader.h in Headers */, + 686ABAEBCE5C0EA6644AA80F9B4B3687 /* MJRefreshNormalHeader.h in Headers */, + 1093AAD9CB7394BDBDD0E287103515F6 /* MJRefreshNormalTrailer.h in Headers */, + 8C077A05101B84731A302657381218CB /* MJRefreshStateHeader.h in Headers */, + 6D4A08865846C0F0DB9A05C617C2A947 /* MJRefreshStateTrailer.h in Headers */, + 77A016AB014A21D60BBFAB9F7134D38B /* MJRefreshTrailer.h in Headers */, + C09A286120D64335EA18D7689720B773 /* NSBundle+MJRefresh.h in Headers */, + E8AD52B68BDE7B679B358601CCAB3F2D /* UICollectionViewLayout+MJRefresh.h in Headers */, + 7A19CD0F168E8C66757012114767A36B /* UIScrollView+MJExtension.h in Headers */, + 9AF14E4B1C52E5AD4C38021C4EC17974 /* UIScrollView+MJRefresh.h in Headers */, + 23EE2A5A9ADF9A6B9A3515CA85E382ED /* UIView+MJExtension.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1530,11 +1811,39 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - B3DAE99DEA0D9CA985DB6708BED1F018 /* Headers */ = { + 85A932520BC40A75F3549F020972CC8B /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - DCE8DA2810BF13609E3F4281AA773569 /* Pods-MusicPlayer-umbrella.h in Headers */, + D4E2EAD773A30B252B6AD6B99A7490F4 /* IQKeyboardManagerSwift-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B454E5400DFCBAAE9FD01EC7644B8C7F /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 5D4490556ADDD36F5100CF5D9F68ABF9 /* Pods-MusicPlayer-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BD2B111EBF8A7845E42930BF05778C63 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D389E4D5F97798BE1AEEB8C317852D7 /* SnapKit-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D3CFD33AB27993819E2EA9267DBD8C8A /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D4A9338A969C1416E3C79CECCB97D514 /* SVIndefiniteAnimatedView.h in Headers */, + 0335018FAC1AD7BC453F8F9A68CDABC4 /* SVProgressAnimatedView.h in Headers */, + 19FE9BC7F25FF5D48B6B2B3B520D4D47 /* SVProgressHUD.h in Headers */, + 82FE3B046FEA46F2BDFE7FB0E9D7CBAD /* SVProgressHUD-umbrella.h in Headers */, + 2E84CD435150EDA1356EE23EAB3CE5E7 /* SVRadialGradientLayer.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1567,16 +1876,17 @@ /* Begin PBXNativeTarget section */ 19622742EBA51E823D6DAE3F8CDBFAD4 /* SnapKit */ = { isa = PBXNativeTarget; - buildConfigurationList = 58EAA7FF29EA237538F747F2AF468203 /* Build configuration list for PBXNativeTarget "SnapKit" */; + buildConfigurationList = 4C4F25F04C086237315FCAEF7661357E /* Build configuration list for PBXNativeTarget "SnapKit" */; buildPhases = ( - 5FA4790A32ECD84F2CEA55509107BD0A /* Headers */, - 7B7E69B2799BABEB7764F85296B591B7 /* Sources */, - E8E4E7CE8309D3EF7B7476AC57986BE9 /* Frameworks */, - 820C67429A90336F5AF1C850DF03B1B9 /* Resources */, + BD2B111EBF8A7845E42930BF05778C63 /* Headers */, + B52EB97EAADC4B42F512DF593D183539 /* Sources */, + 6F796DCACF7FECDF5C5CEF6AFE7BC0FF /* Frameworks */, + 8AFC96B9D49AC279B3790C99847FF1B3 /* Resources */, ); buildRules = ( ); dependencies = ( + 2C7D2C5A1F7AA8FA62801CB4684E0232 /* PBXTargetDependency */, ); name = SnapKit; productName = SnapKit; @@ -1585,12 +1895,12 @@ }; 1C8D67D8B72D6BA42CCEDB648537A340 /* SVProgressHUD */ = { isa = PBXNativeTarget; - buildConfigurationList = 807FEF9D9629A72728B6B83F5CA12C85 /* Build configuration list for PBXNativeTarget "SVProgressHUD" */; + buildConfigurationList = 3B02596C7FAA57EB3E61033F4406577A /* Build configuration list for PBXNativeTarget "SVProgressHUD" */; buildPhases = ( - 6DE9E7B34EB24769860A549107B4F04C /* Headers */, - 108B36464ADE4902E2E2C83461767402 /* Sources */, - E389FF082B036E756B0679583C1BE62E /* Frameworks */, - A4CCC3CC21F770E272C54B18DDDE6DA3 /* Resources */, + D3CFD33AB27993819E2EA9267DBD8C8A /* Headers */, + AAB3338BD40E4E170628192E4D18FE79 /* Sources */, + 2560AEF01B4ED19DB7D7B4882A6F90F9 /* Frameworks */, + AC47CEB36BE3DE7A7A5DB7547DA55F3D /* Resources */, ); buildRules = ( ); @@ -1603,11 +1913,11 @@ }; 52F43AC38D9FF80196C69FB03AEEFDDA /* JXSegmentedView-JXSegmentedView */ = { isa = PBXNativeTarget; - buildConfigurationList = 5E847D67D7BF704D94E27B4299623A5D /* Build configuration list for PBXNativeTarget "JXSegmentedView-JXSegmentedView" */; + buildConfigurationList = 8192D6E7F891C6FB05E5D01514EABBE2 /* Build configuration list for PBXNativeTarget "JXSegmentedView-JXSegmentedView" */; buildPhases = ( - A08C69BB9CAA0997BFECC7F6967AC6DE /* Sources */, - 8C2D9DF369727E237BEC22EF0C9C2AD5 /* Frameworks */, - 90B553EFDC0BE8866CF847B5B2549611 /* Resources */, + 6B53EDF320432C6FB2F2576B2E116CC6 /* Sources */, + E74997FAADCF49681E528FCB21A4D1AA /* Frameworks */, + 3AB3D3CDA12081B8903F0D5A9C1887FB /* Resources */, ); buildRules = ( ); @@ -1636,39 +1946,76 @@ productReference = 58AE0544E0C381DDBD09356C357EC82B /* SwiftDate */; productType = "com.apple.product-type.framework"; }; - 686C644F1E3D20750B0EA86F7A8674B7 /* Pods-MusicPlayer */ = { + 6868056D761E163D10FDAF8CF1C4D9B8 /* MJRefresh */ = { isa = PBXNativeTarget; - buildConfigurationList = BA1379311C9032331BB3F700DB0A5D13 /* Build configuration list for PBXNativeTarget "Pods-MusicPlayer" */; + buildConfigurationList = F09A4CBED64F267E853B71023517C77A /* Build configuration list for PBXNativeTarget "MJRefresh" */; buildPhases = ( - B3DAE99DEA0D9CA985DB6708BED1F018 /* Headers */, - B0D1A5C6EF59B24ABB2D270C6F67928D /* Sources */, - D1B0699FE073B926EB6BB5C6B177A326 /* Frameworks */, - 4F56E6E64C701CA47C99CCC911468DC4 /* Resources */, + 5F56EC88D89E08B670BB19F6457F198C /* Headers */, + AF7DE4F344610DD30C852DC81D03A879 /* Sources */, + 3FA6BB0E255F3D1C771079154343333B /* Frameworks */, + 49DD1B1DA762309F6890441BBA43F2C8 /* Resources */, ); buildRules = ( ); dependencies = ( - 0EC94FB8AE13C675012996E6E63D99FD /* PBXTargetDependency */, - EFD9C2E055CF05F8BE5E8CA9B7A678DE /* PBXTargetDependency */, - 509168942D78B85F99112CE2B315E87F /* PBXTargetDependency */, - AAD1F6695A6519FD93658C8143599690 /* PBXTargetDependency */, - B7F65E9E76CCD98F97C7BC8F16758F72 /* PBXTargetDependency */, - 7FD7BD432EEA0F0E66B3D4AE62CF4D32 /* PBXTargetDependency */, - E45EF95C462C681ED0E6B2B2CD6E6288 /* PBXTargetDependency */, - A00146B8DA477F7292F9CB3AA37012A7 /* PBXTargetDependency */, + FC0B50042A431604CEA4CD7FE470B9E2 /* PBXTargetDependency */, + ); + name = MJRefresh; + productName = MJRefresh; + productReference = E49D6D248DD1CEE584E6776B9164A1B2 /* MJRefresh */; + productType = "com.apple.product-type.framework"; + }; + 686C644F1E3D20750B0EA86F7A8674B7 /* Pods-MusicPlayer */ = { + isa = PBXNativeTarget; + buildConfigurationList = 38A9DB1BF7DB582FA154E6E85B017967 /* Build configuration list for PBXNativeTarget "Pods-MusicPlayer" */; + buildPhases = ( + B454E5400DFCBAAE9FD01EC7644B8C7F /* Headers */, + 3B6553FDFA7B234E555016891227351E /* Sources */, + 8CB5E1A5B008E0176BA7B33578DFF0C8 /* Frameworks */, + 621AAFBBAEDCEC01847BF59E99E1F36D /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 9F42538473D8CD84E2B00227CCC5270F /* PBXTargetDependency */, + 9C4DCABEE4C8DE1C8C7F5F136424389A /* PBXTargetDependency */, + A419D3F35FFC28E3C110DC1E9BDD907A /* PBXTargetDependency */, + 4A583CB19C34725D587B75745C4FBB1F /* PBXTargetDependency */, + AF753EA8E0B40A33C32A44CAA21E6E1B /* PBXTargetDependency */, + 142AAB4FA977C078DA09CA68CD9F7AB0 /* PBXTargetDependency */, + 3AE06D852AB2AA0F21550B5A31B4B2A8 /* PBXTargetDependency */, + B5571C9BD8ACED22B2133870B863C3F5 /* PBXTargetDependency */, + B58C9ED1F196D76949A6ED62612F50C4 /* PBXTargetDependency */, ); name = "Pods-MusicPlayer"; productName = Pods_MusicPlayer; productReference = F23C669C0B769DC30F5A05CE45FEA445 /* Pods-MusicPlayer */; productType = "com.apple.product-type.framework"; }; + 8A8DB685241263AFDF5E6B20FE67B93A /* SnapKit-SnapKit_Privacy */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9B1967783C7584ADA7A063159ED92F0B /* Build configuration list for PBXNativeTarget "SnapKit-SnapKit_Privacy" */; + buildPhases = ( + 975EC584D1C4839C3ED556A694D283BA /* Sources */, + 4B885211E9E65DAB21AAD17EBC56C6F1 /* Frameworks */, + 1FEFD1E5FA9185094B0AB02E6E69124A /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "SnapKit-SnapKit_Privacy"; + productName = SnapKit_Privacy; + productReference = B9DCB5EC0B1CDADD221717CADDF62359 /* SnapKit-SnapKit_Privacy */; + productType = "com.apple.product-type.bundle"; + }; 976126A1CE06DC6E162563800E1BDF14 /* Alamofire-Alamofire */ = { isa = PBXNativeTarget; - buildConfigurationList = 50A1F214909B860ED2A9D86E88C2BCA3 /* Build configuration list for PBXNativeTarget "Alamofire-Alamofire" */; + buildConfigurationList = 4ABFC85AD568923D7A67A236848CF419 /* Build configuration list for PBXNativeTarget "Alamofire-Alamofire" */; buildPhases = ( - ADBFA9B333C3AA957ED875509E56DB73 /* Sources */, - 5A29158CAB99F1CFF837C37811A7B6A1 /* Frameworks */, - 94A6273DEBA952CDF6133B47B51FE451 /* Resources */, + 986963C7968E6A40070C6340AF987110 /* Sources */, + E77A06A0307FF511269865599FB0CBC8 /* Frameworks */, + D52D9F52394C31B5EDC6D9A7475D483A /* Resources */, ); buildRules = ( ); @@ -1681,11 +2028,11 @@ }; 9828BBC09E9FB1238624113D7456E59E /* Kingfisher-Kingfisher */ = { isa = PBXNativeTarget; - buildConfigurationList = 5C022666992472C94648DC5B812648E6 /* Build configuration list for PBXNativeTarget "Kingfisher-Kingfisher" */; + buildConfigurationList = 387D22F9EF0A1068C65E4F1499A5D232 /* Build configuration list for PBXNativeTarget "Kingfisher-Kingfisher" */; buildPhases = ( - C12BA93052B82ED1329E8A66293C722A /* Sources */, - D76F1A0A75BD4615906466C44D72FDFF /* Frameworks */, - BC290758B47BE8C396CF7669E1A0A398 /* Resources */, + 341A979A7B6136565AD1967B52C3A2E9 /* Sources */, + ACBA24352126BCD74C702B7475807D88 /* Frameworks */, + 038AC83ADCB3D90F02617AEF82ED6BE7 /* Resources */, ); buildRules = ( ); @@ -1696,13 +2043,30 @@ productReference = C298ABB78D9B05529B89D8322DB2E7B0 /* Kingfisher-Kingfisher */; productType = "com.apple.product-type.bundle"; }; + B26054DF1DEA11585A231AF6D1D80D5E /* MJRefresh-MJRefresh.Privacy */ = { + isa = PBXNativeTarget; + buildConfigurationList = B84B7C31B677C791E25D754795F22921 /* Build configuration list for PBXNativeTarget "MJRefresh-MJRefresh.Privacy" */; + buildPhases = ( + D73A00FA16CD75A875D6F6617EE144D2 /* Sources */, + 402E49A24B937179BD48FB96001CBF9D /* Frameworks */, + 3F7DFD623D64A5455DA0E9B055E44974 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "MJRefresh-MJRefresh.Privacy"; + productName = MJRefresh.Privacy; + productReference = 7E3097CFEFDA621E9FB0E62009FF87FC /* MJRefresh-MJRefresh.Privacy */; + productType = "com.apple.product-type.bundle"; + }; B2B2AD5303610D8EBEA025B2660C8EC5 /* JXPagingView-JXPagingView */ = { isa = PBXNativeTarget; - buildConfigurationList = CCB3E4A930ED7224F6C38A8D8820BAAA /* Build configuration list for PBXNativeTarget "JXPagingView-JXPagingView" */; + buildConfigurationList = F1FFFC5DAB1EC2D84580B2C5AD779F80 /* Build configuration list for PBXNativeTarget "JXPagingView-JXPagingView" */; buildPhases = ( - C037E1C181318450ABEBFA4C08492B19 /* Sources */, - CB094C5CC2CE7C14828D233306D629F8 /* Frameworks */, - 48F8F1ACC95C235B95096A6D45316F93 /* Resources */, + 4084A20021837E681EFB708E0F608493 /* Sources */, + 067799593B2F15037103C952D8E15BCA /* Frameworks */, + 35FF713FDC6FF4F02633772BC5868145 /* Resources */, ); buildRules = ( ); @@ -1715,12 +2079,12 @@ }; B490E7485944099E16C9CBD79119D1D4 /* IQKeyboardManagerSwift */ = { isa = PBXNativeTarget; - buildConfigurationList = 916A72CFE2BCEC103A4AB01E3590516C /* Build configuration list for PBXNativeTarget "IQKeyboardManagerSwift" */; + buildConfigurationList = 6EA57D0428E1F541FC55143B3FEA485B /* Build configuration list for PBXNativeTarget "IQKeyboardManagerSwift" */; buildPhases = ( - 4F6172E8C45AC2744C62C2E3F9AA7566 /* Headers */, - 0EBA6C97625662B642676FDF0AD80BBB /* Sources */, - 86543E133EC209AA0A53EECE72BFA079 /* Frameworks */, - 59FBC265DAADE4768C78540BEBE5E80E /* Resources */, + 85A932520BC40A75F3549F020972CC8B /* Headers */, + F15C2AB492606C7255BF91F14E154EC6 /* Sources */, + 65BFC75CE1541E38446FFDA8AFF0DBEC /* Frameworks */, + 7AB4C6E7F42074143BEB486E118CCE8A /* Resources */, ); buildRules = ( ); @@ -1743,7 +2107,7 @@ buildRules = ( ); dependencies = ( - 78F9049871B48C5DDC4BA73D9A69DE49 /* PBXTargetDependency */, + 55177A922D890E642E071AD651EDEFF7 /* PBXTargetDependency */, ); name = JXPagingView; productName = JXPagingView; @@ -1762,7 +2126,7 @@ buildRules = ( ); dependencies = ( - 9B7058B7313481C2F5227C748AEA1C73 /* PBXTargetDependency */, + E2C5174D78C8FF63A8DC3FA82C452A71 /* PBXTargetDependency */, ); name = Kingfisher; productName = Kingfisher; @@ -1781,7 +2145,7 @@ buildRules = ( ); dependencies = ( - B71E18F702CA58047CBE05BEB0FB8063 /* PBXTargetDependency */, + 71CDB0472307C23BD3CD63A4784F44F7 /* PBXTargetDependency */, ); name = JXSegmentedView; productName = JXSegmentedView; @@ -1800,7 +2164,7 @@ buildRules = ( ); dependencies = ( - C5D6DC1AA1F8E8E0EDC4C9B5B2C8C0A6 /* PBXTargetDependency */, + A79D5863A3A25E1BE2AA0034A360CBB2 /* PBXTargetDependency */, ); name = Alamofire; productName = Alamofire; @@ -1825,7 +2189,7 @@ en, ); mainGroup = CF1408CF629C7361332E53B88F7BD30C; - productRefGroup = 9EC42FE8BA9B8FA7438229F51F7FDEAB /* Products */; + productRefGroup = 19C29489FB998EB8E7E019A0A9BE7772 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( @@ -1838,8 +2202,11 @@ 52F43AC38D9FF80196C69FB03AEEFDDA /* JXSegmentedView-JXSegmentedView */, E8022D22FAA6690B5E1C379C1BCE1491 /* Kingfisher */, 9828BBC09E9FB1238624113D7456E59E /* Kingfisher-Kingfisher */, + 6868056D761E163D10FDAF8CF1C4D9B8 /* MJRefresh */, + B26054DF1DEA11585A231AF6D1D80D5E /* MJRefresh-MJRefresh.Privacy */, 686C644F1E3D20750B0EA86F7A8674B7 /* Pods-MusicPlayer */, 19622742EBA51E823D6DAE3F8CDBFAD4 /* SnapKit */, + 8A8DB685241263AFDF5E6B20FE67B93A /* SnapKit-SnapKit_Privacy */, 1C8D67D8B72D6BA42CCEDB648537A340 /* SVProgressHUD */, 6038CE6006EFBE9D905454CF01909C42 /* SwiftDate */, ); @@ -1847,6 +2214,14 @@ /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 038AC83ADCB3D90F02617AEF82ED6BE7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0FBCA5C01FA487754C6D0B1690FC9CDA /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 0BAF278E95DCCDFBCB49933C4F5A6284 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -1863,6 +2238,38 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 1FEFD1E5FA9185094B0AB02E6E69124A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2C1014EEE6B2404C98A9F7AA534B534C /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 35FF713FDC6FF4F02633772BC5868145 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AC46B7DF5115A19C887EDDC9C226B66E /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3AB3D3CDA12081B8903F0D5A9C1887FB /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AD3CE903FA2BEE3EFA153E7FA7C9610E /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3F7DFD623D64A5455DA0E9B055E44974 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 02298A4639A27A1808AA3188B7A566E9 /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 42606EB786EF0846751B55D95E3F3AC1 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -1871,26 +2278,12 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 48F8F1ACC95C235B95096A6D45316F93 /* Resources */ = { + 49DD1B1DA762309F6890441BBA43F2C8 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 81202C96DE677B10C9F8F8CE7E8F483E /* PrivacyInfo.xcprivacy in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4F56E6E64C701CA47C99CCC911468DC4 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 59FBC265DAADE4768C78540BEBE5E80E /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 419464E3F898FD98316E39355FF35B0C /* PrivacyInfo.xcprivacy in Resources */, + 3035E05E0216ED11647680F9C2127B01 /* MJRefresh.bundle in Resources */, + 60CE1AC69D95F0F7C6637C601A84C069 /* MJRefresh-MJRefresh.Privacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1902,6 +2295,21 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 621AAFBBAEDCEC01847BF59E99E1F36D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7AB4C6E7F42074143BEB486E118CCE8A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A50A72FCD270217D99ECA1D2700CFAD4 /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 7D08E1D5F67A5709A06B4D00BE75A131 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -1910,91 +2318,34 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 820C67429A90336F5AF1C850DF03B1B9 /* Resources */ = { + 8AFC96B9D49AC279B3790C99847FF1B3 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + D091D9EA20CEB92609BF1E622E8CA348 /* SnapKit-SnapKit_Privacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 90B553EFDC0BE8866CF847B5B2549611 /* Resources */ = { + AC47CEB36BE3DE7A7A5DB7547DA55F3D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - E7E74B56BBD14101D9D391410FCAD323 /* PrivacyInfo.xcprivacy in Resources */, + 92A81311D8592CB3D907E9DA59023E38 /* PrivacyInfo.xcprivacy in Resources */, + C9D65759B4F36BDD6F29F0D4EA18AEFF /* SVProgressHUD.bundle in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 94A6273DEBA952CDF6133B47B51FE451 /* Resources */ = { + D52D9F52394C31B5EDC6D9A7475D483A /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - E27BD12C9CBA52D3E501FB2AE769B135 /* PrivacyInfo.xcprivacy in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A4CCC3CC21F770E272C54B18DDDE6DA3 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 943B0A1B436BAF4D419574466EF70FB3 /* SVProgressHUD.bundle in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - BC290758B47BE8C396CF7669E1A0A398 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 28212776FD42960CDE96CE78D98F5A43 /* PrivacyInfo.xcprivacy in Resources */, + 34DE07309F7BF7F614A480667602D079 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 0EBA6C97625662B642676FDF0AD80BBB /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 34966E12C60EA5E3295F91618492D76C /* IQBarButtonItem.swift in Sources */, - CBC1AE6750CA581BF0EBB5857C119552 /* IQInvocation.swift in Sources */, - E34DBE5BF2885EB48F3F0B8E6FE703AB /* IQKeyboardManager.swift in Sources */, - 9D5654F75F726E0B176684741CA9A1C6 /* IQKeyboardManager+Debug.swift in Sources */, - 52CA20D0D7072BA85F22361EAD5C41F6 /* IQKeyboardManager+Internal.swift in Sources */, - 2F1EF2B296BBE6BB2B25C16FE4454444 /* IQKeyboardManager+OrientationNotification.swift in Sources */, - 76F871A99E11BE8B63BF2FB2A30068A7 /* IQKeyboardManager+Position.swift in Sources */, - 2887D1CB726611AE4AF5918318B36712 /* IQKeyboardManager+Toolbar.swift in Sources */, - 893B6A268524ABD700BE29D240AD0458 /* IQKeyboardManager+UIKeyboardNotification.swift in Sources */, - 3DFF965F16137F3DA3AA3835B328EFB4 /* IQKeyboardManager+UITextFieldViewNotification.swift in Sources */, - B5E3B2C7AE25969552E18A5083E73D08 /* IQKeyboardManagerConstants.swift in Sources */, - 29378021941FBC3A89E5EC565110180C /* IQKeyboardManagerConstantsInternal.swift in Sources */, - 146999B1FCD6D467CC69DB8F6B0A4E79 /* IQKeyboardManagerSwift-dummy.m in Sources */, - 32E0490E336AF2371589D77723F8AA69 /* IQKeyboardReturnKeyHandler.swift in Sources */, - 70DA8965F2816B1992A48342A90953BE /* IQNSArray+Sort.swift in Sources */, - 51E5E4EC9A8AF80C7BEAF1BBED48FCF3 /* IQPreviousNextView.swift in Sources */, - AA9BF7A395D928D03794FCF7063056DB /* IQTextView.swift in Sources */, - 98A6234F16C6C27B7618386B842E6D64 /* IQTitleBarButtonItem.swift in Sources */, - F4E0886D3A9B4FC44D50099AD867A839 /* IQToolbar.swift in Sources */, - C28B9E7727B5131A76E454A52F32FFC2 /* IQUIScrollView+Additions.swift in Sources */, - 4653D1D4B40D19F203638552FC8CE1BB /* IQUITextFieldView+Additions.swift in Sources */, - 92592305D7EDCC7D117E563F9CB09B4A /* IQUIView+Hierarchy.swift in Sources */, - 62B187638CAD57515889A98D90ED3860 /* IQUIView+IQKeyboardToolbar.swift in Sources */, - 7A9A6B9B17AACD040A4A99E5DE07B428 /* IQUIViewController+Additions.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 108B36464ADE4902E2E2C83461767402 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 52BCC3B2F8AE7F59556925DEC603C634 /* SVIndefiniteAnimatedView.m in Sources */, - 1F4A13FD6675FCFCD9C19DF350348899 /* SVProgressAnimatedView.m in Sources */, - 89DF2D9C5EFB02A72EC0CE2138B77F35 /* SVProgressHUD.m in Sources */, - FFD43D91BF1FA4ADF714D56E7A10B2A8 /* SVProgressHUD-dummy.m in Sources */, - 1D325CFE11FE13A075C835E922BE1017 /* SVRadialGradientLayer.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 18CAFAC1E7DFA6B85E4A461A1071AE7C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2039,6 +2390,28 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 341A979A7B6136565AD1967B52C3A2E9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3B6553FDFA7B234E555016891227351E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 64B7C1BD8191B0963F3897F64977A7AA /* Pods-MusicPlayer-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4084A20021837E681EFB708E0F608493 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5146C05A7DF5B5E54B7AE49C979FF34A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2091,48 +2464,24 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 7B7E69B2799BABEB7764F85296B591B7 /* Sources */ = { + 6B53EDF320432C6FB2F2576B2E116CC6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 975EC584D1C4839C3ED556A694D283BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 986963C7968E6A40070C6340AF987110 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6EAC8B6FA2D115DE708A58C601DD25E1 /* Constraint.swift in Sources */, - 0B994CDC79B1AD3A7BE62490D27C60C8 /* ConstraintAttributes.swift in Sources */, - 3660B4F629053ABC3C1DF69366770289 /* ConstraintConfig.swift in Sources */, - 9C9548E8B4675954566202F7B87FF0E6 /* ConstraintConstantTarget.swift in Sources */, - 5380454C48A12A6E376122ABD8096968 /* ConstraintDescription.swift in Sources */, - E98DC8FB2578E76A812E0C94BA10E1B1 /* ConstraintDirectionalInsets.swift in Sources */, - 04637C70546B34F93C3A1D79C3F78B37 /* ConstraintDirectionalInsetTarget.swift in Sources */, - 56AC6DC6459AE47E7BC4AF06E5B148D2 /* ConstraintDSL.swift in Sources */, - 604D3C93C17978C23600EC415949AB64 /* ConstraintInsets.swift in Sources */, - 9E02CFFEFE1BEC978B512286F03D31DA /* ConstraintInsetTarget.swift in Sources */, - 69DE75BA185BBAB5FDAA28321F3C849F /* ConstraintItem.swift in Sources */, - 611CEF7FF1EF9EA1BCEF6C73EEE3ACCF /* ConstraintLayoutGuide.swift in Sources */, - 6AC1B881BB319C89AD023A02CDC8FC3D /* ConstraintLayoutGuide+Extensions.swift in Sources */, - EF21586EC3DFF6097A58EEC87376A0C1 /* ConstraintLayoutGuideDSL.swift in Sources */, - 00A2749F46C967ED4725A32357E3FB1B /* ConstraintLayoutSupport.swift in Sources */, - 56A72F6D13D930C4A2568F24DEA33C8D /* ConstraintLayoutSupportDSL.swift in Sources */, - FAB03959C2357E325B19E08BC4775DAB /* ConstraintMaker.swift in Sources */, - 220D6AC9B1B1EC8EFFB204F9C1EAC842 /* ConstraintMakerEditable.swift in Sources */, - A5A8BF973BFE9C9304372A26C9F2E35B /* ConstraintMakerExtendable.swift in Sources */, - 42B6ACFCF650183030867CB3EF345E95 /* ConstraintMakerFinalizable.swift in Sources */, - B43017FEC99D227D4CDD81DD2C27D9D9 /* ConstraintMakerPrioritizable.swift in Sources */, - 183D8B3E057B885EA7DF9A8CDCCE9029 /* ConstraintMakerRelatable.swift in Sources */, - 95E194A3AABB5407231E898B6686F73E /* ConstraintMakerRelatable+Extensions.swift in Sources */, - F7C0960CEEB8F0C18F4503B405EAC08F /* ConstraintMultiplierTarget.swift in Sources */, - A03FDA8BC5741880B1EF11AFD248EF48 /* ConstraintOffsetTarget.swift in Sources */, - 06E43B4751069B47B3BD4AFD936A57E3 /* ConstraintPriority.swift in Sources */, - 4DA72FD7F1FB2C0449EDEF4B8A579807 /* ConstraintPriorityTarget.swift in Sources */, - 55E51F45F1E157D3B4942BA7252C277E /* ConstraintRelatableTarget.swift in Sources */, - 4BAD99B7394E225CEDBF94B8100BCC7F /* ConstraintRelation.swift in Sources */, - B752F7C4BECB65894B1F49421049CE5F /* ConstraintView.swift in Sources */, - F953AA9104BFE0C2DAD639EA60104A75 /* ConstraintView+Extensions.swift in Sources */, - 256558233B40ACA6818F143BBC5B8017 /* ConstraintViewDSL.swift in Sources */, - 5D36B99F3CAB1FC7337082D9581FECA6 /* Debugging.swift in Sources */, - 0591132B5EA1BE4DDA268D8A9C3D0421 /* LayoutConstraint.swift in Sources */, - 98F570DA48370453D648BD526FDAAEAA /* LayoutConstraintItem.swift in Sources */, - BD47CB74CD9B2B4D2D942C9B65748DFB /* SnapKit-dummy.m in Sources */, - B03B5579590D528CBA6D11FF638BC2AF /* Typealiases.swift in Sources */, - 38B9D58E94D9C1CECD7E381C64A2329D /* UILayoutSupport+Extensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2149,25 +2498,92 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - A08C69BB9CAA0997BFECC7F6967AC6DE /* Sources */ = { + AAB3338BD40E4E170628192E4D18FE79 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9A07F0B734748735A80119550AC32104 /* SVIndefiniteAnimatedView.m in Sources */, + 279E3C4211663A097FFE575249B19BC3 /* SVProgressAnimatedView.m in Sources */, + ACDFC76B3486D1E62FD11EFAA88678ED /* SVProgressHUD.m in Sources */, + E06C5FBFE7D88C3630BA1FD51F7AF1E7 /* SVProgressHUD-dummy.m in Sources */, + D6D4AB4590700B3706919889BF614D26 /* SVRadialGradientLayer.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - ADBFA9B333C3AA957ED875509E56DB73 /* Sources */ = { + AF7DE4F344610DD30C852DC81D03A879 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + B962ED35C37063794B7D8468FB007AD5 /* MJRefresh-dummy.m in Sources */, + D6A1AB77D9F4C84779521FAF5E469343 /* MJRefreshAutoFooter.m in Sources */, + F00E48AB2D923607D9B91DC61DBDEB8F /* MJRefreshAutoGifFooter.m in Sources */, + D4C21761CC592857F35B99ACDD62ADAB /* MJRefreshAutoNormalFooter.m in Sources */, + 346855A32221981DE16BBB5C1E636BA4 /* MJRefreshAutoStateFooter.m in Sources */, + 4F80144C5D33EFDAC14379838CF9720E /* MJRefreshBackFooter.m in Sources */, + E702D99CA55B52C306544C4DDF9083DA /* MJRefreshBackGifFooter.m in Sources */, + F2E9C9068E8434E9FC9B60755A354FA8 /* MJRefreshBackNormalFooter.m in Sources */, + 081815B67871C182C0D337274DEDCE69 /* MJRefreshBackStateFooter.m in Sources */, + 74BF3CC58474F118E0E3953ADBBD233F /* MJRefreshComponent.m in Sources */, + CE453C62D0DA474AEE306AF3DF6DDAF1 /* MJRefreshConfig.m in Sources */, + EB126B698D642942058D9B676EC1E32B /* MJRefreshConst.m in Sources */, + D191F3F5F0841B63F1F54A430608830E /* MJRefreshFooter.m in Sources */, + 23B1B9EA25E2C943FCE5EC6D4EE19D6A /* MJRefreshGifHeader.m in Sources */, + 18B137C1708A9B9DC45BBB1ECF1CE4A8 /* MJRefreshHeader.m in Sources */, + 2927AE446998C11370D49E4A2CFD17AC /* MJRefreshNormalHeader.m in Sources */, + 45131830DC22C22B4A21C4A54A147947 /* MJRefreshNormalTrailer.m in Sources */, + 30DBC87A501715FE2328B9FF011F1BB9 /* MJRefreshStateHeader.m in Sources */, + B99F90601D5EED64587743374BBC44F6 /* MJRefreshStateTrailer.m in Sources */, + B9A56C1C079CE609AD4404964A95A170 /* MJRefreshTrailer.m in Sources */, + 514A19E702520E6E336D77E2615D17CF /* NSBundle+MJRefresh.m in Sources */, + 1A39B80A5083C84CF22A0D9FBB27761E /* UICollectionViewLayout+MJRefresh.m in Sources */, + FC745954D9A2704BCACCB3A03336976E /* UIScrollView+MJExtension.m in Sources */, + 244119912087C6ECC078CB0E740833EB /* UIScrollView+MJRefresh.m in Sources */, + E55E592D62CAE3D0B2960146E3D15CC6 /* UIView+MJExtension.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - B0D1A5C6EF59B24ABB2D270C6F67928D /* Sources */ = { + B52EB97EAADC4B42F512DF593D183539 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E521F6DAB5E30920772B66F0C67C7028 /* Pods-MusicPlayer-dummy.m in Sources */, + B133BB9C9B03481C7F1D221F35A617F2 /* Constraint.swift in Sources */, + 9779D52AD8CDA703D6EEE1C6D38E019F /* ConstraintAttributes.swift in Sources */, + E94B31DCAF75D93405D3BAE188604EB2 /* ConstraintConfig.swift in Sources */, + B3F75D115D5150C258F5E68404751010 /* ConstraintConstantTarget.swift in Sources */, + A051999781E1280746F7743BDEEA6C49 /* ConstraintDescription.swift in Sources */, + BE355F69F84788D334FDAC7D1CD9B8C4 /* ConstraintDirectionalInsets.swift in Sources */, + B4F9C9EC1B3F1689AE56BB719AE5439C /* ConstraintDirectionalInsetTarget.swift in Sources */, + F366D04DEA0EBBCA9CA4F1F4E29695E8 /* ConstraintDSL.swift in Sources */, + A0371DF7D93D9B86BD50474D4B9294FD /* ConstraintInsets.swift in Sources */, + 7052944C657F270E47777446D0E10E1C /* ConstraintInsetTarget.swift in Sources */, + 906EF891E58A035281766993F82373E3 /* ConstraintItem.swift in Sources */, + 0A5C290276F7453D9471E25BEA655842 /* ConstraintLayoutGuide.swift in Sources */, + 938CFF5F6DE6E7E8CE94373E51F3E07A /* ConstraintLayoutGuide+Extensions.swift in Sources */, + 0DA9A9D2F8960818017E26DA480FA143 /* ConstraintLayoutGuideDSL.swift in Sources */, + 13CC0CFB1C56F23BBC872801F983C1A3 /* ConstraintLayoutSupport.swift in Sources */, + D92AEF78B87F929D88D5C876ABBAD79A /* ConstraintLayoutSupportDSL.swift in Sources */, + 8640829049AE9907FE93825E5510C33D /* ConstraintMaker.swift in Sources */, + 0AD7A0DA8FF5880E3D8599062129AB12 /* ConstraintMakerEditable.swift in Sources */, + 6431218578A566C5EBF5FD166F164059 /* ConstraintMakerExtendable.swift in Sources */, + BF567AEFDD52DC43AC75122734D571E2 /* ConstraintMakerFinalizable.swift in Sources */, + 87996D11DC92EE19EAF9305DAEA4ACF2 /* ConstraintMakerPrioritizable.swift in Sources */, + 950B809760A8CE4375DCE1016FB9859F /* ConstraintMakerRelatable.swift in Sources */, + 15F68E09ADCDB843B938C490059485BD /* ConstraintMakerRelatable+Extensions.swift in Sources */, + 50E4E24710A4C5A77BE6594A10DFE773 /* ConstraintMultiplierTarget.swift in Sources */, + 56CD198002D3D45274F6719725B983CF /* ConstraintOffsetTarget.swift in Sources */, + EFC90283F9AB43BB6FF377812BD3673F /* ConstraintPriority.swift in Sources */, + 77D782DE125D322922466676E2FFA289 /* ConstraintPriorityTarget.swift in Sources */, + FFD7E1B8FA0F3960BE24DA2D20647332 /* ConstraintRelatableTarget.swift in Sources */, + F94703ED86C58DDBE5A2503D148CD040 /* ConstraintRelation.swift in Sources */, + 8868BA37E3CE7C58D26123806D543F3F /* ConstraintView.swift in Sources */, + C04DBE6AE13FC5CFD01D363A351EF76A /* ConstraintView+Extensions.swift in Sources */, + 0D665B6767B345D8C70D7E029A2A48D8 /* ConstraintViewDSL.swift in Sources */, + 1E7E37C51375285EA22294CD2ADB3159 /* Debugging.swift in Sources */, + 6E2884B29CD49EE91C48C725105F295A /* LayoutConstraint.swift in Sources */, + A35877DE0C3D6B4CF2A10E666EF5F490 /* LayoutConstraintItem.swift in Sources */, + 3DAFEDCDC5094007E329D71FE84FF704 /* SnapKit-dummy.m in Sources */, + 73F8AC99A58E5837924C056E89543B97 /* Typealiases.swift in Sources */, + 891D1BF14C8881C74262EE9DBE5D67A9 /* UILayoutSupport+Extensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2241,14 +2657,7 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - C037E1C181318450ABEBFA4C08492B19 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - C12BA93052B82ED1329E8A66293C722A /* Sources */ = { + D73A00FA16CD75A875D6F6617EE144D2 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -2305,122 +2714,139 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F15C2AB492606C7255BF91F14E154EC6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B0CB5FB63262E1A67317045B8960F363 /* IQBarButtonItem.swift in Sources */, + A8DD3F39B4D1F0C7B11866484A03336E /* IQInvocation.swift in Sources */, + 16E5F9C7FE2C499D21F3E7AF1FFC2FA7 /* IQKeyboardManager.swift in Sources */, + 1B4B180E84924CF99663817A2AFFAA92 /* IQKeyboardManager+Debug.swift in Sources */, + 6735E4B11C64D20B4E05A92811F5A721 /* IQKeyboardManager+Internal.swift in Sources */, + 9C292E2C761CB97ACD00F95FA4D60E85 /* IQKeyboardManager+OrientationNotification.swift in Sources */, + 7E59ABF8A1AC8F61FEFB9B8C72EFB9E5 /* IQKeyboardManager+Position.swift in Sources */, + BDAD667B60A9D9981738646851C825A0 /* IQKeyboardManager+Toolbar.swift in Sources */, + 9C2584A9CCF8CA6C9DF2AD79DB831E70 /* IQKeyboardManager+UIKeyboardNotification.swift in Sources */, + 9E4E278A3C1543798E1912699886023E /* IQKeyboardManager+UITextFieldViewNotification.swift in Sources */, + 41A536E6CE1C85116A756B710B2C660B /* IQKeyboardManagerConstants.swift in Sources */, + ECAA15FA3C4560E3287F2226EC8C1ECF /* IQKeyboardManagerConstantsInternal.swift in Sources */, + 930B495B7A3197730A016E2339A4CBA7 /* IQKeyboardManagerSwift-dummy.m in Sources */, + 506C1EE2968687F178BB2DFA34D185CE /* IQKeyboardReturnKeyHandler.swift in Sources */, + AB651DB3A97A623234B6544AD030406A /* IQNSArray+Sort.swift in Sources */, + F47587932A67D8E3820DAFD9A0E1995E /* IQPlaceholderable.swift in Sources */, + 07F83DE63FB5CC8015F48F7B9B800B6F /* IQPreviousNextView.swift in Sources */, + D0DF994786BCEC54939BC8216B42FBC4 /* IQTextView.swift in Sources */, + 373502D50A1B2266D86409E19EC46DDB /* IQTitleBarButtonItem.swift in Sources */, + 07FD274BC01F578C7B37989F79350C1E /* IQToolbar.swift in Sources */, + AAC2529A1B4F4832A052B348C5093018 /* IQUIScrollView+Additions.swift in Sources */, + BE60EC19FCBB8F301081E9C31BB85F3E /* IQUITextFieldView+Additions.swift in Sources */, + 5E8E9469BF126E918EADF79EC4BB5CA2 /* IQUIView+Hierarchy.swift in Sources */, + 19C5CA44D4D4D5B711D33A73525D453F /* IQUIView+IQKeyboardToolbar.swift in Sources */, + B46A36CA19ED6C09341D8E4031F66D5C /* IQUIViewController+Additions.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 0EC94FB8AE13C675012996E6E63D99FD /* PBXTargetDependency */ = { + 142AAB4FA977C078DA09CA68CD9F7AB0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = Alamofire; - target = EAAA1AD3A8A1B59AB91319EE40752C6D /* Alamofire */; - targetProxy = 86E184579D2A3A2E9E152CB03CD170CA /* PBXContainerItemProxy */; + name = MJRefresh; + target = 6868056D761E163D10FDAF8CF1C4D9B8 /* MJRefresh */; + targetProxy = 201623F455C6F19F61031B03545147D2 /* PBXContainerItemProxy */; }; - 509168942D78B85F99112CE2B315E87F /* PBXTargetDependency */ = { + 2C7D2C5A1F7AA8FA62801CB4684E0232 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = JXPagingView; - target = C4E1020AF425614337737213AA26DBD5 /* JXPagingView */; - targetProxy = 4B054C05A7B4D35DAC66F62602DBBBA8 /* PBXContainerItemProxy */; + name = "SnapKit-SnapKit_Privacy"; + target = 8A8DB685241263AFDF5E6B20FE67B93A /* SnapKit-SnapKit_Privacy */; + targetProxy = 4679EE8967F1A89961ECB2793E44547B /* PBXContainerItemProxy */; }; - 78F9049871B48C5DDC4BA73D9A69DE49 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = "JXPagingView-JXPagingView"; - target = B2B2AD5303610D8EBEA025B2660C8EC5 /* JXPagingView-JXPagingView */; - targetProxy = 3BFEE7E797791F14CB73632777FC7E0A /* PBXContainerItemProxy */; - }; - 7FD7BD432EEA0F0E66B3D4AE62CF4D32 /* PBXTargetDependency */ = { + 3AE06D852AB2AA0F21550B5A31B4B2A8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = SVProgressHUD; target = 1C8D67D8B72D6BA42CCEDB648537A340 /* SVProgressHUD */; - targetProxy = FFFD2037F7EB41815943CEB089778B47 /* PBXContainerItemProxy */; + targetProxy = 142BCA0E13C05E1A83FB4666F22A1552 /* PBXContainerItemProxy */; }; - 9B7058B7313481C2F5227C748AEA1C73 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = "Kingfisher-Kingfisher"; - target = 9828BBC09E9FB1238624113D7456E59E /* Kingfisher-Kingfisher */; - targetProxy = 8E906C346976DD165C3801A68B69CA36 /* PBXContainerItemProxy */; - }; - A00146B8DA477F7292F9CB3AA37012A7 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = SwiftDate; - target = 6038CE6006EFBE9D905454CF01909C42 /* SwiftDate */; - targetProxy = E5CF03012635B743F552559DE12FB67B /* PBXContainerItemProxy */; - }; - AAD1F6695A6519FD93658C8143599690 /* PBXTargetDependency */ = { + 4A583CB19C34725D587B75745C4FBB1F /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = JXSegmentedView; target = E863A9A96F52A35F47491E7B41ECEF9A /* JXSegmentedView */; - targetProxy = 14CFBBAAE542CF39A18203BDB5B9BFF8 /* PBXContainerItemProxy */; + targetProxy = 2D57819E56EE60F3DF2C6E678E7D3569 /* PBXContainerItemProxy */; }; - B71E18F702CA58047CBE05BEB0FB8063 /* PBXTargetDependency */ = { + 55177A922D890E642E071AD651EDEFF7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "JXPagingView-JXPagingView"; + target = B2B2AD5303610D8EBEA025B2660C8EC5 /* JXPagingView-JXPagingView */; + targetProxy = 2C2690B3E48F2A7DAC7365AE33F00B17 /* PBXContainerItemProxy */; + }; + 71CDB0472307C23BD3CD63A4784F44F7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "JXSegmentedView-JXSegmentedView"; target = 52F43AC38D9FF80196C69FB03AEEFDDA /* JXSegmentedView-JXSegmentedView */; - targetProxy = 9E0BC0EAEF34022CBA17D9D2C31CA096 /* PBXContainerItemProxy */; + targetProxy = 44996704F085A77FFFD3669AD2AD3058 /* PBXContainerItemProxy */; }; - B7F65E9E76CCD98F97C7BC8F16758F72 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = Kingfisher; - target = E8022D22FAA6690B5E1C379C1BCE1491 /* Kingfisher */; - targetProxy = D286B63CF5B76BA9E11E563F7C46E005 /* PBXContainerItemProxy */; - }; - C5D6DC1AA1F8E8E0EDC4C9B5B2C8C0A6 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = "Alamofire-Alamofire"; - target = 976126A1CE06DC6E162563800E1BDF14 /* Alamofire-Alamofire */; - targetProxy = 641D58C69E949A855265B8A2A3DF416D /* PBXContainerItemProxy */; - }; - E45EF95C462C681ED0E6B2B2CD6E6288 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = SnapKit; - target = 19622742EBA51E823D6DAE3F8CDBFAD4 /* SnapKit */; - targetProxy = 337E73A4312787E508FB5683B01CA08C /* PBXContainerItemProxy */; - }; - EFD9C2E055CF05F8BE5E8CA9B7A678DE /* PBXTargetDependency */ = { + 9C4DCABEE4C8DE1C8C7F5F136424389A /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = IQKeyboardManagerSwift; target = B490E7485944099E16C9CBD79119D1D4 /* IQKeyboardManagerSwift */; - targetProxy = FC6F7551C370BC1C321567C80999546D /* PBXContainerItemProxy */; + targetProxy = 2799C4D2D7768534EDE92F178DE24D47 /* PBXContainerItemProxy */; + }; + 9F42538473D8CD84E2B00227CCC5270F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Alamofire; + target = EAAA1AD3A8A1B59AB91319EE40752C6D /* Alamofire */; + targetProxy = 30FFF29F3A02744304E52EE68F953BF3 /* PBXContainerItemProxy */; + }; + A419D3F35FFC28E3C110DC1E9BDD907A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = JXPagingView; + target = C4E1020AF425614337737213AA26DBD5 /* JXPagingView */; + targetProxy = 668AF990E71B0FD610A0100A739B125C /* PBXContainerItemProxy */; + }; + A79D5863A3A25E1BE2AA0034A360CBB2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Alamofire-Alamofire"; + target = 976126A1CE06DC6E162563800E1BDF14 /* Alamofire-Alamofire */; + targetProxy = D80071531B55B03F9F25899249DEDFC3 /* PBXContainerItemProxy */; + }; + AF753EA8E0B40A33C32A44CAA21E6E1B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Kingfisher; + target = E8022D22FAA6690B5E1C379C1BCE1491 /* Kingfisher */; + targetProxy = E34EB63D4E4B105244F3DA6DA3F80E0D /* PBXContainerItemProxy */; + }; + B5571C9BD8ACED22B2133870B863C3F5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SnapKit; + target = 19622742EBA51E823D6DAE3F8CDBFAD4 /* SnapKit */; + targetProxy = 7912D6332CD6248A05C5E894EA0DE591 /* PBXContainerItemProxy */; + }; + B58C9ED1F196D76949A6ED62612F50C4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftDate; + target = 6038CE6006EFBE9D905454CF01909C42 /* SwiftDate */; + targetProxy = A7BFC44123CBC428C300871C2A5C0B39 /* PBXContainerItemProxy */; + }; + E2C5174D78C8FF63A8DC3FA82C452A71 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Kingfisher-Kingfisher"; + target = 9828BBC09E9FB1238624113D7456E59E /* Kingfisher-Kingfisher */; + targetProxy = 0A0E1A8C5689F0474D3549298F7E19CB /* PBXContainerItemProxy */; + }; + FC0B50042A431604CEA4CD7FE470B9E2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "MJRefresh-MJRefresh.Privacy"; + target = B26054DF1DEA11585A231AF6D1D80D5E /* MJRefresh-MJRefresh.Privacy */; + targetProxy = 04009532C9602DFA4571AF336AFB7C5C /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 03697A88AAAD0F7EBAF9C2D799F74513 /* Release */ = { + 083EEC7FA1F0E9764FD5954A7D3E35AA /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 890F8EEE5DAE16274422CC38E258B8D1 /* Kingfisher.release.xcconfig */; - buildSettings = { - CODE_SIGNING_ALLOWED = NO; - CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Kingfisher"; - IBSC_MODULE = Kingfisher; - INFOPLIST_FILE = "Target Support Files/Kingfisher/ResourceBundle-Kingfisher-Kingfisher-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - PRODUCT_NAME = Kingfisher; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - WRAPPER_EXTENSION = bundle; - }; - name = Release; - }; - 0920231774AC91203B27946C4633A043 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = C434D6410430E92943DEAD104FCC27BE /* JXSegmentedView.debug.xcconfig */; - buildSettings = { - CODE_SIGNING_ALLOWED = NO; - CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/JXSegmentedView"; - IBSC_MODULE = JXSegmentedView; - INFOPLIST_FILE = "Target Support Files/JXSegmentedView/ResourceBundle-JXSegmentedView-JXSegmentedView-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - PRODUCT_NAME = JXSegmentedView; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - WRAPPER_EXTENSION = bundle; - }; - name = Debug; - }; - 121DC7F0CEBD6AB7043275AB037C6E83 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 947DA5BA2E9A379BFEC2E827244B0CE0 /* IQKeyboardManagerSwift.debug.xcconfig */; + baseConfigurationReference = E623870FC6E557F7D90E41BF1892B184 /* Pods-MusicPlayer.debug.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -2430,31 +2856,49 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-Info.plist"; + INFOPLIST_FILE = "Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MODULEMAP_FILE = "Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.modulemap"; - PRODUCT_MODULE_NAME = IQKeyboardManagerSwift; - PRODUCT_NAME = IQKeyboardManagerSwift; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.9; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; + 14A34A929E243AD045487F198E80C530 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5EBCD15895605FBBBCD96B9C8E928D3B /* Alamofire.debug.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Alamofire"; + IBSC_MODULE = Alamofire; + INFOPLIST_FILE = "Target Support Files/Alamofire/ResourceBundle-Alamofire-Alamofire-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + PRODUCT_NAME = Alamofire; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; 1AAF3B5EE94AF573BC39D3167C5DF211 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7DAC46988C621826DE9C8B685C307E5B /* SwiftDate.release.xcconfig */; + baseConfigurationReference = AA2205F6575D1182446627195A2B2D7D /* SwiftDate.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -2487,6 +2931,61 @@ }; name = Release; }; + 250A2303614C24E78E54410625196FE7 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F0F27AFF60F54ECC48396ECBB22D94EC /* Pods-MusicPlayer.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 266511746DBC33197FD9CF409AAE2718 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D473476568C2D2300CCBAE8BAC883DCE /* JXPagingView.release.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/JXPagingView"; + IBSC_MODULE = JXPagingView; + INFOPLIST_FILE = "Target Support Files/JXPagingView/ResourceBundle-JXPagingView-JXPagingView-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + PRODUCT_NAME = JXPagingView; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; 2B9E26EAE2CD392AD762421F663075A1 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2553,47 +3052,28 @@ }; name = Debug; }; - 315273B3E6A9C750F940C5E326D7929D /* Debug */ = { + 2F988DCED078E24B8A93349A767C9757 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = E623870FC6E557F7D90E41BF1892B184 /* Pods-MusicPlayer.debug.xcconfig */; + baseConfigurationReference = E18618FEAC0ECEE393834FA4EEDDD337 /* Kingfisher.release.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Kingfisher"; + IBSC_MODULE = Kingfisher; + INFOPLIST_FILE = "Target Support Files/Kingfisher/ResourceBundle-Kingfisher-Kingfisher-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = Kingfisher; SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; + WRAPPER_EXTENSION = bundle; }; - name = Debug; + name = Release; }; - 3A9EA29ED6921878E3F25F2AEACA9FB3 /* Debug */ = { + 563564487BD399E6F70C91C5FDCCBDA8 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3F7D2073948007C3D9C254DB4DFBBAB8 /* SVProgressHUD.debug.xcconfig */; + baseConfigurationReference = 6B82834CA67E7FF1B8610BF181E51004 /* SVProgressHUD.release.xcconfig */; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -2605,7 +3085,7 @@ GCC_PREFIX_HEADER = "Target Support Files/SVProgressHUD/SVProgressHUD-prefix.pch"; INFOPLIST_FILE = "Target Support Files/SVProgressHUD/SVProgressHUD-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -2619,76 +3099,22 @@ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 3DA337228B1298116506ED00626FCDAF /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = B942DFB5FFD9E8DA9A4C3E8B8FC26306 /* Alamofire.release.xcconfig */; - buildSettings = { - CODE_SIGNING_ALLOWED = NO; - CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Alamofire"; - IBSC_MODULE = Alamofire; - INFOPLIST_FILE = "Target Support Files/Alamofire/ResourceBundle-Alamofire-Alamofire-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - PRODUCT_NAME = Alamofire; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - WRAPPER_EXTENSION = bundle; - }; - name = Release; - }; - 3F6441B1D8AB43A784FD3692706BAB1F /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = F0F27AFF60F54ECC48396ECBB22D94EC /* Pods-MusicPlayer.release.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; - 5D28DEA1E11052B091CDDD664EF00686 /* Debug */ = { + 5C17DF439E18B7DF01FF5E6083AF4D67 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B88842C93039689D079B0F4AA14852C6 /* Kingfisher.debug.xcconfig */; + baseConfigurationReference = 3AE4A701F7BAB983ED11B504E6487F76 /* MJRefresh.debug.xcconfig */; buildSettings = { CODE_SIGNING_ALLOWED = NO; - CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Kingfisher"; - IBSC_MODULE = Kingfisher; - INFOPLIST_FILE = "Target Support Files/Kingfisher/ResourceBundle-Kingfisher-Kingfisher-Info.plist"; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/MJRefresh"; + IBSC_MODULE = MJRefresh; + INFOPLIST_FILE = "Target Support Files/MJRefresh/ResourceBundle-MJRefresh.Privacy-MJRefresh-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - PRODUCT_NAME = Kingfisher; + PRODUCT_NAME = MJRefresh.Privacy; SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; @@ -2698,7 +3124,7 @@ }; 5EA01C8F2E402725AC281C80AB12CDC0 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B88842C93039689D079B0F4AA14852C6 /* Kingfisher.debug.xcconfig */; + baseConfigurationReference = DF2C075BA691343B5759F4F639FA08A6 /* Kingfisher.debug.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -2731,6 +3157,23 @@ }; name = Debug; }; + 6181874010C287EFEE382F18DBCA7E59 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9DB02FC7AC88AE54321E64548CBFD1FF /* SnapKit.release.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/SnapKit"; + IBSC_MODULE = SnapKit; + INFOPLIST_FILE = "Target Support Files/SnapKit/ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = SnapKit_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; 63FAF33E1C55B71A5F5A8B3CC8749F99 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2795,7 +3238,7 @@ }; 714A038955EDD712335B7293B4D7DAB3 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 37B75E2E8CD6D8FBCEEA2C814BD288E2 /* Alamofire.debug.xcconfig */; + baseConfigurationReference = 5EBCD15895605FBBBCD96B9C8E928D3B /* Alamofire.debug.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -2830,7 +3273,7 @@ }; 796A20FEF97A102A877A06F7C64B8D4B /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = C434D6410430E92943DEAD104FCC27BE /* JXSegmentedView.debug.xcconfig */; + baseConfigurationReference = 0DB2B3B9A91393821FCD01D47CB39B40 /* JXSegmentedView.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -2862,9 +3305,131 @@ }; name = Debug; }; - 8B474089F929285602B0C4FDDBF5F4A6 /* Release */ = { + 91A90B0A1A76F626BFDB353BF2D519BA /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D378275D09B96773C488D7591063EC86 /* IQKeyboardManagerSwift.release.xcconfig */; + baseConfigurationReference = 7BD8D5C9444C4C58CF152CD4CC8DB0A3 /* Alamofire.release.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Alamofire"; + IBSC_MODULE = Alamofire; + INFOPLIST_FILE = "Target Support Files/Alamofire/ResourceBundle-Alamofire-Alamofire-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + PRODUCT_NAME = Alamofire; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 930F34F38147A861C25AB4A6F37A415B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0DB2B3B9A91393821FCD01D47CB39B40 /* JXSegmentedView.debug.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/JXSegmentedView"; + IBSC_MODULE = JXSegmentedView; + INFOPLIST_FILE = "Target Support Files/JXSegmentedView/ResourceBundle-JXSegmentedView-JXSegmentedView-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + PRODUCT_NAME = JXSegmentedView; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 965E63B0D5A8B44B1B484E0859EBAE62 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 451FEDBFD2A922230CA33D46534CD7F7 /* JXSegmentedView.release.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/JXSegmentedView"; + IBSC_MODULE = JXSegmentedView; + INFOPLIST_FILE = "Target Support Files/JXSegmentedView/ResourceBundle-JXSegmentedView-JXSegmentedView-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + PRODUCT_NAME = JXSegmentedView; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 984240AE6A3D535525200348828211E3 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9DB02FC7AC88AE54321E64548CBFD1FF /* SnapKit.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SnapKit/SnapKit-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SnapKit/SnapKit-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SnapKit/SnapKit.modulemap"; + PRODUCT_MODULE_NAME = SnapKit; + PRODUCT_NAME = SnapKit; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 9C0B415A54C1C30F674208B8ADAB6C17 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BC90E0F634A75E57580CB83CB0B039E4 /* SnapKit.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SnapKit/SnapKit-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SnapKit/SnapKit-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SnapKit/SnapKit.modulemap"; + PRODUCT_MODULE_NAME = SnapKit; + PRODUCT_NAME = SnapKit; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + A6260E74821A6D83D56C6FD7B057B34D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A3841A0A7F5A5EABE2100147A429E0C6 /* IQKeyboardManagerSwift.debug.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -2892,78 +3457,6 @@ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 5.9; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 8C925430B65BE03F92ABCD1B2005EE0C /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3BB776688BCCFEAA2C9D7ADDE83D4CA3 /* SnapKit.release.xcconfig */; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/SnapKit/SnapKit-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/SnapKit/SnapKit-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MODULEMAP_FILE = "Target Support Files/SnapKit/SnapKit.modulemap"; - PRODUCT_MODULE_NAME = SnapKit; - PRODUCT_NAME = SnapKit; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - A6F0173BAEB974532D93E05E5A94E50A /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = F8765B4E3D1104165E5D1E435F4945D9 /* SnapKit.debug.xcconfig */; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/SnapKit/SnapKit-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/SnapKit/SnapKit-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MODULEMAP_FILE = "Target Support Files/SnapKit/SnapKit.modulemap"; - PRODUCT_MODULE_NAME = SnapKit; - PRODUCT_NAME = SnapKit; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -2971,7 +3464,7 @@ }; A7D05D839D2CE193DCEADAAF8897CD53 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 53AD73B43463C9D32A0BF66D80A09BFB /* JXSegmentedView.release.xcconfig */; + baseConfigurationReference = 451FEDBFD2A922230CA33D46534CD7F7 /* JXSegmentedView.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -3004,9 +3497,26 @@ }; name = Release; }; - B6F2BF778734EA1466F3600DA77605B1 /* Release */ = { + B08D3C8F5A68D8459A91B94E9FBB57AB /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A7767A0D4F0D3EBD1C8E13F6F05FB25B /* JXPagingView.release.xcconfig */; + baseConfigurationReference = DF2C075BA691343B5759F4F639FA08A6 /* Kingfisher.debug.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Kingfisher"; + IBSC_MODULE = Kingfisher; + INFOPLIST_FILE = "Target Support Files/Kingfisher/ResourceBundle-Kingfisher-Kingfisher-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = Kingfisher; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + B22BD24E361F59ABEF30513214AB91C0 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3EF5F786A9CD8F2E78E95733362FE187 /* JXPagingView.debug.xcconfig */; buildSettings = { CODE_SIGNING_ALLOWED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/JXPagingView"; @@ -3019,11 +3529,98 @@ TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = bundle; }; - name = Release; + name = Debug; + }; + B2B495D503BC782A9468D7FD0FB1800E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BC90E0F634A75E57580CB83CB0B039E4 /* SnapKit.debug.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/SnapKit"; + IBSC_MODULE = SnapKit; + INFOPLIST_FILE = "Target Support Files/SnapKit/ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = SnapKit_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + B31CF9907306152728F440F1F94804FD /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3AE4A701F7BAB983ED11B504E6487F76 /* MJRefresh.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/MJRefresh/MJRefresh-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/MJRefresh/MJRefresh-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/MJRefresh/MJRefresh.modulemap"; + PRODUCT_MODULE_NAME = MJRefresh; + PRODUCT_NAME = MJRefresh; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + C107A00E8915CBCD07039B1CDC63628E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B06108CF75D8C3024C894159C039AF1C /* SVProgressHUD.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SVProgressHUD/SVProgressHUD-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SVProgressHUD/SVProgressHUD-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SVProgressHUD/SVProgressHUD.modulemap"; + PRODUCT_MODULE_NAME = SVProgressHUD; + PRODUCT_NAME = SVProgressHUD; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; }; C37261D9FB6D4AFE04B143C9910CD592 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 237F6B26512B98501CC693A53DCB92AB /* SwiftDate.debug.xcconfig */; + baseConfigurationReference = BE0D9928CC4ABC217232D13CC2A41C53 /* SwiftDate.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -3057,7 +3654,7 @@ }; CA60CF70D0AF64CB6C7F697460FBE2FE /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B942DFB5FFD9E8DA9A4C3E8B8FC26306 /* Alamofire.release.xcconfig */; + baseConfigurationReference = 7BD8D5C9444C4C58CF152CD4CC8DB0A3 /* Alamofire.release.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -3093,7 +3690,7 @@ }; D289924F49E290957622EAA7EBE53538 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 890F8EEE5DAE16274422CC38E258B8D1 /* Kingfisher.release.xcconfig */; + baseConfigurationReference = E18618FEAC0ECEE393834FA4EEDDD337 /* Kingfisher.release.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -3127,9 +3724,45 @@ }; name = Release; }; + D71AFD6535C82AF9CF91933A9687B877 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AC5E8113942F4B6D5C87580AA549D92C /* MJRefresh.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/MJRefresh/MJRefresh-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/MJRefresh/MJRefresh-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/MJRefresh/MJRefresh.modulemap"; + PRODUCT_MODULE_NAME = MJRefresh; + PRODUCT_NAME = MJRefresh; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; E0D85AC35AE1FCCF988F5CD7503DDB0F /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A7767A0D4F0D3EBD1C8E13F6F05FB25B /* JXPagingView.release.xcconfig */; + baseConfigurationReference = D473476568C2D2300CCBAE8BAC883DCE /* JXPagingView.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -3162,95 +3795,9 @@ }; name = Release; }; - E6C136F42805813E8E3463DCC92AFA7A /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 999C15F4A94DD7E4875ED8928BAE4925 /* JXPagingView.debug.xcconfig */; - buildSettings = { - CODE_SIGNING_ALLOWED = NO; - CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/JXPagingView"; - IBSC_MODULE = JXPagingView; - INFOPLIST_FILE = "Target Support Files/JXPagingView/ResourceBundle-JXPagingView-JXPagingView-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - PRODUCT_NAME = JXPagingView; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - WRAPPER_EXTENSION = bundle; - }; - name = Debug; - }; - E7118F2863FB6D2611D4E8C691656A72 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 53AD73B43463C9D32A0BF66D80A09BFB /* JXSegmentedView.release.xcconfig */; - buildSettings = { - CODE_SIGNING_ALLOWED = NO; - CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/JXSegmentedView"; - IBSC_MODULE = JXSegmentedView; - INFOPLIST_FILE = "Target Support Files/JXSegmentedView/ResourceBundle-JXSegmentedView-JXSegmentedView-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - PRODUCT_NAME = JXSegmentedView; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - WRAPPER_EXTENSION = bundle; - }; - name = Release; - }; - E7C4E72588BA38523B53DEC049091E02 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 2C39947ECE9F9309B3ED71BEFD21C4BC /* SVProgressHUD.release.xcconfig */; - buildSettings = { - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/SVProgressHUD/SVProgressHUD-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/SVProgressHUD/SVProgressHUD-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MODULEMAP_FILE = "Target Support Files/SVProgressHUD/SVProgressHUD.modulemap"; - PRODUCT_MODULE_NAME = SVProgressHUD; - PRODUCT_NAME = SVProgressHUD; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - EDD5BABE4FAE46D890DCA96AAFCE599B /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 37B75E2E8CD6D8FBCEEA2C814BD288E2 /* Alamofire.debug.xcconfig */; - buildSettings = { - CODE_SIGNING_ALLOWED = NO; - CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Alamofire"; - IBSC_MODULE = Alamofire; - INFOPLIST_FILE = "Target Support Files/Alamofire/ResourceBundle-Alamofire-Alamofire-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - PRODUCT_NAME = Alamofire; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - WRAPPER_EXTENSION = bundle; - }; - name = Debug; - }; F0C13041D6C39FC95F94A7215BB92DF1 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 999C15F4A94DD7E4875ED8928BAE4925 /* JXPagingView.debug.xcconfig */; + baseConfigurationReference = 3EF5F786A9CD8F2E78E95733362FE187 /* JXPagingView.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -3282,9 +3829,89 @@ }; name = Debug; }; + FB818BDDADBD0A197A07D52CF5BB68F5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AB089815F261E66CDE44D5F4DE72EE32 /* IQKeyboardManagerSwift.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.modulemap"; + PRODUCT_MODULE_NAME = IQKeyboardManagerSwift; + PRODUCT_NAME = IQKeyboardManagerSwift; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.9; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + FE83682BF7CD2CFBBEFCEB21D24471E9 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AC5E8113942F4B6D5C87580AA549D92C /* MJRefresh.release.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/MJRefresh"; + IBSC_MODULE = MJRefresh; + INFOPLIST_FILE = "Target Support Files/MJRefresh/ResourceBundle-MJRefresh.Privacy-MJRefresh-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = MJRefresh.Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 387D22F9EF0A1068C65E4F1499A5D232 /* Build configuration list for PBXNativeTarget "Kingfisher-Kingfisher" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B08D3C8F5A68D8459A91B94E9FBB57AB /* Debug */, + 2F988DCED078E24B8A93349A767C9757 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 38A9DB1BF7DB582FA154E6E85B017967 /* Build configuration list for PBXNativeTarget "Pods-MusicPlayer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 083EEC7FA1F0E9764FD5954A7D3E35AA /* Debug */, + 250A2303614C24E78E54410625196FE7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3B02596C7FAA57EB3E61033F4406577A /* Build configuration list for PBXNativeTarget "SVProgressHUD" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C107A00E8915CBCD07039B1CDC63628E /* Debug */, + 563564487BD399E6F70C91C5FDCCBDA8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -3294,11 +3921,20 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 50A1F214909B860ED2A9D86E88C2BCA3 /* Build configuration list for PBXNativeTarget "Alamofire-Alamofire" */ = { + 4ABFC85AD568923D7A67A236848CF419 /* Build configuration list for PBXNativeTarget "Alamofire-Alamofire" */ = { isa = XCConfigurationList; buildConfigurations = ( - EDD5BABE4FAE46D890DCA96AAFCE599B /* Debug */, - 3DA337228B1298116506ED00626FCDAF /* Release */, + 14A34A929E243AD045487F198E80C530 /* Debug */, + 91A90B0A1A76F626BFDB353BF2D519BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4C4F25F04C086237315FCAEF7661357E /* Build configuration list for PBXNativeTarget "SnapKit" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9C0B415A54C1C30F674208B8ADAB6C17 /* Debug */, + 984240AE6A3D535525200348828211E3 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -3312,38 +3948,20 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 58EAA7FF29EA237538F747F2AF468203 /* Build configuration list for PBXNativeTarget "SnapKit" */ = { + 6EA57D0428E1F541FC55143B3FEA485B /* Build configuration list for PBXNativeTarget "IQKeyboardManagerSwift" */ = { isa = XCConfigurationList; buildConfigurations = ( - A6F0173BAEB974532D93E05E5A94E50A /* Debug */, - 8C925430B65BE03F92ABCD1B2005EE0C /* Release */, + A6260E74821A6D83D56C6FD7B057B34D /* Debug */, + FB818BDDADBD0A197A07D52CF5BB68F5 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 5C022666992472C94648DC5B812648E6 /* Build configuration list for PBXNativeTarget "Kingfisher-Kingfisher" */ = { + 8192D6E7F891C6FB05E5D01514EABBE2 /* Build configuration list for PBXNativeTarget "JXSegmentedView-JXSegmentedView" */ = { isa = XCConfigurationList; buildConfigurations = ( - 5D28DEA1E11052B091CDDD664EF00686 /* Debug */, - 03697A88AAAD0F7EBAF9C2D799F74513 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5E847D67D7BF704D94E27B4299623A5D /* Build configuration list for PBXNativeTarget "JXSegmentedView-JXSegmentedView" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 0920231774AC91203B27946C4633A043 /* Debug */, - E7118F2863FB6D2611D4E8C691656A72 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 807FEF9D9629A72728B6B83F5CA12C85 /* Build configuration list for PBXNativeTarget "SVProgressHUD" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3A9EA29ED6921878E3F25F2AEACA9FB3 /* Debug */, - E7C4E72588BA38523B53DEC049091E02 /* Release */, + 930F34F38147A861C25AB4A6F37A415B /* Debug */, + 965E63B0D5A8B44B1B484E0859EBAE62 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -3357,29 +3975,20 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 916A72CFE2BCEC103A4AB01E3590516C /* Build configuration list for PBXNativeTarget "IQKeyboardManagerSwift" */ = { + 9B1967783C7584ADA7A063159ED92F0B /* Build configuration list for PBXNativeTarget "SnapKit-SnapKit_Privacy" */ = { isa = XCConfigurationList; buildConfigurations = ( - 121DC7F0CEBD6AB7043275AB037C6E83 /* Debug */, - 8B474089F929285602B0C4FDDBF5F4A6 /* Release */, + B2B495D503BC782A9468D7FD0FB1800E /* Debug */, + 6181874010C287EFEE382F18DBCA7E59 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - BA1379311C9032331BB3F700DB0A5D13 /* Build configuration list for PBXNativeTarget "Pods-MusicPlayer" */ = { + B84B7C31B677C791E25D754795F22921 /* Build configuration list for PBXNativeTarget "MJRefresh-MJRefresh.Privacy" */ = { isa = XCConfigurationList; buildConfigurations = ( - 315273B3E6A9C750F940C5E326D7929D /* Debug */, - 3F6441B1D8AB43A784FD3692706BAB1F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - CCB3E4A930ED7224F6C38A8D8820BAAA /* Build configuration list for PBXNativeTarget "JXPagingView-JXPagingView" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - E6C136F42805813E8E3463DCC92AFA7A /* Debug */, - B6F2BF778734EA1466F3600DA77605B1 /* Release */, + 5C17DF439E18B7DF01FF5E6083AF4D67 /* Debug */, + FE83682BF7CD2CFBBEFCEB21D24471E9 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -3402,6 +4011,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + F09A4CBED64F267E853B71023517C77A /* Build configuration list for PBXNativeTarget "MJRefresh" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B31CF9907306152728F440F1F94804FD /* Debug */, + D71AFD6535C82AF9CF91933A9687B877 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F1FFFC5DAB1EC2D84580B2C5AD779F80 /* Build configuration list for PBXNativeTarget "JXPagingView-JXPagingView" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B22BD24E361F59ABEF30513214AB91C0 /* Debug */, + 266511746DBC33197FD9CF409AAE2718 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; FA92BF783257A026FB1E05B4B536DD6E /* Build configuration list for PBXNativeTarget "Alamofire" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Pods/SVProgressHUD/LICENSE b/Pods/SVProgressHUD/LICENSE index f8c911b..081a2f7 100644 --- a/Pods/SVProgressHUD/LICENSE +++ b/Pods/SVProgressHUD/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2011-2018 Sam Vermette, Tobias Tiemerding and contributors. +Copyright (c) 2011-2023 Sam Vermette, Tobias Totzek and contributors. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Pods/SVProgressHUD/README.md b/Pods/SVProgressHUD/README.md index a9ce9e0..602aefe 100644 --- a/Pods/SVProgressHUD/README.md +++ b/Pods/SVProgressHUD/README.md @@ -3,19 +3,29 @@ ![Pod Version](https://img.shields.io/cocoapods/v/SVProgressHUD.svg?style=flat) ![Pod Platform](https://img.shields.io/cocoapods/p/SVProgressHUD.svg?style=flat) ![Pod License](https://img.shields.io/cocoapods/l/SVProgressHUD.svg?style=flat) -[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-green.svg?style=flat)](https://github.com/Carthage/Carthage) +[![SwiftPM compatible](https://img.shields.io/badge/SwiftPM-compatible-brightgreen.svg)](https://swift.org/package-manager/) [![CocoaPods compatible](https://img.shields.io/badge/CocoaPods-compatible-green.svg?style=flat)](https://cocoapods.org) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-green.svg?style=flat)](https://github.com/Carthage/Carthage) `SVProgressHUD` is a clean and easy-to-use HUD meant to display the progress of an ongoing task on iOS and tvOS. -![SVProgressHUD](http://f.cl.ly/items/2G1F1Z0M0k0h2U3V1p39/SVProgressHUD.gif) - -## Demo - -Try `SVProgressHUD` on [Appetize.io](https://appetize.io/app/p8r2cvy8kq74x7q7tjqf5gyatr). +![SVProgressHUD](https://raw.githubusercontent.com/SVProgressHUD/SVProgressHUD/master/Images/SVProgressHUD.png) ## Installation +### Swift Package Manager + +[Swift Package Manager](https://swift.org/package-manager/) (SwiftPM) is a tool for managing the distribution of Swift code. It simplifies the process of managing Swift package dependencies. + +To integrate `SVProgressHUD` into your project using SwiftPM: + +1. In Xcode, select **File > Add Package Dependency**. +2. Enter the following package repository URL: https://github.com/SVProgressHUD/SVProgressHUD.git +3. Choose the appropriate version (e.g. a specific version, branch, or commit). +4. Add `SVProgressHUD` to your target dependencies. + +`SVProgressHUD` requires at least Swift tools version 5.3. + ### From CocoaPods [CocoaPods](http://cocoapods.org) is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like `SVProgressHUD` in your projects. First, add the following line to your [Podfile](http://guides.cocoapods.org/using/using-cocoapods.html): @@ -56,7 +66,9 @@ Run `carthage bootstrap` to build the framework in your repository's Carthage di ## Swift -Even though `SVProgressHUD` is written in Objective-C, it can be used in Swift with no hassle. If you use [CocoaPods](http://cocoapods.org) add the following line to your [Podfile](http://guides.cocoapods.org/using/using-cocoapods.html): +Even though `SVProgressHUD` is written in Objective-C, it can be used in Swift with no hassle. + +If you use [CocoaPods](http://cocoapods.org) add the following line to your [Podfile](http://guides.cocoapods.org/using/using-cocoapods.html): ```ruby use_frameworks! @@ -68,11 +80,13 @@ If you added `SVProgressHUD` manually, just add a [bridging header](https://deve (see sample Xcode project in `/Demo`) -`SVProgressHUD` is created as a singleton (i.e. it doesn't need to be explicitly allocated and instantiated; you directly call `[SVProgressHUD method]`). +`SVProgressHUD` is created as a singleton (i.e. it doesn't need to be explicitly allocated and instantiated; you directly call `[SVProgressHUD method]` / `SVProgressHUD.method()`). **Use `SVProgressHUD` wisely! Only use it if you absolutely need to perform a task before taking the user forward. Bad use case examples: pull to refresh, infinite scrolling, sending message.** -Using `SVProgressHUD` in your app will usually look as simple as this (using Grand Central Dispatch): +Using `SVProgressHUD` in your app will usually look as simple as this. + +**Objective-C:** ```objective-c [SVProgressHUD show]; @@ -84,6 +98,18 @@ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ }); ``` +**Swift:** + +```swift +SVProgressHUD.show() +DispatchQueue.global(qos: .default).async { + // time-consuming task + DispatchQueue.main.async { + SVProgressHUD.dismiss() + } +} +``` + ### Showing the HUD You can show the status of indeterminate tasks using one of the following: @@ -115,9 +141,9 @@ If you'd like to stack HUDs, you can balance out every show call using: + (void)popActivity; ``` -The HUD will get dismissed once the popActivity calls will match the number of show calls. +The HUD will get dismissed once the `popActivity` calls will match the number of show calls. -Or show a confirmation glyph before before getting dismissed a little bit later. The display time depends on `minimumDismissTimeInterval` and the length of the given string. +Or show an image with status before getting dismissed a little bit later. The display time depends on `minimumDismissTimeInterval` and the length of the given string. ```objective-c + (void)showInfoWithStatus:(NSString*)string; @@ -128,53 +154,27 @@ Or show a confirmation glyph before before getting dismissed a little bit later. ## Customization -`SVProgressHUD` can be customized via the following methods: +`SVProgressHUD` is designed with flexibility in mind, providing a myriad of customization options to fit the look and feel of your application seamlessly. -```objective-c -+ (void)setDefaultStyle:(SVProgressHUDStyle)style; // default is SVProgressHUDStyleLight -+ (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType; // default is SVProgressHUDMaskTypeNone -+ (void)setDefaultAnimationType:(SVProgressHUDAnimationType)type; // default is SVProgressHUDAnimationTypeFlat -+ (void)setContainerView:(UIView*)containerView; // default is window level -+ (void)setMinimumSize:(CGSize)minimumSize; // default is CGSizeZero, can be used to avoid resizing -+ (void)setRingThickness:(CGFloat)width; // default is 2 pt -+ (void)setRingRadius:(CGFloat)radius; // default is 18 pt -+ (void)setRingNoTextRadius:(CGFloat)radius; // default is 24 pt -+ (void)setCornerRadius:(CGFloat)cornerRadius; // default is 14 pt -+ (void)setBorderColor:(nonnull UIColor*)color; // default is nil -+ (void)setBorderWidth:(CGFloat)width; // default is 0 -+ (void)setFont:(UIFont*)font; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] -+ (void)setForegroundColor:(UIColor*)color; // default is [UIColor blackColor], only used for SVProgressHUDStyleCustom -+ (void)setBackgroundColor:(UIColor*)color; // default is [UIColor whiteColor], only used for SVProgressHUDStyleCustom -+ (void)setBackgroundLayerColor:(UIColor*)color; // default is [UIColor colorWithWhite:0 alpha:0.4], only used for SVProgressHUDMaskTypeCustom -+ (void)setImageViewSize:(CGSize)size; // default is 28x28 pt -+ (void)setShouldTintImages:(BOOL)shouldTintImages; // default is YES -+ (void)setInfoImage:(UIImage*)image; // default is the bundled info image provided by Freepik -+ (void)setSuccessImage:(UIImage*)image; // default is bundled success image from Freepik -+ (void)setErrorImage:(UIImage*)image; // default is bundled error image from Freepik -+ (void)setViewForExtension:(UIView*)view; // default is nil, only used if #define SV_APP_EXTENSIONS is set -+ (void)setGraceTimeInterval:(NSTimeInterval)interval; // default is 0 seconds -+ (void)setMinimumDismissTimeInterval:(NSTimeInterval)interval; // default is 5.0 seconds -+ (void)setMaximumDismissTimeInterval:(NSTimeInterval)interval; // default is CGFLOAT_MAX -+ (void)setFadeInAnimationDuration:(NSTimeInterval)duration; // default is 0.15 seconds -+ (void)setFadeOutAnimationDuration:(NSTimeInterval)duration; // default is 0.15 seconds -+ (void)setMaxSupportedWindowLevel:(UIWindowLevel)windowLevel; // default is UIWindowLevelNormal -+ (void)setHapticsEnabled:(BOOL)hapticsEnabled; // default is NO -``` +* Appearance: Make use of the `UI_APPEARANCE_SELECTOR` to adjust styles, colors, fonts, size, and images app-wide. +* Behavior: Control visibility durations, display delays, and animation speeds. +* Feedback: Enhance the user experience with options for haptic feedback and motion effects. -Additionally `SVProgressHUD` supports the `UIAppearance` protocol for most of the above methods. +For a comprehensive list of properties and detailed explanations, refer to the `SVProgressHUD.h` file in the API documentation. ### Hint -As standard `SVProgressHUD` offers two preconfigured styles: +As standard `SVProgressHUD` offers three preconfigured styles: +* `SVProgressHUDStyleAutomatic`: Automatically switch between the light and dark style * `SVProgressHUDStyleLight`: White background with black spinner and text * `SVProgressHUDStyleDark`: Black background with white spinner and text -If you want to use custom colors use `setForegroundColor` and `setBackgroundColor:`. These implicitly set the HUD's style to `SVProgressHUDStyleCustom`. +If you want to use custom colors use `setForegroundColor:` and/or `setBackgroundColor:`. These implicitly set the HUD's style to `SVProgressHUDStyleCustom`. ## Haptic Feedback -For users with newer devices (starting with the iPhone 7), `SVProgressHUD` can automatically trigger haptic feedback depending on which HUD is being displayed. The feedback maps as follows: +Available on iPhone 7 and newer, `SVProgressHUD` can automatically trigger haptic feedback depending on which HUD is being displayed. The feedback maps as follows: * `showSuccessWithStatus:` <-> `UINotificationFeedbackTypeSuccess` * `showInfoWithStatus:` <-> `UINotificationFeedbackTypeWarning` @@ -182,11 +182,10 @@ For users with newer devices (starting with the iPhone 7), `SVProgressHUD` can a To enable this functionality, use `setHapticsEnabled:`. -Users with devices prior to iPhone 7 will have no change in functionality. - ## Notifications `SVProgressHUD` posts four notifications via `NSNotificationCenter` in response to being shown/dismissed: + * `SVProgressHUDWillAppearNotification` when the show animation starts * `SVProgressHUDDidAppearNotification` when the show animation completes * `SVProgressHUDWillDisappearNotification` when the dismiss animation starts @@ -194,11 +193,11 @@ Users with devices prior to iPhone 7 will have no change in functionality. Each notification passes a `userInfo` dictionary holding the HUD's status string (if any), retrievable via `SVProgressHUDStatusUserInfoKey`. -`SVProgressHUD` also posts `SVProgressHUDDidReceiveTouchEventNotification` when users touch on the overall screen or `SVProgressHUDDidTouchDownInsideNotification` when a user touches on the HUD directly. For this notifications `userInfo` is not passed but the object parameter contains the `UIEvent` that related to the touch. +`SVProgressHUD` also posts `SVProgressHUDDidReceiveTouchEventNotification` when users touch on the overall screen or `SVProgressHUDDidTouchDownInsideNotification` when a user touches on the HUD directly. For these notifications `userInfo` is not passed but the object parameter contains the `UIEvent` that related to the touch. ## App Extensions -When using `SVProgressHUD` in an App Extension, `#define SV_APP_EXTENSIONS` to avoid using unavailable APIs. Additionally call `setViewForExtension:` from your extensions view controller with `self.view`. +When using `SVProgressHUD` in an App Extension, `#define SV_APP_EXTENSIONS` to avoid using unavailable APIs. This will be done automatically when using the `AppExtension` CocoaPods subspec. Additionally, call `setViewForExtension:` from your extensions view controller with `self.view`. ## Contributing to this project @@ -211,8 +210,12 @@ review the guidelines written by [Nicolas Gallagher](https://github.com/necolas) ## License -`SVProgressHUD` is distributed under the terms and conditions of the [MIT license](https://github.com/SVProgressHUD/SVProgressHUD/blob/master/LICENSE.txt). The success, error and info icons are made by [Freepik](http://www.freepik.com) from [Flaticon](http://www.flaticon.com) and are licensed under [Creative Commons BY 3.0](http://creativecommons.org/licenses/by/3.0/). +`SVProgressHUD` is distributed under the terms and conditions of the [MIT license](https://github.com/SVProgressHUD/SVProgressHUD/blob/master/LICENSE). The success, error and info icons used on iOS 12 are made by [Freepik](http://www.freepik.com) from [Flaticon](https://www.flaticon.com) and are licensed under [Creative Commons BY 3.0](https://creativecommons.org/licenses/by/3.0/). + +## Privacy + +`SVProgressHUD` does not collect any data. A [privacy manifest file](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files) is [provided](SVProgressHUD/PrivacyInfo.xcprivacy). ## Credits -`SVProgressHUD` is brought to you by [Sam Vermette](http://samvermette.com), [Tobias Tiemerding](http://tiemerding.com) and [contributors to the project](https://github.com/SVProgressHUD/SVProgressHUD/contributors). If you're using `SVProgressHUD` in your project, attribution would be very appreciated. +`SVProgressHUD` is brought to you by Sam Vermette, [Tobias Totzek](https://totzek.me) and [contributors to the project](https://github.com/SVProgressHUD/SVProgressHUD/contributors). If you're using `SVProgressHUD` in your project, attribution would be very appreciated. diff --git a/Pods/SVProgressHUD/SVProgressHUD/PrivacyInfo.xcprivacy b/Pods/SVProgressHUD/SVProgressHUD/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..6af1641 --- /dev/null +++ b/Pods/SVProgressHUD/SVProgressHUD/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ + + + + + NSPrivacyTracking + + NSPrivacyCollectedDataTypes + + NSPrivacyTrackingDomains + + NSPrivacyAccessedAPITypes + + + diff --git a/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.h b/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.h index b624dd0..2e103c0 100644 --- a/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.h +++ b/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.h @@ -2,7 +2,7 @@ // SVIndefiniteAnimatedView.h // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD // -// Copyright (c) 2014-2018 Guillaume Campagna. All rights reserved. +// Copyright (c) 2014-2023 Guillaume Campagna and contributors. All rights reserved. // #import diff --git a/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.m b/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.m index 09a38d0..14cb1cc 100644 --- a/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.m +++ b/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.m @@ -2,7 +2,7 @@ // SVIndefiniteAnimatedView.m // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD // -// Copyright (c) 2014-2018 Guillaume Campagna. All rights reserved. +// Copyright (c) 2014-2023 Guillaume Campagna and contributors. All rights reserved. // #import "SVIndefiniteAnimatedView.h" @@ -25,9 +25,18 @@ } } +- (void)layoutSubviews { + [super layoutSubviews]; + + [self layoutAnimatedLayer]; +} + - (void)layoutAnimatedLayer { CALayer *layer = self.indefiniteAnimatedLayer; - [self.layer addSublayer:layer]; + + if (!layer.superlayer) { + [self.layer addSublayer:layer]; + } CGFloat widthDiff = CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds); CGFloat heightDiff = CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds); @@ -51,13 +60,9 @@ CALayer *maskLayer = [CALayer layer]; - NSBundle *bundle = [NSBundle bundleForClass:[SVProgressHUD class]]; - NSURL *url = [bundle URLForResource:@"SVProgressHUD" withExtension:@"bundle"]; - NSBundle *imageBundle = [NSBundle bundleWithURL:url]; + NSBundle *imageBundle = [SVProgressHUD imageBundle]; - NSString *path = [imageBundle pathForResource:@"angle-mask" ofType:@"png"]; - - maskLayer.contents = (__bridge id)[[UIImage imageWithContentsOfFile:path] CGImage]; + maskLayer.contents = (__bridge id)[[UIImage imageNamed:@"angle-mask.png" inBundle:imageBundle compatibleWithTraitCollection:nil] CGImage]; maskLayer.frame = _indefiniteAnimatedLayer.bounds; _indefiniteAnimatedLayer.mask = maskLayer; diff --git a/Pods/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.h b/Pods/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.h index 6de23b4..fe124e9 100644 --- a/Pods/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.h +++ b/Pods/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.h @@ -2,7 +2,7 @@ // SVProgressAnimatedView.h // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD // -// Copyright (c) 2017-2018 Tobias Tiemerding. All rights reserved. +// Copyright (c) 2017-2023 Tobias Totzek and contributors. All rights reserved. // #import diff --git a/Pods/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.m b/Pods/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.m index a347c85..a8932d1 100644 --- a/Pods/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.m +++ b/Pods/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.m @@ -2,7 +2,7 @@ // SVProgressAnimatedView.m // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD // -// Copyright (c) 2017-2018 Tobias Tiemerding. All rights reserved. +// Copyright (c) 2017-2023 Tobias Totzek and contributors. All rights reserved. // #import "SVProgressAnimatedView.h" diff --git a/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.h b/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.h index 6aa935c..1119761 100644 --- a/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.h +++ b/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.h @@ -2,7 +2,7 @@ // SVProgressHUD.h // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD // -// Copyright (c) 2011-2018 Sam Vermette and contributors. All rights reserved. +// Copyright (c) 2011-2023 Sam Vermette and contributors. All rights reserved. // #import @@ -17,23 +17,46 @@ extern NSString * _Nonnull const SVProgressHUDDidAppearNotification; extern NSString * _Nonnull const SVProgressHUDStatusUserInfoKey; +/// Represents the appearance style of the HUD. typedef NS_ENUM(NSInteger, SVProgressHUDStyle) { - SVProgressHUDStyleLight, // default style, white HUD with black text, HUD background will be blurred - SVProgressHUDStyleDark, // black HUD and white text, HUD background will be blurred - SVProgressHUDStyleCustom // uses the fore- and background color properties + /// White HUD with black text. HUD background will be blurred. + SVProgressHUDStyleLight NS_SWIFT_NAME(light), + + /// Black HUD with white text. HUD background will be blurred. + SVProgressHUDStyleDark NS_SWIFT_NAME(dark), + + /// Uses the fore- and background color properties. + SVProgressHUDStyleCustom NS_SWIFT_NAME(custom), + + /// Automatically switch between light or dark mode appearance. + SVProgressHUDStyleAutomatic NS_SWIFT_NAME(automatic) }; +/// Represents the type of mask to be applied when the HUD is displayed. typedef NS_ENUM(NSUInteger, SVProgressHUDMaskType) { - SVProgressHUDMaskTypeNone = 1, // default mask type, allow user interactions while HUD is displayed - SVProgressHUDMaskTypeClear, // don't allow user interactions with background objects - SVProgressHUDMaskTypeBlack, // don't allow user interactions with background objects and dim the UI in the back of the HUD (as seen in iOS 7 and above) - SVProgressHUDMaskTypeGradient, // don't allow user interactions with background objects and dim the UI with a a-la UIAlertView background gradient (as seen in iOS 6) - SVProgressHUDMaskTypeCustom // don't allow user interactions with background objects and dim the UI in the back of the HUD with a custom color + /// Allow user interactions while HUD is displayed. + SVProgressHUDMaskTypeNone NS_SWIFT_NAME(none) = 1, + + /// Don't allow user interactions with background objects. + SVProgressHUDMaskTypeClear NS_SWIFT_NAME(clear), + + /// Don't allow user interactions and dim the UI behind the HUD (as in iOS 7+). + SVProgressHUDMaskTypeBlack NS_SWIFT_NAME(black), + + /// Don't allow user interactions and dim the UI with an UIAlertView-like background gradient (as in iOS 6). + SVProgressHUDMaskTypeGradient NS_SWIFT_NAME(gradient), + + /// Don't allow user interactions and dim the UI behind the HUD with a custom color. + SVProgressHUDMaskTypeCustom NS_SWIFT_NAME(custom) }; +/// Represents the animation type of the HUD when it's shown or hidden. typedef NS_ENUM(NSUInteger, SVProgressHUDAnimationType) { - SVProgressHUDAnimationTypeFlat, // default animation type, custom flat animation (indefinite animated ring) - SVProgressHUDAnimationTypeNative // iOS native UIActivityIndicatorView + /// Custom flat animation (indefinite animated ring). + SVProgressHUDAnimationTypeFlat NS_SWIFT_NAME(flat), + + /// iOS native UIActivityIndicatorView. + SVProgressHUDAnimationTypeNative NS_SWIFT_NAME(native) }; typedef void (^SVProgressHUDShowCompletion)(void); @@ -43,104 +66,326 @@ typedef void (^SVProgressHUDDismissCompletion)(void); #pragma mark - Customization -@property (assign, nonatomic) SVProgressHUDStyle defaultStyle UI_APPEARANCE_SELECTOR; // default is SVProgressHUDStyleLight -@property (assign, nonatomic) SVProgressHUDMaskType defaultMaskType UI_APPEARANCE_SELECTOR; // default is SVProgressHUDMaskTypeNone -@property (assign, nonatomic) SVProgressHUDAnimationType defaultAnimationType UI_APPEARANCE_SELECTOR; // default is SVProgressHUDAnimationTypeFlat -@property (strong, nonatomic, nullable) UIView *containerView; // if nil then use default window level -@property (assign, nonatomic) CGSize minimumSize UI_APPEARANCE_SELECTOR; // default is CGSizeZero, can be used to avoid resizing for a larger message -@property (assign, nonatomic) CGFloat ringThickness UI_APPEARANCE_SELECTOR; // default is 2 pt -@property (assign, nonatomic) CGFloat ringRadius UI_APPEARANCE_SELECTOR; // default is 18 pt -@property (assign, nonatomic) CGFloat ringNoTextRadius UI_APPEARANCE_SELECTOR; // default is 24 pt -@property (assign, nonatomic) CGFloat cornerRadius UI_APPEARANCE_SELECTOR; // default is 14 pt -@property (strong, nonatomic, nonnull) UIFont *font UI_APPEARANCE_SELECTOR; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] -@property (strong, nonatomic, nonnull) UIColor *backgroundColor UI_APPEARANCE_SELECTOR; // default is [UIColor whiteColor] -@property (strong, nonatomic, nonnull) UIColor *foregroundColor UI_APPEARANCE_SELECTOR; // default is [UIColor blackColor] -@property (strong, nonatomic, nonnull) UIColor *backgroundLayerColor UI_APPEARANCE_SELECTOR;// default is [UIColor colorWithWhite:0 alpha:0.4] -@property (assign, nonatomic) CGSize imageViewSize UI_APPEARANCE_SELECTOR; // default is 28x28 pt -@property (assign, nonatomic) BOOL shouldTintImages UI_APPEARANCE_SELECTOR; // default is YES -@property (strong, nonatomic, nonnull) UIImage *infoImage UI_APPEARANCE_SELECTOR; // default is the bundled info image provided by Freepik -@property (strong, nonatomic, nonnull) UIImage *successImage UI_APPEARANCE_SELECTOR; // default is the bundled success image provided by Freepik -@property (strong, nonatomic, nonnull) UIImage *errorImage UI_APPEARANCE_SELECTOR; // default is the bundled error image provided by Freepik -@property (strong, nonatomic, nonnull) UIView *viewForExtension UI_APPEARANCE_SELECTOR; // default is nil, only used if #define SV_APP_EXTENSIONS is set -@property (assign, nonatomic) NSTimeInterval graceTimeInterval; // default is 0 seconds -@property (assign, nonatomic) NSTimeInterval minimumDismissTimeInterval; // default is 5.0 seconds -@property (assign, nonatomic) NSTimeInterval maximumDismissTimeInterval; // default is CGFLOAT_MAX +/// Represents the default style for the HUD. +/// @discussion Default: SVProgressHUDStyleAutomatic. +@property (assign, nonatomic) SVProgressHUDStyle defaultStyle UI_APPEARANCE_SELECTOR; -@property (assign, nonatomic) UIOffset offsetFromCenter UI_APPEARANCE_SELECTOR; // default is 0, 0 +/// Represents the type of mask applied when the HUD is displayed. +/// @discussion Default: SVProgressHUDMaskTypeNone. +@property (assign, nonatomic) SVProgressHUDMaskType defaultMaskType UI_APPEARANCE_SELECTOR; -@property (assign, nonatomic) NSTimeInterval fadeInAnimationDuration UI_APPEARANCE_SELECTOR; // default is 0.15 -@property (assign, nonatomic) NSTimeInterval fadeOutAnimationDuration UI_APPEARANCE_SELECTOR; // default is 0.15 +/// Defines the animation type used when the HUD is displayed. +/// @discussion Default: SVProgressHUDAnimationTypeFlat. +@property (assign, nonatomic) SVProgressHUDAnimationType defaultAnimationType UI_APPEARANCE_SELECTOR; -@property (assign, nonatomic) UIWindowLevel maxSupportedWindowLevel; // default is UIWindowLevelNormal +/// The container view used for displaying the HUD. If nil, the default window level is used. +@property (strong, nonatomic, nullable) UIView *containerView; -@property (assign, nonatomic) BOOL hapticsEnabled; // default is NO +/// The minimum size for the HUD. Useful for maintaining a consistent size when the message might cause resizing. +/// @discussion Default: CGSizeZero. +@property (assign, nonatomic) CGSize minimumSize UI_APPEARANCE_SELECTOR; + +/// Thickness of the ring shown in the HUD. +/// @discussion Default: 2 pt. +@property (assign, nonatomic) CGFloat ringThickness UI_APPEARANCE_SELECTOR; + +/// Radius of the ring shown in the HUD when there's associated text. +/// @discussion Default: 18 pt. +@property (assign, nonatomic) CGFloat ringRadius UI_APPEARANCE_SELECTOR; + +/// Radius of the ring shown in the HUD when there's no associated text. +/// @discussion Default: 24 pt. +@property (assign, nonatomic) CGFloat ringNoTextRadius UI_APPEARANCE_SELECTOR; + +/// Corner radius of the HUD view. +/// @discussion Default: 14 pt. +@property (assign, nonatomic) CGFloat cornerRadius UI_APPEARANCE_SELECTOR; + +/// Font used for text within the HUD. +/// @discussion Default: [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]. +@property (strong, nonatomic, nonnull) UIFont *font UI_APPEARANCE_SELECTOR; + +/// Background color of the HUD. +/// @discussion Default: [UIColor whiteColor]. +@property (strong, nonatomic, nonnull) UIColor *backgroundColor UI_APPEARANCE_SELECTOR; + +/// Foreground color used for content in the HUD. +/// @discussion Default: [UIColor blackColor]. +@property (strong, nonatomic, nonnull) UIColor *foregroundColor UI_APPEARANCE_SELECTOR; + +/// Color for any foreground images in the HUD. +/// @discussion Default: same as foregroundColor. +@property (strong, nonatomic, nullable) UIColor *foregroundImageColor UI_APPEARANCE_SELECTOR; + +/// Color for the background layer behind the HUD. +/// @discussion Default: [UIColor colorWithWhite:0 alpha:0.4]. +@property (strong, nonatomic, nonnull) UIColor *backgroundLayerColor UI_APPEARANCE_SELECTOR; + +/// Size of any images displayed within the HUD. +/// @discussion Default: 28x28 pt. +@property (assign, nonatomic) CGSize imageViewSize UI_APPEARANCE_SELECTOR; + +/// Indicates whether images within the HUD should be tinted. +/// @discussion Default: YES. +@property (assign, nonatomic) BOOL shouldTintImages UI_APPEARANCE_SELECTOR; + +/// The image displayed when showing informational messages. +/// @discussion Default: info.circle from SF Symbols (iOS 13+) or the bundled info image provided by Freepik. +@property (strong, nonatomic, nonnull) UIImage *infoImage UI_APPEARANCE_SELECTOR; + +/// The image displayed when showing success messages. +/// @discussion Default: checkmark from SF Symbols (iOS 13+) or the bundled success image provided by Freepik. +@property (strong, nonatomic, nonnull) UIImage *successImage UI_APPEARANCE_SELECTOR; + +/// The image displayed when showing error messages. +/// @discussion Default: xmark from SF Symbols (iOS 13+) or the bundled error image provided by Freepik. +@property (strong, nonatomic, nonnull) UIImage *errorImage UI_APPEARANCE_SELECTOR; + +/// A specific view for extensions. This property is only used if #define SV_APP_EXTENSIONS is set. +/// @discussion Default: nil. +@property (strong, nonatomic, nonnull) UIView *viewForExtension UI_APPEARANCE_SELECTOR; + +/// The interval in seconds to wait before displaying the HUD. If the HUD is displayed before this time elapses, this timer is reset. +/// @discussion Default: 0 seconds. +@property (assign, nonatomic) NSTimeInterval graceTimeInterval; + +/// The minimum amount of time in seconds the HUD will display. +/// @discussion Default: 5.0 seconds. +@property (assign, nonatomic) NSTimeInterval minimumDismissTimeInterval; + +/// The maximum amount of time in seconds the HUD will display. +/// @discussion Default: CGFLOAT_MAX. +@property (assign, nonatomic) NSTimeInterval maximumDismissTimeInterval; + +/// Offset from the center position, can be used to adjust the HUD position. +/// @discussion Default: 0, 0. +@property (assign, nonatomic) UIOffset offsetFromCenter UI_APPEARANCE_SELECTOR; + +/// Duration of the fade-in animation when showing the HUD. +/// @discussion Default: 0.15. +@property (assign, nonatomic) NSTimeInterval fadeInAnimationDuration UI_APPEARANCE_SELECTOR; + +/// Duration of the fade-out animation when hiding the HUD. +/// @discussion Default: 0.15. +@property (assign, nonatomic) NSTimeInterval fadeOutAnimationDuration UI_APPEARANCE_SELECTOR; + +/// The maximum window level on which the HUD can be displayed. +/// @discussion Default: UIWindowLevelNormal. +@property (assign, nonatomic) UIWindowLevel maxSupportedWindowLevel; + +/// Indicates if haptic feedback should be used. +/// @discussion Default: NO. +@property (assign, nonatomic) BOOL hapticsEnabled; + +/// Indicates if motion effects should be applied to the HUD. +/// @discussion Default: YES. +@property (assign, nonatomic) BOOL motionEffectEnabled; + +@property (class, strong, nonatomic, readonly, nonnull) NSBundle *imageBundle; + +/// Sets the default style for the HUD. +/// @param style The desired style for the HUD. ++ (void)setDefaultStyle:(SVProgressHUDStyle)style; + +/// Sets the default mask type for the HUD. +/// @param maskType The mask type to apply. ++ (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType; + +/// Sets the default animation type for the HUD. +/// @param type The desired animation type. ++ (void)setDefaultAnimationType:(SVProgressHUDAnimationType)type; + +/// Sets the container view for the HUD. +/// @param containerView The view to contain the HUD. ++ (void)setContainerView:(nullable UIView*)containerView; + +/// Sets the minimum size for the HUD. +/// @param minimumSize The minimum size for the HUD. ++ (void)setMinimumSize:(CGSize)minimumSize; + +/// Sets the ring thickness for the HUD. +/// @param ringThickness Thickness of the ring. ++ (void)setRingThickness:(CGFloat)ringThickness; + +/// Sets the ring radius for the HUD. +/// @param radius Radius of the ring. ++ (void)setRingRadius:(CGFloat)radius; + +/// Sets the no text ring radius for the HUD. +/// @param radius Radius of the ring when no text is displayed. ++ (void)setRingNoTextRadius:(CGFloat)radius; + +/// Sets the corner radius for the HUD. +/// @param cornerRadius Desired corner radius. ++ (void)setCornerRadius:(CGFloat)cornerRadius; + +/// Sets the border color for the HUD. +/// @param color Desired border color. ++ (void)setBorderColor:(nonnull UIColor*)color; + +/// Sets the border width for the HUD. +/// @param width Desired border width. ++ (void)setBorderWidth:(CGFloat)width; + +/// Sets the font for the HUD's text. +/// @param font Desired font for the text. ++ (void)setFont:(nonnull UIFont*)font; + +/// Sets the foreground color for the HUD. +/// @param color Desired foreground color. +/// @discussion These implicitly set the HUD's style to `SVProgressHUDStyleCustom`. ++ (void)setForegroundColor:(nonnull UIColor*)color; + +/// Sets the foreground image color for the HUD. +/// @param color Desired color for the image. +/// @discussion These implicitly set the HUD's style to `SVProgressHUDStyleCustom`. ++ (void)setForegroundImageColor:(nullable UIColor*)color; + +/// Sets the background color for the HUD. +/// @param color Desired background color. +/// @discussion These implicitly set the HUD's style to `SVProgressHUDStyleCustom`. ++ (void)setBackgroundColor:(nonnull UIColor*)color; + +/// Sets a custom blur effect for the HUD view. +/// @param blurEffect Desired blur effect. +/// @discussion These implicitly set the HUD's style to `SVProgressHUDStyleCustom`. ++ (void)setHudViewCustomBlurEffect:(nullable UIBlurEffect*)blurEffect; + +/// Sets the background layer color for the HUD. +/// @param color Desired color for the background layer. ++ (void)setBackgroundLayerColor:(nonnull UIColor*)color; + +/// Sets the size for the HUD's image view. +/// @param size Desired size for the image view. ++ (void)setImageViewSize:(CGSize)size; + +/// Determines if images should be tinted in the HUD. +/// @param shouldTintImages Whether images should be tinted. ++ (void)setShouldTintImages:(BOOL)shouldTintImages; + +/// Sets the info image for the HUD. +/// @param image The desired info image. ++ (void)setInfoImage:(nonnull UIImage*)image; + +/// Sets the success image for the HUD. +/// @param image The desired success image. ++ (void)setSuccessImage:(nonnull UIImage*)image; + +/// Sets the error image for the HUD. +/// @param image The desired error image. ++ (void)setErrorImage:(nonnull UIImage*)image; + +/// Sets the view for extensions. +/// @param view The desired view for extensions. ++ (void)setViewForExtension:(nonnull UIView*)view; + +/// Sets the grace time interval for the HUD. +/// @param interval Desired grace time interval. ++ (void)setGraceTimeInterval:(NSTimeInterval)interval; + +/// Sets the minimum dismiss time interval. +/// @param interval The minimum time interval, in seconds, that the HUD should be displayed. ++ (void)setMinimumDismissTimeInterval:(NSTimeInterval)interval; + +/// Sets the maximum dismiss time interval. +/// @param interval The maximum time interval, in seconds, that the HUD should be displayed. ++ (void)setMaximumDismissTimeInterval:(NSTimeInterval)interval; + +/// Sets the fade-in animation duration. +/// @param duration The duration, in seconds, for the fade-in animation. ++ (void)setFadeInAnimationDuration:(NSTimeInterval)duration; + +/// Sets the fade-out animation duration. +/// @param duration The duration, in seconds, for the fade-out animation. ++ (void)setFadeOutAnimationDuration:(NSTimeInterval)duration; + +/// Sets the max supported window level. +/// @param windowLevel The UIWindowLevel to which the HUD should be displayed. ++ (void)setMaxSupportedWindowLevel:(UIWindowLevel)windowLevel; + +/// Determines if haptics are enabled. +/// @param hapticsEnabled A boolean that determines if haptic feedback is enabled. ++ (void)setHapticsEnabled:(BOOL)hapticsEnabled; + +/// Determines if motion effect is enabled. +/// @param motionEffectEnabled A boolean that determines if motion effects are enabled. ++ (void)setMotionEffectEnabled:(BOOL)motionEffectEnabled; -+ (void)setDefaultStyle:(SVProgressHUDStyle)style; // default is SVProgressHUDStyleLight -+ (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType; // default is SVProgressHUDMaskTypeNone -+ (void)setDefaultAnimationType:(SVProgressHUDAnimationType)type; // default is SVProgressHUDAnimationTypeFlat -+ (void)setContainerView:(nullable UIView*)containerView; // default is window level -+ (void)setMinimumSize:(CGSize)minimumSize; // default is CGSizeZero, can be used to avoid resizing for a larger message -+ (void)setRingThickness:(CGFloat)ringThickness; // default is 2 pt -+ (void)setRingRadius:(CGFloat)radius; // default is 18 pt -+ (void)setRingNoTextRadius:(CGFloat)radius; // default is 24 pt -+ (void)setCornerRadius:(CGFloat)cornerRadius; // default is 14 pt -+ (void)setBorderColor:(nonnull UIColor*)color; // default is nil -+ (void)setBorderWidth:(CGFloat)width; // default is 0 -+ (void)setFont:(nonnull UIFont*)font; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] -+ (void)setForegroundColor:(nonnull UIColor*)color; // default is [UIColor blackColor], only used for SVProgressHUDStyleCustom -+ (void)setBackgroundColor:(nonnull UIColor*)color; // default is [UIColor whiteColor], only used for SVProgressHUDStyleCustom -+ (void)setBackgroundLayerColor:(nonnull UIColor*)color; // default is [UIColor colorWithWhite:0 alpha:0.5], only used for SVProgressHUDMaskTypeCustom -+ (void)setImageViewSize:(CGSize)size; // default is 28x28 pt -+ (void)setShouldTintImages:(BOOL)shouldTintImages; // default is YES -+ (void)setInfoImage:(nonnull UIImage*)image; // default is the bundled info image provided by Freepik -+ (void)setSuccessImage:(nonnull UIImage*)image; // default is the bundled success image provided by Freepik -+ (void)setErrorImage:(nonnull UIImage*)image; // default is the bundled error image provided by Freepik -+ (void)setViewForExtension:(nonnull UIView*)view; // default is nil, only used if #define SV_APP_EXTENSIONS is set -+ (void)setGraceTimeInterval:(NSTimeInterval)interval; // default is 0 seconds -+ (void)setMinimumDismissTimeInterval:(NSTimeInterval)interval; // default is 5.0 seconds -+ (void)setMaximumDismissTimeInterval:(NSTimeInterval)interval; // default is infinite -+ (void)setFadeInAnimationDuration:(NSTimeInterval)duration; // default is 0.15 seconds -+ (void)setFadeOutAnimationDuration:(NSTimeInterval)duration; // default is 0.15 seconds -+ (void)setMaxSupportedWindowLevel:(UIWindowLevel)windowLevel; // default is UIWindowLevelNormal -+ (void)setHapticsEnabled:(BOOL)hapticsEnabled; // default is NO #pragma mark - Show Methods +/// Shows the HUD without any additional status message. + (void)show; -+ (void)showWithMaskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use show and setDefaultMaskType: instead."))); + +/// Shows the HUD with a provided status message. +/// @param status The message to be displayed alongside the HUD. + (void)showWithStatus:(nullable NSString*)status; -+ (void)showWithStatus:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showWithStatus: and setDefaultMaskType: instead."))); +/// Display methods to show progress on the HUD. + +/// Shows the HUD with a progress indicator. +/// @param progress A float value between 0.0 and 1.0 indicating the progress. + (void)showProgress:(float)progress; -+ (void)showProgress:(float)progress maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showProgress: and setDefaultMaskType: instead."))); + +/// Shows the HUD with a progress indicator and a provided status message. +/// @param progress A float value between 0.0 and 1.0 indicating the progress. +/// @param status The message to be displayed alongside the progress indicator. + (void)showProgress:(float)progress status:(nullable NSString*)status; -+ (void)showProgress:(float)progress status:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showProgress:status: and setDefaultMaskType: instead."))); -+ (void)setStatus:(nullable NSString*)status; // change the HUD loading status while it's showing +/// Updates the current status of the loading HUD. +/// @param status The new status message to update the HUD with. ++ (void)setStatus:(nullable NSString*)status; -// stops the activity indicator, shows a glyph + status, and dismisses the HUD a little bit later +/// Shows an info status with the provided message. +/// @param status The info message to be displayed. + (void)showInfoWithStatus:(nullable NSString*)status; -+ (void)showInfoWithStatus:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showInfoWithStatus: and setDefaultMaskType: instead."))); + +/// Shows a success status with the provided message. +/// @param status The success message to be displayed. + (void)showSuccessWithStatus:(nullable NSString*)status; -+ (void)showSuccessWithStatus:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showSuccessWithStatus: and setDefaultMaskType: instead."))); + +/// Shows an error status with the provided message. +/// @param status The error message to be displayed. + (void)showErrorWithStatus:(nullable NSString*)status; -+ (void)showErrorWithStatus:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showErrorWithStatus: and setDefaultMaskType: instead."))); -// shows a image + status, use white PNGs with the imageViewSize (default is 28x28 pt) +/// Shows a custom image with the provided status message. +/// @param image The custom image to be displayed. +/// @param status The message to accompany the custom image. + (void)showImage:(nonnull UIImage*)image status:(nullable NSString*)status; -+ (void)showImage:(nonnull UIImage*)image status:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showImage:status: and setDefaultMaskType: instead."))); +/// Sets the offset from the center for the HUD. +/// @param offset The UIOffset value indicating how much the HUD should be offset from its center position. + (void)setOffsetFromCenter:(UIOffset)offset; + +/// Resets the offset to center the HUD. + (void)resetOffsetFromCenter; -+ (void)popActivity; // decrease activity count, if activity count == 0 the HUD is dismissed +/// Decreases the activity count, dismissing the HUD if count reaches 0. ++ (void)popActivity; + +/// Dismisses the HUD immediately. + (void)dismiss; + +/// Dismisses the HUD and triggers a completion block. +/// @param completion A block that gets executed after the HUD is dismissed. + (void)dismissWithCompletion:(nullable SVProgressHUDDismissCompletion)completion; + +/// Dismisses the HUD after a specified delay. +/// @param delay The time in seconds after which the HUD should be dismissed. + (void)dismissWithDelay:(NSTimeInterval)delay; + +/// Dismisses the HUD after a specified delay and triggers a completion block. +/// @param delay The time in seconds after which the HUD should be dismissed. +/// @param completion A block that gets executed after the HUD is dismissed. + (void)dismissWithDelay:(NSTimeInterval)delay completion:(nullable SVProgressHUDDismissCompletion)completion; +/// Checks if the HUD is currently visible. +/// @return A boolean value indicating whether the HUD is visible. + (BOOL)isVisible; +/// Calculates the display duration based on a given string's length. +/// @param string The string whose length determines the display duration. +/// @return A time interval representing the display duration. + (NSTimeInterval)displayDurationForString:(nullable NSString*)string; @end diff --git a/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.m b/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.m index 2b66992..fad5571 100644 --- a/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.m +++ b/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.m @@ -2,7 +2,7 @@ // SVProgressHUD.h // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD // -// Copyright (c) 2011-2018 Sam Vermette and contributors. All rights reserved. +// Copyright (c) 2011-2023 Sam Vermette and contributors. All rights reserved. // #if !__has_feature(objc_arc) @@ -40,6 +40,7 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; @property (nonatomic, strong) UIView *backgroundView; @property (nonatomic, strong) SVRadialGradientLayer *backgroundRadialGradientLayer; @property (nonatomic, strong) UIVisualEffectView *hudView; +@property (nonatomic, strong) UIBlurEffect *hudViewCustomBlurEffect; @property (nonatomic, strong) UILabel *statusLabel; @property (nonatomic, strong) UIImageView *imageView; @@ -53,8 +54,8 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; @property (nonatomic, readonly) CGFloat visibleKeyboardHeight; @property (nonatomic, readonly) UIWindow *frontWindow; -#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 -@property (nonatomic, strong) UINotificationFeedbackGenerator *hapticGenerator NS_AVAILABLE_IOS(10_0); +#if TARGET_OS_IOS +@property (nonatomic, strong) UINotificationFeedbackGenerator *hapticGenerator; #endif @end @@ -68,13 +69,41 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; static SVProgressHUD *sharedView; #if !defined(SV_APP_EXTENSIONS) - dispatch_once(&once, ^{ sharedView = [[self alloc] initWithFrame:[[[UIApplication sharedApplication] delegate] window].bounds]; }); + dispatch_once(&once, ^{ sharedView = [[self alloc] initWithFrame:[SVProgressHUD mainWindow].bounds]; }); #else dispatch_once(&once, ^{ sharedView = [[self alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; }); #endif return sharedView; } ++ (UIWindow *)mainWindow { + if (@available(iOS 13.0, *)) { + for (UIWindowScene* windowScene in [UIApplication sharedApplication].connectedScenes) { + if (windowScene.activationState == UISceneActivationStateForegroundActive) { + return windowScene.windows.firstObject; + } + } + // If a window has not been returned by now, the first scene's window is returned (regardless of activationState). + UIWindowScene *windowScene = (UIWindowScene *)[[UIApplication sharedApplication].connectedScenes allObjects].firstObject; + return windowScene.windows.firstObject; + } else { +#if TARGET_OS_IOS + return [[[UIApplication sharedApplication] delegate] window]; +#else + return [UIApplication sharedApplication].keyWindow; +#endif + } +} + ++ (NSBundle *)imageBundle { +#if defined(SWIFTPM_MODULE_BUNDLE) + NSBundle *bundle = SWIFTPM_MODULE_BUNDLE; +#else + NSBundle *bundle = [NSBundle bundleForClass:[SVProgressHUD class]]; +#endif + NSURL *url = [bundle URLForResource:@"SVProgressHUD" withExtension:@"bundle"]; + return [NSBundle bundleWithURL:url]; + } #pragma mark - Setters @@ -135,11 +164,21 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; [self setDefaultStyle:SVProgressHUDStyleCustom]; } ++ (void)setForegroundImageColor:(UIColor *)color { + [self sharedView].foregroundImageColor = color; + [self setDefaultStyle:SVProgressHUDStyleCustom]; +} + + (void)setBackgroundColor:(UIColor*)color { [self sharedView].backgroundColor = color; [self setDefaultStyle:SVProgressHUDStyleCustom]; } ++ (void)setHudViewCustomBlurEffect:(UIBlurEffect*)blurEffect { + [self sharedView].hudViewCustomBlurEffect = blurEffect; + [self setDefaultStyle:SVProgressHUDStyleCustom]; +} + + (void)setBackgroundLayerColor:(UIColor*)color { [self sharedView].backgroundLayerColor = color; } @@ -196,125 +235,58 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; [self sharedView].hapticsEnabled = hapticsEnabled; } ++ (void)setMotionEffectEnabled:(BOOL)motionEffectEnabled { + [self sharedView].motionEffectEnabled = motionEffectEnabled; +} + #pragma mark - Show Methods + (void)show { [self showWithStatus:nil]; } -+ (void)showWithMaskType:(SVProgressHUDMaskType)maskType { - SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; - [self setDefaultMaskType:maskType]; - [self show]; - [self setDefaultMaskType:existingMaskType]; -} - + (void)showWithStatus:(NSString*)status { [self showProgress:SVProgressHUDUndefinedProgress status:status]; } -+ (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { - SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; - [self setDefaultMaskType:maskType]; - [self showWithStatus:status]; - [self setDefaultMaskType:existingMaskType]; -} - + (void)showProgress:(float)progress { [self showProgress:progress status:nil]; } -+ (void)showProgress:(float)progress maskType:(SVProgressHUDMaskType)maskType { - SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; - [self setDefaultMaskType:maskType]; - [self showProgress:progress]; - [self setDefaultMaskType:existingMaskType]; -} - + (void)showProgress:(float)progress status:(NSString*)status { [[self sharedView] showProgress:progress status:status]; } -+ (void)showProgress:(float)progress status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { - SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; - [self setDefaultMaskType:maskType]; - [self showProgress:progress status:status]; - [self setDefaultMaskType:existingMaskType]; -} - #pragma mark - Show, then automatically dismiss methods + (void)showInfoWithStatus:(NSString*)status { [self showImage:[self sharedView].infoImage status:status]; -#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 - if (@available(iOS 10.0, *)) { - dispatch_async(dispatch_get_main_queue(), ^{ - [[self sharedView].hapticGenerator notificationOccurred:UINotificationFeedbackTypeWarning]; - }); - } +#if TARGET_OS_IOS + dispatch_async(dispatch_get_main_queue(), ^{ + [[self sharedView].hapticGenerator notificationOccurred:UINotificationFeedbackTypeWarning]; + }); #endif } -+ (void)showInfoWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { - SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; - [self setDefaultMaskType:maskType]; - [self showInfoWithStatus:status]; - [self setDefaultMaskType:existingMaskType]; -} - + (void)showSuccessWithStatus:(NSString*)status { [self showImage:[self sharedView].successImage status:status]; -#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 - if (@available(iOS 10, *)) { - dispatch_async(dispatch_get_main_queue(), ^{ - [[self sharedView].hapticGenerator notificationOccurred:UINotificationFeedbackTypeSuccess]; - }); - } -#endif -} - -+ (void)showSuccessWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { - SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; - [self setDefaultMaskType:maskType]; - [self showSuccessWithStatus:status]; - [self setDefaultMaskType:existingMaskType]; - -#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 - if (@available(iOS 10.0, *)) { - dispatch_async(dispatch_get_main_queue(), ^{ - [[self sharedView].hapticGenerator notificationOccurred:UINotificationFeedbackTypeSuccess]; - }); - } +#if TARGET_OS_IOS + dispatch_async(dispatch_get_main_queue(), ^{ + [[self sharedView].hapticGenerator notificationOccurred:UINotificationFeedbackTypeSuccess]; + }); #endif } + (void)showErrorWithStatus:(NSString*)status { [self showImage:[self sharedView].errorImage status:status]; -#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 - if (@available(iOS 10.0, *)) { - dispatch_async(dispatch_get_main_queue(), ^{ - [[self sharedView].hapticGenerator notificationOccurred:UINotificationFeedbackTypeError]; - }); - } -#endif -} - -+ (void)showErrorWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { - SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; - [self setDefaultMaskType:maskType]; - [self showErrorWithStatus:status]; - [self setDefaultMaskType:existingMaskType]; - -#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 - if (@available(iOS 10.0, *)) { - dispatch_async(dispatch_get_main_queue(), ^{ - [[self sharedView].hapticGenerator notificationOccurred:UINotificationFeedbackTypeError]; - }); - } +#if TARGET_OS_IOS + dispatch_async(dispatch_get_main_queue(), ^{ + [[self sharedView].hapticGenerator notificationOccurred:UINotificationFeedbackTypeError]; + }); #endif } @@ -323,13 +295,6 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; [[self sharedView] showImage:image status:status duration:displayInterval]; } -+ (void)showImage:(UIImage*)image status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { - SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; - [self setDefaultMaskType:maskType]; - [self showImage:image status:status]; - [self setDefaultMaskType:existingMaskType]; -} - #pragma mark - Dismiss Methods @@ -392,7 +357,7 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; // Set default values _defaultMaskType = SVProgressHUDMaskTypeNone; - _defaultStyle = SVProgressHUDStyleLight; + _defaultStyle = SVProgressHUDStyleAutomatic; _defaultAnimationType = SVProgressHUDAnimationTypeFlat; _minimumSize = CGSizeZero; _font = [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]; @@ -400,14 +365,18 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; _imageViewSize = CGSizeMake(28.0f, 28.0f); _shouldTintImages = YES; - NSBundle *bundle = [NSBundle bundleForClass:[SVProgressHUD class]]; - NSURL *url = [bundle URLForResource:@"SVProgressHUD" withExtension:@"bundle"]; - NSBundle *imageBundle = [NSBundle bundleWithURL:url]; + NSBundle *imageBundle = [SVProgressHUD imageBundle]; + + if (@available(iOS 13.0, *)) { + _infoImage = [UIImage systemImageNamed:@"info.circle"]; + _successImage = [UIImage systemImageNamed:@"checkmark"]; + _errorImage = [UIImage systemImageNamed:@"xmark"]; + } else { + _infoImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"info" ofType:@"png"]]; + _successImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"success" ofType:@"png"]]; + _errorImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"error" ofType:@"png"]]; + } - _infoImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"info" ofType:@"png"]]; - _successImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"success" ofType:@"png"]]; - _errorImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"error" ofType:@"png"]]; - _ringThickness = 2.0f; _ringRadius = 18.0f; _ringNoTextRadius = 24.0f; @@ -424,6 +393,7 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; _maxSupportedWindowLevel = UIWindowLevelNormal; _hapticsEnabled = NO; + _motionEffectEnabled = YES; // Accessibility support self.accessibilityIdentifier = @"SVProgressHUD"; @@ -436,7 +406,7 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; - (void)updateHUDFrame { // Check if an image or progress ring is displayed - BOOL imageUsed = (self.imageView.image) && !(self.imageView.hidden); + BOOL imageUsed = (self.imageView.image) && !(self.imageView.hidden) && (self.imageViewSize.height > 0 && self.imageViewSize.width > 0); BOOL progressUsed = self.imageView.hidden; // Calculate size of string @@ -513,8 +483,9 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; #if TARGET_OS_IOS - (void)updateMotionEffectForOrientation:(UIInterfaceOrientation)orientation { - UIInterpolatingMotionEffectType xMotionEffectType = UIInterfaceOrientationIsPortrait(orientation) ? UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis : UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis; - UIInterpolatingMotionEffectType yMotionEffectType = UIInterfaceOrientationIsPortrait(orientation) ? UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis : UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis; + bool isPortrait = UIInterfaceOrientationIsPortrait(orientation); + UIInterpolatingMotionEffectType xMotionEffectType = isPortrait ? UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis : UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis; + UIInterpolatingMotionEffectType yMotionEffectType = isPortrait ? UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis : UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis; [self updateMotionEffectForXMotionEffectType:xMotionEffectType yMotionEffectType:yMotionEffectType]; } #endif @@ -635,10 +606,10 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; double animationDuration = 0.0; #if !defined(SV_APP_EXTENSIONS) && TARGET_OS_IOS - self.frame = [[[UIApplication sharedApplication] delegate] window].bounds; + self.frame = [SVProgressHUD mainWindow].bounds; UIInterfaceOrientation orientation = UIApplication.sharedApplication.statusBarOrientation; #elif !defined(SV_APP_EXTENSIONS) && !TARGET_OS_IOS - self.frame= [UIApplication sharedApplication].keyWindow.bounds; + self.frame = [SVProgressHUD mainWindow].bounds; #else if (self.viewForExtension) { self.frame = self.viewForExtension.frame; @@ -678,12 +649,14 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; CGRect statusBarFrame = CGRectZero; #endif + if (_motionEffectEnabled) { #if TARGET_OS_IOS - // Update the motion effects in regard to orientation - [self updateMotionEffectForOrientation:orientation]; + // Update the motion effects in regard to orientation + [self updateMotionEffectForOrientation:orientation]; #else - [self updateMotionEffectForXMotionEffectType:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis yMotionEffectType:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; + [self updateMotionEffectForXMotionEffectType:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis yMotionEffectType:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; #endif + } // Calculate available height for display CGFloat activeHeight = CGRectGetHeight(orientationFrame); @@ -813,10 +786,8 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; } // Tell the Haptics Generator to prepare for feedback, which may come soon -#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 - if (@available(iOS 10.0, *)) { - [strongSelf.hapticGenerator prepare]; - } +#if TARGET_OS_IOS + [strongSelf.hapticGenerator prepare]; #endif } }]; @@ -843,8 +814,10 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; if (self.shouldTintImages) { if (image.renderingMode != UIImageRenderingModeAlwaysTemplate) { strongSelf.imageView.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + } else { + strongSelf.imageView.image = image; } - strongSelf.imageView.tintColor = strongSelf.foregroundColorForStyle;; + strongSelf.imageView.tintColor = strongSelf.foregroundImageColorForStyle; } else { strongSelf.imageView.image = image; } @@ -872,14 +845,19 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; [self positionHUD:nil]; // Update accessibility as well as user interaction + // \n cause to read text twice so remove "\n" new line character before setting up accessiblity label + NSString *accessibilityString = [[self.statusLabel.text componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:@" "]; if(self.defaultMaskType != SVProgressHUDMaskTypeNone) { self.controlView.userInteractionEnabled = YES; - self.accessibilityLabel = self.statusLabel.text ?: NSLocalizedString(@"Loading", nil); + self.accessibilityLabel = accessibilityString ?: NSLocalizedString(@"Loading", nil); self.isAccessibilityElement = YES; + self.controlView.accessibilityViewIsModal = YES; } else { self.controlView.userInteractionEnabled = NO; - self.hudView.accessibilityLabel = self.statusLabel.text ?: NSLocalizedString(@"Loading", nil); + self.hudView.accessibilityLabel = accessibilityString ?: NSLocalizedString(@"Loading", nil); + self.isAccessibilityElement = NO; self.hudView.isAccessibilityElement = YES; + self.controlView.accessibilityViewIsModal = NO; } // Get duration @@ -892,8 +870,8 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; object:self userInfo:[self notificationUserInfo]]; - // Shrink HUD to to make a nice appear / pop up animation - self.hudView.transform = self.hudView.transform = CGAffineTransformScale(self.hudView.transform, 1/1.5f, 1/1.5f); + // Zoom HUD a little to to make a nice appear / pop up animation + self.hudView.transform = self.hudView.transform = CGAffineTransformScale(self.hudView.transform, 1.3f, 1.3f); __block void (^animationsBlock)(void) = ^{ // Zoom HUD a little to make a nice appear / pop up animation @@ -969,8 +947,6 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; [[NSOperationQueue mainQueue] addOperationWithBlock:^{ __strong SVProgressHUD *strongSelf = weakSelf; if(strongSelf){ - // Stop timer - strongSelf.graceTimer = nil; // Post notification to inform user [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDWillDisappearNotification @@ -1013,7 +989,7 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; // Tell the rootViewController to update the StatusBar appearance #if !defined(SV_APP_EXTENSIONS) && TARGET_OS_IOS - UIViewController *rootController = [[UIApplication sharedApplication] keyWindow].rootViewController; + UIViewController *rootController = [SVProgressHUD mainWindow].rootViewController; [rootController setNeedsStatusBarAppearanceUpdate]; #endif @@ -1031,6 +1007,10 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; dispatch_time_t dipatchTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)); dispatch_after(dipatchTime, dispatch_get_main_queue(), ^{ + + // Stop timer + strongSelf.graceTimer = nil; + if (strongSelf.fadeOutAnimationDuration > 0) { // Animate appearance [UIView animateWithDuration:strongSelf.fadeOutAnimationDuration @@ -1071,7 +1051,7 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; // Update styling SVIndefiniteAnimatedView *indefiniteAnimatedView = (SVIndefiniteAnimatedView*)_indefiniteAnimatedView; - indefiniteAnimatedView.strokeColor = self.foregroundColorForStyle; + indefiniteAnimatedView.strokeColor = self.foregroundImageColorForStyle; indefiniteAnimatedView.strokeThickness = self.ringThickness; indefiniteAnimatedView.radius = self.statusLabel.text ? self.ringRadius : self.ringNoTextRadius; } else { @@ -1087,7 +1067,7 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; // Update styling UIActivityIndicatorView *activityIndicatorView = (UIActivityIndicatorView*)_indefiniteAnimatedView; - activityIndicatorView.color = self.foregroundColorForStyle; + activityIndicatorView.color = self.foregroundImageColorForStyle; } [_indefiniteAnimatedView sizeToFit]; @@ -1100,7 +1080,7 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; } // Update styling - _ringView.strokeColor = self.foregroundColorForStyle; + _ringView.strokeColor = self.foregroundImageColorForStyle; _ringView.strokeThickness = self.ringThickness; _ringView.radius = self.statusLabel.text ? self.ringRadius : self.ringNoTextRadius; @@ -1114,7 +1094,7 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; } // Update styling - _backgroundRingView.strokeColor = [self.foregroundColorForStyle colorWithAlphaComponent:0.1f]; + _backgroundRingView.strokeColor = [self.foregroundImageColorForStyle colorWithAlphaComponent:0.1f]; _backgroundRingView.strokeThickness = self.ringThickness; _backgroundRingView.radius = self.statusLabel.text ? self.ringRadius : self.ringNoTextRadius; @@ -1162,19 +1142,31 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; } - (UIColor*)foregroundColorForStyle { - if(self.defaultStyle == SVProgressHUDStyleLight) { + SVProgressHUDStyle style = [self defaultStyleResolvingAutomatic]; + + if(style == SVProgressHUDStyleLight) { return [UIColor blackColor]; - } else if(self.defaultStyle == SVProgressHUDStyleDark) { + } else if(style == SVProgressHUDStyleDark) { return [UIColor whiteColor]; } else { return self.foregroundColor; } } +- (UIColor*)foregroundImageColorForStyle { + if (self.foregroundImageColor) { + return self.foregroundImageColor; + } else { + return [self foregroundColorForStyle]; + } +} + - (UIColor*)backgroundColorForStyle { - if(self.defaultStyle == SVProgressHUDStyleLight) { + SVProgressHUDStyle style = [self defaultStyleResolvingAutomatic]; + + if(style == SVProgressHUDStyleLight) { return [UIColor whiteColor]; - } else if(self.defaultStyle == SVProgressHUDStyleDark) { + } else if(style == SVProgressHUDStyleDark) { return [UIColor blackColor]; } else { return self.backgroundColor; @@ -1190,10 +1182,9 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; [_controlView addTarget:self action:@selector(controlViewDidReceiveTouchEvent:forEvent:) forControlEvents:UIControlEventTouchDown]; } - // Update frames + // Update frame #if !defined(SV_APP_EXTENSIONS) - CGRect windowBounds = [[[UIApplication sharedApplication] delegate] window].bounds; - _controlView.frame = windowBounds; + _controlView.frame = [SVProgressHUD mainWindow].bounds; #else _controlView.frame = [UIScreen mainScreen].bounds; #endif @@ -1269,6 +1260,7 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; _statusLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _statusLabel.backgroundColor = [UIColor clearColor]; _statusLabel.adjustsFontSizeToFitWidth = YES; + _statusLabel.adjustsFontForContentSizeCategory = YES; _statusLabel.textAlignment = NSTextAlignmentCenter; _statusLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters; _statusLabel.numberOfLines = 0; @@ -1302,7 +1294,15 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; #pragma mark - Helper + +- (SVProgressHUDStyle) defaultStyleResolvingAutomatic { + if(self.defaultStyle == SVProgressHUDStyleAutomatic) { + return self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark ? SVProgressHUDStyleDark : SVProgressHUDStyleLight; + } + return self.defaultStyle; +} + - (CGFloat)visibleKeyboardHeight { #if !defined(SV_APP_EXTENSIONS) UIWindow *keyboardWindow = nil; @@ -1356,7 +1356,17 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; - (void)fadeInEffects { if(self.defaultStyle != SVProgressHUDStyleCustom) { // Add blur effect - UIBlurEffectStyle blurEffectStyle = self.defaultStyle == SVProgressHUDStyleDark ? UIBlurEffectStyleDark : UIBlurEffectStyleLight; + UIBlurEffectStyle blurEffectStyle; +#if TARGET_OS_IOS + if (@available(iOS 13.0, *)) { + blurEffectStyle = [self defaultStyleResolvingAutomatic] == SVProgressHUDStyleLight ? UIBlurEffectStyleSystemMaterial : UIBlurEffectStyleSystemMaterialDark; + } else { + blurEffectStyle = [self defaultStyleResolvingAutomatic] == SVProgressHUDStyleLight ? UIBlurEffectStyleLight : UIBlurEffectStyleDark; + } +#else + blurEffectStyle = [self defaultStyleResolvingAutomatic] == SVProgressHUDStyleLight ? UIBlurEffectStyleLight : UIBlurEffectStyleDark; +#endif + UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:blurEffectStyle]; self.hudView.effect = blurEffect; @@ -1366,6 +1376,7 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; self.hudView.backgroundColor = [self.backgroundColorForStyle colorWithAlphaComponent:0.6f]; } else { + self.hudView.effect = self.hudViewCustomBlurEffect; self.hudView.backgroundColor = self.backgroundColorForStyle; } @@ -1397,8 +1408,8 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; self.ringView.alpha = self.backgroundRingView.alpha = 0.0f; } -#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 -- (UINotificationFeedbackGenerator *)hapticGenerator NS_AVAILABLE_IOS(10_0) { +#if TARGET_OS_IOS +- (UINotificationFeedbackGenerator *)hapticGenerator { // Only return if haptics are enabled if(!self.hapticsEnabled) { return nil; @@ -1458,6 +1469,10 @@ static const CGFloat SVProgressHUDLabelSpacing = 8.0f; if (!_isInitializing) _foregroundColor = color; } +- (void)setForegroundImageColor:(UIColor *)color { + if (!_isInitializing) _foregroundImageColor = color; +} + - (void)setBackgroundColor:(UIColor*)color { if (!_isInitializing) _backgroundColor = color; } diff --git a/Pods/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.h b/Pods/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.h index 68d452a..98302c0 100644 --- a/Pods/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.h +++ b/Pods/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.h @@ -2,7 +2,7 @@ // SVRadialGradientLayer.h // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD // -// Copyright (c) 2014-2018 Tobias Tiemerding. All rights reserved. +// Copyright (c) 2014-2023 Tobias Totzek and contributors. All rights reserved. // #import diff --git a/Pods/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.m b/Pods/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.m index c62e0f8..8a79710 100644 --- a/Pods/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.m +++ b/Pods/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.m @@ -2,7 +2,7 @@ // SVRadialGradientLayer.m // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD // -// Copyright (c) 2014-2018 Tobias Tiemerding. All rights reserved. +// Copyright (c) 2014-2023 Tobias Totzek and contributors. All rights reserved. // #import "SVRadialGradientLayer.h" diff --git a/Pods/SnapKit/README.md b/Pods/SnapKit/README.md index b36df7a..e1be307 100644 --- a/Pods/SnapKit/README.md +++ b/Pods/SnapKit/README.md @@ -22,7 +22,7 @@ SnapKit is a DSL to make Auto Layout easy on both iOS and OS X. ## Requirements -- iOS 10.0+ / Mac OS X 10.12+ / tvOS 10.0+ +- iOS 12.0+ / Mac OS X 10.13+ / tvOS 10.0+ - Xcode 10.0+ - Swift 4.0+ @@ -59,7 +59,7 @@ platform :ios, '10.0' use_frameworks! target '' do - pod 'SnapKit', '~> 5.6.0' + pod 'SnapKit', '~> 5.7.0' end ``` diff --git a/Pods/SnapKit/Sources/Constraint.swift b/Pods/SnapKit/Sources/Constraint.swift index 37409b3..b890152 100644 --- a/Pods/SnapKit/Sources/Constraint.swift +++ b/Pods/SnapKit/Sources/Constraint.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit @@ -101,7 +101,7 @@ public final class Constraint { for layoutFromAttribute in layoutFromAttributes { // get layout to attribute let layoutToAttribute: LayoutAttribute - #if os(iOS) || os(tvOS) + #if canImport(UIKit) if layoutToAttributes.count > 0 { if self.from.attributes == .edges && self.to.attributes == .margins { switch layoutFromAttribute { @@ -245,7 +245,7 @@ public final class Constraint { return self } - #if os(iOS) || os(tvOS) + #if canImport(UIKit) @discardableResult @available(iOS 11.0, tvOS 11.0, *) public func update(inset: ConstraintDirectionalInsetTarget) -> Constraint { diff --git a/Pods/SnapKit/Sources/ConstraintAttributes.swift b/Pods/SnapKit/Sources/ConstraintAttributes.swift index 408308b..c1a79c2 100644 --- a/Pods/SnapKit/Sources/ConstraintAttributes.swift +++ b/Pods/SnapKit/Sources/ConstraintAttributes.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit @@ -152,7 +152,7 @@ internal struct ConstraintAttributes : OptionSet, ExpressibleByIntegerLiteral { attrs.append(.lastBaseline) } - #if os(iOS) || os(tvOS) + #if canImport(UIKit) if (self.contains(ConstraintAttributes.firstBaseline)) { attrs.append(.firstBaseline) } diff --git a/Pods/SnapKit/Sources/ConstraintConfig.swift b/Pods/SnapKit/Sources/ConstraintConfig.swift index 2746b7d..9bd0f23 100644 --- a/Pods/SnapKit/Sources/ConstraintConfig.swift +++ b/Pods/SnapKit/Sources/ConstraintConfig.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit public typealias ConstraintInterfaceLayoutDirection = UIUserInterfaceLayoutDirection #else diff --git a/Pods/SnapKit/Sources/ConstraintConstantTarget.swift b/Pods/SnapKit/Sources/ConstraintConstantTarget.swift index 7f54907..e16f503 100644 --- a/Pods/SnapKit/Sources/ConstraintConstantTarget.swift +++ b/Pods/SnapKit/Sources/ConstraintConstantTarget.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit @@ -40,7 +40,7 @@ extension CGSize: ConstraintConstantTarget { extension ConstraintInsets: ConstraintConstantTarget { } -#if os(iOS) || os(tvOS) +#if canImport(UIKit) @available(iOS 11.0, tvOS 11.0, *) extension ConstraintDirectionalInsets: ConstraintConstantTarget { } @@ -80,7 +80,7 @@ extension ConstraintConstantTarget { } if let value = self as? CGPoint { - #if os(iOS) || os(tvOS) + #if canImport(UIKit) switch layoutAttribute { case .left, .right, .leading, .trailing, .centerX, .leftMargin, .rightMargin, .leadingMargin, .trailingMargin, .centerXWithinMargins: return value.x @@ -110,7 +110,7 @@ extension ConstraintConstantTarget { } if let value = self as? ConstraintInsets { - #if os(iOS) || os(tvOS) + #if canImport(UIKit) switch layoutAttribute { case .left, .leftMargin: return value.left @@ -171,7 +171,7 @@ extension ConstraintConstantTarget { #endif } - #if os(iOS) || os(tvOS) + #if canImport(UIKit) if #available(iOS 11.0, tvOS 11.0, *), let value = self as? ConstraintDirectionalInsets { switch layoutAttribute { case .left, .leftMargin: diff --git a/Pods/SnapKit/Sources/ConstraintDSL.swift b/Pods/SnapKit/Sources/ConstraintDSL.swift index 20f153d..5683b7f 100644 --- a/Pods/SnapKit/Sources/ConstraintDSL.swift +++ b/Pods/SnapKit/Sources/ConstraintDSL.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/ConstraintDescription.swift b/Pods/SnapKit/Sources/ConstraintDescription.swift index 3521f9f..b9d476c 100644 --- a/Pods/SnapKit/Sources/ConstraintDescription.swift +++ b/Pods/SnapKit/Sources/ConstraintDescription.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/ConstraintDirectionalInsetTarget.swift b/Pods/SnapKit/Sources/ConstraintDirectionalInsetTarget.swift index 955aec3..4c3c418 100644 --- a/Pods/SnapKit/Sources/ConstraintDirectionalInsetTarget.swift +++ b/Pods/SnapKit/Sources/ConstraintDirectionalInsetTarget.swift @@ -21,13 +21,13 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit #endif -#if os(iOS) || os(tvOS) +#if canImport(UIKit) public protocol ConstraintDirectionalInsetTarget: ConstraintConstantTarget { } diff --git a/Pods/SnapKit/Sources/ConstraintDirectionalInsets.swift b/Pods/SnapKit/Sources/ConstraintDirectionalInsets.swift index ada8ed5..056b5c8 100644 --- a/Pods/SnapKit/Sources/ConstraintDirectionalInsets.swift +++ b/Pods/SnapKit/Sources/ConstraintDirectionalInsets.swift @@ -21,14 +21,14 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit #endif -#if os(iOS) || os(tvOS) +#if canImport(UIKit) @available(iOS 11.0, tvOS 11.0, *) public typealias ConstraintDirectionalInsets = NSDirectionalEdgeInsets #endif diff --git a/Pods/SnapKit/Sources/ConstraintInsetTarget.swift b/Pods/SnapKit/Sources/ConstraintInsetTarget.swift index ba8a0f3..43c0220 100644 --- a/Pods/SnapKit/Sources/ConstraintInsetTarget.swift +++ b/Pods/SnapKit/Sources/ConstraintInsetTarget.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/ConstraintInsets.swift b/Pods/SnapKit/Sources/ConstraintInsets.swift index 738ca05..64d781d 100644 --- a/Pods/SnapKit/Sources/ConstraintInsets.swift +++ b/Pods/SnapKit/Sources/ConstraintInsets.swift @@ -21,14 +21,14 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit #endif -#if os(iOS) || os(tvOS) +#if canImport(UIKit) public typealias ConstraintInsets = UIEdgeInsets #else public typealias ConstraintInsets = NSEdgeInsets diff --git a/Pods/SnapKit/Sources/ConstraintItem.swift b/Pods/SnapKit/Sources/ConstraintItem.swift index a342c1d..2f92221 100644 --- a/Pods/SnapKit/Sources/ConstraintItem.swift +++ b/Pods/SnapKit/Sources/ConstraintItem.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/ConstraintLayoutGuide+Extensions.swift b/Pods/SnapKit/Sources/ConstraintLayoutGuide+Extensions.swift index d429e0c..e9fd9b3 100644 --- a/Pods/SnapKit/Sources/ConstraintLayoutGuide+Extensions.swift +++ b/Pods/SnapKit/Sources/ConstraintLayoutGuide+Extensions.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #endif diff --git a/Pods/SnapKit/Sources/ConstraintLayoutGuide.swift b/Pods/SnapKit/Sources/ConstraintLayoutGuide.swift index e3e50c8..fd89556 100644 --- a/Pods/SnapKit/Sources/ConstraintLayoutGuide.swift +++ b/Pods/SnapKit/Sources/ConstraintLayoutGuide.swift @@ -21,14 +21,14 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit #endif -#if os(iOS) || os(tvOS) +#if canImport(UIKit) @available(iOS 9.0, *) public typealias ConstraintLayoutGuide = UILayoutGuide #else diff --git a/Pods/SnapKit/Sources/ConstraintLayoutGuideDSL.swift b/Pods/SnapKit/Sources/ConstraintLayoutGuideDSL.swift index 0007819..7e78261 100644 --- a/Pods/SnapKit/Sources/ConstraintLayoutGuideDSL.swift +++ b/Pods/SnapKit/Sources/ConstraintLayoutGuideDSL.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/ConstraintLayoutSupport.swift b/Pods/SnapKit/Sources/ConstraintLayoutSupport.swift index e92e9fb..085f5cd 100644 --- a/Pods/SnapKit/Sources/ConstraintLayoutSupport.swift +++ b/Pods/SnapKit/Sources/ConstraintLayoutSupport.swift @@ -21,14 +21,14 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit #endif -#if os(iOS) || os(tvOS) +#if canImport(UIKit) @available(iOS 8.0, *) public typealias ConstraintLayoutSupport = UILayoutSupport #else diff --git a/Pods/SnapKit/Sources/ConstraintLayoutSupportDSL.swift b/Pods/SnapKit/Sources/ConstraintLayoutSupportDSL.swift index 5d6ae89..71e1158 100644 --- a/Pods/SnapKit/Sources/ConstraintLayoutSupportDSL.swift +++ b/Pods/SnapKit/Sources/ConstraintLayoutSupportDSL.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/ConstraintMaker.swift b/Pods/SnapKit/Sources/ConstraintMaker.swift index 50d7402..7c352f6 100644 --- a/Pods/SnapKit/Sources/ConstraintMaker.swift +++ b/Pods/SnapKit/Sources/ConstraintMaker.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/ConstraintMakerEditable.swift b/Pods/SnapKit/Sources/ConstraintMakerEditable.swift index 4869bc2..0e08e38 100644 --- a/Pods/SnapKit/Sources/ConstraintMakerEditable.swift +++ b/Pods/SnapKit/Sources/ConstraintMakerEditable.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit @@ -53,7 +53,7 @@ public class ConstraintMakerEditable: ConstraintMakerPrioritizable { return self } - #if os(iOS) || os(tvOS) + #if canImport(UIKit) @discardableResult @available(iOS 11.0, tvOS 11.0, *) public func inset(_ amount: ConstraintDirectionalInsetTarget) -> ConstraintMakerEditable { diff --git a/Pods/SnapKit/Sources/ConstraintMakerExtendable.swift b/Pods/SnapKit/Sources/ConstraintMakerExtendable.swift index d834649..b30688e 100644 --- a/Pods/SnapKit/Sources/ConstraintMakerExtendable.swift +++ b/Pods/SnapKit/Sources/ConstraintMakerExtendable.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/ConstraintMakerFinalizable.swift b/Pods/SnapKit/Sources/ConstraintMakerFinalizable.swift index 4e1379e..8342476 100644 --- a/Pods/SnapKit/Sources/ConstraintMakerFinalizable.swift +++ b/Pods/SnapKit/Sources/ConstraintMakerFinalizable.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/ConstraintMakerPrioritizable.swift b/Pods/SnapKit/Sources/ConstraintMakerPrioritizable.swift index 5af5303..05451e6 100644 --- a/Pods/SnapKit/Sources/ConstraintMakerPrioritizable.swift +++ b/Pods/SnapKit/Sources/ConstraintMakerPrioritizable.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/ConstraintMakerRelatable+Extensions.swift b/Pods/SnapKit/Sources/ConstraintMakerRelatable+Extensions.swift index 63100d7..bfde272 100644 --- a/Pods/SnapKit/Sources/ConstraintMakerRelatable+Extensions.swift +++ b/Pods/SnapKit/Sources/ConstraintMakerRelatable+Extensions.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit @@ -47,7 +47,7 @@ extension ConstraintMakerRelatable { } @discardableResult - public func greaterThanOrEqualTo(_ closure: (ConstraintView) -> T, _ file: String = #file, line: UInt = #line) -> ConstraintMakerEditable { + public func greaterThanOrEqualToSuperview(_ closure: (ConstraintView) -> T, _ file: String = #file, line: UInt = #line) -> ConstraintMakerEditable { guard let other = self.description.item.superview else { fatalError("Expected superview but found nil when attempting make constraint `greaterThanOrEqualToSuperview`.") } diff --git a/Pods/SnapKit/Sources/ConstraintMakerRelatable.swift b/Pods/SnapKit/Sources/ConstraintMakerRelatable.swift index 7889532..0a3d5ee 100644 --- a/Pods/SnapKit/Sources/ConstraintMakerRelatable.swift +++ b/Pods/SnapKit/Sources/ConstraintMakerRelatable.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/ConstraintMultiplierTarget.swift b/Pods/SnapKit/Sources/ConstraintMultiplierTarget.swift index 6fecd33..ac537ba 100644 --- a/Pods/SnapKit/Sources/ConstraintMultiplierTarget.swift +++ b/Pods/SnapKit/Sources/ConstraintMultiplierTarget.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/ConstraintOffsetTarget.swift b/Pods/SnapKit/Sources/ConstraintOffsetTarget.swift index bd9e0a1..6ec1107 100644 --- a/Pods/SnapKit/Sources/ConstraintOffsetTarget.swift +++ b/Pods/SnapKit/Sources/ConstraintOffsetTarget.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/ConstraintPriority.swift b/Pods/SnapKit/Sources/ConstraintPriority.swift index f9dab16..bf90693 100644 --- a/Pods/SnapKit/Sources/ConstraintPriority.swift +++ b/Pods/SnapKit/Sources/ConstraintPriority.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/ConstraintPriorityTarget.swift b/Pods/SnapKit/Sources/ConstraintPriorityTarget.swift index 064f750..1aa701e 100644 --- a/Pods/SnapKit/Sources/ConstraintPriorityTarget.swift +++ b/Pods/SnapKit/Sources/ConstraintPriorityTarget.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit @@ -74,7 +74,7 @@ extension CGFloat: ConstraintPriorityTarget { } -#if os(iOS) || os(tvOS) +#if canImport(UIKit) extension UILayoutPriority: ConstraintPriorityTarget { public var constraintPriorityTargetValue: Float { diff --git a/Pods/SnapKit/Sources/ConstraintRelatableTarget.swift b/Pods/SnapKit/Sources/ConstraintRelatableTarget.swift index d517a61..df04464 100644 --- a/Pods/SnapKit/Sources/ConstraintRelatableTarget.swift +++ b/Pods/SnapKit/Sources/ConstraintRelatableTarget.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit @@ -55,7 +55,7 @@ extension CGPoint: ConstraintRelatableTarget { extension ConstraintInsets: ConstraintRelatableTarget { } -#if os(iOS) || os(tvOS) +#if canImport(UIKit) @available(iOS 11.0, tvOS 11.0, *) extension ConstraintDirectionalInsets: ConstraintRelatableTarget { } diff --git a/Pods/SnapKit/Sources/ConstraintRelation.swift b/Pods/SnapKit/Sources/ConstraintRelation.swift index 446aaf7..643d499 100644 --- a/Pods/SnapKit/Sources/ConstraintRelation.swift +++ b/Pods/SnapKit/Sources/ConstraintRelation.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/ConstraintView+Extensions.swift b/Pods/SnapKit/Sources/ConstraintView+Extensions.swift index e0f71c1..1225c04 100644 --- a/Pods/SnapKit/Sources/ConstraintView+Extensions.swift +++ b/Pods/SnapKit/Sources/ConstraintView+Extensions.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/ConstraintView.swift b/Pods/SnapKit/Sources/ConstraintView.swift index 6ff8a76..1203300 100644 --- a/Pods/SnapKit/Sources/ConstraintView.swift +++ b/Pods/SnapKit/Sources/ConstraintView.swift @@ -21,14 +21,14 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit #endif -#if os(iOS) || os(tvOS) +#if canImport(UIKit) public typealias ConstraintView = UIView #else public typealias ConstraintView = NSView diff --git a/Pods/SnapKit/Sources/ConstraintViewDSL.swift b/Pods/SnapKit/Sources/ConstraintViewDSL.swift index a0187f9..8567e54 100644 --- a/Pods/SnapKit/Sources/ConstraintViewDSL.swift +++ b/Pods/SnapKit/Sources/ConstraintViewDSL.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/Debugging.swift b/Pods/SnapKit/Sources/Debugging.swift index a78579a..f4120b2 100644 --- a/Pods/SnapKit/Sources/Debugging.swift +++ b/Pods/SnapKit/Sources/Debugging.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit @@ -89,7 +89,7 @@ private func descriptionForRelation(_ relation: LayoutRelation) -> String { } private func descriptionForAttribute(_ attribute: LayoutAttribute) -> String { - #if os(iOS) || os(tvOS) + #if canImport(UIKit) switch attribute { case .notAnAttribute: return "notAnAttribute" case .top: return "top" diff --git a/Pods/SnapKit/Sources/LayoutConstraint.swift b/Pods/SnapKit/Sources/LayoutConstraint.swift index 5425ea8..607616d 100644 --- a/Pods/SnapKit/Sources/LayoutConstraint.swift +++ b/Pods/SnapKit/Sources/LayoutConstraint.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/LayoutConstraintItem.swift b/Pods/SnapKit/Sources/LayoutConstraintItem.swift index 9b61d18..4f41b5d 100644 --- a/Pods/SnapKit/Sources/LayoutConstraintItem.swift +++ b/Pods/SnapKit/Sources/LayoutConstraintItem.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #else import AppKit diff --git a/Pods/SnapKit/Sources/PrivacyInfo.xcprivacy b/Pods/SnapKit/Sources/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..e540750 --- /dev/null +++ b/Pods/SnapKit/Sources/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ + + + + + NSPrivacyTracking + + NSPrivacyAccessedAPITypes + + NSPrivacyCollectedDataTypes + + NSPrivacyTrackingDomains + + + diff --git a/Pods/SnapKit/Sources/Typealiases.swift b/Pods/SnapKit/Sources/Typealiases.swift index ded96cc..c0e6982 100644 --- a/Pods/SnapKit/Sources/Typealiases.swift +++ b/Pods/SnapKit/Sources/Typealiases.swift @@ -23,7 +23,7 @@ import Foundation -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #if swift(>=4.2) typealias LayoutRelation = NSLayoutConstraint.Relation diff --git a/Pods/SnapKit/Sources/UILayoutSupport+Extensions.swift b/Pods/SnapKit/Sources/UILayoutSupport+Extensions.swift index 8e7644c..801cc3c 100644 --- a/Pods/SnapKit/Sources/UILayoutSupport+Extensions.swift +++ b/Pods/SnapKit/Sources/UILayoutSupport+Extensions.swift @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit #endif diff --git a/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-Info.plist b/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-Info.plist index 4a3167b..b56571c 100644 --- a/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-Info.plist +++ b/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 6.5.13 + 6.5.16 CFBundleSignature ???? CFBundleVersion diff --git a/Pods/Target Support Files/MJRefresh/MJRefresh-Info.plist b/Pods/Target Support Files/MJRefresh/MJRefresh-Info.plist new file mode 100644 index 0000000..1b9a556 --- /dev/null +++ b/Pods/Target Support Files/MJRefresh/MJRefresh-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 3.7.9 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/MJRefresh/MJRefresh-dummy.m b/Pods/Target Support Files/MJRefresh/MJRefresh-dummy.m new file mode 100644 index 0000000..d43259d --- /dev/null +++ b/Pods/Target Support Files/MJRefresh/MJRefresh-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_MJRefresh : NSObject +@end +@implementation PodsDummy_MJRefresh +@end diff --git a/Pods/Target Support Files/MJRefresh/MJRefresh-prefix.pch b/Pods/Target Support Files/MJRefresh/MJRefresh-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Pods/Target Support Files/MJRefresh/MJRefresh-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/MJRefresh/MJRefresh-umbrella.h b/Pods/Target Support Files/MJRefresh/MJRefresh-umbrella.h new file mode 100644 index 0000000..7168200 --- /dev/null +++ b/Pods/Target Support Files/MJRefresh/MJRefresh-umbrella.h @@ -0,0 +1,41 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "MJRefreshAutoFooter.h" +#import "MJRefreshBackFooter.h" +#import "MJRefreshComponent.h" +#import "MJRefreshFooter.h" +#import "MJRefreshHeader.h" +#import "MJRefreshTrailer.h" +#import "MJRefreshAutoGifFooter.h" +#import "MJRefreshAutoNormalFooter.h" +#import "MJRefreshAutoStateFooter.h" +#import "MJRefreshBackGifFooter.h" +#import "MJRefreshBackNormalFooter.h" +#import "MJRefreshBackStateFooter.h" +#import "MJRefreshGifHeader.h" +#import "MJRefreshNormalHeader.h" +#import "MJRefreshStateHeader.h" +#import "MJRefreshNormalTrailer.h" +#import "MJRefreshStateTrailer.h" +#import "MJRefresh.h" +#import "MJRefreshConfig.h" +#import "MJRefreshConst.h" +#import "NSBundle+MJRefresh.h" +#import "UICollectionViewLayout+MJRefresh.h" +#import "UIScrollView+MJExtension.h" +#import "UIScrollView+MJRefresh.h" +#import "UIView+MJExtension.h" + +FOUNDATION_EXPORT double MJRefreshVersionNumber; +FOUNDATION_EXPORT const unsigned char MJRefreshVersionString[]; + diff --git a/Pods/Target Support Files/MJRefresh/MJRefresh.debug.xcconfig b/Pods/Target Support Files/MJRefresh/MJRefresh.debug.xcconfig new file mode 100644 index 0000000..68622eb --- /dev/null +++ b/Pods/Target Support Files/MJRefresh/MJRefresh.debug.xcconfig @@ -0,0 +1,12 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/MJRefresh +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/MJRefresh/MJRefresh.modulemap b/Pods/Target Support Files/MJRefresh/MJRefresh.modulemap new file mode 100644 index 0000000..ec3d85e --- /dev/null +++ b/Pods/Target Support Files/MJRefresh/MJRefresh.modulemap @@ -0,0 +1,6 @@ +framework module MJRefresh { + umbrella header "MJRefresh-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/MJRefresh/MJRefresh.release.xcconfig b/Pods/Target Support Files/MJRefresh/MJRefresh.release.xcconfig new file mode 100644 index 0000000..68622eb --- /dev/null +++ b/Pods/Target Support Files/MJRefresh/MJRefresh.release.xcconfig @@ -0,0 +1,12 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/MJRefresh +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/MJRefresh/ResourceBundle-MJRefresh.Privacy-MJRefresh-Info.plist b/Pods/Target Support Files/MJRefresh/ResourceBundle-MJRefresh.Privacy-MJRefresh-Info.plist new file mode 100644 index 0000000..84806d0 --- /dev/null +++ b/Pods/Target Support Files/MJRefresh/ResourceBundle-MJRefresh.Privacy-MJRefresh-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 3.7.9 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-acknowledgements.markdown b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-acknowledgements.markdown index 91b1b1e..3ce329d 100644 --- a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-acknowledgements.markdown +++ b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-acknowledgements.markdown @@ -125,11 +125,34 @@ SOFTWARE. +## MJRefresh + +Copyright (c) 2013-2015 MJRefresh (https://github.com/CoderMJLee/MJRefresh) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + ## SVProgressHUD MIT License -Copyright (c) 2011-2018 Sam Vermette, Tobias Tiemerding and contributors. +Copyright (c) 2011-2023 Sam Vermette, Tobias Totzek and contributors. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-acknowledgements.plist b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-acknowledgements.plist index 7dadd4f..9321de0 100644 --- a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-acknowledgements.plist +++ b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-acknowledgements.plist @@ -166,11 +166,40 @@ SOFTWARE. Type PSGroupSpecifier + + FooterText + Copyright (c) 2013-2015 MJRefresh (https://github.com/CoderMJLee/MJRefresh) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + License + MIT + Title + MJRefresh + Type + PSGroupSpecifier + FooterText MIT License -Copyright (c) 2011-2018 Sam Vermette, Tobias Tiemerding and contributors. +Copyright (c) 2011-2023 Sam Vermette, Tobias Totzek and contributors. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks-Debug-input-files.xcfilelist b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks-Debug-input-files.xcfilelist index 386f653..b2fd609 100644 --- a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks-Debug-input-files.xcfilelist +++ b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks-Debug-input-files.xcfilelist @@ -4,6 +4,7 @@ ${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework ${BUILT_PRODUCTS_DIR}/JXPagingView/JXPagingView.framework ${BUILT_PRODUCTS_DIR}/JXSegmentedView/JXSegmentedView.framework ${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework +${BUILT_PRODUCTS_DIR}/MJRefresh/MJRefresh.framework ${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework ${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework ${BUILT_PRODUCTS_DIR}/SwiftDate/SwiftDate.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks-Debug-output-files.xcfilelist b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks-Debug-output-files.xcfilelist index 44e9a88..94bc59d 100644 --- a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks-Debug-output-files.xcfilelist +++ b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks-Debug-output-files.xcfilelist @@ -3,6 +3,7 @@ ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManagerSwift.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JXPagingView.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JXSegmentedView.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Kingfisher.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MJRefresh.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVProgressHUD.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftDate.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks-Release-input-files.xcfilelist b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks-Release-input-files.xcfilelist index 386f653..b2fd609 100644 --- a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks-Release-input-files.xcfilelist +++ b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks-Release-input-files.xcfilelist @@ -4,6 +4,7 @@ ${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework ${BUILT_PRODUCTS_DIR}/JXPagingView/JXPagingView.framework ${BUILT_PRODUCTS_DIR}/JXSegmentedView/JXSegmentedView.framework ${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework +${BUILT_PRODUCTS_DIR}/MJRefresh/MJRefresh.framework ${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework ${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework ${BUILT_PRODUCTS_DIR}/SwiftDate/SwiftDate.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks-Release-output-files.xcfilelist b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks-Release-output-files.xcfilelist index 44e9a88..94bc59d 100644 --- a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks-Release-output-files.xcfilelist +++ b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks-Release-output-files.xcfilelist @@ -3,6 +3,7 @@ ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManagerSwift.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JXPagingView.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JXSegmentedView.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Kingfisher.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MJRefresh.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVProgressHUD.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftDate.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks.sh b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks.sh index cd75cd2..cb695ba 100755 --- a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks.sh +++ b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer-frameworks.sh @@ -181,6 +181,7 @@ if [[ "$CONFIGURATION" == "Debug" ]]; then install_framework "${BUILT_PRODUCTS_DIR}/JXPagingView/JXPagingView.framework" install_framework "${BUILT_PRODUCTS_DIR}/JXSegmentedView/JXSegmentedView.framework" install_framework "${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework" + install_framework "${BUILT_PRODUCTS_DIR}/MJRefresh/MJRefresh.framework" install_framework "${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework" install_framework "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework" install_framework "${BUILT_PRODUCTS_DIR}/SwiftDate/SwiftDate.framework" @@ -191,6 +192,7 @@ if [[ "$CONFIGURATION" == "Release" ]]; then install_framework "${BUILT_PRODUCTS_DIR}/JXPagingView/JXPagingView.framework" install_framework "${BUILT_PRODUCTS_DIR}/JXSegmentedView/JXSegmentedView.framework" install_framework "${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework" + install_framework "${BUILT_PRODUCTS_DIR}/MJRefresh/MJRefresh.framework" install_framework "${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework" install_framework "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework" install_framework "${BUILT_PRODUCTS_DIR}/SwiftDate/SwiftDate.framework" diff --git a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer.debug.xcconfig b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer.debug.xcconfig index 51b57bc..98ffa17 100644 --- a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer.debug.xcconfig +++ b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer.debug.xcconfig @@ -1,11 +1,11 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "${PODS_CONFIGURATION_BUILD_DIR}/JXSegmentedView" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftDate" +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "${PODS_CONFIGURATION_BUILD_DIR}/JXSegmentedView" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftDate" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView/JXPagingView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXSegmentedView/JXSegmentedView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftDate/SwiftDate.framework/Headers" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView/JXPagingView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXSegmentedView/JXSegmentedView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftDate/SwiftDate.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift $(SDKROOT)/usr/lib/swift -OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics" -framework "Accelerate" -framework "Alamofire" -framework "CFNetwork" -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManagerSwift" -framework "JXPagingView" -framework "JXSegmentedView" -framework "Kingfisher" -framework "QuartzCore" -framework "SVProgressHUD" -framework "SnapKit" -framework "SwiftDate" -framework "UIKit" -weak_framework "Combine" -weak_framework "SwiftUI" +OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics" -framework "Accelerate" -framework "Alamofire" -framework "CFNetwork" -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManagerSwift" -framework "JXPagingView" -framework "JXSegmentedView" -framework "Kingfisher" -framework "MJRefresh" -framework "QuartzCore" -framework "SVProgressHUD" -framework "SnapKit" -framework "SwiftDate" -framework "UIKit" -weak_framework "Combine" -weak_framework "SwiftUI" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) diff --git a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer.release.xcconfig b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer.release.xcconfig index 51b57bc..98ffa17 100644 --- a/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer.release.xcconfig +++ b/Pods/Target Support Files/Pods-MusicPlayer/Pods-MusicPlayer.release.xcconfig @@ -1,11 +1,11 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "${PODS_CONFIGURATION_BUILD_DIR}/JXSegmentedView" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftDate" +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView" "${PODS_CONFIGURATION_BUILD_DIR}/JXSegmentedView" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftDate" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView/JXPagingView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXSegmentedView/JXSegmentedView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftDate/SwiftDate.framework/Headers" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXPagingView/JXPagingView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/JXSegmentedView/JXSegmentedView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh/MJRefresh.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftDate/SwiftDate.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift $(SDKROOT)/usr/lib/swift -OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics" -framework "Accelerate" -framework "Alamofire" -framework "CFNetwork" -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManagerSwift" -framework "JXPagingView" -framework "JXSegmentedView" -framework "Kingfisher" -framework "QuartzCore" -framework "SVProgressHUD" -framework "SnapKit" -framework "SwiftDate" -framework "UIKit" -weak_framework "Combine" -weak_framework "SwiftUI" +OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics" -framework "Accelerate" -framework "Alamofire" -framework "CFNetwork" -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManagerSwift" -framework "JXPagingView" -framework "JXSegmentedView" -framework "Kingfisher" -framework "MJRefresh" -framework "QuartzCore" -framework "SVProgressHUD" -framework "SnapKit" -framework "SwiftDate" -framework "UIKit" -weak_framework "Combine" -weak_framework "SwiftUI" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) diff --git a/Pods/Target Support Files/SVProgressHUD/SVProgressHUD-Info.plist b/Pods/Target Support Files/SVProgressHUD/SVProgressHUD-Info.plist index 91b625b..d1f4eb5 100644 --- a/Pods/Target Support Files/SVProgressHUD/SVProgressHUD-Info.plist +++ b/Pods/Target Support Files/SVProgressHUD/SVProgressHUD-Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.2.5 + 2.3.1 CFBundleSignature ???? CFBundleVersion diff --git a/Pods/Target Support Files/SnapKit/ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist b/Pods/Target Support Files/SnapKit/ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist new file mode 100644 index 0000000..d6be571 --- /dev/null +++ b/Pods/Target Support Files/SnapKit/ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 5.7.1 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/SnapKit/SnapKit-Info.plist b/Pods/Target Support Files/SnapKit/SnapKit-Info.plist index 8b4dc1d..af3ef2c 100644 --- a/Pods/Target Support Files/SnapKit/SnapKit-Info.plist +++ b/Pods/Target Support Files/SnapKit/SnapKit-Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 5.6.0 + 5.7.1 CFBundleSignature ???? CFBundleVersion diff --git a/Pods/Target Support Files/SnapKit/SnapKit.debug.xcconfig b/Pods/Target Support Files/SnapKit/SnapKit.debug.xcconfig index 3aab1a8..3e6e223 100644 --- a/Pods/Target Support Files/SnapKit/SnapKit.debug.xcconfig +++ b/Pods/Target Support Files/SnapKit/SnapKit.debug.xcconfig @@ -1,7 +1,8 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SnapKit GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift $(SDKROOT)/usr/lib/swift +OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) diff --git a/Pods/Target Support Files/SnapKit/SnapKit.release.xcconfig b/Pods/Target Support Files/SnapKit/SnapKit.release.xcconfig index 3aab1a8..3e6e223 100644 --- a/Pods/Target Support Files/SnapKit/SnapKit.release.xcconfig +++ b/Pods/Target Support Files/SnapKit/SnapKit.release.xcconfig @@ -1,7 +1,8 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SnapKit GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift $(SDKROOT)/usr/lib/swift +OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)