├── .DS_Store ├── .gitignore ├── DemoCacheDirectory ├── .DS_Store ├── DemoCacheDirectory.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── DemoCacheDirectory │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── ViewController.h │ ├── ViewController.m │ └── main.m ├── DemoCacheDirectoryTests │ ├── DemoCacheDirectoryTests.m │ └── Info.plist └── DemoCacheDirectoryUITests │ ├── DemoCacheDirectoryUITests.m │ └── Info.plist ├── LICENSE ├── README.md ├── SYCacheFileViewController.podspec ├── SYCacheFileViewController ├── .DS_Store ├── SYCacheFileAudio.h ├── SYCacheFileAudio.m ├── SYCacheFileCell.h ├── SYCacheFileCell.m ├── SYCacheFileCollection.h ├── SYCacheFileCollection.m ├── SYCacheFileCollectionCell.h ├── SYCacheFileCollectionCell.m ├── SYCacheFileDefine.h ├── SYCacheFileImage.h ├── SYCacheFileImage.m ├── SYCacheFileImages │ ├── apk_cacheFile.png │ ├── audio_cacheFile.png │ ├── audio_cacheFile@2x.png │ ├── audio_cacheFile@3x.png │ ├── doc_cacheFile.png │ ├── doc_cacheFile@2x.png │ ├── doc_cacheFile@3x.png │ ├── file_cacheFile.png │ ├── file_cacheFile@2x.png │ ├── file_cacheFile@3x.png │ ├── folder_cacheFile.png │ ├── folder_cacheFile@2x.png │ ├── folder_cacheFile@3x.png │ ├── image_cacheFile.png │ ├── image_cacheFile@2x.png │ ├── image_cacheFile@3x.png │ ├── line_cacheFile.png │ ├── pdf_cacheFile.png │ ├── pdf_cacheFile@2x.png │ ├── pdf_cacheFile@3x.png │ ├── ppt_cacheFile.png │ ├── ppt_cacheFile@2x.png │ ├── ppt_cacheFile@3x.png │ ├── video_cacheFile.png │ ├── video_cacheFile@2x.png │ ├── video_cacheFile@3x.png │ ├── xls_cacheFile.png │ ├── xls_cacheFile@2x.png │ ├── xls_cacheFile@3x.png │ ├── zip_cacheFile.png │ ├── zip_cacheFile@2x.png │ └── zip_cacheFile@3x.png ├── SYCacheFileManager.h ├── SYCacheFileManager.m ├── SYCacheFileModel.h ├── SYCacheFileModel.m ├── SYCacheFileRead.h ├── SYCacheFileRead.m ├── SYCacheFileTable.h ├── SYCacheFileTable.m ├── SYCacheFileVideo.h ├── SYCacheFileVideo.m ├── SYCacheFileViewController.h └── SYCacheFileViewController.m └── images ├── .DS_Store ├── SYCacheFileViewController.mindnode ├── QuickLook │ └── Preview.jpg ├── contents.xml ├── style.mindnodestyle │ ├── contents.xml │ └── metadata.plist └── viewState.plist ├── SYCacheFileViewController.png ├── cacheFile_File01.gif ├── cacheFile_File02.gif ├── cacheFile_audio.gif ├── cacheFile_delete.gif ├── cacheFile_delete.png ├── cacheFile_directory.gif ├── cacheFile_image.gif └── cacheFile_video.gif /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | # CocoaPods 32 | # 33 | # We recommend against adding the Pods directory to your .gitignore. However 34 | # you should judge for yourself, the pros and cons are mentioned at: 35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 36 | # 37 | # Pods/ 38 | 39 | # Carthage 40 | # 41 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 42 | # Carthage/Checkouts 43 | 44 | Carthage/Build 45 | 46 | # fastlane 47 | # 48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 49 | # screenshots whenever they are needed. 50 | # For more information about the recommended setup visit: 51 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 52 | 53 | fastlane/report.xml 54 | fastlane/Preview.html 55 | fastlane/screenshots 56 | fastlane/test_output 57 | 58 | # Code Injection 59 | # 60 | # After new code Injection tools there's a generated folder /iOSInjectionProject 61 | # https://github.com/johnno1962/injectionforxcode 62 | 63 | iOSInjectionProject/ 64 | -------------------------------------------------------------------------------- /DemoCacheDirectory/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/DemoCacheDirectory/.DS_Store -------------------------------------------------------------------------------- /DemoCacheDirectory/DemoCacheDirectory.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | A7522B2E21E7186800C102F2 /* AVKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7522B2D21E7186800C102F2 /* AVKit.framework */; }; 11 | A75581D121EC76020015A71F /* zip_cacheFile.png in Resources */ = {isa = PBXBuildFile; fileRef = A75581CE21EC76010015A71F /* zip_cacheFile.png */; }; 12 | A75581D221EC76020015A71F /* zip_cacheFile@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A75581CF21EC76010015A71F /* zip_cacheFile@2x.png */; }; 13 | A75581D321EC76020015A71F /* zip_cacheFile@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = A75581D021EC76010015A71F /* zip_cacheFile@3x.png */; }; 14 | A75581D521EC76EC0015A71F /* apk_cacheFile.png in Resources */ = {isa = PBXBuildFile; fileRef = A75581D421EC76EC0015A71F /* apk_cacheFile.png */; }; 15 | A75BFEFB221E46BB008C7D10 /* SYCacheFileAudio.m in Sources */ = {isa = PBXBuildFile; fileRef = A75BFEFA221E46BB008C7D10 /* SYCacheFileAudio.m */; }; 16 | A75BFEFE221E46D8008C7D10 /* SYCacheFileVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A75BFEFD221E46D8008C7D10 /* SYCacheFileVideo.m */; }; 17 | A760EE491F03A57300594860 /* SYCacheFileCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A760EE251F03A57300594860 /* SYCacheFileCell.m */; }; 18 | A760EE4A1F03A57300594860 /* SYCacheFileRead.m in Sources */ = {isa = PBXBuildFile; fileRef = A760EE271F03A57300594860 /* SYCacheFileRead.m */; }; 19 | A760EE4B1F03A57300594860 /* SYCacheFileTable.m in Sources */ = {isa = PBXBuildFile; fileRef = A760EE291F03A57300594860 /* SYCacheFileTable.m */; }; 20 | A760EE4D1F03A57300594860 /* SYCacheFileViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A760EE2D1F03A57300594860 /* SYCacheFileViewController.m */; }; 21 | A760EE4E1F03A57300594860 /* audio_cacheFile.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE2F1F03A57300594860 /* audio_cacheFile.png */; }; 22 | A760EE4F1F03A57300594860 /* audio_cacheFile@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE301F03A57300594860 /* audio_cacheFile@2x.png */; }; 23 | A760EE501F03A57300594860 /* audio_cacheFile@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE311F03A57300594860 /* audio_cacheFile@3x.png */; }; 24 | A760EE511F03A57300594860 /* doc_cacheFile.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE321F03A57300594860 /* doc_cacheFile.png */; }; 25 | A760EE521F03A57300594860 /* doc_cacheFile@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE331F03A57300594860 /* doc_cacheFile@2x.png */; }; 26 | A760EE531F03A57300594860 /* doc_cacheFile@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE341F03A57300594860 /* doc_cacheFile@3x.png */; }; 27 | A760EE541F03A57300594860 /* file_cacheFile.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE351F03A57300594860 /* file_cacheFile.png */; }; 28 | A760EE551F03A57300594860 /* file_cacheFile@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE361F03A57300594860 /* file_cacheFile@2x.png */; }; 29 | A760EE561F03A57300594860 /* file_cacheFile@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE371F03A57300594860 /* file_cacheFile@3x.png */; }; 30 | A760EE571F03A57300594860 /* image_cacheFile.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE381F03A57300594860 /* image_cacheFile.png */; }; 31 | A760EE581F03A57300594860 /* image_cacheFile@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE391F03A57300594860 /* image_cacheFile@2x.png */; }; 32 | A760EE591F03A57300594860 /* image_cacheFile@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE3A1F03A57300594860 /* image_cacheFile@3x.png */; }; 33 | A760EE5A1F03A57300594860 /* pdf_cacheFile.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE3B1F03A57300594860 /* pdf_cacheFile.png */; }; 34 | A760EE5B1F03A57300594860 /* pdf_cacheFile@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE3C1F03A57300594860 /* pdf_cacheFile@2x.png */; }; 35 | A760EE5C1F03A57300594860 /* pdf_cacheFile@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE3D1F03A57300594860 /* pdf_cacheFile@3x.png */; }; 36 | A760EE5D1F03A57300594860 /* ppt_cacheFile.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE3E1F03A57300594860 /* ppt_cacheFile.png */; }; 37 | A760EE5E1F03A57300594860 /* ppt_cacheFile@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE3F1F03A57300594860 /* ppt_cacheFile@2x.png */; }; 38 | A760EE5F1F03A57300594860 /* ppt_cacheFile@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE401F03A57300594860 /* ppt_cacheFile@3x.png */; }; 39 | A760EE601F03A57300594860 /* video_cacheFile.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE411F03A57300594860 /* video_cacheFile.png */; }; 40 | A760EE611F03A57300594860 /* video_cacheFile@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE421F03A57300594860 /* video_cacheFile@2x.png */; }; 41 | A760EE621F03A57300594860 /* video_cacheFile@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE431F03A57300594860 /* video_cacheFile@3x.png */; }; 42 | A760EE631F03A57300594860 /* xls_cacheFile.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE441F03A57300594860 /* xls_cacheFile.png */; }; 43 | A760EE641F03A57300594860 /* xls_cacheFile@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE451F03A57300594860 /* xls_cacheFile@2x.png */; }; 44 | A760EE651F03A57300594860 /* xls_cacheFile@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE461F03A57300594860 /* xls_cacheFile@3x.png */; }; 45 | A760EE661F03A57300594860 /* SYCacheFileModel.m in Sources */ = {isa = PBXBuildFile; fileRef = A760EE481F03A57300594860 /* SYCacheFileModel.m */; }; 46 | A760EE691F03A74C00594860 /* SYCacheFileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = A760EE681F03A74C00594860 /* SYCacheFileManager.m */; }; 47 | A760EE6E1F03B44E00594860 /* folder_cacheFile.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE6B1F03B44E00594860 /* folder_cacheFile.png */; }; 48 | A760EE6F1F03B44E00594860 /* folder_cacheFile@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE6C1F03B44E00594860 /* folder_cacheFile@2x.png */; }; 49 | A760EE701F03B44E00594860 /* folder_cacheFile@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = A760EE6D1F03B44E00594860 /* folder_cacheFile@3x.png */; }; 50 | A7845A5D2110765100239867 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7845A5C2110765100239867 /* UIKit.framework */; }; 51 | A7845A5F2110767A00239867 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7845A5E2110767A00239867 /* Foundation.framework */; }; 52 | A7845A612110767F00239867 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7845A602110767F00239867 /* AVFoundation.framework */; }; 53 | A7957A10221259180063D32F /* SYCacheFileImage.m in Sources */ = {isa = PBXBuildFile; fileRef = A7957A0F221259180063D32F /* SYCacheFileImage.m */; }; 54 | A7C33F3F1F063E16007B4BC4 /* line_cacheFile.png in Resources */ = {isa = PBXBuildFile; fileRef = A7C33F3E1F063E16007B4BC4 /* line_cacheFile.png */; }; 55 | A7F0F0B21F022DEA001E482B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A7F0F0B11F022DEA001E482B /* main.m */; }; 56 | A7F0F0B51F022DEA001E482B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A7F0F0B41F022DEA001E482B /* AppDelegate.m */; }; 57 | A7F0F0B81F022DEA001E482B /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A7F0F0B71F022DEA001E482B /* ViewController.m */; }; 58 | A7F0F0BB1F022DEA001E482B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A7F0F0B91F022DEA001E482B /* Main.storyboard */; }; 59 | A7F0F0BD1F022DEA001E482B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A7F0F0BC1F022DEA001E482B /* Assets.xcassets */; }; 60 | A7F0F0C01F022DEA001E482B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A7F0F0BE1F022DEA001E482B /* LaunchScreen.storyboard */; }; 61 | A7F0F0CB1F022DEA001E482B /* DemoCacheDirectoryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A7F0F0CA1F022DEA001E482B /* DemoCacheDirectoryTests.m */; }; 62 | A7F0F0D61F022DEA001E482B /* DemoCacheDirectoryUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = A7F0F0D51F022DEA001E482B /* DemoCacheDirectoryUITests.m */; }; 63 | A7F9262022261BC30081DC8A /* SYCacheFileCollectionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A7F9261F22261BC30081DC8A /* SYCacheFileCollectionCell.m */; }; 64 | A7F9262322261BEA0081DC8A /* SYCacheFileCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = A7F9262222261BEA0081DC8A /* SYCacheFileCollection.m */; }; 65 | /* End PBXBuildFile section */ 66 | 67 | /* Begin PBXContainerItemProxy section */ 68 | A7F0F0C71F022DEA001E482B /* PBXContainerItemProxy */ = { 69 | isa = PBXContainerItemProxy; 70 | containerPortal = A7F0F0A51F022DEA001E482B /* Project object */; 71 | proxyType = 1; 72 | remoteGlobalIDString = A7F0F0AC1F022DEA001E482B; 73 | remoteInfo = DemoCacheDirectory; 74 | }; 75 | A7F0F0D21F022DEA001E482B /* PBXContainerItemProxy */ = { 76 | isa = PBXContainerItemProxy; 77 | containerPortal = A7F0F0A51F022DEA001E482B /* Project object */; 78 | proxyType = 1; 79 | remoteGlobalIDString = A7F0F0AC1F022DEA001E482B; 80 | remoteInfo = DemoCacheDirectory; 81 | }; 82 | /* End PBXContainerItemProxy section */ 83 | 84 | /* Begin PBXFileReference section */ 85 | A7522B2D21E7186800C102F2 /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = System/Library/Frameworks/AVKit.framework; sourceTree = SDKROOT; }; 86 | A75581CE21EC76010015A71F /* zip_cacheFile.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = zip_cacheFile.png; sourceTree = ""; }; 87 | A75581CF21EC76010015A71F /* zip_cacheFile@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "zip_cacheFile@2x.png"; sourceTree = ""; }; 88 | A75581D021EC76010015A71F /* zip_cacheFile@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "zip_cacheFile@3x.png"; sourceTree = ""; }; 89 | A75581D421EC76EC0015A71F /* apk_cacheFile.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = apk_cacheFile.png; sourceTree = ""; }; 90 | A75BFEF9221E46BB008C7D10 /* SYCacheFileAudio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SYCacheFileAudio.h; sourceTree = ""; }; 91 | A75BFEFA221E46BB008C7D10 /* SYCacheFileAudio.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SYCacheFileAudio.m; sourceTree = ""; }; 92 | A75BFEFC221E46D8008C7D10 /* SYCacheFileVideo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SYCacheFileVideo.h; sourceTree = ""; }; 93 | A75BFEFD221E46D8008C7D10 /* SYCacheFileVideo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SYCacheFileVideo.m; sourceTree = ""; }; 94 | A760EE241F03A57300594860 /* SYCacheFileCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SYCacheFileCell.h; sourceTree = ""; }; 95 | A760EE251F03A57300594860 /* SYCacheFileCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SYCacheFileCell.m; sourceTree = ""; }; 96 | A760EE261F03A57300594860 /* SYCacheFileRead.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SYCacheFileRead.h; sourceTree = ""; }; 97 | A760EE271F03A57300594860 /* SYCacheFileRead.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SYCacheFileRead.m; sourceTree = ""; }; 98 | A760EE281F03A57300594860 /* SYCacheFileTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SYCacheFileTable.h; sourceTree = ""; }; 99 | A760EE291F03A57300594860 /* SYCacheFileTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SYCacheFileTable.m; sourceTree = ""; }; 100 | A760EE2C1F03A57300594860 /* SYCacheFileViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SYCacheFileViewController.h; sourceTree = ""; }; 101 | A760EE2D1F03A57300594860 /* SYCacheFileViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SYCacheFileViewController.m; sourceTree = ""; }; 102 | A760EE2F1F03A57300594860 /* audio_cacheFile.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = audio_cacheFile.png; sourceTree = ""; }; 103 | A760EE301F03A57300594860 /* audio_cacheFile@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "audio_cacheFile@2x.png"; sourceTree = ""; }; 104 | A760EE311F03A57300594860 /* audio_cacheFile@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "audio_cacheFile@3x.png"; sourceTree = ""; }; 105 | A760EE321F03A57300594860 /* doc_cacheFile.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = doc_cacheFile.png; sourceTree = ""; }; 106 | A760EE331F03A57300594860 /* doc_cacheFile@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "doc_cacheFile@2x.png"; sourceTree = ""; }; 107 | A760EE341F03A57300594860 /* doc_cacheFile@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "doc_cacheFile@3x.png"; sourceTree = ""; }; 108 | A760EE351F03A57300594860 /* file_cacheFile.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = file_cacheFile.png; sourceTree = ""; }; 109 | A760EE361F03A57300594860 /* file_cacheFile@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_cacheFile@2x.png"; sourceTree = ""; }; 110 | A760EE371F03A57300594860 /* file_cacheFile@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_cacheFile@3x.png"; sourceTree = ""; }; 111 | A760EE381F03A57300594860 /* image_cacheFile.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = image_cacheFile.png; sourceTree = ""; }; 112 | A760EE391F03A57300594860 /* image_cacheFile@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image_cacheFile@2x.png"; sourceTree = ""; }; 113 | A760EE3A1F03A57300594860 /* image_cacheFile@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image_cacheFile@3x.png"; sourceTree = ""; }; 114 | A760EE3B1F03A57300594860 /* pdf_cacheFile.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pdf_cacheFile.png; sourceTree = ""; }; 115 | A760EE3C1F03A57300594860 /* pdf_cacheFile@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "pdf_cacheFile@2x.png"; sourceTree = ""; }; 116 | A760EE3D1F03A57300594860 /* pdf_cacheFile@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "pdf_cacheFile@3x.png"; sourceTree = ""; }; 117 | A760EE3E1F03A57300594860 /* ppt_cacheFile.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ppt_cacheFile.png; sourceTree = ""; }; 118 | A760EE3F1F03A57300594860 /* ppt_cacheFile@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ppt_cacheFile@2x.png"; sourceTree = ""; }; 119 | A760EE401F03A57300594860 /* ppt_cacheFile@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ppt_cacheFile@3x.png"; sourceTree = ""; }; 120 | A760EE411F03A57300594860 /* video_cacheFile.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = video_cacheFile.png; sourceTree = ""; }; 121 | A760EE421F03A57300594860 /* video_cacheFile@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "video_cacheFile@2x.png"; sourceTree = ""; }; 122 | A760EE431F03A57300594860 /* video_cacheFile@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "video_cacheFile@3x.png"; sourceTree = ""; }; 123 | A760EE441F03A57300594860 /* xls_cacheFile.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = xls_cacheFile.png; sourceTree = ""; }; 124 | A760EE451F03A57300594860 /* xls_cacheFile@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "xls_cacheFile@2x.png"; sourceTree = ""; }; 125 | A760EE461F03A57300594860 /* xls_cacheFile@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "xls_cacheFile@3x.png"; sourceTree = ""; }; 126 | A760EE471F03A57300594860 /* SYCacheFileModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SYCacheFileModel.h; sourceTree = ""; }; 127 | A760EE481F03A57300594860 /* SYCacheFileModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SYCacheFileModel.m; sourceTree = ""; }; 128 | A760EE671F03A74C00594860 /* SYCacheFileManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SYCacheFileManager.h; sourceTree = ""; }; 129 | A760EE681F03A74C00594860 /* SYCacheFileManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SYCacheFileManager.m; sourceTree = ""; }; 130 | A760EE6A1F03A92400594860 /* SYCacheFileDefine.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SYCacheFileDefine.h; sourceTree = ""; }; 131 | A760EE6B1F03B44E00594860 /* folder_cacheFile.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = folder_cacheFile.png; sourceTree = ""; }; 132 | A760EE6C1F03B44E00594860 /* folder_cacheFile@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "folder_cacheFile@2x.png"; sourceTree = ""; }; 133 | A760EE6D1F03B44E00594860 /* folder_cacheFile@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "folder_cacheFile@3x.png"; sourceTree = ""; }; 134 | A7845A5C2110765100239867 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 135 | A7845A5E2110767A00239867 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 136 | A7845A602110767F00239867 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; 137 | A7957A0E221259180063D32F /* SYCacheFileImage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SYCacheFileImage.h; sourceTree = ""; }; 138 | A7957A0F221259180063D32F /* SYCacheFileImage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SYCacheFileImage.m; sourceTree = ""; }; 139 | A7C33F3E1F063E16007B4BC4 /* line_cacheFile.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = line_cacheFile.png; sourceTree = ""; }; 140 | A7F0F0AD1F022DEA001E482B /* DemoCacheDirectory.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DemoCacheDirectory.app; sourceTree = BUILT_PRODUCTS_DIR; }; 141 | A7F0F0B11F022DEA001E482B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 142 | A7F0F0B31F022DEA001E482B /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 143 | A7F0F0B41F022DEA001E482B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 144 | A7F0F0B61F022DEA001E482B /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 145 | A7F0F0B71F022DEA001E482B /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 146 | A7F0F0BA1F022DEA001E482B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 147 | A7F0F0BC1F022DEA001E482B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 148 | A7F0F0BF1F022DEA001E482B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 149 | A7F0F0C11F022DEA001E482B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 150 | A7F0F0C61F022DEA001E482B /* DemoCacheDirectoryTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DemoCacheDirectoryTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 151 | A7F0F0CA1F022DEA001E482B /* DemoCacheDirectoryTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DemoCacheDirectoryTests.m; sourceTree = ""; }; 152 | A7F0F0CC1F022DEA001E482B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 153 | A7F0F0D11F022DEA001E482B /* DemoCacheDirectoryUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DemoCacheDirectoryUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 154 | A7F0F0D51F022DEA001E482B /* DemoCacheDirectoryUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DemoCacheDirectoryUITests.m; sourceTree = ""; }; 155 | A7F0F0D71F022DEA001E482B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 156 | A7F9261E22261BC30081DC8A /* SYCacheFileCollectionCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SYCacheFileCollectionCell.h; sourceTree = ""; }; 157 | A7F9261F22261BC30081DC8A /* SYCacheFileCollectionCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SYCacheFileCollectionCell.m; sourceTree = ""; }; 158 | A7F9262122261BEA0081DC8A /* SYCacheFileCollection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SYCacheFileCollection.h; sourceTree = ""; }; 159 | A7F9262222261BEA0081DC8A /* SYCacheFileCollection.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SYCacheFileCollection.m; sourceTree = ""; }; 160 | /* End PBXFileReference section */ 161 | 162 | /* Begin PBXFrameworksBuildPhase section */ 163 | A7F0F0AA1F022DEA001E482B /* Frameworks */ = { 164 | isa = PBXFrameworksBuildPhase; 165 | buildActionMask = 2147483647; 166 | files = ( 167 | A7522B2E21E7186800C102F2 /* AVKit.framework in Frameworks */, 168 | A7845A612110767F00239867 /* AVFoundation.framework in Frameworks */, 169 | A7845A5F2110767A00239867 /* Foundation.framework in Frameworks */, 170 | A7845A5D2110765100239867 /* UIKit.framework in Frameworks */, 171 | ); 172 | runOnlyForDeploymentPostprocessing = 0; 173 | }; 174 | A7F0F0C31F022DEA001E482B /* Frameworks */ = { 175 | isa = PBXFrameworksBuildPhase; 176 | buildActionMask = 2147483647; 177 | files = ( 178 | ); 179 | runOnlyForDeploymentPostprocessing = 0; 180 | }; 181 | A7F0F0CE1F022DEA001E482B /* Frameworks */ = { 182 | isa = PBXFrameworksBuildPhase; 183 | buildActionMask = 2147483647; 184 | files = ( 185 | ); 186 | runOnlyForDeploymentPostprocessing = 0; 187 | }; 188 | /* End PBXFrameworksBuildPhase section */ 189 | 190 | /* Begin PBXGroup section */ 191 | A760EE231F03A57300594860 /* SYCacheFileViewController */ = { 192 | isa = PBXGroup; 193 | children = ( 194 | A760EE241F03A57300594860 /* SYCacheFileCell.h */, 195 | A760EE251F03A57300594860 /* SYCacheFileCell.m */, 196 | A760EE261F03A57300594860 /* SYCacheFileRead.h */, 197 | A760EE271F03A57300594860 /* SYCacheFileRead.m */, 198 | A760EE281F03A57300594860 /* SYCacheFileTable.h */, 199 | A760EE291F03A57300594860 /* SYCacheFileTable.m */, 200 | A760EE671F03A74C00594860 /* SYCacheFileManager.h */, 201 | A760EE681F03A74C00594860 /* SYCacheFileManager.m */, 202 | A7957A0E221259180063D32F /* SYCacheFileImage.h */, 203 | A7957A0F221259180063D32F /* SYCacheFileImage.m */, 204 | A75BFEF9221E46BB008C7D10 /* SYCacheFileAudio.h */, 205 | A75BFEFA221E46BB008C7D10 /* SYCacheFileAudio.m */, 206 | A75BFEFC221E46D8008C7D10 /* SYCacheFileVideo.h */, 207 | A75BFEFD221E46D8008C7D10 /* SYCacheFileVideo.m */, 208 | A760EE2C1F03A57300594860 /* SYCacheFileViewController.h */, 209 | A760EE2D1F03A57300594860 /* SYCacheFileViewController.m */, 210 | A760EE2E1F03A57300594860 /* SYCacheFileImages */, 211 | A760EE471F03A57300594860 /* SYCacheFileModel.h */, 212 | A760EE481F03A57300594860 /* SYCacheFileModel.m */, 213 | A760EE6A1F03A92400594860 /* SYCacheFileDefine.h */, 214 | A7F9261E22261BC30081DC8A /* SYCacheFileCollectionCell.h */, 215 | A7F9261F22261BC30081DC8A /* SYCacheFileCollectionCell.m */, 216 | A7F9262122261BEA0081DC8A /* SYCacheFileCollection.h */, 217 | A7F9262222261BEA0081DC8A /* SYCacheFileCollection.m */, 218 | ); 219 | name = SYCacheFileViewController; 220 | path = ../../SYCacheFileViewController; 221 | sourceTree = ""; 222 | }; 223 | A760EE2E1F03A57300594860 /* SYCacheFileImages */ = { 224 | isa = PBXGroup; 225 | children = ( 226 | A75581D421EC76EC0015A71F /* apk_cacheFile.png */, 227 | A75581CE21EC76010015A71F /* zip_cacheFile.png */, 228 | A75581CF21EC76010015A71F /* zip_cacheFile@2x.png */, 229 | A75581D021EC76010015A71F /* zip_cacheFile@3x.png */, 230 | A7C33F3E1F063E16007B4BC4 /* line_cacheFile.png */, 231 | A760EE6B1F03B44E00594860 /* folder_cacheFile.png */, 232 | A760EE6C1F03B44E00594860 /* folder_cacheFile@2x.png */, 233 | A760EE6D1F03B44E00594860 /* folder_cacheFile@3x.png */, 234 | A760EE2F1F03A57300594860 /* audio_cacheFile.png */, 235 | A760EE301F03A57300594860 /* audio_cacheFile@2x.png */, 236 | A760EE311F03A57300594860 /* audio_cacheFile@3x.png */, 237 | A760EE321F03A57300594860 /* doc_cacheFile.png */, 238 | A760EE331F03A57300594860 /* doc_cacheFile@2x.png */, 239 | A760EE341F03A57300594860 /* doc_cacheFile@3x.png */, 240 | A760EE351F03A57300594860 /* file_cacheFile.png */, 241 | A760EE361F03A57300594860 /* file_cacheFile@2x.png */, 242 | A760EE371F03A57300594860 /* file_cacheFile@3x.png */, 243 | A760EE381F03A57300594860 /* image_cacheFile.png */, 244 | A760EE391F03A57300594860 /* image_cacheFile@2x.png */, 245 | A760EE3A1F03A57300594860 /* image_cacheFile@3x.png */, 246 | A760EE3B1F03A57300594860 /* pdf_cacheFile.png */, 247 | A760EE3C1F03A57300594860 /* pdf_cacheFile@2x.png */, 248 | A760EE3D1F03A57300594860 /* pdf_cacheFile@3x.png */, 249 | A760EE3E1F03A57300594860 /* ppt_cacheFile.png */, 250 | A760EE3F1F03A57300594860 /* ppt_cacheFile@2x.png */, 251 | A760EE401F03A57300594860 /* ppt_cacheFile@3x.png */, 252 | A760EE411F03A57300594860 /* video_cacheFile.png */, 253 | A760EE421F03A57300594860 /* video_cacheFile@2x.png */, 254 | A760EE431F03A57300594860 /* video_cacheFile@3x.png */, 255 | A760EE441F03A57300594860 /* xls_cacheFile.png */, 256 | A760EE451F03A57300594860 /* xls_cacheFile@2x.png */, 257 | A760EE461F03A57300594860 /* xls_cacheFile@3x.png */, 258 | ); 259 | path = SYCacheFileImages; 260 | sourceTree = ""; 261 | }; 262 | A7845A5B2110765100239867 /* Frameworks */ = { 263 | isa = PBXGroup; 264 | children = ( 265 | A7522B2D21E7186800C102F2 /* AVKit.framework */, 266 | A7845A602110767F00239867 /* AVFoundation.framework */, 267 | A7845A5E2110767A00239867 /* Foundation.framework */, 268 | A7845A5C2110765100239867 /* UIKit.framework */, 269 | ); 270 | name = Frameworks; 271 | sourceTree = ""; 272 | }; 273 | A7F0F0A41F022DEA001E482B = { 274 | isa = PBXGroup; 275 | children = ( 276 | A7F0F0AF1F022DEA001E482B /* DemoCacheDirectory */, 277 | A7F0F0C91F022DEA001E482B /* DemoCacheDirectoryTests */, 278 | A7F0F0D41F022DEA001E482B /* DemoCacheDirectoryUITests */, 279 | A7F0F0AE1F022DEA001E482B /* Products */, 280 | A7845A5B2110765100239867 /* Frameworks */, 281 | ); 282 | sourceTree = ""; 283 | }; 284 | A7F0F0AE1F022DEA001E482B /* Products */ = { 285 | isa = PBXGroup; 286 | children = ( 287 | A7F0F0AD1F022DEA001E482B /* DemoCacheDirectory.app */, 288 | A7F0F0C61F022DEA001E482B /* DemoCacheDirectoryTests.xctest */, 289 | A7F0F0D11F022DEA001E482B /* DemoCacheDirectoryUITests.xctest */, 290 | ); 291 | name = Products; 292 | sourceTree = ""; 293 | }; 294 | A7F0F0AF1F022DEA001E482B /* DemoCacheDirectory */ = { 295 | isa = PBXGroup; 296 | children = ( 297 | A7F0F0B31F022DEA001E482B /* AppDelegate.h */, 298 | A7F0F0B41F022DEA001E482B /* AppDelegate.m */, 299 | A7F0F0B61F022DEA001E482B /* ViewController.h */, 300 | A7F0F0B71F022DEA001E482B /* ViewController.m */, 301 | A760EE231F03A57300594860 /* SYCacheFileViewController */, 302 | A7F0F0B01F022DEA001E482B /* Supporting Files */, 303 | ); 304 | path = DemoCacheDirectory; 305 | sourceTree = ""; 306 | }; 307 | A7F0F0B01F022DEA001E482B /* Supporting Files */ = { 308 | isa = PBXGroup; 309 | children = ( 310 | A7F0F0B91F022DEA001E482B /* Main.storyboard */, 311 | A7F0F0BC1F022DEA001E482B /* Assets.xcassets */, 312 | A7F0F0BE1F022DEA001E482B /* LaunchScreen.storyboard */, 313 | A7F0F0C11F022DEA001E482B /* Info.plist */, 314 | A7F0F0B11F022DEA001E482B /* main.m */, 315 | ); 316 | name = "Supporting Files"; 317 | sourceTree = ""; 318 | }; 319 | A7F0F0C91F022DEA001E482B /* DemoCacheDirectoryTests */ = { 320 | isa = PBXGroup; 321 | children = ( 322 | A7F0F0CA1F022DEA001E482B /* DemoCacheDirectoryTests.m */, 323 | A7F0F0CC1F022DEA001E482B /* Info.plist */, 324 | ); 325 | path = DemoCacheDirectoryTests; 326 | sourceTree = ""; 327 | }; 328 | A7F0F0D41F022DEA001E482B /* DemoCacheDirectoryUITests */ = { 329 | isa = PBXGroup; 330 | children = ( 331 | A7F0F0D51F022DEA001E482B /* DemoCacheDirectoryUITests.m */, 332 | A7F0F0D71F022DEA001E482B /* Info.plist */, 333 | ); 334 | path = DemoCacheDirectoryUITests; 335 | sourceTree = ""; 336 | }; 337 | /* End PBXGroup section */ 338 | 339 | /* Begin PBXNativeTarget section */ 340 | A7F0F0AC1F022DEA001E482B /* DemoCacheDirectory */ = { 341 | isa = PBXNativeTarget; 342 | buildConfigurationList = A7F0F0DA1F022DEA001E482B /* Build configuration list for PBXNativeTarget "DemoCacheDirectory" */; 343 | buildPhases = ( 344 | A7F0F0A91F022DEA001E482B /* Sources */, 345 | A7F0F0AA1F022DEA001E482B /* Frameworks */, 346 | A7F0F0AB1F022DEA001E482B /* Resources */, 347 | ); 348 | buildRules = ( 349 | ); 350 | dependencies = ( 351 | ); 352 | name = DemoCacheDirectory; 353 | productName = DemoCacheDirectory; 354 | productReference = A7F0F0AD1F022DEA001E482B /* DemoCacheDirectory.app */; 355 | productType = "com.apple.product-type.application"; 356 | }; 357 | A7F0F0C51F022DEA001E482B /* DemoCacheDirectoryTests */ = { 358 | isa = PBXNativeTarget; 359 | buildConfigurationList = A7F0F0DD1F022DEA001E482B /* Build configuration list for PBXNativeTarget "DemoCacheDirectoryTests" */; 360 | buildPhases = ( 361 | A7F0F0C21F022DEA001E482B /* Sources */, 362 | A7F0F0C31F022DEA001E482B /* Frameworks */, 363 | A7F0F0C41F022DEA001E482B /* Resources */, 364 | ); 365 | buildRules = ( 366 | ); 367 | dependencies = ( 368 | A7F0F0C81F022DEA001E482B /* PBXTargetDependency */, 369 | ); 370 | name = DemoCacheDirectoryTests; 371 | productName = DemoCacheDirectoryTests; 372 | productReference = A7F0F0C61F022DEA001E482B /* DemoCacheDirectoryTests.xctest */; 373 | productType = "com.apple.product-type.bundle.unit-test"; 374 | }; 375 | A7F0F0D01F022DEA001E482B /* DemoCacheDirectoryUITests */ = { 376 | isa = PBXNativeTarget; 377 | buildConfigurationList = A7F0F0E01F022DEA001E482B /* Build configuration list for PBXNativeTarget "DemoCacheDirectoryUITests" */; 378 | buildPhases = ( 379 | A7F0F0CD1F022DEA001E482B /* Sources */, 380 | A7F0F0CE1F022DEA001E482B /* Frameworks */, 381 | A7F0F0CF1F022DEA001E482B /* Resources */, 382 | ); 383 | buildRules = ( 384 | ); 385 | dependencies = ( 386 | A7F0F0D31F022DEA001E482B /* PBXTargetDependency */, 387 | ); 388 | name = DemoCacheDirectoryUITests; 389 | productName = DemoCacheDirectoryUITests; 390 | productReference = A7F0F0D11F022DEA001E482B /* DemoCacheDirectoryUITests.xctest */; 391 | productType = "com.apple.product-type.bundle.ui-testing"; 392 | }; 393 | /* End PBXNativeTarget section */ 394 | 395 | /* Begin PBXProject section */ 396 | A7F0F0A51F022DEA001E482B /* Project object */ = { 397 | isa = PBXProject; 398 | attributes = { 399 | LastUpgradeCheck = 0720; 400 | ORGANIZATIONNAME = zhangshaoyu; 401 | TargetAttributes = { 402 | A7F0F0AC1F022DEA001E482B = { 403 | CreatedOnToolsVersion = 7.2.1; 404 | DevelopmentTeam = 9YWJ3PZHZG; 405 | ProvisioningStyle = Manual; 406 | }; 407 | A7F0F0C51F022DEA001E482B = { 408 | CreatedOnToolsVersion = 7.2.1; 409 | TestTargetID = A7F0F0AC1F022DEA001E482B; 410 | }; 411 | A7F0F0D01F022DEA001E482B = { 412 | CreatedOnToolsVersion = 7.2.1; 413 | TestTargetID = A7F0F0AC1F022DEA001E482B; 414 | }; 415 | }; 416 | }; 417 | buildConfigurationList = A7F0F0A81F022DEA001E482B /* Build configuration list for PBXProject "DemoCacheDirectory" */; 418 | compatibilityVersion = "Xcode 3.2"; 419 | developmentRegion = English; 420 | hasScannedForEncodings = 0; 421 | knownRegions = ( 422 | en, 423 | Base, 424 | ); 425 | mainGroup = A7F0F0A41F022DEA001E482B; 426 | productRefGroup = A7F0F0AE1F022DEA001E482B /* Products */; 427 | projectDirPath = ""; 428 | projectRoot = ""; 429 | targets = ( 430 | A7F0F0AC1F022DEA001E482B /* DemoCacheDirectory */, 431 | A7F0F0C51F022DEA001E482B /* DemoCacheDirectoryTests */, 432 | A7F0F0D01F022DEA001E482B /* DemoCacheDirectoryUITests */, 433 | ); 434 | }; 435 | /* End PBXProject section */ 436 | 437 | /* Begin PBXResourcesBuildPhase section */ 438 | A7F0F0AB1F022DEA001E482B /* Resources */ = { 439 | isa = PBXResourcesBuildPhase; 440 | buildActionMask = 2147483647; 441 | files = ( 442 | A760EE551F03A57300594860 /* file_cacheFile@2x.png in Resources */, 443 | A760EE641F03A57300594860 /* xls_cacheFile@2x.png in Resources */, 444 | A760EE5A1F03A57300594860 /* pdf_cacheFile.png in Resources */, 445 | A760EE601F03A57300594860 /* video_cacheFile.png in Resources */, 446 | A7F0F0C01F022DEA001E482B /* LaunchScreen.storyboard in Resources */, 447 | A75581D521EC76EC0015A71F /* apk_cacheFile.png in Resources */, 448 | A760EE591F03A57300594860 /* image_cacheFile@3x.png in Resources */, 449 | A760EE4F1F03A57300594860 /* audio_cacheFile@2x.png in Resources */, 450 | A760EE581F03A57300594860 /* image_cacheFile@2x.png in Resources */, 451 | A760EE6F1F03B44E00594860 /* folder_cacheFile@2x.png in Resources */, 452 | A7C33F3F1F063E16007B4BC4 /* line_cacheFile.png in Resources */, 453 | A75581D121EC76020015A71F /* zip_cacheFile.png in Resources */, 454 | A760EE521F03A57300594860 /* doc_cacheFile@2x.png in Resources */, 455 | A760EE531F03A57300594860 /* doc_cacheFile@3x.png in Resources */, 456 | A75581D221EC76020015A71F /* zip_cacheFile@2x.png in Resources */, 457 | A75581D321EC76020015A71F /* zip_cacheFile@3x.png in Resources */, 458 | A760EE541F03A57300594860 /* file_cacheFile.png in Resources */, 459 | A760EE561F03A57300594860 /* file_cacheFile@3x.png in Resources */, 460 | A760EE511F03A57300594860 /* doc_cacheFile.png in Resources */, 461 | A760EE651F03A57300594860 /* xls_cacheFile@3x.png in Resources */, 462 | A760EE6E1F03B44E00594860 /* folder_cacheFile.png in Resources */, 463 | A760EE701F03B44E00594860 /* folder_cacheFile@3x.png in Resources */, 464 | A7F0F0BD1F022DEA001E482B /* Assets.xcassets in Resources */, 465 | A760EE631F03A57300594860 /* xls_cacheFile.png in Resources */, 466 | A760EE5E1F03A57300594860 /* ppt_cacheFile@2x.png in Resources */, 467 | A760EE5F1F03A57300594860 /* ppt_cacheFile@3x.png in Resources */, 468 | A760EE611F03A57300594860 /* video_cacheFile@2x.png in Resources */, 469 | A760EE5B1F03A57300594860 /* pdf_cacheFile@2x.png in Resources */, 470 | A760EE5C1F03A57300594860 /* pdf_cacheFile@3x.png in Resources */, 471 | A760EE571F03A57300594860 /* image_cacheFile.png in Resources */, 472 | A7F0F0BB1F022DEA001E482B /* Main.storyboard in Resources */, 473 | A760EE4E1F03A57300594860 /* audio_cacheFile.png in Resources */, 474 | A760EE501F03A57300594860 /* audio_cacheFile@3x.png in Resources */, 475 | A760EE621F03A57300594860 /* video_cacheFile@3x.png in Resources */, 476 | A760EE5D1F03A57300594860 /* ppt_cacheFile.png in Resources */, 477 | ); 478 | runOnlyForDeploymentPostprocessing = 0; 479 | }; 480 | A7F0F0C41F022DEA001E482B /* Resources */ = { 481 | isa = PBXResourcesBuildPhase; 482 | buildActionMask = 2147483647; 483 | files = ( 484 | ); 485 | runOnlyForDeploymentPostprocessing = 0; 486 | }; 487 | A7F0F0CF1F022DEA001E482B /* Resources */ = { 488 | isa = PBXResourcesBuildPhase; 489 | buildActionMask = 2147483647; 490 | files = ( 491 | ); 492 | runOnlyForDeploymentPostprocessing = 0; 493 | }; 494 | /* End PBXResourcesBuildPhase section */ 495 | 496 | /* Begin PBXSourcesBuildPhase section */ 497 | A7F0F0A91F022DEA001E482B /* Sources */ = { 498 | isa = PBXSourcesBuildPhase; 499 | buildActionMask = 2147483647; 500 | files = ( 501 | A7F9262022261BC30081DC8A /* SYCacheFileCollectionCell.m in Sources */, 502 | A760EE4A1F03A57300594860 /* SYCacheFileRead.m in Sources */, 503 | A760EE4B1F03A57300594860 /* SYCacheFileTable.m in Sources */, 504 | A760EE691F03A74C00594860 /* SYCacheFileManager.m in Sources */, 505 | A7F0F0B81F022DEA001E482B /* ViewController.m in Sources */, 506 | A760EE661F03A57300594860 /* SYCacheFileModel.m in Sources */, 507 | A75BFEFB221E46BB008C7D10 /* SYCacheFileAudio.m in Sources */, 508 | A7F0F0B51F022DEA001E482B /* AppDelegate.m in Sources */, 509 | A7F9262322261BEA0081DC8A /* SYCacheFileCollection.m in Sources */, 510 | A760EE491F03A57300594860 /* SYCacheFileCell.m in Sources */, 511 | A75BFEFE221E46D8008C7D10 /* SYCacheFileVideo.m in Sources */, 512 | A760EE4D1F03A57300594860 /* SYCacheFileViewController.m in Sources */, 513 | A7957A10221259180063D32F /* SYCacheFileImage.m in Sources */, 514 | A7F0F0B21F022DEA001E482B /* main.m in Sources */, 515 | ); 516 | runOnlyForDeploymentPostprocessing = 0; 517 | }; 518 | A7F0F0C21F022DEA001E482B /* Sources */ = { 519 | isa = PBXSourcesBuildPhase; 520 | buildActionMask = 2147483647; 521 | files = ( 522 | A7F0F0CB1F022DEA001E482B /* DemoCacheDirectoryTests.m in Sources */, 523 | ); 524 | runOnlyForDeploymentPostprocessing = 0; 525 | }; 526 | A7F0F0CD1F022DEA001E482B /* Sources */ = { 527 | isa = PBXSourcesBuildPhase; 528 | buildActionMask = 2147483647; 529 | files = ( 530 | A7F0F0D61F022DEA001E482B /* DemoCacheDirectoryUITests.m in Sources */, 531 | ); 532 | runOnlyForDeploymentPostprocessing = 0; 533 | }; 534 | /* End PBXSourcesBuildPhase section */ 535 | 536 | /* Begin PBXTargetDependency section */ 537 | A7F0F0C81F022DEA001E482B /* PBXTargetDependency */ = { 538 | isa = PBXTargetDependency; 539 | target = A7F0F0AC1F022DEA001E482B /* DemoCacheDirectory */; 540 | targetProxy = A7F0F0C71F022DEA001E482B /* PBXContainerItemProxy */; 541 | }; 542 | A7F0F0D31F022DEA001E482B /* PBXTargetDependency */ = { 543 | isa = PBXTargetDependency; 544 | target = A7F0F0AC1F022DEA001E482B /* DemoCacheDirectory */; 545 | targetProxy = A7F0F0D21F022DEA001E482B /* PBXContainerItemProxy */; 546 | }; 547 | /* End PBXTargetDependency section */ 548 | 549 | /* Begin PBXVariantGroup section */ 550 | A7F0F0B91F022DEA001E482B /* Main.storyboard */ = { 551 | isa = PBXVariantGroup; 552 | children = ( 553 | A7F0F0BA1F022DEA001E482B /* Base */, 554 | ); 555 | name = Main.storyboard; 556 | sourceTree = ""; 557 | }; 558 | A7F0F0BE1F022DEA001E482B /* LaunchScreen.storyboard */ = { 559 | isa = PBXVariantGroup; 560 | children = ( 561 | A7F0F0BF1F022DEA001E482B /* Base */, 562 | ); 563 | name = LaunchScreen.storyboard; 564 | sourceTree = ""; 565 | }; 566 | /* End PBXVariantGroup section */ 567 | 568 | /* Begin XCBuildConfiguration section */ 569 | A7F0F0D81F022DEA001E482B /* Debug */ = { 570 | isa = XCBuildConfiguration; 571 | buildSettings = { 572 | ALWAYS_SEARCH_USER_PATHS = NO; 573 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 574 | CLANG_CXX_LIBRARY = "libc++"; 575 | CLANG_ENABLE_MODULES = YES; 576 | CLANG_ENABLE_OBJC_ARC = YES; 577 | CLANG_WARN_BOOL_CONVERSION = YES; 578 | CLANG_WARN_CONSTANT_CONVERSION = YES; 579 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 580 | CLANG_WARN_EMPTY_BODY = YES; 581 | CLANG_WARN_ENUM_CONVERSION = YES; 582 | CLANG_WARN_INT_CONVERSION = YES; 583 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 584 | CLANG_WARN_UNREACHABLE_CODE = YES; 585 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 586 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 587 | COPY_PHASE_STRIP = NO; 588 | DEBUG_INFORMATION_FORMAT = dwarf; 589 | ENABLE_STRICT_OBJC_MSGSEND = YES; 590 | ENABLE_TESTABILITY = YES; 591 | GCC_C_LANGUAGE_STANDARD = gnu99; 592 | GCC_DYNAMIC_NO_PIC = NO; 593 | GCC_NO_COMMON_BLOCKS = YES; 594 | GCC_OPTIMIZATION_LEVEL = 0; 595 | GCC_PREPROCESSOR_DEFINITIONS = ( 596 | "DEBUG=1", 597 | "$(inherited)", 598 | ); 599 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 600 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 601 | GCC_WARN_UNDECLARED_SELECTOR = YES; 602 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 603 | GCC_WARN_UNUSED_FUNCTION = YES; 604 | GCC_WARN_UNUSED_VARIABLE = YES; 605 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 606 | MTL_ENABLE_DEBUG_INFO = YES; 607 | ONLY_ACTIVE_ARCH = YES; 608 | SDKROOT = iphoneos; 609 | }; 610 | name = Debug; 611 | }; 612 | A7F0F0D91F022DEA001E482B /* Release */ = { 613 | isa = XCBuildConfiguration; 614 | buildSettings = { 615 | ALWAYS_SEARCH_USER_PATHS = NO; 616 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 617 | CLANG_CXX_LIBRARY = "libc++"; 618 | CLANG_ENABLE_MODULES = YES; 619 | CLANG_ENABLE_OBJC_ARC = YES; 620 | CLANG_WARN_BOOL_CONVERSION = YES; 621 | CLANG_WARN_CONSTANT_CONVERSION = YES; 622 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 623 | CLANG_WARN_EMPTY_BODY = YES; 624 | CLANG_WARN_ENUM_CONVERSION = YES; 625 | CLANG_WARN_INT_CONVERSION = YES; 626 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 627 | CLANG_WARN_UNREACHABLE_CODE = YES; 628 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 629 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 630 | COPY_PHASE_STRIP = NO; 631 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 632 | ENABLE_NS_ASSERTIONS = NO; 633 | ENABLE_STRICT_OBJC_MSGSEND = YES; 634 | GCC_C_LANGUAGE_STANDARD = gnu99; 635 | GCC_NO_COMMON_BLOCKS = YES; 636 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 637 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 638 | GCC_WARN_UNDECLARED_SELECTOR = YES; 639 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 640 | GCC_WARN_UNUSED_FUNCTION = YES; 641 | GCC_WARN_UNUSED_VARIABLE = YES; 642 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 643 | MTL_ENABLE_DEBUG_INFO = NO; 644 | SDKROOT = iphoneos; 645 | VALIDATE_PRODUCT = YES; 646 | }; 647 | name = Release; 648 | }; 649 | A7F0F0DB1F022DEA001E482B /* Debug */ = { 650 | isa = XCBuildConfiguration; 651 | buildSettings = { 652 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 653 | CODE_SIGN_STYLE = Manual; 654 | DEVELOPMENT_TEAM = 9YWJ3PZHZG; 655 | INFOPLIST_FILE = DemoCacheDirectory/Info.plist; 656 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 657 | PRODUCT_BUNDLE_IDENTIFIER = com.byd.common; 658 | PRODUCT_NAME = "$(TARGET_NAME)"; 659 | PROVISIONING_PROFILE_SPECIFIER = Development_Provisioning_BYDCommon; 660 | TARGETED_DEVICE_FAMILY = "1,2"; 661 | }; 662 | name = Debug; 663 | }; 664 | A7F0F0DC1F022DEA001E482B /* Release */ = { 665 | isa = XCBuildConfiguration; 666 | buildSettings = { 667 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 668 | CODE_SIGN_STYLE = Manual; 669 | DEVELOPMENT_TEAM = 9YWJ3PZHZG; 670 | INFOPLIST_FILE = DemoCacheDirectory/Info.plist; 671 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 672 | PRODUCT_BUNDLE_IDENTIFIER = com.byd.common; 673 | PRODUCT_NAME = "$(TARGET_NAME)"; 674 | PROVISIONING_PROFILE_SPECIFIER = Development_Provisioning_BYDCommon; 675 | TARGETED_DEVICE_FAMILY = "1,2"; 676 | }; 677 | name = Release; 678 | }; 679 | A7F0F0DE1F022DEA001E482B /* Debug */ = { 680 | isa = XCBuildConfiguration; 681 | buildSettings = { 682 | BUNDLE_LOADER = "$(TEST_HOST)"; 683 | INFOPLIST_FILE = DemoCacheDirectoryTests/Info.plist; 684 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 685 | PRODUCT_BUNDLE_IDENTIFIER = com.devZhang.DemoCacheDirectoryTests; 686 | PRODUCT_NAME = "$(TARGET_NAME)"; 687 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DemoCacheDirectory.app/DemoCacheDirectory"; 688 | }; 689 | name = Debug; 690 | }; 691 | A7F0F0DF1F022DEA001E482B /* Release */ = { 692 | isa = XCBuildConfiguration; 693 | buildSettings = { 694 | BUNDLE_LOADER = "$(TEST_HOST)"; 695 | INFOPLIST_FILE = DemoCacheDirectoryTests/Info.plist; 696 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 697 | PRODUCT_BUNDLE_IDENTIFIER = com.devZhang.DemoCacheDirectoryTests; 698 | PRODUCT_NAME = "$(TARGET_NAME)"; 699 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DemoCacheDirectory.app/DemoCacheDirectory"; 700 | }; 701 | name = Release; 702 | }; 703 | A7F0F0E11F022DEA001E482B /* Debug */ = { 704 | isa = XCBuildConfiguration; 705 | buildSettings = { 706 | INFOPLIST_FILE = DemoCacheDirectoryUITests/Info.plist; 707 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 708 | PRODUCT_BUNDLE_IDENTIFIER = com.devZhang.DemoCacheDirectoryUITests; 709 | PRODUCT_NAME = "$(TARGET_NAME)"; 710 | TEST_TARGET_NAME = DemoCacheDirectory; 711 | USES_XCTRUNNER = YES; 712 | }; 713 | name = Debug; 714 | }; 715 | A7F0F0E21F022DEA001E482B /* Release */ = { 716 | isa = XCBuildConfiguration; 717 | buildSettings = { 718 | INFOPLIST_FILE = DemoCacheDirectoryUITests/Info.plist; 719 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 720 | PRODUCT_BUNDLE_IDENTIFIER = com.devZhang.DemoCacheDirectoryUITests; 721 | PRODUCT_NAME = "$(TARGET_NAME)"; 722 | TEST_TARGET_NAME = DemoCacheDirectory; 723 | USES_XCTRUNNER = YES; 724 | }; 725 | name = Release; 726 | }; 727 | /* End XCBuildConfiguration section */ 728 | 729 | /* Begin XCConfigurationList section */ 730 | A7F0F0A81F022DEA001E482B /* Build configuration list for PBXProject "DemoCacheDirectory" */ = { 731 | isa = XCConfigurationList; 732 | buildConfigurations = ( 733 | A7F0F0D81F022DEA001E482B /* Debug */, 734 | A7F0F0D91F022DEA001E482B /* Release */, 735 | ); 736 | defaultConfigurationIsVisible = 0; 737 | defaultConfigurationName = Release; 738 | }; 739 | A7F0F0DA1F022DEA001E482B /* Build configuration list for PBXNativeTarget "DemoCacheDirectory" */ = { 740 | isa = XCConfigurationList; 741 | buildConfigurations = ( 742 | A7F0F0DB1F022DEA001E482B /* Debug */, 743 | A7F0F0DC1F022DEA001E482B /* Release */, 744 | ); 745 | defaultConfigurationIsVisible = 0; 746 | defaultConfigurationName = Release; 747 | }; 748 | A7F0F0DD1F022DEA001E482B /* Build configuration list for PBXNativeTarget "DemoCacheDirectoryTests" */ = { 749 | isa = XCConfigurationList; 750 | buildConfigurations = ( 751 | A7F0F0DE1F022DEA001E482B /* Debug */, 752 | A7F0F0DF1F022DEA001E482B /* Release */, 753 | ); 754 | defaultConfigurationIsVisible = 0; 755 | defaultConfigurationName = Release; 756 | }; 757 | A7F0F0E01F022DEA001E482B /* Build configuration list for PBXNativeTarget "DemoCacheDirectoryUITests" */ = { 758 | isa = XCConfigurationList; 759 | buildConfigurations = ( 760 | A7F0F0E11F022DEA001E482B /* Debug */, 761 | A7F0F0E21F022DEA001E482B /* Release */, 762 | ); 763 | defaultConfigurationIsVisible = 0; 764 | defaultConfigurationName = Release; 765 | }; 766 | /* End XCConfigurationList section */ 767 | }; 768 | rootObject = A7F0F0A51F022DEA001E482B /* Project object */; 769 | } 770 | -------------------------------------------------------------------------------- /DemoCacheDirectory/DemoCacheDirectory.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DemoCacheDirectory/DemoCacheDirectory.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /DemoCacheDirectory/DemoCacheDirectory/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // DemoCacheDirectory 4 | // 5 | // Created by zhangshaoyu on 17/6/27. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /DemoCacheDirectory/DemoCacheDirectory/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // DemoCacheDirectory 4 | // 5 | // Created by zhangshaoyu on 17/6/27. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "ViewController.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | // Override point for customization after application launch. 21 | 22 | ViewController *rootVC = [[ViewController alloc] init]; 23 | UINavigationController *rootNav = [[UINavigationController alloc] initWithRootViewController:rootVC]; 24 | self.window.rootViewController = rootNav; 25 | self.window.backgroundColor = [UIColor whiteColor]; 26 | [self.window makeKeyAndVisible]; 27 | 28 | return YES; 29 | } 30 | 31 | - (void)applicationWillResignActive:(UIApplication *)application { 32 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 33 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 34 | } 35 | 36 | - (void)applicationDidEnterBackground:(UIApplication *)application { 37 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 38 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 39 | } 40 | 41 | - (void)applicationWillEnterForeground:(UIApplication *)application { 42 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 43 | } 44 | 45 | - (void)applicationDidBecomeActive:(UIApplication *)application { 46 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 47 | } 48 | 49 | - (void)applicationWillTerminate:(UIApplication *)application { 50 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /DemoCacheDirectory/DemoCacheDirectory/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /DemoCacheDirectory/DemoCacheDirectory/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /DemoCacheDirectory/DemoCacheDirectory/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /DemoCacheDirectory/DemoCacheDirectory/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | 文件管理 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0.0 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /DemoCacheDirectory/DemoCacheDirectory/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // DemoCacheDirectory 4 | // 5 | // Created by zhangshaoyu on 17/6/27. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /DemoCacheDirectory/DemoCacheDirectory/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // DemoCacheDirectory 4 | // 5 | // Created by zhangshaoyu on 17/6/27. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "SYCacheFileViewController.h" 11 | #import "SYCacheFileManager.h" 12 | 13 | @interface ViewController () 14 | 15 | @end 16 | 17 | @implementation ViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | // Do any additional setup after loading the view, typically from a nib. 22 | 23 | self.title = @"缓存目录"; 24 | 25 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Cache" style:UIBarButtonItemStyleDone target:self action:@selector(buttonClick)]; 26 | } 27 | 28 | - (void)didReceiveMemoryWarning { 29 | [super didReceiveMemoryWarning]; 30 | // Dispose of any resources that can be recreated. 31 | } 32 | 33 | - (void)buttonClick 34 | { 35 | // 默认 36 | SYCacheFileViewController *cacheVC = [[SYCacheFileViewController alloc] init]; 37 | [SYCacheFileManager shareManager].showImageShuffling = YES; 38 | cacheVC.showType = 1; 39 | [self.navigationController pushViewController:cacheVC animated:YES]; 40 | 41 | NSString *path = [SYCacheFileManager homeDirectoryPath]; 42 | NSLog(@"path = %@", path); 43 | 44 | // 自定义 45 | // SYCacheFileViewController *cacheVC = [[SYCacheFileViewController alloc] init]; 46 | // // 指定文件格式 47 | // [SYCacheFileManager shareManager].cacheDocumentTypes = @[@".pages", @"wps", @".xls", @".pdf", @".rar"]; 48 | //// [SYCacheFileManager shareManager].showDoucumentUI = YES; 49 | // // 指定目录,或默认目录 50 | // NSString *pathDocument = [SYCacheFileManager documentDirectoryPath]; 51 | // NSArray *arrayDocument = [[SYCacheFileManager shareManager] fileModelsWithFilePath:pathDocument]; 52 | // NSString *pathCache = [SYCacheFileManager cacheDirectoryPath]; 53 | // NSArray *arrayCache = [[SYCacheFileManager shareManager] fileModelsWithFilePath:pathCache]; 54 | // NSMutableArray *array = [NSMutableArray arrayWithArray:arrayDocument]; 55 | // [array addObjectsFromArray:arrayCache]; 56 | // cacheVC.cacheArray = array; 57 | // // 其它属性设置 58 | // cacheVC.cacheTitle = @"我的缓存文件"; 59 | // // 60 | // [self.navigationController pushViewController:cacheVC animated:YES]; 61 | 62 | 63 | // path = [SYCacheFileManager documentDirectoryPath]; 64 | // NSLog(@"path = %@", path); 65 | // 66 | // path = [SYCacheFileManager cacheDirectoryPath]; 67 | // NSLog(@"path = %@", path); 68 | // 69 | // path = [SYCacheFileManager libraryDirectoryPath]; 70 | // NSLog(@"path = %@", path); 71 | // 72 | // path = [SYCacheFileManager tmpDirectoryPath]; 73 | // NSLog(@"path = %@", path); 74 | // 75 | // path = [SYCacheFileManager newFilePathWithPath:[SYCacheFileManager tmpDirectoryPath] name:@"Tmp001"]; 76 | // NSLog(@"path = %@", path); 77 | // 78 | // path = [SYCacheFileManager newFilePathCacheWithName:@"Tmp002"]; 79 | // NSLog(@"path = %@", path); 80 | // 81 | // path = [SYCacheFileManager newFilePathDocumentWithName:@"Document001"]; 82 | // NSLog(@"path = %@", path); 83 | // 84 | // path = [SYCacheFileManager newFilePathWithPath:[SYCacheFileManager tmpDirectoryPath] name:@"Tmp001.png"]; 85 | // NSLog(@"path = %@", path); 86 | } 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /DemoCacheDirectory/DemoCacheDirectory/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // DemoCacheDirectory 4 | // 5 | // Created by zhangshaoyu on 17/6/27. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /DemoCacheDirectory/DemoCacheDirectoryTests/DemoCacheDirectoryTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // DemoCacheDirectoryTests.m 3 | // DemoCacheDirectoryTests 4 | // 5 | // Created by zhangshaoyu on 17/6/27. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DemoCacheDirectoryTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation DemoCacheDirectoryTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /DemoCacheDirectory/DemoCacheDirectoryTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /DemoCacheDirectory/DemoCacheDirectoryUITests/DemoCacheDirectoryUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // DemoCacheDirectoryUITests.m 3 | // DemoCacheDirectoryUITests 4 | // 5 | // Created by zhangshaoyu on 17/6/27. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DemoCacheDirectoryUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation DemoCacheDirectoryUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /DemoCacheDirectory/DemoCacheDirectoryUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 herman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SYCacheFileViewController 2 | 缓存文件视图控制器 3 | 4 | 查看指定目录下的缓存文件,缓存文件的显示方式默认是列表样式,也可以设置成九宫格样式;文件查看包括音频播放,视频播放,图片多图或单图浏览,同时支持缩放,以及文档的查看;另外,可以将缓存中的图片,或视频通过长按方式选择保存到相册,或删除操作;列表显示时,可通过左滑操作删除缓存文件。 5 | 6 | 7 | * 显示指定目录下的子目录及文件 8 | * 子目录可以继续点击进入下级子目录,及显示下级文件 9 | * 文件可以点击查看,根据不格式进行展示 10 | * 音频播放:播放时图标旋转,并显示播放进度 11 | * 视频播放:使用系统播放器进行播放 12 | * 文档类浏览:使用系统控件查看浏览,如:doc/excel/ppt/pdf/txt等打开 13 | * 图片浏览:查看时可通过手势进行缩放 14 | * apk文件:无法查看,且提示不可查看 15 | 16 | * 目录与文件的操作 17 | * 文件浏览 18 | * 图片浏览 19 | * 手势拿捏放大或缩小 20 | * 单图查看 21 | * 多图轮播 22 | * 音频播放 23 | * 开始,或停止播放 24 | * 页面消失时,停止播放 25 | * 切换音频时,播放当前选中,并停止播放上一首 26 | * 视频播放 27 | * 系统播放器播放 28 | * 文件查看 29 | * 调用系统浏览工具查看文档文件 30 | * 删除操作 31 | * 左滑出现删除按钮 32 | * 系统文件及文件夹不可删除 33 | * 长按操作 34 | * 删除:所有文件格式适用 35 | * 保存到相册:只支持视频、图片 36 | 37 | 38 | ![SYCacheFileViewController.png](./images/SYCacheFileViewController.png) 39 | 40 | 41 | # 效果图-目录与文件 42 | 43 | ![cacheFile_directory.gif](./images/cacheFile_directory.gif) 44 | 45 | # 效果图-图片查看 46 | 47 | ![cacheFile_image.gif](./images/cacheFile_image.gif) 48 | 49 | # 效果图-视频播放 50 | 51 | ![cacheFile_video.gif](./images/cacheFile_video.gif) 52 | 53 | # 效果图-音频播放 54 | 55 | ![cacheFile_audio.gif](./images/cacheFile_audio.gif) 56 | 57 | # 效果图-文档查看-word/excel/ppt/pdf 58 | 59 | ![cacheFile_File01.gif](./images/cacheFile_File01.gif) 60 | 61 | # 效果图-文档查看:txt/htm/…… 62 | 63 | ![cacheFile_File02.gif](./images/cacheFile_File02.gif) 64 | 65 | 66 | # 效果图-删除操作(系统文件不可删除) 67 | 68 | ![cacheFile_delete.gif](./images/cacheFile_delete.gif) 69 | 70 | ![cacheFile_delete.png](./images/cacheFile_delete.png) 71 | 72 | 73 | 74 | * 使用介绍 75 | * 自动导入:使用命令`pod 'SYCacheFileViewController'`导入到项目中 76 | * 手动导入:或下载源码后,将源码添加到项目中 77 | 78 | 79 | # 使用示例 80 | ~~~ javascript 81 | 82 | // 导入头文件 83 | #import "SYCacheFileViewController.h" 84 | 85 | ~~~ 86 | 87 | ~~~ javascript 88 | 89 | // 实例化 使用默认路径home 90 | SYCacheFileViewController *cacheVC = [[SYCacheFileViewController alloc] init]; 91 | [self.navigationController pushViewController:cacheVC animated:YES]; 92 | 93 | ~~~ 94 | 95 | ~~~ javascript 96 | 97 | // 自定义 98 | SYCacheFileViewController *cacheVC = [[SYCacheFileViewController alloc] init]; 99 | // 指定文件格式 100 | [SYCacheFileManager shareManager].cacheDocumentArray = @[@".pages", @"wps", @".xls", @".pdf", @".rar"]; 101 | 102 | // 指定目录,或默认目录 103 | NSString *path = [SYCacheFileManager documentDirectoryPath]; 104 | NSArray *array = [[SYCacheFileManager shareManager] fileModelsWithFilePath:path]; 105 | cacheVC.cacheArray = [NSMutableArray arrayWithArray:array]; 106 | 107 | // 标题 108 | cacheVC.cacheTitle = @"我的缓存文件"; 109 | 110 | // 单图或多图浏览 111 | [SYCacheFileManager shareManager].showImageShuffling = YES; 112 | 113 | // 文件浏览方式 114 | [SYCacheFileManager shareManager].showDoucumentUI = YES; 115 | 116 | // 列表,或九宫格显示 117 | cacheVC.showType = 1; 118 | 119 | // 120 | [self.navigationController pushViewController:cacheVC animated:YES]; 121 | ~~~ 122 | 123 | 124 | 125 | 126 | # 修改完善 127 | * 20190227 128 | * 版本号:1.2.9 129 | * 优化修改 130 | * 显示样式:列表、九宫格 131 | * 多图显示数量及索引异常bug 132 | 133 | * 20190221 134 | * 版本号:1.2.8 135 | * 优化修改 136 | * 功能分离:图片浏览、音乐播放、视频播放 137 | 138 | * 20190212 139 | * 版本号:1.2.5 1.2.6 1.2.7 140 | * 功能完善 141 | * 多图浏览 142 | * 显示数量 143 | * 显示指定图片 144 | * 单图浏览 145 | 146 | * 20190114 147 | * 版本号:1.2.4 148 | * 修改bug 149 | * 音频播放时,删除操作异常处理 150 | * 文件夹名称带有.识别异常 151 | * 左滑删除和长按删除时,异常处理 152 | 153 | * 版本号:1.2.3 154 | * 修改bug 155 | * apk无法打开提示 156 | 157 | * 20190110 158 | * 版本号:1.2.2 159 | * 修改完善 160 | * 图片缩放功能 161 | * 长按响应 162 | * 保存到相册 163 | * 图片 164 | * 视频 165 | * 删除 166 | * 新增图标:压缩文件、apk程序 167 | * 音频播放 168 | * 播放时图标旋转状态 169 | * 停止播放时,多首音频异常 170 | 171 | * SYCacheFileManager修改 172 | * @property (nonatomic, strong) NSArray *cacheVideoTypes; 改成 @property (nonatomic, strong) NSArray *cacheVideoTypes; 173 | * @property (nonatomic, strong) NSArray *cacheAudioArray; 改成 @property (nonatomic, strong) NSArray *cacheAudioTypes; 174 | * @property (nonatomic, strong) NSArray *cacheImageArray; 改成 @property (nonatomic, strong) NSArray *cacheImageTypes; 175 | * @property (nonatomic, strong) NSArray *cacheDocumentArray; 改成 @property (nonatomic, strong) NSArray *cacheDocumentTypes; 176 | 177 | 178 | * 20190103 179 | * 版本号:1.2.1 180 | * 修改完善 181 | * 图片独立窗口播放 182 | * 音乐独立窗口播放 183 | 184 | * 20190102 185 | * 版本号:1.2.0 186 | * 修改完善 187 | * 区分音视频播放模式 188 | * 单独窗口播放音乐 189 | * 单独窗口播放视频 190 | * 播放前文件异常判断 191 | 192 | * 20181120 193 | * 版本号:1.1.0 194 | * 修改完善 195 | * 添加自定义文件格式 196 | 197 | * 20180731 198 | * 版本号:1.0.0 199 | * 完善方法 200 | * 文件复制 201 | * 文件移动 202 | * 文件重命名 203 | 204 | * 待完善 205 | * 文件删除后文件目录大小改变 206 | 207 | 208 | 209 | -------------------------------------------------------------------------------- /SYCacheFileViewController.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "SYCacheFileViewController" 3 | s.version = "1.2.9" 4 | s.summary = "SYCacheFileViewController used to manager cache file." 5 | s.homepage = "https://github.com/potato512/SYCacheFileViewController" 6 | s.license = { :type => "MIT", :file => "LICENSE" } 7 | s.author = { "herman" => "zhangsy757@163.com" } 8 | s.platform = :ios, "8.0" 9 | s.source = { :git => "https://github.com/potato512/SYCacheFileViewController.git", :tag => "#{s.version}" } 10 | s.source_files = "SYCacheFileViewController/*.{h,m}" 11 | s.resources = "SYCacheFileViewController/SYCacheFileImages/*.png" 12 | s.frameworks = "UIKit", "Foundation", "AVFoundation", "AVKit", "QuickLook" 13 | s.requires_arc = true 14 | end -------------------------------------------------------------------------------- /SYCacheFileViewController/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/.DS_Store -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileAudio.h: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileAudio.h 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 2019/2/21. 6 | // Copyright © 2019年 zhangshaoyu. All rights reserved. 7 | // 音频播放 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | static NSString *const SYCacheFileAudioDurationValueChangeNotificationName = @"AudioDurationValueChangeNotificationName"; 14 | static NSString *const SYCacheFileAudioStopNotificationName = @"AudioStopNotificationName"; 15 | static NSString *const SYCacheFileAudioDeleteNotificationName = @"AudioDeleteNotificationName"; 16 | 17 | @interface SYCacheFileAudio : NSObject 18 | 19 | + (instancetype)shareAudio; 20 | 21 | - (void)playAudioWithFilePath:(NSString *)filePath; 22 | 23 | - (void)stopAudio; 24 | 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileAudio.m: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileAudio.m 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 2019/2/21. 6 | // Copyright © 2019年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import "SYCacheFileAudio.h" 10 | #import 11 | // 音频 12 | #import 13 | 14 | @interface SYCacheFileAudio () 15 | 16 | // 音频播放 17 | @property (nonatomic, strong) AVAudioPlayer *audioPlayer; 18 | @property (nonatomic, assign) NSTimeInterval durationTotal; 19 | @property (nonatomic, assign) NSTimeInterval duration; 20 | 21 | @end 22 | 23 | @implementation SYCacheFileAudio 24 | 25 | 26 | + (instancetype)shareAudio 27 | { 28 | static SYCacheFileAudio *fileAudio; 29 | static dispatch_once_t onceToken; 30 | dispatch_once(&onceToken, ^{ 31 | fileAudio = [[self alloc] init]; 32 | }); 33 | return fileAudio; 34 | } 35 | 36 | - (instancetype)init 37 | { 38 | self = [super init]; 39 | if (self) { 40 | 41 | } 42 | return self; 43 | } 44 | 45 | // 内存管理 46 | - (void)dealloc 47 | { 48 | [self fileAudioStop]; 49 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 50 | NSLog(@"%@ 被释放了!", [self class]); 51 | } 52 | 53 | - (void)playAudioWithFilePath:(NSString *)filePath 54 | { 55 | if (filePath && [filePath isKindOfClass:[NSString class]] && filePath.length > 0) { 56 | NSURL *url = [NSURL fileURLWithPath:filePath]; 57 | if ([filePath hasPrefix:@"https://"] || [filePath hasPrefix:@"http://"]) { 58 | url = [NSURL URLWithString:filePath]; 59 | } 60 | 61 | if (self.audioPlayer) { 62 | [self releaseSYCacheFileRead]; 63 | 64 | NSString *pathPrevious = self.audioPlayer.url.relativeString; 65 | pathPrevious = [pathPrevious stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 66 | 67 | if (self.audioPlayer.isPlaying) { 68 | [self.audioPlayer stop]; 69 | } 70 | 71 | self.audioPlayer = nil; 72 | 73 | // 同一个文件时,停止播放后不再开始开始 74 | NSRange range = [pathPrevious rangeOfString:filePath]; 75 | if (range.location != NSNotFound) { 76 | [[NSNotificationCenter defaultCenter] postNotificationName:SYCacheFileAudioStopNotificationName object:nil]; 77 | return; 78 | } 79 | } 80 | 81 | [self addNotificationDelete]; 82 | if (self.audioPlayer == nil) { 83 | self.durationTotal = 0.0; 84 | self.duration = 0.0; 85 | 86 | NSError *error; 87 | self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error]; 88 | 89 | self.audioPlayer.volume = 1.0; 90 | self.audioPlayer.numberOfLoops = 1; 91 | self.audioPlayer.currentTime = 0.0; 92 | 93 | self.audioPlayer.delegate = self; 94 | 95 | if (self.audioPlayer.prepareToPlay) { 96 | [self.audioPlayer play]; 97 | } 98 | 99 | self.durationTotal = self.audioPlayer.duration; 100 | [self fileReadAuionDuration]; 101 | } 102 | } 103 | } 104 | 105 | - (void)stopAudio 106 | { 107 | [self fileAudioStop]; 108 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 109 | } 110 | 111 | 112 | - (void)fileAudioStop 113 | { 114 | if (self.audioPlayer) { 115 | if (self.audioPlayer.isPlaying) { 116 | [self.audioPlayer stop]; 117 | } 118 | self.audioPlayer = nil; 119 | // 120 | NSNumber *number = [NSNumber numberWithFloat:0.0]; 121 | [[NSNotificationCenter defaultCenter] postNotificationName:SYCacheFileAudioDurationValueChangeNotificationName object:number]; 122 | // 123 | [self releaseSYCacheFileRead]; 124 | [[NSNotificationCenter defaultCenter] postNotificationName:SYCacheFileAudioStopNotificationName object:nil]; 125 | } 126 | } 127 | 128 | - (void)releaseSYCacheFileRead 129 | { 130 | [NSObject cancelPreviousPerformRequestsWithTarget:self]; 131 | } 132 | 133 | #pragma mark 通知处理 134 | 135 | - (void)addNotificationDelete 136 | { 137 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deleteAudioStop) name:SYCacheFileAudioDeleteNotificationName object:nil]; 138 | } 139 | 140 | - (void)deleteAudioStop 141 | { 142 | [self fileAudioStop]; 143 | } 144 | 145 | #pragma mark 代理方法 146 | 147 | - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag 148 | { 149 | // 播放结束时执行的动作 150 | self.audioPlayer = nil; 151 | 152 | [self releaseSYCacheFileRead]; 153 | [[NSNotificationCenter defaultCenter] postNotificationName:SYCacheFileAudioStopNotificationName object:nil]; 154 | } 155 | 156 | - (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error 157 | { 158 | // 解码错误执行的动作 159 | [self.audioPlayer stop]; 160 | } 161 | 162 | - (void)audioPlayerBeginInteruption:(AVAudioPlayer *)player 163 | { 164 | // 处理中断的代码 165 | [self.audioPlayer stop]; 166 | } 167 | 168 | - (void)audioPlayerEndInteruption:(AVAudioPlayer *)player 169 | { 170 | // 处理中断结束的代码 171 | [self.audioPlayer stop]; 172 | } 173 | 174 | #pragma mark 回调方法 175 | 176 | - (void)fileReadAuionDuration 177 | { 178 | self.duration = self.audioPlayer.currentTime; 179 | NSTimeInterval progress = self.duration / self.durationTotal; 180 | NSNumber *number = [NSNumber numberWithFloat:progress]; 181 | [[NSNotificationCenter defaultCenter] postNotificationName:SYCacheFileAudioDurationValueChangeNotificationName object:number]; 182 | 183 | #ifdef DEBUG 184 | NSLog(@"duration = %.2f, durationTotal = %.2f", self.duration, self.durationTotal); 185 | #endif 186 | 187 | [self performSelector:@selector(fileReadAuionDuration) withObject:nil afterDelay:0.3]; 188 | } 189 | 190 | 191 | @end 192 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileCell.h 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 17/6/27. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 文件显示单元格 8 | 9 | #import 10 | #import "SYCacheFileModel.h" 11 | 12 | static NSString *const reuseSYCacheDirectoryCell = @"SYCacheDirectoryCell"; 13 | static CGFloat const heightSYCacheDirectoryCell = 60.0; 14 | 15 | @interface SYCacheFileCell : UITableViewCell 16 | 17 | /// 数据源 18 | @property (nonatomic, strong) SYCacheFileModel *model; 19 | /// 长按回调 20 | @property (nonatomic, copy) void (^longPress)(void); 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileCell.m 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 17/6/27. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import "SYCacheFileCell.h" 10 | #import "SYCacheFileManager.h" 11 | 12 | static CGFloat const originXY = 10.0; 13 | static CGFloat const heightTitle = 40.0; 14 | static CGFloat const heightDetail = 20.0; 15 | 16 | #define sizeImage (heightSYCacheDirectoryCell - originXY * 2) 17 | #define frameImage (CGRectMake(originXY, originXY, (heightSYCacheDirectoryCell - originXY * 2), (heightSYCacheDirectoryCell - originXY * 2))) 18 | 19 | #define widthScreen [UIScreen mainScreen].bounds.size.width 20 | 21 | @interface SYCacheFileCell () 22 | 23 | @property (nonatomic, strong) UIView *backView; 24 | @property (nonatomic, strong) UIImageView *typeImageView; 25 | @property (nonatomic, strong) UILabel *typeTitleLabel; 26 | @property (nonatomic, strong) UILabel *typeDetailLabel; 27 | 28 | @property (nonatomic, strong) UIProgressView *progressView; 29 | 30 | @end 31 | 32 | @implementation SYCacheFileCell 33 | 34 | - (void)awakeFromNib { 35 | // Initialization code 36 | [super awakeFromNib]; 37 | } 38 | 39 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 40 | [super setSelected:selected animated:animated]; 41 | 42 | // Configure the view for the selected state 43 | } 44 | 45 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 46 | { 47 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 48 | if (self) { 49 | self.backgroundColor = [UIColor whiteColor]; 50 | self.backgroundView.backgroundColor = [UIColor whiteColor]; 51 | 52 | self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 53 | 54 | [self setUI]; 55 | } 56 | return self; 57 | } 58 | 59 | - (void)dealloc 60 | { 61 | [self removeNotificationDuration]; 62 | 63 | NSLog(@"<-- %@ 被释放了-->" , [self class]); 64 | } 65 | 66 | #pragma mark - 视图 67 | 68 | - (void)setUI 69 | { 70 | _backView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, widthScreen, heightSYCacheDirectoryCell)]; 71 | _backView.backgroundColor = [UIColor whiteColor]; 72 | [self.contentView addSubview:_backView]; 73 | // 74 | UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)]; 75 | _backView.userInteractionEnabled = YES; 76 | [_backView addGestureRecognizer:longPressRecognizer]; 77 | // 78 | self.typeImageView = [[UIImageView alloc] initWithFrame:frameImage]; 79 | self.typeImageView.backgroundColor = [UIColor clearColor]; 80 | self.typeImageView.contentMode = UIViewContentModeScaleAspectFill; 81 | self.typeImageView.clipsToBounds = YES; 82 | [_backView addSubview:self.typeImageView]; 83 | // 84 | CGFloat originTitle = (originXY + sizeImage + originXY); 85 | CGFloat widthTitle = (widthScreen - originXY - sizeImage * 1.5 - originXY - originXY); 86 | // 87 | self.typeTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(originTitle, 0.0, widthTitle, heightTitle)]; 88 | self.typeTitleLabel.backgroundColor = [UIColor clearColor]; 89 | self.typeTitleLabel.font = [UIFont systemFontOfSize:13.0]; 90 | self.typeTitleLabel.textColor = [UIColor blackColor]; 91 | self.typeTitleLabel.numberOfLines = 2; 92 | [_backView addSubview:self.typeTitleLabel]; 93 | // 94 | self.typeDetailLabel = [[UILabel alloc] initWithFrame:CGRectMake(originTitle, (_backView.frame.size.height - heightDetail - originXY / 2), widthTitle, heightDetail)]; 95 | self.typeDetailLabel.backgroundColor = [UIColor clearColor]; 96 | self.typeDetailLabel.font = [UIFont systemFontOfSize:11.0]; 97 | self.typeDetailLabel.textColor = [UIColor lightGrayColor]; 98 | [_backView addSubview:self.typeDetailLabel]; 99 | // 100 | UIImageView *lineImage = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, (_backView.frame.size.height - 0.5), _backView.frame.size.width, 0.5)]; 101 | lineImage.backgroundColor = [UIColor clearColor]; 102 | lineImage.image = [UIImage imageNamed:@"line_cacheFile"]; 103 | [_backView addSubview:lineImage]; 104 | } 105 | 106 | #pragma mark - methord 107 | 108 | - (void)addNotificationDuration 109 | { 110 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resetAudioProgress:) name:SYCacheFileAudioDurationValueChangeNotificationName object:nil]; 111 | 112 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resetAudioStop) name:SYCacheFileAudioStopNotificationName object:nil]; 113 | } 114 | 115 | - (void)removeNotificationDuration 116 | { 117 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 118 | } 119 | 120 | - (void)resetAudioProgress:(NSNotification *)notification 121 | { 122 | if (self.model.fileType == SYCacheFileTypeAudio) { 123 | if (self.model.fileProgressShow) { 124 | self.progressView.hidden = NO; 125 | 126 | NSNumber *number = notification.object; 127 | NSTimeInterval progress = number.floatValue; 128 | self.model.fileProgress = progress; 129 | // 130 | [UIView animateWithDuration:0.5 animations:^{ 131 | self.progressView.progress = progress; 132 | self.typeImageView.transform = CGAffineTransformMakeRotation(M_PI_2 * progress * 100); 133 | }]; 134 | } else { 135 | 136 | if (self.progressView.hidden) { 137 | return; 138 | } else { 139 | [UIView animateWithDuration:0.5 animations:^{ 140 | self.progressView.hidden = YES; 141 | self.progressView.progress = 0.0; 142 | 143 | self.typeImageView.transform = CGAffineTransformMakeRotation(0.0); 144 | }]; 145 | } 146 | } 147 | } 148 | } 149 | 150 | - (void)resetAudioStop 151 | { 152 | if (self.model.fileType == SYCacheFileTypeAudio) { 153 | [UIView animateWithDuration:0.5 animations:^{ 154 | self.progressView.hidden = YES; 155 | self.progressView.progress = 0.0; 156 | // 157 | self.typeImageView.transform = CGAffineTransformMakeRotation(0.0); 158 | }]; 159 | } 160 | } 161 | 162 | - (void)longPress:(UILongPressGestureRecognizer *)recognizer 163 | { 164 | if (recognizer.state == UIGestureRecognizerStateBegan) { 165 | if (self.longPress) { 166 | self.longPress(); 167 | } 168 | } 169 | } 170 | 171 | #pragma mark - getter 172 | 173 | - (UIProgressView *)progressView 174 | { 175 | if (_progressView == nil) { 176 | _progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault]; 177 | _progressView.progressTintColor = [UIColor redColor]; 178 | CGFloat height = 3.0; 179 | _progressView.frame = CGRectMake(0.0, (_backView.frame.size.height - height), _backView.frame.size.width, height); 180 | [_backView addSubview:_progressView]; 181 | } 182 | return _progressView; 183 | } 184 | 185 | #pragma mark - setter 186 | 187 | - (void)setModel:(SYCacheFileModel *)model 188 | { 189 | _model = model; 190 | if (_model) { 191 | // 图标 192 | UIImage *image = [[SYCacheFileManager shareManager] fileTypeImageWithFilePath:_model.filePath]; 193 | self.typeImageView.image = image; 194 | 195 | // 标题 196 | NSString *nameText = _model.fileName; 197 | self.typeTitleLabel.text = nameText; 198 | // 大小 199 | NSString *sizeText = _model.fileSize; 200 | self.typeDetailLabel.text = sizeText; 201 | 202 | SYCacheFileType type = _model.fileType; 203 | if (type == SYCacheFileTypeAudio) { 204 | self.progressView.hidden = !_model.fileProgressShow; 205 | self.progressView.progress = _model.fileProgress; 206 | [self addNotificationDuration]; 207 | } else { 208 | self.progressView.hidden = YES; 209 | [self removeNotificationDuration]; 210 | } 211 | } 212 | } 213 | 214 | @end 215 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileCollection.h: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileCollection.h 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 2019/2/27. 6 | // Copyright © 2019年 zhangshaoyu. All rights reserved. 7 | // 文件列表九宫格显示 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface SYCacheFileCollection : UICollectionView 14 | 15 | + (UICollectionViewLayout *)collectionlayout; 16 | 17 | /// 数据源 18 | @property (nonatomic, strong) NSMutableArray *cacheDatas; 19 | 20 | /// 响应回调 21 | @property (nonatomic, copy) void (^itemClick)(NSIndexPath *indexPath); 22 | /// 长按回调 23 | @property (nonatomic, copy) void (^longPress)(SYCacheFileCollection *collection, NSIndexPath *indexPath); 24 | 25 | - (void)deleItemAtIndex:(NSIndexPath *)indexPath; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileCollection.m: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileCollection.m 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 2019/2/27. 6 | // Copyright © 2019年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import "SYCacheFileCollection.h" 10 | #import "SYCacheFileCollectionCell.h" 11 | #import "SYCacheFileModel.h" 12 | #import "SYCacheFileManager.h" 13 | 14 | @interface SYCacheFileCollection () 15 | 16 | @property (nonatomic, strong) NSIndexPath *previousIndex; 17 | 18 | @end 19 | 20 | @implementation SYCacheFileCollection 21 | 22 | - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout 23 | { 24 | self = [super initWithFrame:frame collectionViewLayout:layout]; 25 | if (self) { 26 | self.backgroundColor = [UIColor clearColor]; 27 | 28 | self.delegate = self; 29 | self.dataSource = self; 30 | self.autoresizingMask = UIViewAutoresizingFlexibleHeight; 31 | [self registerClass:[SYCacheFileCollectionCell class] forCellWithReuseIdentifier:identifierCollectionViewCell]; 32 | self.allowsSelection = YES; 33 | self.allowsMultipleSelection = NO; 34 | self.alwaysBounceVertical = YES; 35 | } 36 | return self; 37 | } 38 | 39 | + (UICollectionViewLayout *)collectionlayout 40 | { 41 | // 确定是水平滚动,还是垂直滚动 42 | UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; 43 | [flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical]; 44 | return flowLayout; 45 | } 46 | 47 | #pragma mark - UICollectionViewDataSource 48 | 49 | // 定义展示的UICollectionViewCell的个数 50 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 51 | { 52 | return self.cacheDatas.count; 53 | } 54 | 55 | // 每个UICollectionView展示的内容 56 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 57 | { 58 | SYCacheFileCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifierCollectionViewCell forIndexPath:indexPath]; 59 | 60 | // 数据 61 | SYCacheFileModel *model = self.cacheDatas[indexPath.row]; 62 | cell.model = model; 63 | // 长按 64 | SYCacheFileCollection __weak *weakSelf = self; 65 | cell.longPress = ^{ 66 | if (weakSelf.longPress) { 67 | weakSelf.longPress(weakSelf, indexPath); 68 | } 69 | }; 70 | 71 | return cell; 72 | } 73 | 74 | #pragma mark - UICollectionViewDelegateFlowLayout 75 | 76 | // 定义每个UICollectionView的大小 77 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath 78 | { 79 | return CGSizeMake(widthCollectionViewCell, heightCollectionViewCell); 80 | } 81 | 82 | // 定义每个UICollectionView的 margin 83 | - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section 84 | { 85 | return UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0); 86 | } 87 | 88 | // 最小行间距 89 | - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section 90 | { 91 | return 10.0; 92 | } 93 | 94 | // 最小列间距 95 | - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section 96 | { 97 | return 0.0; 98 | } 99 | 100 | // 设定页眉的尺寸 101 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section 102 | { 103 | return CGSizeZero; 104 | } 105 | 106 | // 设定页脚的尺寸 107 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section 108 | { 109 | return CGSizeZero; 110 | } 111 | 112 | #pragma mark - UICollectionViewDelegate 113 | 114 | // UICollectionView被选中时调用的方法 115 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath 116 | { 117 | [collectionView deselectItemAtIndexPath:indexPath animated:YES]; 118 | 119 | SYCacheFileModel *model = self.cacheDatas[indexPath.row]; 120 | 121 | // 音频播放 122 | SYCacheFileType type = [[SYCacheFileManager shareManager] fileTypeReadWithFilePath:model.filePath]; 123 | if (SYCacheFileTypeAudio == type) { 124 | model.fileProgressShow = YES; 125 | NSString *currentPath = model.filePath; 126 | 127 | if (self.previousIndex) { 128 | SYCacheFileModel *previousModel = self.cacheDatas[self.previousIndex.row]; 129 | NSString *previousPath = previousModel.filePath; 130 | if (![currentPath isEqualToString:previousPath]) { 131 | previousModel.fileProgress = 0.0; 132 | previousModel.fileProgressShow = NO; 133 | [collectionView reloadItemsAtIndexPaths:@[self.previousIndex]]; 134 | } 135 | } 136 | 137 | self.previousIndex = indexPath; 138 | } 139 | 140 | // 回调响应 141 | if (self.itemClick) { 142 | self.itemClick(indexPath); 143 | } 144 | } 145 | 146 | // 返回这个UICollectionView是否可以被选择 147 | - (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath 148 | { 149 | return YES; 150 | } 151 | 152 | #pragma mark - 删除操作 153 | 154 | - (void)deleItemAtIndex:(NSIndexPath *)indexPath 155 | { 156 | if (indexPath.row > self.cacheDatas.count - 1) { 157 | return; 158 | } 159 | SYCacheFileModel *model = self.cacheDatas[indexPath.row]; 160 | // 系统数据不可删除 161 | if ([[SYCacheFileManager shareManager] isFileSystemWithFilePath:model.filePath]) { 162 | [[[UIAlertView alloc] initWithTitle:nil message:@"系统文件不能删除" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil] show]; 163 | return; 164 | } 165 | // 当前删除的是音频时,先停止播放 166 | if (model.fileType == SYCacheFileTypeAudio) { 167 | [[NSNotificationCenter defaultCenter] postNotificationName:SYCacheFileAudioDeleteNotificationName object:nil]; 168 | } 169 | if (self.previousIndex) { 170 | self.previousIndex = nil; 171 | } 172 | // 删除数据:删除数组、删除本地文件/文件夹、刷新页面、发通知刷新文件大小统计 173 | // 删除数组 174 | [self.cacheDatas removeObjectAtIndex:indexPath.row]; 175 | // 删除本地文件/文件夹 176 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 177 | BOOL isDelete = [SYCacheFileManager deleteFileWithDirectory:model.filePath]; 178 | NSLog(@"删除:%@", (isDelete ? @"成功" : @"失败")); 179 | }); 180 | // 刷新页面 181 | // [self deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; 182 | [self reloadData]; 183 | } 184 | 185 | @end 186 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileCollectionCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileCollectionCell.h 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 2019/2/27. 6 | // Copyright © 2019年 zhangshaoyu. All rights reserved. 7 | // 文件列表单元格 8 | 9 | #import 10 | #import "SYCacheFileModel.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | static NSInteger const columnNumber = 2; 15 | 16 | #define widthScreen ([[UIScreen mainScreen] bounds].size.width) 17 | 18 | #define widthCollectionViewCell ((widthScreen - 10.0 * (columnNumber + 1)) / columnNumber) 19 | static CGFloat const heightCollectionViewCell = 120.0; 20 | static NSString *const identifierCollectionViewCell = @"CollectionViewCell"; 21 | 22 | @interface SYCacheFileCollectionCell : UICollectionViewCell 23 | 24 | /// 数据源 25 | @property (nonatomic, strong) SYCacheFileModel *model; 26 | /// 长按回调 27 | @property (nonatomic, copy) void (^longPress)(void); 28 | 29 | @end 30 | 31 | NS_ASSUME_NONNULL_END 32 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileCollectionCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileCollectionCell.m 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 2019/2/27. 6 | // Copyright © 2019年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import "SYCacheFileCollectionCell.h" 10 | #import "SYCacheFileManager.h" 11 | 12 | static CGFloat const originXY = 10.0; 13 | static CGFloat const heightTitle = 40.0; 14 | static CGFloat const heightDetail = 20.0; 15 | static CGFloat const sizeImage = 40.0; 16 | 17 | #define frameImage (CGRectMake((widthCollectionViewCell - sizeImage) / 2, originXY, sizeImage, sizeImage)) 18 | 19 | @interface SYCacheFileCollectionCell () 20 | 21 | @property (nonatomic, strong) UIView *backView; 22 | @property (nonatomic, strong) UIImageView *typeImageView; 23 | @property (nonatomic, strong) UILabel *typeTitleLabel; 24 | @property (nonatomic, strong) UILabel *typeDetailLabel; 25 | 26 | @property (nonatomic, strong) UIProgressView *progressView; 27 | 28 | @end 29 | 30 | @implementation SYCacheFileCollectionCell 31 | 32 | - (instancetype)initWithFrame:(CGRect)frame 33 | { 34 | self = [super initWithFrame:frame]; 35 | if (self) { 36 | self.backgroundColor = [UIColor clearColor]; 37 | self.backgroundView.backgroundColor = [UIColor clearColor]; 38 | 39 | [self setUI]; 40 | } 41 | 42 | return self; 43 | } 44 | 45 | #pragma mark - 视图 46 | 47 | - (void)dealloc 48 | { 49 | [self removeNotificationDuration]; 50 | 51 | NSLog(@"<-- %@ 被释放了-->" , [self class]); 52 | } 53 | 54 | #pragma mark - 视图 55 | 56 | - (void)setUI 57 | { 58 | _backView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, widthCollectionViewCell, heightCollectionViewCell)]; 59 | _backView.backgroundColor = [UIColor whiteColor]; 60 | _backView.layer.cornerRadius = 10.0; 61 | _backView.layer.masksToBounds = YES; 62 | [self.contentView addSubview:_backView]; 63 | // 64 | UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)]; 65 | _backView.userInteractionEnabled = YES; 66 | [_backView addGestureRecognizer:longPressRecognizer]; 67 | // 68 | self.typeImageView = [[UIImageView alloc] initWithFrame:frameImage]; 69 | self.typeImageView.backgroundColor = [UIColor clearColor]; 70 | self.typeImageView.contentMode = UIViewContentModeScaleAspectFill; 71 | self.typeImageView.clipsToBounds = YES; 72 | [_backView addSubview:self.typeImageView]; 73 | // 74 | CGFloat originYTitle = (originXY + sizeImage + originXY); 75 | CGFloat widthTitle = (self.backView.frame.size.width - originXY * 2); 76 | // 77 | self.typeTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(originXY, originYTitle, widthTitle, heightTitle)]; 78 | self.typeTitleLabel.backgroundColor = [UIColor clearColor]; 79 | self.typeTitleLabel.font = [UIFont systemFontOfSize:13.0]; 80 | self.typeTitleLabel.textColor = [UIColor blackColor]; 81 | self.typeTitleLabel.numberOfLines = 2; 82 | [_backView addSubview:self.typeTitleLabel]; 83 | // 84 | self.typeDetailLabel = [[UILabel alloc] initWithFrame:CGRectMake(originXY, (originYTitle + heightTitle), widthTitle, heightDetail)]; 85 | self.typeDetailLabel.backgroundColor = [UIColor clearColor]; 86 | self.typeDetailLabel.font = [UIFont systemFontOfSize:11.0]; 87 | self.typeDetailLabel.textColor = [UIColor lightGrayColor]; 88 | [_backView addSubview:self.typeDetailLabel]; 89 | } 90 | 91 | #pragma mark - methord 92 | 93 | - (void)addNotificationDuration 94 | { 95 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resetAudioProgress:) name:SYCacheFileAudioDurationValueChangeNotificationName object:nil]; 96 | 97 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resetAudioStop) name:SYCacheFileAudioStopNotificationName object:nil]; 98 | } 99 | 100 | - (void)removeNotificationDuration 101 | { 102 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 103 | } 104 | 105 | - (void)resetAudioProgress:(NSNotification *)notification 106 | { 107 | if (self.model.fileType == SYCacheFileTypeAudio) { 108 | if (self.model.fileProgressShow) { 109 | self.progressView.hidden = NO; 110 | 111 | NSNumber *number = notification.object; 112 | NSTimeInterval progress = number.floatValue; 113 | self.model.fileProgress = progress; 114 | // 115 | [UIView animateWithDuration:0.5 animations:^{ 116 | self.progressView.progress = progress; 117 | self.typeImageView.transform = CGAffineTransformMakeRotation(M_PI_2 * progress * 100); 118 | }]; 119 | } else { 120 | 121 | if (self.progressView.hidden) { 122 | return; 123 | } else { 124 | [UIView animateWithDuration:0.5 animations:^{ 125 | self.progressView.hidden = YES; 126 | self.progressView.progress = 0.0; 127 | 128 | self.typeImageView.transform = CGAffineTransformMakeRotation(0.0); 129 | }]; 130 | } 131 | } 132 | } 133 | } 134 | 135 | - (void)resetAudioStop 136 | { 137 | if (self.model.fileType == SYCacheFileTypeAudio) { 138 | [UIView animateWithDuration:0.5 animations:^{ 139 | self.progressView.hidden = YES; 140 | self.progressView.progress = 0.0; 141 | // 142 | self.typeImageView.transform = CGAffineTransformMakeRotation(0.0); 143 | }]; 144 | } 145 | } 146 | 147 | - (void)longPress:(UILongPressGestureRecognizer *)recognizer 148 | { 149 | if (recognizer.state == UIGestureRecognizerStateBegan) { 150 | if (self.longPress) { 151 | self.longPress(); 152 | } 153 | } 154 | } 155 | 156 | #pragma mark - getter 157 | 158 | - (UIProgressView *)progressView 159 | { 160 | if (_progressView == nil) { 161 | _progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault]; 162 | _progressView.progressTintColor = [UIColor redColor]; 163 | CGFloat height = 3.0; 164 | _progressView.frame = CGRectMake(0.0, (_backView.frame.size.height - height), _backView.frame.size.width, height); 165 | [_backView addSubview:_progressView]; 166 | } 167 | return _progressView; 168 | } 169 | 170 | #pragma mark - setter 171 | 172 | - (void)setModel:(SYCacheFileModel *)model 173 | { 174 | _model = model; 175 | if (_model) { 176 | // 图标 177 | UIImage *image = [[SYCacheFileManager shareManager] fileTypeImageWithFilePath:_model.filePath]; 178 | self.typeImageView.image = image; 179 | 180 | // 标题 181 | NSString *nameText = _model.fileName; 182 | self.typeTitleLabel.text = nameText; 183 | // 大小 184 | NSString *sizeText = _model.fileSize; 185 | self.typeDetailLabel.text = sizeText; 186 | 187 | SYCacheFileType type = _model.fileType; 188 | if (type == SYCacheFileTypeAudio) { 189 | self.progressView.hidden = !_model.fileProgressShow; 190 | self.progressView.progress = _model.fileProgress; 191 | [self addNotificationDuration]; 192 | } else { 193 | self.progressView.hidden = YES; 194 | [self removeNotificationDuration]; 195 | } 196 | } 197 | } 198 | 199 | @end 200 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileDefine.h: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileDefine.h 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 17/6/28. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // https://github.com/potato512/SYCacheFileViewController 8 | 9 | #ifndef SYCacheFileDefine_h 10 | #define SYCacheFileDefine_h 11 | 12 | static NSString *const SYCacheFileTitle = @"缓存文件"; 13 | 14 | /** 15 | * 默认显示文件 16 | * 视频:.avi、.dat、.mkv、.flv、.vob、.mp4、.m4v、.mpg、.mpeg、.mpe、.3pg、.mov、.swf、.wmv、.asf、.asx、.rm、.rmvb 17 | * 音频:.wav、.aif、.au、.mp3、.ram、.wma、.mmf、.amr、.aac、.flac、.midi、.mp3、.oog、.cd、.asf、.rm、.real、.ape、.vqf 18 | * 图片:.jpg、.png、.jpeg、.gif、.bmp 19 | * 文档:.txt、.sh、.doc、.docx、.xls、.xlsx、.pdf、.hlp、.wps、.rtf、.html、@".htm", .iso、.rar、.zip、.exe、.mdf、.ppt、.pptx、.apk 20 | */ 21 | 22 | /// 文件类型 23 | typedef NS_ENUM(NSInteger, SYCacheFileType) 24 | { 25 | /// 文件类型 0未知 26 | SYCacheFileTypeUnknow = 0, 27 | 28 | /// 文件类型 1视频 29 | SYCacheFileTypeVideo = 1, 30 | 31 | /// 文件类型 2音频 32 | SYCacheFileTypeAudio = 2, 33 | 34 | /// 文件类型 3图片 35 | SYCacheFileTypeImage = 3, 36 | 37 | /// 文件类型 4文档 38 | SYCacheFileTypeDocument = 4, 39 | }; 40 | 41 | #endif /* SYCacheFileDefine_h */ 42 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileImage.h 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 2019/2/12. 6 | // Copyright © 2019年 zhangshaoyu. All rights reserved. 7 | // 图片浏览,单图,或多图轮播 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface SYCacheScaleImage : UIView 14 | 15 | /// 图片点击回调 16 | @property (nonatomic, copy) void (^imageTap)(void); 17 | 18 | /// 图片显示(根据路径) 19 | - (void)showImageWithFilePath:(NSString *)filePath; 20 | 21 | @end 22 | 23 | #pragma mark - 24 | 25 | @interface SYCacheFileImage : UIView 26 | 27 | /// 图片数组 28 | @property (nonatomic, strong) NSArray *images; 29 | /// 图片索引(默认0第一张) 30 | @property (nonatomic, assign) NSInteger index; 31 | /// 图片刷新 32 | - (void)reloadImages; 33 | 34 | @end 35 | 36 | NS_ASSUME_NONNULL_END 37 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImage.m: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileImage.m 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 2019/2/12. 6 | // Copyright © 2019年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import "SYCacheFileImage.h" 10 | 11 | static CGFloat const scaleMini = 1.0; 12 | static CGFloat const scaleMax = 3.0; 13 | 14 | @interface SYCacheScaleImage () 15 | 16 | @property (nonatomic, strong) UIImageView *imageView; 17 | 18 | @end 19 | 20 | @implementation SYCacheScaleImage 21 | 22 | - (void)showImageWithFilePath:(NSString *)filePath 23 | { 24 | UIImage *image = [[UIImage alloc] initWithContentsOfFile:filePath]; 25 | if (self.imageView == nil) { 26 | UIView *superView = self; 27 | UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:superView.bounds]; 28 | scrollView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:1.0]; 29 | scrollView.delegate = self; 30 | [scrollView setMinimumZoomScale:scaleMini]; 31 | [scrollView setMaximumZoomScale:scaleMax]; 32 | [superView addSubview:scrollView]; 33 | // 34 | self.imageView = [[UIImageView alloc] init]; 35 | self.imageView.contentMode = UIViewContentModeScaleAspectFit; 36 | // 隐藏 37 | UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideClick:)]; 38 | self.imageView.userInteractionEnabled = YES; 39 | [self.imageView addGestureRecognizer:tapRecognizer]; 40 | // 41 | self.imageView.frame = scrollView.bounds; 42 | [scrollView addSubview:self.imageView]; 43 | } 44 | self.imageView.image = image; 45 | } 46 | 47 | - (void)hideClick:(UITapGestureRecognizer *)recognizer 48 | { 49 | if (self.imageTap) { 50 | // 51 | UIScrollView *scrollView = (UIScrollView *)self.imageView.superview; 52 | [scrollView setZoomScale:scaleMini]; 53 | // 54 | self.imageTap(); 55 | } 56 | } 57 | 58 | - (void)showInCenter:(UIScrollView *)scrollView imageView:(UIImageView *)imageView 59 | { 60 | // 居中显示 61 | CGFloat offsetX = (scrollView.bounds.size.width > scrollView.contentSize.width) ? (scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5 : 0.0; 62 | CGFloat offsetY = (scrollView.bounds.size.height > scrollView.contentSize.height) ? 63 | (scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5 : 0.0; 64 | imageView.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX, scrollView.contentSize.height * 0.5 + offsetY); 65 | } 66 | 67 | - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView 68 | { 69 | return self.imageView; 70 | } 71 | 72 | - (void)scrollViewDidZoom:(UIScrollView *)scrollView 73 | { 74 | for (UIView *view in scrollView.subviews) { 75 | if ([view isKindOfClass:[UIImageView class]]) { 76 | UIImageView *imageView = (UIImageView *)view; 77 | [self showInCenter:scrollView imageView:imageView]; 78 | } 79 | } 80 | } 81 | 82 | - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale 83 | { 84 | // 缩放效果 放大或缩小 85 | if (scrollView.minimumZoomScale >= scale) { 86 | [scrollView setZoomScale:scaleMini animated:YES]; 87 | } 88 | if (scrollView.maximumZoomScale <= scale) { 89 | [scrollView setZoomScale:scaleMax animated:YES]; 90 | } 91 | } 92 | 93 | @end 94 | #pragma mark - 95 | 96 | @interface SYCacheFileImage () 97 | 98 | @property (nonatomic, strong) UILabel *titleLabel; 99 | @property (nonatomic, strong) UIScrollView *scrollView; 100 | 101 | @end 102 | 103 | @implementation SYCacheFileImage 104 | 105 | - (instancetype)init 106 | { 107 | self = [super init]; 108 | if (self) { 109 | UIView *superView = [UIApplication sharedApplication].delegate.window; 110 | self.frame = CGRectMake(0.0, superView.frame.size.height, superView.frame.size.width, superView.frame.size.height); 111 | [superView addSubview:self]; 112 | [self addSubview:self.scrollView]; 113 | [self addSubview:self.titleLabel]; 114 | } 115 | return self; 116 | } 117 | 118 | - (void)reloadImages 119 | { 120 | if (self.images && self.images.count > 0) { 121 | // 122 | [self.scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; 123 | 124 | // 125 | self.titleLabel.text = [NSString stringWithFormat:@"%@/%@", @(self.index + 1), @(self.images.count)]; 126 | // 127 | SYCacheFileImage __weak *weakSelf = self; 128 | [self.images enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 129 | NSString *filePath = (NSString *)obj; 130 | CGRect rect = CGRectMake((weakSelf.scrollView.frame.size.width * idx), 0.0, weakSelf.scrollView.frame.size.width, weakSelf.frame.size.height); 131 | 132 | SYCacheScaleImage *imageView = [[SYCacheScaleImage alloc] initWithFrame:rect]; 133 | [weakSelf.scrollView addSubview:imageView]; 134 | [imageView showImageWithFilePath:filePath]; 135 | imageView.imageTap = ^{ 136 | [UIView animateWithDuration:0.3 animations:^{ 137 | weakSelf.frame = CGRectMake(0.0, weakSelf.superview.frame.size.height, weakSelf.superview.frame.size.width, weakSelf.superview.frame.size.height); 138 | } completion:^(BOOL finished) { 139 | [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault; 140 | }]; 141 | }; 142 | }]; 143 | 144 | // 145 | self.scrollView.contentSize = CGSizeMake(self.images.count * self.scrollView.frame.size.width, self.scrollView.frame.size.height); 146 | 147 | // 148 | self.scrollView.scrollEnabled = NO; 149 | self.titleLabel.hidden = YES; 150 | if (self.images.count > 1) { 151 | self.titleLabel.hidden = NO; 152 | self.scrollView.scrollEnabled = YES; 153 | [self.scrollView setContentOffset:CGPointMake((self.scrollView.frame.size.width * self.index), 0.0)]; 154 | } 155 | 156 | // 157 | if (self.frame.origin.y != 0.0) { 158 | [UIView animateWithDuration:0.3 animations:^{ 159 | self.frame = CGRectMake(0.0, 0.0, self.superview.frame.size.width, self.superview.frame.size.height); 160 | } completion:^(BOOL finished) { 161 | [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent; 162 | }]; 163 | } 164 | } 165 | } 166 | 167 | #pragma mark - getter 168 | 169 | - (UIScrollView *)scrollView 170 | { 171 | if (_scrollView == nil) { 172 | _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds]; 173 | _scrollView.backgroundColor = [UIColor blackColor]; 174 | _scrollView.pagingEnabled = YES; 175 | _scrollView.delegate = self; 176 | } 177 | return _scrollView; 178 | } 179 | 180 | - (UILabel *)titleLabel 181 | { 182 | if (_titleLabel == nil) { 183 | CGFloat top = 0.0; 184 | if (@available(iOS 11.0, *)) { 185 | UIWindow *window = [UIApplication sharedApplication].delegate.window; 186 | if (window.safeAreaInsets.bottom > 0.0) { 187 | top = 34.0; 188 | } 189 | } 190 | 191 | _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, top, self.bounds.size.width, 40.0)]; 192 | _titleLabel.backgroundColor = [UIColor clearColor]; 193 | _titleLabel.textAlignment = NSTextAlignmentCenter; 194 | _titleLabel.font = [UIFont boldSystemFontOfSize:18.0]; 195 | _titleLabel.textColor = [UIColor whiteColor]; 196 | } 197 | return _titleLabel; 198 | } 199 | 200 | #pragma mark - 201 | 202 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView 203 | { 204 | NSInteger page = (scrollView.contentOffset.x / scrollView.frame.size.width); 205 | self.titleLabel.text = [NSString stringWithFormat:@"%@/%@", @(page + 1), @(self.images.count)]; 206 | } 207 | 208 | @end 209 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/apk_cacheFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/apk_cacheFile.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/audio_cacheFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/audio_cacheFile.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/audio_cacheFile@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/audio_cacheFile@2x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/audio_cacheFile@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/audio_cacheFile@3x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/doc_cacheFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/doc_cacheFile.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/doc_cacheFile@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/doc_cacheFile@2x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/doc_cacheFile@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/doc_cacheFile@3x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/file_cacheFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/file_cacheFile.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/file_cacheFile@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/file_cacheFile@2x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/file_cacheFile@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/file_cacheFile@3x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/folder_cacheFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/folder_cacheFile.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/folder_cacheFile@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/folder_cacheFile@2x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/folder_cacheFile@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/folder_cacheFile@3x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/image_cacheFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/image_cacheFile.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/image_cacheFile@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/image_cacheFile@2x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/image_cacheFile@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/image_cacheFile@3x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/line_cacheFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/line_cacheFile.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/pdf_cacheFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/pdf_cacheFile.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/pdf_cacheFile@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/pdf_cacheFile@2x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/pdf_cacheFile@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/pdf_cacheFile@3x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/ppt_cacheFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/ppt_cacheFile.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/ppt_cacheFile@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/ppt_cacheFile@2x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/ppt_cacheFile@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/ppt_cacheFile@3x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/video_cacheFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/video_cacheFile.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/video_cacheFile@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/video_cacheFile@2x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/video_cacheFile@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/video_cacheFile@3x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/xls_cacheFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/xls_cacheFile.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/xls_cacheFile@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/xls_cacheFile@2x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/xls_cacheFile@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/xls_cacheFile@3x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/zip_cacheFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/zip_cacheFile.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/zip_cacheFile@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/zip_cacheFile@2x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileImages/zip_cacheFile@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/SYCacheFileViewController/SYCacheFileImages/zip_cacheFile@3x.png -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileManager.h 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 17/6/28. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 文件管理 8 | 9 | #import 10 | #import 11 | #import "SYCacheFileDefine.h" 12 | #import "SYCacheFileAudio.h" 13 | 14 | @interface SYCacheFileManager : NSObject 15 | 16 | + (instancetype)shareManager; 17 | 18 | /// 视频文件(如:.mp4) 19 | @property (nonatomic, strong) NSArray *cacheVideoTypes; 20 | /// 音频文件(如:.mp3) 21 | @property (nonatomic, strong) NSArray *cacheAudioTypes; 22 | /// 图片文件(如:.png) 23 | @property (nonatomic, strong) NSArray *cacheImageTypes; 24 | /// 文档文件(如:.txt) 25 | @property (nonatomic, strong) NSArray *cacheDocumentTypes; 26 | 27 | /// 音视频文件浏览模式(默认NO) 28 | @property (nonatomic, assign) BOOL showDoucumentUI; 29 | /// 图片浏览(默认 NO单图,YES多图) 30 | @property (nonatomic, assign) BOOL showImageShuffling; 31 | /// 被选中浏览图片名称(默认nil,多图时匹配并显示当前索引图片) 32 | @property (nonatomic, strong) NSString *nameImage; 33 | 34 | /** 35 | * 文件model 36 | * 37 | * @param filePath 文件路径 38 | * 39 | * @return NSArray 40 | */ 41 | - (NSArray *)fileModelsWithFilePath:(NSString *)filePath; 42 | 43 | #pragma mark - 文件类型 44 | 45 | /** 46 | * 判断是否是系统文件夹 47 | * 48 | * @param filePath 文件路径 49 | * 50 | * @return BOOL 51 | */ 52 | - (BOOL)isFileSystemWithFilePath:(NSString *)filePath; 53 | 54 | /** 55 | * 筛选所需类型文件 56 | * 57 | * @param type 文件类型 58 | * 59 | * @return BOOL 60 | */ 61 | - (BOOL)isFilterFileTypeWithFileType:(NSString *)type; 62 | 63 | /** 64 | * 判断文件类型 65 | * 66 | * @param filePath 文件路径 67 | * 68 | * @return SYCacheFileType 69 | */ 70 | - (SYCacheFileType)fileTypeReadWithFilePath:(NSString *)filePath; 71 | 72 | #pragma mark - 文件类型对应图标 73 | 74 | /** 75 | * 文件类型对应图标 76 | * 77 | * @param filePath 文件路径 78 | * 79 | * @return UIImage 80 | */ 81 | - (UIImage *)fileTypeImageWithFilePath:(NSString *)filePath; 82 | 83 | #pragma mark - 文件名称与类型 84 | 85 | /** 86 | * 文件名称(如:hello.png) 87 | * 88 | * @param filePath 文件路径 89 | * 90 | * @return NSString 91 | */ 92 | + (NSString *)fileNameWithFilePath:(NSString *)filePath; 93 | 94 | /** 95 | * 文件类型(如:.png) 96 | * 97 | * @param filePath 文件路径 98 | * 99 | * @return NSString 100 | */ 101 | + (NSString *)fileTypeWithFilePath:(NSString *)filePath; 102 | 103 | /** 104 | * 文件类型(如:png) 105 | * 106 | * @param filePath 文件路径 107 | * 108 | * @return NSString 109 | */ 110 | + (NSString *)fileTypeExtensionWithFilePath:(NSString *)filePath; 111 | 112 | #pragma mark - 文件目录 113 | 114 | #pragma mark 系统目录 115 | 116 | /** 117 | * Home目录路径 118 | * 119 | * @return NSString 120 | */ 121 | + (NSString *)homeDirectoryPath; 122 | 123 | /** 124 | * Document目录路径 125 | * 126 | * @return NSString 127 | */ 128 | + (NSString *)documentDirectoryPath; 129 | 130 | /** 131 | * Cache目录路径 132 | * 133 | * @return NSString 134 | */ 135 | + (NSString *)cacheDirectoryPath; 136 | 137 | /** 138 | * Library目录路径 139 | * 140 | * @return NSString 141 | */ 142 | + (NSString *)libraryDirectoryPath; 143 | 144 | /** 145 | * Tmp目录路径 146 | * 147 | * @return NSString 148 | */ 149 | + (NSString *)tmpDirectoryPath; 150 | 151 | #pragma mark 目录文件 152 | 153 | /** 154 | * 获取目录列表里所有层级子目录下的所有文件,及目录 155 | * 156 | * @param filePath 文件路径 157 | * 158 | * @return NSArray 159 | */ 160 | + (NSArray *)subPathsWithFilePath:(NSString *)filePath; 161 | 162 | /** 163 | * 获取目录列表里当前层级的文件名及文件夹名 164 | * 165 | * @param filePath 文件路径 166 | * 167 | * @return NSArray 168 | */ 169 | + (NSArray *)subFilesPathsWithFilePath:(NSString *)filePath; 170 | 171 | /** 172 | * 判断一个文件路径是否是文件夹 173 | * 174 | * @param filePath 文件路径 175 | * 176 | * @return BOOL 177 | */ 178 | + (BOOL)isFileDirectoryWithFilePath:(NSString *)filePath; 179 | 180 | /** 181 | * 获取指定文件路径的所有文件夹 182 | * 183 | * @param filePath 文件路径 184 | * 185 | * @return NSArray 186 | */ 187 | + (NSArray *)subfileDirectionsWithFilePath:(NSString *)filePath; 188 | 189 | /** 190 | * 获取指定文件路径的所有文件 191 | * 192 | * @param filePath 文件路径 193 | * 194 | * @return NSArray 195 | */ 196 | + (NSArray *)subfilesWithFilePath:(NSString *)filePath; 197 | 198 | /** 199 | * 获取指定文件路径的所有图片文件 200 | * 201 | * @param filePath 文件路径 202 | * 203 | * @return NSArray 204 | */ 205 | + (NSArray *)imagefilesWithFilePath:(NSString *)filePath; 206 | 207 | #pragma mark - 文件与目录的操作 208 | 209 | /** 210 | * 文件,或文件夹是否存在 211 | * 212 | * @param filePath 文件路径 213 | * 214 | * @return BOOL 215 | */ 216 | + (BOOL)isFileExists:(NSString *)filePath; 217 | 218 | #pragma mark 文件写入 219 | 220 | // 比如NSArray、NSDictionary、NSData、NSString都可以直接调用writeToFile方法写入文件 221 | + (BOOL)writeFileWithFilePath:(NSString *)filePath data:(id)data; 222 | 223 | #pragma mark 文件数据 224 | 225 | /** 226 | * 指定文件路径的二进制数据 227 | * 228 | * @param filePath 文件路径 229 | * 230 | * @return NSData 231 | */ 232 | + (NSData *)readFileWithFilePath:(NSString *)filePath; 233 | 234 | #pragma mark 文件创建 235 | 236 | /** 237 | * 新建目录,或文件 238 | * 239 | * @param filePath 新建目录所在的目录 240 | * @param fileName 新建目录的目录名称,如xxx,或xxx/xxx,或xxx.png,或xxx/xx.png 241 | * 242 | * @return NSString 243 | */ 244 | + (NSString *)newFilePathWithPath:(NSString *)filePath name:(NSString *)fileName; 245 | 246 | /** 247 | * 新建Document目录的目录 248 | * 249 | * @param fileName 新建的目录名称 250 | * 251 | * @return NSString 252 | */ 253 | + (NSString *)newFilePathDocumentWithName:(NSString *)fileName; 254 | 255 | /** 256 | * 新建Cache目录下的目录 257 | * 258 | * @param fileName 新建的目录名称 259 | * 260 | * @return NSString 261 | */ 262 | + (NSString *)newFilePathCacheWithName:(NSString *)fileName; 263 | 264 | #pragma mark 文件删除 265 | 266 | /** 267 | * 删除指定文件路径的文件 268 | * 269 | * @param filePath 文件路径 270 | * 271 | * @return BOOL 272 | */ 273 | + (BOOL)deleteFileWithFilePath:(NSString *)filePath; 274 | 275 | /** 276 | * 删除指定目录的所有文件 277 | * 278 | * @param directory 指定目录 279 | * 280 | * @return BOOL 281 | */ 282 | + (BOOL)deleteFileWithDirectory:(NSString *)directory; 283 | 284 | #pragma mark 文件复制 285 | 286 | /** 287 | * 文件复制 288 | * 289 | * @param fromPath 目标文件路径 290 | * @param toPath 复制后文件路径 291 | * 292 | * @return BOOL 293 | */ 294 | + (BOOL)copyFileWithFilePath:(NSString *)fromPath toPath:(NSString *)toPath; 295 | 296 | #pragma mark 文件移动 297 | 298 | /** 299 | * 文件移动 300 | * 301 | * @param fromPath 移动前位置 302 | * @param toPath 移动后位置 303 | * 304 | * @return BOOL 305 | */ 306 | 307 | + (BOOL)moveFileWithFilePath:(NSString *)fromPath toPath:(NSString *)toPath; 308 | 309 | #pragma mark 文件重命名 310 | 311 | /** 312 | * 文件重命名 313 | * 314 | * @param filePath 文件路径 315 | * @param newName 文件新名称 316 | * 317 | * @return BOOL 318 | */ 319 | + (BOOL)renameFileWithFilePath:(NSString *)filePath newName:(NSString *)newName; 320 | 321 | #pragma mark - 文件信息 322 | 323 | /** 324 | * 文件信息字典 325 | * 326 | * @param filePath 文件路径 327 | * 328 | * @return NSDictionary 329 | */ 330 | + (NSDictionary *)fileAttributesWithFilePath:(NSString *)filePath; 331 | 332 | /** 333 | * 单个文件的大小 double 334 | * 335 | * @param filePath 文件路径 336 | * 337 | * @return double 338 | */ 339 | + (double)fileSizeNumberWithFilePath:(NSString *)filePath; 340 | 341 | /** 342 | * 文件类型转换:数值型转字符型 343 | * 344 | * 1MB = 1024KB 1KB = 1024B 345 | * 346 | * @param fileSize 文件大小 347 | * 348 | * @return NSString 349 | */ 350 | + (NSString *)fileSizeStringConversionWithNumber:(double)fileSize; 351 | 352 | /** 353 | * 单个文件的大小 String 354 | * 355 | * @param filePath 文件路径 356 | * 357 | * @return String 358 | */ 359 | + (NSString *)fileSizeStringWithFilePath:(NSString *)filePath; 360 | 361 | /** 362 | * 遍历文件夹大小 double 363 | * 364 | * @param directory 指定目录 365 | * 366 | * @return double 367 | */ 368 | + (double)fileSizeTotalNumberWithDirectory:(NSString *)directory; 369 | 370 | /** 371 | * 遍历文件夹大小 NSString 372 | * 373 | * @param directory 指定目录 374 | * 375 | * @return NSString 376 | */ 377 | + (NSString *)fileSizeTotalStringWithDirectory:(NSString *)directory; 378 | 379 | 380 | @end 381 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileManager.m 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 17/6/28. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import "SYCacheFileManager.h" 10 | #import "SYCacheFileModel.h" 11 | 12 | #include 13 | #include 14 | 15 | @interface SYCacheFileManager () 16 | 17 | /// 视频文件 18 | @property (nonatomic, strong) NSMutableArray *cacheVideoArrayUsing; 19 | /// 音频文件 20 | @property (nonatomic, strong) NSMutableArray *cacheAudioArrayUsing; 21 | /// 图片文件 22 | @property (nonatomic, strong) NSMutableArray *cacheImageArrayUsing; 23 | /// 文档文件 24 | @property (nonatomic, strong) NSMutableArray *cacheDocumentArrayUsing; 25 | 26 | /// 不能删除系统文件及文件夹 27 | @property (nonatomic, strong) NSArray *cacheSystemArrayUsing; 28 | 29 | @end 30 | 31 | @implementation SYCacheFileManager 32 | 33 | 34 | + (instancetype)shareManager 35 | { 36 | static SYCacheFileManager *fileManager; 37 | static dispatch_once_t onceToken; 38 | dispatch_once(&onceToken, ^{ 39 | fileManager = [[SYCacheFileManager alloc] init]; 40 | }); 41 | return fileManager; 42 | } 43 | 44 | #pragma mark - getter 45 | 46 | - (NSMutableArray *)cacheVideoArrayUsing 47 | { 48 | if (_cacheVideoArrayUsing == nil) { 49 | _cacheVideoArrayUsing = [[NSMutableArray alloc] initWithObjects:@".avi", @".dat", @".mkv", @".flv", @".vob", @".mp4", @".m4v", @".mpg", @".mpeg", @".mpe", @".3pg", @".mov", @".swf", @".wmv", @".asf", @".asx", @".rm", @".rmvb", nil]; 50 | } 51 | return _cacheVideoArrayUsing; 52 | } 53 | 54 | - (NSMutableArray *)cacheAudioArrayUsing 55 | { 56 | if (_cacheAudioArrayUsing == nil) { 57 | _cacheAudioArrayUsing = [[NSMutableArray alloc] initWithObjects:@".wav", @".aif", @".au", @".mp3", @".ram", @".wma", @".mmf", @".amr", @".aac", @".flac", @".midi", @".mp3", @".oog", @".cd", @".asf", @".rm", @".real", @".ape", @".vqf", nil]; 58 | } 59 | return _cacheAudioArrayUsing; 60 | } 61 | 62 | - (NSMutableArray *)cacheImageArrayUsing 63 | { 64 | if (_cacheImageArrayUsing == nil) { 65 | _cacheImageArrayUsing = [[NSMutableArray alloc] initWithObjects:@".jpg", @".png", @".jpeg", @".gif", @".bmp", nil]; 66 | } 67 | return _cacheImageArrayUsing; 68 | } 69 | 70 | - (NSMutableArray *)cacheDocumentArrayUsing 71 | { 72 | if (_cacheDocumentArrayUsing == nil) { 73 | _cacheDocumentArrayUsing = [[NSMutableArray alloc] initWithObjects:@".txt", @".sh", @".doc", @".docx", @".xls", @".xlsx", @".pdf", @".hlp", @".wps", @".rtf", @".html", @".htm", @".iso", @".rar", @".zip", @".exe", @".mdf", @".ppt", @".pptx", @".apk", nil]; 74 | } 75 | return _cacheDocumentArrayUsing; 76 | } 77 | 78 | - (NSArray *)cacheSystemArrayUsing 79 | { 80 | if (_cacheSystemArrayUsing == nil) { 81 | _cacheSystemArrayUsing = @[@"/tmp", @"/Library/Preferences", @"/Library/Caches/Snapshots", @"/Library/Caches", @"/Library", @"/Documents", @"/Snapshots", @"/SystemData"]; 82 | } 83 | return _cacheSystemArrayUsing; 84 | } 85 | 86 | #pragma mark - setter 87 | 88 | - (void)setCacheVideoTypes:(NSArray *)cacheVideoTypes 89 | { 90 | _cacheVideoTypes = cacheVideoTypes; 91 | if (_cacheVideoTypes.count > 0) { 92 | NSMutableArray *array = [NSMutableArray arrayWithArray:_cacheVideoTypes]; 93 | [array addObjectsFromArray:self.cacheVideoArrayUsing]; 94 | NSSet *set = [NSSet setWithArray:array]; 95 | self.cacheVideoArrayUsing = (NSMutableArray *)[set allObjects]; 96 | } 97 | } 98 | 99 | - (void)setCacheAudioTypes:(NSArray *)cacheAudioTypes 100 | { 101 | _cacheAudioTypes = cacheAudioTypes; 102 | if (_cacheAudioTypes.count > 0) { 103 | NSMutableArray *array = [NSMutableArray arrayWithArray:_cacheAudioTypes]; 104 | [array addObjectsFromArray:self.cacheAudioArrayUsing]; 105 | NSSet *set = [NSSet setWithArray:array]; 106 | self.cacheAudioArrayUsing = (NSMutableArray *)[set allObjects]; 107 | } 108 | } 109 | 110 | - (void)setCacheImageTypes:(NSArray *)cacheImageTypes 111 | { 112 | _cacheImageTypes = cacheImageTypes; 113 | if (_cacheImageTypes.count > 0) { 114 | NSMutableArray *array = [NSMutableArray arrayWithArray:_cacheImageTypes]; 115 | [array addObjectsFromArray:self.cacheImageArrayUsing]; 116 | NSSet *set = [NSSet setWithArray:array]; 117 | self.cacheImageArrayUsing = (NSMutableArray *)[set allObjects]; 118 | } 119 | } 120 | 121 | - (void)setCacheDocumentTypes:(NSArray *)cacheDocumentTypes 122 | { 123 | _cacheDocumentTypes = cacheDocumentTypes; 124 | if (_cacheDocumentTypes.count > 0) { 125 | NSMutableArray *array = [NSMutableArray arrayWithArray:_cacheDocumentTypes]; 126 | [array addObjectsFromArray:self.cacheDocumentArrayUsing]; 127 | NSSet *set = [NSSet setWithArray:array]; 128 | self.cacheDocumentArrayUsing = (NSMutableArray *)[set allObjects]; 129 | } 130 | } 131 | 132 | #pragma mark - 133 | 134 | /** 135 | * 文件model 136 | * 137 | * @param filePath 文件路径 138 | * 139 | * @return NSArray 140 | */ 141 | - (NSArray *)fileModelsWithFilePath:(NSString *)filePath 142 | { 143 | NSArray *array = [SYCacheFileManager subFilesPathsWithFilePath:filePath]; 144 | NSMutableArray *fileArray = [NSMutableArray arrayWithCapacity:array.count]; 145 | for (id object in array) { 146 | SYCacheFileModel *model = [SYCacheFileModel new]; 147 | model.fileName = object; 148 | model.filePath = [filePath stringByAppendingPathComponent:object]; 149 | 150 | SYCacheFileType type = [self fileTypeReadWithFilePath:model.filePath]; 151 | if (SYCacheFileTypeUnknow == type) { 152 | // 过滤系统文件夹 153 | // 原方法 154 | // NSRange range = [model.filePath rangeOfString:@"." options:NSBackwardsSearch]; 155 | // if (range.location != NSNotFound) { 156 | // continue; 157 | // } 158 | if ([model.fileName hasPrefix:@"."] || ![SYCacheFileManager isFileDirectoryWithFilePath:model.filePath]) { 159 | continue; 160 | } 161 | } else { 162 | // 过滤系统文件 163 | NSString *typeName = [SYCacheFileManager fileTypeWithFilePath:model.filePath]; 164 | if (![self isFilterFileTypeWithFileType:typeName]) { 165 | continue; 166 | } 167 | } 168 | 169 | [fileArray addObject:model]; 170 | } 171 | 172 | return fileArray; 173 | } 174 | 175 | 176 | #pragma mark - 文件类型 177 | 178 | - (NSArray *)fileTypeArray 179 | { 180 | NSMutableArray *array = [NSMutableArray array]; 181 | [array addObjectsFromArray:self.cacheVideoArrayUsing]; 182 | [array addObjectsFromArray:self.cacheAudioArrayUsing]; 183 | [array addObjectsFromArray:self.cacheImageArrayUsing]; 184 | [array addObjectsFromArray:self.cacheDocumentArrayUsing]; 185 | 186 | return array; 187 | } 188 | 189 | /** 190 | * 判断是否是系统文件夹 191 | * 192 | * @param filePath 文件路径 193 | * 194 | * @return BOOL 195 | */ 196 | - (BOOL)isFileSystemWithFilePath:(NSString *)filePath 197 | { 198 | for (NSString *file in self.cacheSystemArrayUsing) { 199 | if ([filePath hasSuffix:file]) { 200 | return YES; 201 | break; 202 | } 203 | } 204 | return NO; 205 | } 206 | 207 | /** 208 | * 筛选所需类型文件 209 | * 210 | * @param type 文件类型 211 | * 212 | * @return BOOL 213 | */ 214 | - (BOOL)isFilterFileTypeWithFileType:(NSString *)type 215 | { 216 | if ([self.fileTypeArray containsObject:type]) { 217 | return YES; 218 | } 219 | return NO; 220 | } 221 | 222 | /** 223 | * 判断文件类型 224 | * 225 | * @param filePath 文件路径 226 | * 227 | * @return SYCacheFileType 228 | */ 229 | - (SYCacheFileType)fileTypeReadWithFilePath:(NSString *)filePath 230 | { 231 | NSString *fileType = [SYCacheFileManager fileTypeWithFilePath:filePath]; 232 | fileType = fileType.lowercaseString; 233 | SYCacheFileType type = SYCacheFileTypeUnknow; 234 | if ([self.cacheVideoArrayUsing containsObject:fileType]) { 235 | type = SYCacheFileTypeVideo; 236 | } else if ([self.cacheAudioArrayUsing containsObject:fileType]) { 237 | type = SYCacheFileTypeAudio; 238 | } else if ([self.cacheImageArrayUsing containsObject:fileType]) { 239 | type = SYCacheFileTypeImage; 240 | } else if ([self.cacheDocumentArrayUsing containsObject:fileType]) { 241 | type = SYCacheFileTypeDocument; 242 | } 243 | return type; 244 | } 245 | 246 | #pragma mark - 文件类型对应图标 247 | 248 | /** 249 | * 文件类型对应图标 250 | * 251 | * @param filePath 文件路径 252 | * 253 | * @return UIImage 254 | */ 255 | - (UIImage *)fileTypeImageWithFilePath:(NSString *)filePath 256 | { 257 | UIImage *image = [UIImage imageNamed:@"folder_cacheFile"]; 258 | if (filePath && 0 < filePath.length) { 259 | SYCacheFileType type = [self fileTypeReadWithFilePath:filePath]; 260 | if (SYCacheFileTypeUnknow == type) { 261 | image = [UIImage imageNamed:@"folder_cacheFile"]; 262 | } else { 263 | NSString *fileType = [SYCacheFileManager fileTypeWithFilePath:filePath]; 264 | fileType = fileType.lowercaseString; 265 | if ([self.cacheImageArrayUsing containsObject:fileType]) { 266 | image = [UIImage imageNamed:@"image_cacheFile"]; 267 | } else if ([self.cacheVideoArrayUsing containsObject:fileType]) { 268 | image = [UIImage imageNamed:@"video_cacheFile"]; 269 | } else if ([self.cacheAudioArrayUsing containsObject:fileType]) { 270 | image = [UIImage imageNamed:@"audio_cacheFile"]; 271 | } else if ([@[@".doc", @".docx"] containsObject:fileType]) { 272 | image = [UIImage imageNamed:@"doc_cacheFile"]; 273 | } else if ([@[@".xls", @".xlsx"] containsObject:fileType]) { 274 | image = [UIImage imageNamed:@"xls_cacheFile"]; 275 | } else if ([@[@".pdf"] containsObject:fileType]) { 276 | image = [UIImage imageNamed:@"pdf_cacheFile"]; 277 | } else if ([@[@".ppt", @".pptx"] containsObject:fileType]) { 278 | image = [UIImage imageNamed:@"ppt_cacheFile"]; 279 | } else if ([@[@".zip", @".rar", @".iso"] containsObject:fileType]) { 280 | image = [UIImage imageNamed:@"zip_cacheFile"]; 281 | } else if ([@[@".apk"] containsObject:fileType]) { 282 | image = [UIImage imageNamed:@"apk_cacheFile"]; 283 | } else { 284 | image = [UIImage imageNamed:@"file_cacheFile"]; 285 | } 286 | } 287 | } 288 | return image; 289 | } 290 | 291 | #pragma mark - 文件名称与类型 292 | 293 | /** 294 | * 文件名称(如:hello.png) 295 | * 296 | * @param filePath 文件路径 297 | * 298 | * @return NSString 299 | */ 300 | + (NSString *)fileNameWithFilePath:(NSString *)filePath 301 | { 302 | // if ([self isFileExists:filePath]) { 303 | // NSRange range = [filePath rangeOfString:@"/" options:NSBackwardsSearch]; 304 | // if (range.location != NSNotFound) { 305 | // NSString *text = [filePath substringFromIndex:(range.location + range.length)]; 306 | // return text; 307 | // } 308 | // 309 | // return nil; 310 | // } 311 | // 312 | // return nil; 313 | 314 | NSString *text = filePath.lastPathComponent; 315 | return text; 316 | } 317 | 318 | /** 319 | * 文件类型(如:.png) 320 | * 321 | * @param filePath 文件路径 322 | * 323 | * @return NSString 324 | */ 325 | + (NSString *)fileTypeWithFilePath:(NSString *)filePath 326 | { 327 | // if ([self isFileExists:filePath]) { 328 | // NSRange range = [filePath rangeOfString:@"." options:NSBackwardsSearch]; 329 | // if (range.location != NSNotFound) { 330 | // NSString *text = [filePath substringFromIndex:(range.location)]; 331 | // text = text.lowercaseString; 332 | // return text; 333 | // } 334 | // 335 | // return nil; 336 | // } 337 | // 338 | // return nil; 339 | 340 | NSString *text = filePath.pathExtension; 341 | text = [NSString stringWithFormat:@".%@", text]; 342 | return text; 343 | } 344 | 345 | /** 346 | * 文件类型(如:png) 347 | * 348 | * @param filePath 文件路径 349 | * 350 | * @return NSString 351 | */ 352 | + (NSString *)fileTypeExtensionWithFilePath:(NSString *)filePath 353 | { 354 | // if ([self isFileExists:filePath]) { 355 | // NSString *text = filePath.pathExtension; 356 | // return text; 357 | // } 358 | // 359 | // return nil; 360 | 361 | NSString *text = filePath.pathExtension; 362 | return text; 363 | } 364 | 365 | #pragma mark - 文件目录 366 | 367 | #pragma mark 系统目录 368 | 369 | /** 370 | * Home目录路径 371 | * 372 | * @return NSString 373 | */ 374 | + (NSString *)homeDirectoryPath 375 | { 376 | return NSHomeDirectory(); 377 | } 378 | 379 | /** 380 | * Document目录路径 381 | * 382 | * @return NSString 383 | */ 384 | + (NSString *)documentDirectoryPath 385 | { 386 | NSArray *Paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 387 | NSString *path = [Paths objectAtIndex:0]; 388 | return path; 389 | } 390 | 391 | /** 392 | * Cache目录路径 393 | * 394 | * @return NSString 395 | */ 396 | + (NSString *)cacheDirectoryPath 397 | { 398 | NSArray *Paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 399 | NSString *path = [Paths objectAtIndex:0]; 400 | return path; 401 | } 402 | 403 | /** 404 | * Library目录路径 405 | * 406 | * @return NSString 407 | */ 408 | + (NSString *)libraryDirectoryPath 409 | { 410 | NSArray *Paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); 411 | NSString *path = [Paths objectAtIndex:0]; 412 | return path; 413 | } 414 | 415 | /** 416 | * Tmp目录路径 417 | * 418 | * @return NSString 419 | */ 420 | + (NSString *)tmpDirectoryPath 421 | { 422 | return NSTemporaryDirectory(); 423 | } 424 | 425 | #pragma mark 目录文件 426 | 427 | /** 428 | * 获取目录列表里所有层级子目录下的所有文件,及目录 429 | * 430 | * @param filePath 文件路径 431 | * 432 | * @return NSArray 433 | */ 434 | + (NSArray *)subPathsWithFilePath:(NSString *)filePath 435 | { 436 | NSArray *files = [[NSFileManager defaultManager] subpathsAtPath:filePath]; 437 | return files; 438 | } 439 | 440 | /** 441 | * 获取目录列表里当前层级的文件名及文件夹名 442 | * 443 | * @param filePath 文件路径 444 | * 445 | * @return NSArray 446 | */ 447 | + (NSArray *)subFilesPathsWithFilePath:(NSString *)filePath 448 | { 449 | NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:filePath error:nil]; 450 | return files; 451 | } 452 | 453 | /** 454 | * 判断一个文件路径是否是文件夹 455 | * 456 | * @param filePath 文件路径 457 | * 458 | * @return BOOL 459 | */ 460 | + (BOOL)isFileDirectoryWithFilePath:(NSString *)filePath 461 | { 462 | BOOL isDirectory = NO; 463 | [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory]; 464 | return isDirectory; 465 | } 466 | 467 | /// 获取沙盒目录中指定目录的所有文件夹,或文件 468 | + (NSArray *)filesWithFilePath:(NSString *)filePath isDirectory:(BOOL)isDirectory 469 | { 470 | NSMutableArray *directions = [NSMutableArray array]; 471 | NSArray *files = [[self class] subFilesPathsWithFilePath:filePath]; 472 | for (id object in files) { 473 | BOOL isDir = [[self class] isFileDirectoryWithFilePath:object]; 474 | if (isDirectory) { 475 | if (isDir) { 476 | [directions addObject:object]; 477 | } 478 | } else { 479 | if (!isDir) { 480 | [directions addObject:object]; 481 | } 482 | } 483 | } 484 | return directions; 485 | } 486 | 487 | /** 488 | * 获取指定文件路径的所有文件夹 489 | * 490 | * @param filePath 文件路径 491 | * 492 | * @return NSArray 493 | */ 494 | + (NSArray *)subfileDirectionsWithFilePath:(NSString *)filePath 495 | { 496 | NSArray *directorys = [[self class] filesWithFilePath:filePath isDirectory:YES]; 497 | return directorys; 498 | } 499 | 500 | /** 501 | * 获取指定文件路径的所有文件 502 | * 503 | * @param filePath 文件路径 504 | * 505 | * @return NSArray 506 | */ 507 | + (NSArray *)subfilesWithFilePath:(NSString *)filePath 508 | { 509 | NSArray *files = [[self class] filesWithFilePath:filePath isDirectory:NO]; 510 | return files; 511 | } 512 | 513 | /** 514 | * 获取指定文件路径的所有图片文件 515 | * 516 | * @param filePath 文件路径 517 | * 518 | * @return NSArray 519 | */ 520 | + (NSArray *)imagefilesWithFilePath:(NSString *)filePath 521 | { 522 | NSArray *files = [[self class] filesWithFilePath:filePath isDirectory:NO]; 523 | NSMutableArray *array = [[NSMutableArray alloc] init]; 524 | [files enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 525 | NSString *file = (NSString *)obj; 526 | SYCacheFileType type = [[SYCacheFileManager shareManager] fileTypeReadWithFilePath:file]; 527 | if (type == SYCacheFileTypeImage) { 528 | file = [filePath stringByAppendingPathComponent:file]; 529 | [array addObject:file]; 530 | } 531 | }]; 532 | return array; 533 | } 534 | 535 | #pragma mark - 文件与目录的操作 536 | 537 | /** 538 | * 文件,或文件夹是否存在 539 | * 540 | * @param filePath 文件路径 541 | * 542 | * @return BOOL 543 | */ 544 | + (BOOL)isFileExists:(NSString *)filePath 545 | { 546 | return [[NSFileManager defaultManager] fileExistsAtPath:filePath]; 547 | } 548 | 549 | #pragma mark 文件写入 550 | 551 | // 比如NSArray、NSDictionary、NSData、NSString都可以直接调用writeToFile方法写入文件 552 | + (BOOL)writeFileWithFilePath:(NSString *)filePath data:(id)data 553 | { 554 | if (![self isFileExists:filePath]) { 555 | filePath = [self newFilePathWithPath:filePath name:nil]; 556 | } 557 | return [data writeToFile:filePath atomically:YES]; 558 | } 559 | 560 | #pragma mark 文件数据 561 | 562 | /** 563 | * 指定文件路径的二进制数据 564 | * 565 | * @param filePath 文件路径 566 | * 567 | * @return NSData 568 | */ 569 | + (NSData *)readFileWithFilePath:(NSString *)filePath 570 | { 571 | if ([self isFileExists:filePath]) { 572 | return [[NSFileManager defaultManager] contentsAtPath:filePath]; 573 | } 574 | return nil; 575 | } 576 | 577 | #pragma mark 文件创建 578 | 579 | /** 580 | * 新建目录,或文件 581 | * 582 | * @param filePath 新建目录所在的目录 583 | * @param fileName 新建目录的目录名称,如xxx,或xxx/xxx,或xxx.png,或xxx/xx.png 584 | * 585 | * @return NSString 586 | */ 587 | + (NSString *)newFilePathWithPath:(NSString *)filePath name:(NSString *)fileName 588 | { 589 | NSString *fileDirectory = [filePath stringByAppendingPathComponent:fileName]; 590 | if ([self isFileExists:fileDirectory]) { 591 | NSLog(@"<--exist-->%@", fileDirectory); 592 | } else { 593 | NSError *error; 594 | BOOL isSuccessDirectory = [[NSFileManager defaultManager] createDirectoryAtPath:fileDirectory withIntermediateDirectories:YES attributes:nil error:&error]; 595 | if (!isSuccessDirectory) { 596 | NSLog(@"create dir error: %@", error.debugDescription); 597 | return nil; 598 | } 599 | } 600 | return fileDirectory; 601 | } 602 | 603 | /** 604 | * 新建Document目录的目录 605 | * 606 | * @param fileName 新建的目录名称 607 | * 608 | * @return NSString 609 | */ 610 | + (NSString *)newFilePathDocumentWithName:(NSString *)fileName 611 | { 612 | return [self newFilePathWithPath:[self documentDirectoryPath] name:fileName]; 613 | } 614 | 615 | /** 616 | * 新建Cache目录下的目录 617 | * 618 | * @param fileName 新建的目录名称 619 | * 620 | * @return NSString 621 | */ 622 | + (NSString *)newFilePathCacheWithName:(NSString *)fileName 623 | { 624 | return [self newFilePathWithPath:[self cacheDirectoryPath] name:fileName]; 625 | } 626 | 627 | #pragma mark 文件删除 628 | 629 | /** 630 | * 删除指定文件路径的文件 631 | * 632 | * @param filePath 文件路径 633 | * 634 | * @return BOOL 635 | */ 636 | + (BOOL)deleteFileWithFilePath:(NSString *)filePath 637 | { 638 | if ([self isFileExists:filePath]) { 639 | return [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil]; 640 | } 641 | return NO; 642 | } 643 | 644 | /** 645 | * 删除指定目录的所有文件 646 | * 647 | * @param directory 指定目录 648 | * 649 | * @return BOOL 650 | */ 651 | + (BOOL)deleteFileWithDirectory:(NSString *)directory; 652 | { 653 | return [self deleteFileWithFilePath:directory]; 654 | } 655 | 656 | #pragma mark 文件复制 657 | 658 | /** 659 | * 文件复制 660 | * 661 | * @param fromPath 目标文件路径 662 | * @param toPath 复制后文件路径 663 | * 664 | * @return BOOL 665 | */ 666 | + (BOOL)copyFileWithFilePath:(NSString *)fromPath toPath:(NSString *)toPath 667 | { 668 | BOOL isSuccess = NO; 669 | BOOL isExists = [[NSFileManager defaultManager] fileExistsAtPath:fromPath]; 670 | if (isExists) { 671 | isSuccess = [[NSFileManager defaultManager] copyItemAtPath:fromPath toPath:toPath error:nil]; 672 | } 673 | return isSuccess; 674 | } 675 | 676 | #pragma mark 文件移动 677 | 678 | /** 679 | * 文件移动 680 | * 681 | * @param fromPath 移动前位置 682 | * @param toPath 移动后位置 683 | * 684 | * @return BOOL 685 | */ 686 | 687 | + (BOOL)moveFileWithFilePath:(NSString *)fromPath toPath:(NSString *)toPath 688 | { 689 | BOOL isSuccess = NO; 690 | BOOL isExists = [[NSFileManager defaultManager] fileExistsAtPath:fromPath]; 691 | if (isExists) { 692 | isSuccess = [[NSFileManager defaultManager] moveItemAtPath:fromPath toPath:toPath error:nil]; 693 | } 694 | return isSuccess; 695 | } 696 | 697 | #pragma mark 文件重命名 698 | 699 | /** 700 | * 文件重命名 701 | * 702 | * @param filePath 文件路径 703 | * @param newName 文件新名称 704 | * 705 | * @return BOOL 706 | */ 707 | + (BOOL)renameFileWithFilePath:(NSString *)filePath newName:(NSString *)newName 708 | { 709 | BOOL isSuccess = NO; 710 | BOOL isExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath]; 711 | if (isExists) { 712 | NSString *fileName = filePath.lastPathComponent; 713 | NSString *filePathTmp = [filePath substringToIndex:(filePath.length - fileName.length)]; 714 | filePathTmp = [filePathTmp stringByAppendingPathComponent:newName]; 715 | isSuccess = [[NSFileManager defaultManager] moveItemAtPath:filePath toPath:filePathTmp error:nil]; 716 | } 717 | return isSuccess; 718 | } 719 | 720 | #pragma mark - 文件信息 721 | 722 | /** 723 | * 文件信息字典 724 | * 725 | * @param filePath 文件路径 726 | * 727 | * @return NSDictionary 728 | */ 729 | + (NSDictionary *)fileAttributesWithFilePath:(NSString *)filePath 730 | { 731 | if ([self isFileExists:filePath]) { 732 | return [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil]; 733 | } 734 | return nil; 735 | } 736 | 737 | /** 738 | * 单个文件的大小 double 739 | * 740 | * @param filePath 文件路径 741 | * 742 | * @return double 743 | */ 744 | + (double)fileSizeNumberWithFilePath:(NSString *)filePath 745 | { 746 | if ([self isFileExists:filePath]) { 747 | return [[self fileAttributesWithFilePath:filePath] fileSize]; 748 | } 749 | return 0.0; 750 | } 751 | 752 | /** 753 | * 文件类型转换:数值型转字符型 754 | * 755 | * 1MB = 1024KB 1KB = 1024B 756 | * 757 | * @param fileSize 文件大小 758 | * 759 | * @return NSString 760 | */ 761 | + (NSString *)fileSizeStringConversionWithNumber:(double)fileSize 762 | { 763 | NSString *message = nil; 764 | 765 | // 1MB = 1024KB 1KB = 1024B 766 | double size = fileSize; 767 | if (size > (1024 * 1024)) { 768 | size = size / (1024 * 1024); 769 | message = [NSString stringWithFormat:@"%.2fM", size]; 770 | } else if (size > 1024) { 771 | size = size / 1024; 772 | message = [NSString stringWithFormat:@"%.2fKB", size]; 773 | } else if (size > 0.0) { 774 | message = [NSString stringWithFormat:@"%.2fB", size]; 775 | } 776 | 777 | return message; 778 | } 779 | 780 | /** 781 | * 单个文件的大小 String 782 | * 783 | * @param filePath 文件路径 784 | * 785 | * @return String 786 | */ 787 | + (NSString *)fileSizeStringWithFilePath:(NSString *)filePath 788 | { 789 | // 1MB = 1024KB 1KB = 1024B 790 | double size = [self fileSizeNumberWithFilePath:filePath]; 791 | return [self fileSizeStringConversionWithNumber:size]; 792 | } 793 | 794 | /** 795 | * 遍历文件夹大小 double 796 | * 797 | * @param directory 指定目录 798 | * 799 | * @return double 800 | */ 801 | + (double)fileSizeTotalNumberWithDirectory:(NSString *)directory 802 | { 803 | __block double size = 0.0; 804 | if ([self isFileExists:directory]) { 805 | NSArray *array = [self subPathsWithFilePath:directory]; 806 | 807 | [array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 808 | NSString *filePath = [directory stringByAppendingPathComponent:obj]; 809 | if ([self isFileDirectoryWithFilePath:filePath]) 810 | { 811 | [self fileSizeTotalNumberWithDirectory:filePath]; 812 | } 813 | size += [self fileSizeNumberWithFilePath:filePath]; 814 | }]; 815 | } 816 | 817 | return size; 818 | } 819 | 820 | /** 821 | * 遍历文件夹大小 NSString 822 | * 823 | * @param directory 指定目录 824 | * 825 | * @return NSString 826 | */ 827 | + (NSString *)fileSizeTotalStringWithDirectory:(NSString *)directory 828 | { 829 | double size = [self fileSizeTotalNumberWithDirectory:directory]; 830 | return [self fileSizeStringConversionWithNumber:size]; 831 | } 832 | 833 | @end 834 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileModel.h 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 17/6/28. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SYCacheFileDefine.h" 11 | 12 | @interface SYCacheFileModel : NSObject 13 | 14 | /// 文件路径 15 | @property (nonatomic, strong) NSString *filePath; 16 | /// 文件名称 17 | @property (nonatomic, strong) NSString *fileName; 18 | /// 文件大小 19 | @property (nonatomic, strong) NSString *fileSize; 20 | 21 | /// 文件类型(1视频、2音频、3图片、4文档) 22 | @property (nonatomic, assign) SYCacheFileType fileType; 23 | /// 音频文件进度 24 | @property (nonatomic, assign) float fileProgress; 25 | /// 音频文件进度显示 26 | @property (nonatomic, assign) BOOL fileProgressShow; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileModel.m 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 17/6/28. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import "SYCacheFileModel.h" 10 | #import "SYCacheFileManager.h" 11 | 12 | @implementation SYCacheFileModel 13 | 14 | - (NSString *)fileSize 15 | { 16 | if (self.fileType == SYCacheFileTypeUnknow) { 17 | return [SYCacheFileManager fileSizeTotalStringWithDirectory:self.filePath]; 18 | } 19 | return [SYCacheFileManager fileSizeStringWithFilePath:self.filePath]; 20 | } 21 | 22 | - (SYCacheFileType)fileType 23 | { 24 | return [[SYCacheFileManager shareManager] fileTypeReadWithFilePath:self.filePath]; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileRead.h: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileRead.h 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 17/6/27. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 文件浏览 8 | 9 | #import 10 | 11 | @interface SYCacheFileRead : NSObject 12 | 13 | /** 14 | * 文件阅读:图片浏览、文档查看、音视频播放 15 | * 16 | * @param filePath 文件路径 17 | * @param target UIViewController 18 | */ 19 | - (void)fileReadWithFilePath:(NSString *)filePath target:(id)target; 20 | 21 | /** 22 | * 内存释放 23 | */ 24 | - (void)releaseSYCacheFileRead; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileRead.m: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileRead.m 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 17/6/27. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import "SYCacheFileRead.h" 10 | // 音频 11 | #import "SYCacheFileAudio.h" 12 | // 视频 13 | #import "SYCacheFileVideo.h" 14 | // 文档 15 | #import 16 | 17 | #import "SYCacheFileManager.h" 18 | #import "SYCacheFileImage.h" 19 | 20 | @interface SYCacheFileRead () 21 | 22 | @property (nonatomic, weak) UIViewController *controller; 23 | 24 | // 图片显示 25 | @property (nonatomic, strong) UIImageView *imageView; 26 | @property (nonatomic, strong) SYCacheFileImage *fileImage; 27 | 28 | // 文档查看(文档、图片、视频) 29 | @property (nonatomic, strong) UIDocumentInteractionController *documentController; 30 | 31 | @end 32 | 33 | @implementation SYCacheFileRead 34 | 35 | // 初始化 36 | - (id)init 37 | { 38 | self = [super init]; 39 | if (self) { 40 | 41 | } 42 | return self; 43 | } 44 | 45 | // 内存管理 46 | - (void)dealloc 47 | { 48 | NSLog(@"%@ 被释放了!", [self class]); 49 | } 50 | 51 | - (void)releaseSYCacheFileRead 52 | { 53 | [NSObject cancelPreviousPerformRequestsWithTarget:self]; 54 | } 55 | 56 | /** 57 | * 文件阅读:图片浏览、文档查看、音视频播放 58 | * 59 | * @param filePath 文件路径 60 | * @param target UIViewController 61 | */ 62 | - (void)fileReadWithFilePath:(NSString *)filePath target:(id)target 63 | { 64 | if (filePath == nil || ![[NSFileManager defaultManager] fileExistsAtPath:filePath]) { 65 | [[[UIAlertView alloc] initWithTitle:@"温馨提示" message:@"filePath指向文件不存在" delegate:@"确定" cancelButtonTitle:nil otherButtonTitles:nil, nil] show]; 66 | return; 67 | } 68 | if (target == nil || ![target isKindOfClass:[UIViewController class]]) { 69 | [[[UIAlertView alloc] initWithTitle:@"温馨提示" message:@"target类型不是UIViewController" delegate:@"确定" cancelButtonTitle:nil otherButtonTitles:nil, nil] show]; 70 | return; 71 | } 72 | 73 | if ([SYCacheFileManager shareManager].showDoucumentUI) { 74 | if ([filePath hasSuffix:@"apk"]) { 75 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:@"无法打开apk文件" preferredStyle:UIAlertControllerStyleAlert]; 76 | UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { 77 | 78 | }]; 79 | [alertController addAction:cancelAction]; 80 | [target presentViewController:alertController animated:YES completion:NULL]; 81 | } else { 82 | [self fileDocumentReadWithFilePath:filePath target:target]; 83 | } 84 | } else { 85 | SYCacheFileType type = [[SYCacheFileManager shareManager] fileTypeReadWithFilePath:filePath]; 86 | if (SYCacheFileTypeAudio == type) { 87 | [self fileAudioReadWithFilePath:filePath target:target]; 88 | } else if (SYCacheFileTypeVideo == type) { 89 | [self fileVidioReadWithFilePath:filePath target:target]; 90 | } else if (SYCacheFileTypeImage == type) { 91 | if ([filePath hasSuffix:@"gif"]) { 92 | [self fileDocumentReadWithFilePath:filePath target:target]; 93 | } else { 94 | [self fileImageReadWithFilePath:filePath target:target]; 95 | } 96 | } else { 97 | if ([filePath hasSuffix:@"apk"]) { 98 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:@"无法打开apk文件" preferredStyle:UIAlertControllerStyleAlert]; 99 | UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { 100 | 101 | }]; 102 | [alertController addAction:cancelAction]; 103 | [target presentViewController:alertController animated:YES completion:NULL]; 104 | } else { 105 | [self fileDocumentReadWithFilePath:filePath target:target]; 106 | } 107 | } 108 | } 109 | } 110 | 111 | #pragma mark - 音频播放 112 | 113 | - (void)fileAudioReadWithFilePath:(NSString *)filePath target:(id)target 114 | { 115 | if (filePath && target) { 116 | [[SYCacheFileAudio shareAudio] playAudioWithFilePath:filePath]; 117 | } 118 | } 119 | 120 | #pragma mark - 视频播放 121 | 122 | /// 播放视频(网络地址,或本地路径,或本地文件名称) 123 | - (void)fileVidioReadWithFilePath:(NSString *)filePath target:(id)target 124 | { 125 | if (filePath && target) { 126 | [[SYCacheFileAudio shareAudio] stopAudio]; 127 | 128 | SYCacheFileVideo *videoPlayer = [[SYCacheFileVideo alloc] init]; 129 | [videoPlayer playVideoWithFilePath:filePath target:target]; 130 | } 131 | } 132 | 133 | #pragma mark - 图片播放 134 | 135 | CGFloat scaleMini = 1.0; 136 | CGFloat scaleMax = 3.0; 137 | 138 | - (void)fileImageReadWithFilePath:(NSString *)filePath target:(id)target 139 | { 140 | if (filePath && target) { 141 | [[SYCacheFileAudio shareAudio] stopAudio]; 142 | 143 | self.controller = target; 144 | 145 | NSArray *images = @[filePath]; 146 | if ([SYCacheFileManager shareManager].showImageShuffling) { 147 | NSString *file = filePath.stringByDeletingLastPathComponent; 148 | images = [SYCacheFileManager imagefilesWithFilePath:file]; 149 | } 150 | if (self.fileImage == nil) { 151 | self.fileImage = [[SYCacheFileImage alloc] init]; 152 | } 153 | NSInteger index = 0; 154 | if ([SYCacheFileManager shareManager].nameImage) { 155 | index = [images indexOfObject:[SYCacheFileManager shareManager].nameImage]; 156 | } 157 | self.fileImage.index = index; 158 | self.fileImage.images = images; 159 | [self.fileImage reloadImages]; 160 | } 161 | } 162 | 163 | #pragma mark - 文件阅读 164 | 165 | - (void)fileDocumentReadWithFilePath:(NSString *)filePath target:(id)target 166 | { 167 | if (filePath && target) { 168 | [[SYCacheFileAudio shareAudio] stopAudio]; 169 | 170 | NSURL *url = [NSURL fileURLWithPath:filePath]; 171 | self.controller = target; 172 | if (self.documentController == nil) { 173 | self.documentController = [UIDocumentInteractionController interactionControllerWithURL:url]; 174 | self.documentController.delegate = self; 175 | [self.documentController presentPreviewAnimated:YES]; 176 | } 177 | } 178 | } 179 | 180 | #pragma mark UIDocumentInteractionController 181 | 182 | - (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller 183 | { 184 | return self.controller; 185 | } 186 | 187 | - (UIView *)documentInteractionControllerViewForPreview:(UIDocumentInteractionController *)controller 188 | { 189 | return self.controller.view; 190 | } 191 | 192 | - (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController *)controller 193 | { 194 | return self.controller.view.bounds; 195 | } 196 | 197 | // 点击预览窗口的“Done”(完成)按钮时调用 198 | - (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)_controller 199 | { 200 | self.documentController = nil; 201 | } 202 | 203 | @end 204 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileTable.h: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileTable.h 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 17/6/27. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 文件显示列表视图 8 | 9 | #import 10 | 11 | @interface SYCacheFileTable : UITableView 12 | 13 | /// 数据源 14 | @property (nonatomic, strong) NSMutableArray *cacheDatas; 15 | 16 | /// 响应回调 17 | @property (nonatomic, copy) void (^itemClick)(NSIndexPath *indexPath); 18 | /// 长按回调 19 | @property (nonatomic, copy) void (^longPress)(SYCacheFileTable *table, NSIndexPath *indexPath); 20 | 21 | - (void)deleItemAtIndex:(NSIndexPath *)indexPath; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileTable.m: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileTable.m 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 17/6/27. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import "SYCacheFileTable.h" 10 | #import "SYCacheFileCell.h" 11 | #import "SYCacheFileModel.h" 12 | #import "SYCacheFileManager.h" 13 | 14 | @interface SYCacheFileTable () 15 | 16 | @property (nonatomic, strong) NSIndexPath *previousIndex; 17 | 18 | @end 19 | 20 | @implementation SYCacheFileTable 21 | 22 | - (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style 23 | { 24 | self = [super initWithFrame:frame style:style]; 25 | if (self) { 26 | self.backgroundColor = [UIColor clearColor]; 27 | self.separatorStyle = UITableViewCellSeparatorStyleNone; 28 | [self registerClass:[SYCacheFileCell class] forCellReuseIdentifier:reuseSYCacheDirectoryCell]; 29 | 30 | self.delegate = self; 31 | self.dataSource = self; 32 | 33 | self.tableFooterView = [UIView new]; 34 | } 35 | return self; 36 | } 37 | 38 | #pragma mark - UITableViewDataSource, UITableViewDelegate 39 | 40 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 41 | { 42 | return self.cacheDatas.count; 43 | } 44 | 45 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 46 | { 47 | return heightSYCacheDirectoryCell; 48 | } 49 | 50 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 51 | { 52 | SYCacheFileCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseSYCacheDirectoryCell]; 53 | // 数据 54 | SYCacheFileModel *model = self.cacheDatas[indexPath.row]; 55 | cell.model = model; 56 | // 长按 57 | SYCacheFileTable __weak *weakSelf = self; 58 | cell.longPress = ^{ 59 | if (weakSelf.longPress) { 60 | weakSelf.longPress(weakSelf, indexPath); 61 | } 62 | }; 63 | 64 | return cell; 65 | } 66 | 67 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 68 | { 69 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 70 | 71 | SYCacheFileModel *model = self.cacheDatas[indexPath.row]; 72 | 73 | // 音频播放 74 | SYCacheFileType type = [[SYCacheFileManager shareManager] fileTypeReadWithFilePath:model.filePath]; 75 | if (SYCacheFileTypeAudio == type) { 76 | model.fileProgressShow = YES; 77 | NSString *currentPath = model.filePath; 78 | 79 | if (self.previousIndex) { 80 | SYCacheFileModel *previousModel = self.cacheDatas[self.previousIndex.row]; 81 | NSString *previousPath = previousModel.filePath; 82 | if (![currentPath isEqualToString:previousPath]) { 83 | previousModel.fileProgress = 0.0; 84 | previousModel.fileProgressShow = NO; 85 | [tableView reloadRowsAtIndexPaths:@[self.previousIndex] withRowAnimation:UITableViewRowAnimationNone]; 86 | } 87 | } 88 | 89 | self.previousIndex = indexPath; 90 | } 91 | 92 | // 回调响应 93 | if (self.itemClick) { 94 | self.itemClick(indexPath); 95 | } 96 | } 97 | 98 | #pragma mark 编辑 99 | 100 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 101 | { 102 | if (editingStyle == UITableViewCellEditingStyleDelete) { 103 | [self deleItemAtIndex:indexPath]; 104 | } 105 | } 106 | 107 | - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath 108 | { 109 | return UITableViewCellEditingStyleDelete; 110 | } 111 | 112 | - (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath 113 | { 114 | return @"删除"; 115 | } 116 | 117 | #pragma mark - 删除操作 118 | 119 | - (void)deleItemAtIndex:(NSIndexPath *)indexPath 120 | { 121 | if (indexPath.row > self.cacheDatas.count - 1) { 122 | return; 123 | } 124 | SYCacheFileModel *model = self.cacheDatas[indexPath.row]; 125 | // 系统数据不可删除 126 | if ([[SYCacheFileManager shareManager] isFileSystemWithFilePath:model.filePath]) { 127 | [[[UIAlertView alloc] initWithTitle:nil message:@"系统文件不能删除" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil] show]; 128 | return; 129 | } 130 | // 当前删除的是音频时,先停止播放 131 | if (model.fileType == SYCacheFileTypeAudio) { 132 | [[NSNotificationCenter defaultCenter] postNotificationName:SYCacheFileAudioDeleteNotificationName object:nil]; 133 | } 134 | if (self.previousIndex) { 135 | self.previousIndex = nil; 136 | } 137 | // 删除数据:删除数组、删除本地文件/文件夹、刷新页面、发通知刷新文件大小统计 138 | // 删除数组 139 | [self.cacheDatas removeObjectAtIndex:indexPath.row]; 140 | // 删除本地文件/文件夹 141 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 142 | BOOL isDelete = [SYCacheFileManager deleteFileWithDirectory:model.filePath]; 143 | NSLog(@"删除:%@", (isDelete ? @"成功" : @"失败")); 144 | }); 145 | // 刷新页面 146 | // [self deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; 147 | [self reloadData]; 148 | } 149 | 150 | @end 151 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileVideo.h: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileVideo.h 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 2019/2/21. 6 | // Copyright © 2019年 zhangshaoyu. All rights reserved. 7 | // 视频播放 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface SYCacheFileVideo : NSObject 14 | 15 | /// 视频播放(根据路径) 16 | - (void)playVideoWithFilePath:(NSString *)filePath target:(id)target; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileVideo.m: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileVideo.m 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 2019/2/21. 6 | // Copyright © 2019年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import "SYCacheFileVideo.h" 10 | #import 11 | // 视频 12 | #import 13 | 14 | @implementation SYCacheFileVideo 15 | 16 | /// 视频播放(根据路径) 17 | - (void)playVideoWithFilePath:(NSString *)filePath target:(id)target 18 | { 19 | if ((filePath && [filePath isKindOfClass:[NSString class]] && filePath.length > 0) && (target && [target isKindOfClass:[UIViewController class]])) { 20 | NSURL *videoUrl = [NSURL fileURLWithPath:filePath]; 21 | if ([filePath hasPrefix:@"https://"] || [filePath hasPrefix:@"http://"]) { 22 | videoUrl = [NSURL URLWithString:filePath]; 23 | } 24 | UIViewController *controller = target; 25 | // 26 | AVPlayerViewController *playerController = [[AVPlayerViewController alloc] init]; 27 | playerController.player = [[AVPlayer alloc] initWithURL:videoUrl]; 28 | [playerController.player play]; 29 | [controller presentViewController:playerController animated:YES completion:nil]; 30 | } 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileViewController.h 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 17/6/27. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // https://github.com/potato512/SYCacheFileViewController 8 | 9 | #import 10 | 11 | @interface SYCacheFileViewController : UIViewController 12 | 13 | /// 导航栏标题(默认缓存目录) 14 | @property (nonatomic, strong) NSString *cacheTitle; 15 | /// 数据源(默认home目录) 16 | @property (nonatomic, strong) NSMutableArray *cacheArray; 17 | 18 | /// 显示样式(默认0列表,1九宫格) 19 | @property (nonatomic, assign) NSInteger showType; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /SYCacheFileViewController/SYCacheFileViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SYCacheFileViewController.m 3 | // zhangshaoyu 4 | // 5 | // Created by zhangshaoyu on 17/6/27. 6 | // Copyright © 2017年 zhangshaoyu. All rights reserved. 7 | // 8 | 9 | #import "SYCacheFileViewController.h" 10 | #import "SYCacheFileTable.h" 11 | #import "SYCacheFileCollection.h" 12 | #import "SYCacheFileManager.h" 13 | #import "SYCacheFileModel.h" 14 | #import "SYCacheFileRead.h" 15 | 16 | @interface SYCacheFileViewController () 17 | 18 | @property (nonatomic, strong) SYCacheFileTable *cacheTable; 19 | @property (nonatomic, strong) SYCacheFileCollection *cacheCollection; 20 | 21 | @property (nonatomic, strong) SYCacheFileRead *fileRead; 22 | 23 | @end 24 | 25 | @implementation SYCacheFileViewController 26 | 27 | - (void)viewDidLoad { 28 | [super viewDidLoad]; 29 | // Do any additional setup after loading the view. 30 | 31 | self.navigationItem.title = (_cacheTitle ? _cacheTitle : SYCacheFileTitle); 32 | 33 | [self setUI]; 34 | [self loadData]; 35 | } 36 | 37 | - (void)didReceiveMemoryWarning { 38 | [super didReceiveMemoryWarning]; 39 | // Dispose of any resources that can be recreated. 40 | } 41 | 42 | - (void)loadView 43 | { 44 | [super loadView]; 45 | self.view.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.1]; 46 | if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) { 47 | self.edgesForExtendedLayout = UIRectEdgeNone; 48 | } 49 | } 50 | 51 | - (void)dealloc 52 | { 53 | NSLog(@"<--- %@ 被释放了 --->", [self class]); 54 | } 55 | 56 | - (void)viewWillDisappear:(BOOL)animated 57 | { 58 | [super viewWillDisappear:animated]; 59 | 60 | [[SYCacheFileAudio shareAudio] stopAudio]; 61 | if (self.fileRead) { 62 | [self.fileRead releaseSYCacheFileRead]; 63 | } 64 | } 65 | 66 | #pragma mark - 视图 67 | 68 | - (void)setUI 69 | { 70 | if (self.showType == 0) { 71 | self.cacheTable.hidden = NO; 72 | self.cacheCollection.hidden = YES; 73 | } else if (self.showType == 1) { 74 | self.cacheTable.hidden = YES; 75 | self.cacheCollection.hidden = NO; 76 | } 77 | } 78 | 79 | #pragma mark - 视频图片保存 80 | 81 | - (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo 82 | { 83 | NSString *message = @"保存视频到相册成功"; 84 | if (error) { 85 | message = @"保存视频到相册失败"; 86 | } 87 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:message preferredStyle:UIAlertControllerStyleAlert]; 88 | UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { 89 | 90 | }]; 91 | [alertController addAction:cancelAction]; 92 | [self presentViewController:alertController animated:YES completion:NULL]; 93 | } 94 | 95 | - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo 96 | { 97 | NSString *message = @"保存图片到相册成功"; 98 | if (error) { 99 | message = @"保存图片到相册失败"; 100 | } 101 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:message preferredStyle:UIAlertControllerStyleAlert]; 102 | UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { 103 | 104 | }]; 105 | [alertController addAction:cancelAction]; 106 | [self presentViewController:alertController animated:YES completion:NULL]; 107 | } 108 | 109 | #pragma mark - 响应 110 | 111 | #pragma mark - 数据 112 | 113 | - (void)loadData 114 | { 115 | if (self.cacheArray == nil) { 116 | // 初始化,首次显示总目录 117 | NSString *path = [SYCacheFileManager homeDirectoryPath]; 118 | NSArray *array = [[SYCacheFileManager shareManager] fileModelsWithFilePath:path]; 119 | self.cacheArray = [NSMutableArray arrayWithArray:array]; 120 | } 121 | 122 | if (self.cacheArray && 0 < self.cacheArray.count) { 123 | // self.cacheTable.cacheDatas = self.cacheArray; 124 | // [self.cacheTable reloadData]; 125 | if (self.showType == 0) { 126 | self.cacheTable.cacheDatas = self.cacheArray; 127 | [self.cacheTable reloadData]; 128 | } else if (self.showType == 1) { 129 | self.cacheCollection.cacheDatas = self.cacheArray; 130 | [self.cacheCollection reloadData]; 131 | } 132 | } 133 | } 134 | 135 | #pragma mark - getter 136 | 137 | - (SYCacheFileTable *)cacheTable 138 | { 139 | if (_cacheTable == nil) { 140 | _cacheTable = [[SYCacheFileTable alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; 141 | _cacheTable.backgroundColor = [UIColor clearColor]; 142 | _cacheTable.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 143 | 144 | [self.view addSubview:_cacheTable]; 145 | typeof(self) __weak weakSelf = self; 146 | // 点击 147 | _cacheTable.itemClick = ^(NSIndexPath *indexPath) { 148 | 149 | if (weakSelf.cacheTable.isEditing) { 150 | return ; 151 | } 152 | 153 | if (indexPath.row > weakSelf.cacheArray.count - 1) { 154 | return; 155 | } 156 | SYCacheFileModel *model = weakSelf.cacheArray[indexPath.row]; 157 | NSString *path = model.filePath; // 路径 158 | SYCacheFileType type = model.fileType; // 类型 159 | if (SYCacheFileTypeUnknow == type) { 160 | // 标题 161 | NSString *title = model.fileName; 162 | // 子目录文件 163 | NSArray *files = [[SYCacheFileManager shareManager] fileModelsWithFilePath:path]; 164 | SYCacheFileViewController *cacheVC = [SYCacheFileViewController new]; 165 | cacheVC.cacheTitle = title; 166 | cacheVC.showType = weakSelf.showType; 167 | cacheVC.cacheArray = (NSMutableArray *)files; 168 | [weakSelf.navigationController pushViewController:cacheVC animated:YES]; 169 | } else { 170 | if (type == SYCacheFileTypeImage) { 171 | [SYCacheFileManager shareManager].nameImage = model.filePath; 172 | } 173 | [weakSelf.fileRead fileReadWithFilePath:path target:weakSelf]; 174 | } 175 | }; 176 | // 长按 177 | _cacheTable.longPress = ^(SYCacheFileTable *tableView, NSIndexPath *indexPath) { 178 | if (indexPath.row > weakSelf.cacheArray.count - 1) { 179 | return; 180 | } 181 | // 182 | SYCacheFileModel *model = weakSelf.cacheArray[indexPath.row]; 183 | SYCacheFileType type = model.fileType; 184 | // 185 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; 186 | UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:NULL]; 187 | [alertController addAction:cancelAction]; 188 | if (type == SYCacheFileTypeVideo || type == SYCacheFileTypeImage) { 189 | UIAlertAction *cacheAction = [UIAlertAction actionWithTitle:@"保存到相册" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 190 | if (type == SYCacheFileTypeVideo) { 191 | UISaveVideoAtPathToSavedPhotosAlbum(model.filePath, weakSelf, @selector(video:didFinishSavingWithError: contextInfo:), nil); 192 | } else if (type == SYCacheFileTypeImage) { 193 | UIImage *image = [UIImage imageWithContentsOfFile:model.filePath]; 194 | UIImageWriteToSavedPhotosAlbum(image, weakSelf, @selector(image:didFinishSavingWithError:contextInfo:), nil); 195 | } 196 | }]; 197 | [alertController addAction:cacheAction]; 198 | } 199 | UIAlertAction *deleteAction = [UIAlertAction actionWithTitle:@"删除" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 200 | [tableView deleItemAtIndex:indexPath]; 201 | }]; 202 | [alertController addAction:deleteAction]; 203 | [weakSelf presentViewController:alertController animated:YES completion:NULL]; 204 | }; 205 | } 206 | return _cacheTable; 207 | } 208 | 209 | - (SYCacheFileCollection *)cacheCollection 210 | { 211 | if (_cacheCollection == nil) { 212 | UICollectionViewLayout *layout = SYCacheFileCollection.collectionlayout; 213 | _cacheCollection = [[SYCacheFileCollection alloc] initWithFrame:self.view.bounds collectionViewLayout:layout]; 214 | _cacheCollection.backgroundColor = [UIColor clearColor]; 215 | _cacheCollection.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 216 | 217 | [self.view addSubview:_cacheCollection]; 218 | typeof(self) __weak weakSelf = self; 219 | // 点击 220 | _cacheCollection.itemClick = ^(NSIndexPath *indexPath) { 221 | 222 | if (weakSelf.cacheTable.isEditing) { 223 | return ; 224 | } 225 | 226 | if (indexPath.row > weakSelf.cacheArray.count - 1) { 227 | return; 228 | } 229 | SYCacheFileModel *model = weakSelf.cacheArray[indexPath.row]; 230 | NSString *path = model.filePath; // 路径 231 | SYCacheFileType type = model.fileType; // 类型 232 | if (SYCacheFileTypeUnknow == type) { 233 | // 标题 234 | NSString *title = model.fileName; 235 | // 子目录文件 236 | NSArray *files = [[SYCacheFileManager shareManager] fileModelsWithFilePath:path]; 237 | SYCacheFileViewController *cacheVC = [SYCacheFileViewController new]; 238 | cacheVC.cacheTitle = title; 239 | cacheVC.showType = weakSelf.showType; 240 | cacheVC.cacheArray = (NSMutableArray *)files; 241 | [weakSelf.navigationController pushViewController:cacheVC animated:YES]; 242 | } else { 243 | if (type == SYCacheFileTypeImage) { 244 | [SYCacheFileManager shareManager].nameImage = model.filePath; 245 | } 246 | [weakSelf.fileRead fileReadWithFilePath:path target:weakSelf]; 247 | } 248 | }; 249 | // 长按 250 | _cacheCollection.longPress = ^(SYCacheFileCollection *collection, NSIndexPath *indexPath) { 251 | if (indexPath.row > weakSelf.cacheArray.count - 1) { 252 | return; 253 | } 254 | // 255 | SYCacheFileModel *model = weakSelf.cacheArray[indexPath.row]; 256 | SYCacheFileType type = model.fileType; 257 | // 258 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; 259 | UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:NULL]; 260 | [alertController addAction:cancelAction]; 261 | if (type == SYCacheFileTypeVideo || type == SYCacheFileTypeImage) { 262 | UIAlertAction *cacheAction = [UIAlertAction actionWithTitle:@"保存到相册" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 263 | if (type == SYCacheFileTypeVideo) { 264 | UISaveVideoAtPathToSavedPhotosAlbum(model.filePath, weakSelf, @selector(video:didFinishSavingWithError: contextInfo:), nil); 265 | } else if (type == SYCacheFileTypeImage) { 266 | UIImage *image = [UIImage imageWithContentsOfFile:model.filePath]; 267 | UIImageWriteToSavedPhotosAlbum(image, weakSelf, @selector(image:didFinishSavingWithError:contextInfo:), nil); 268 | } 269 | }]; 270 | [alertController addAction:cacheAction]; 271 | } 272 | UIAlertAction *deleteAction = [UIAlertAction actionWithTitle:@"删除" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 273 | [collection deleItemAtIndex:indexPath]; 274 | }]; 275 | [alertController addAction:deleteAction]; 276 | [weakSelf presentViewController:alertController animated:YES completion:NULL]; 277 | }; 278 | } 279 | return _cacheCollection; 280 | } 281 | 282 | - (SYCacheFileRead *)fileRead 283 | { 284 | if (_fileRead == nil) { 285 | _fileRead = [[SYCacheFileRead alloc] init]; 286 | } 287 | return _fileRead; 288 | } 289 | 290 | @end 291 | -------------------------------------------------------------------------------- /images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/images/.DS_Store -------------------------------------------------------------------------------- /images/SYCacheFileViewController.mindnode/QuickLook/Preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/images/SYCacheFileViewController.mindnode/QuickLook/Preview.jpg -------------------------------------------------------------------------------- /images/SYCacheFileViewController.mindnode/style.mindnodestyle/contents.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/images/SYCacheFileViewController.mindnode/style.mindnodestyle/contents.xml -------------------------------------------------------------------------------- /images/SYCacheFileViewController.mindnode/style.mindnodestyle/metadata.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/images/SYCacheFileViewController.mindnode/style.mindnodestyle/metadata.plist -------------------------------------------------------------------------------- /images/SYCacheFileViewController.mindnode/viewState.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/images/SYCacheFileViewController.mindnode/viewState.plist -------------------------------------------------------------------------------- /images/SYCacheFileViewController.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/images/SYCacheFileViewController.png -------------------------------------------------------------------------------- /images/cacheFile_File01.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/images/cacheFile_File01.gif -------------------------------------------------------------------------------- /images/cacheFile_File02.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/images/cacheFile_File02.gif -------------------------------------------------------------------------------- /images/cacheFile_audio.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/images/cacheFile_audio.gif -------------------------------------------------------------------------------- /images/cacheFile_delete.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/images/cacheFile_delete.gif -------------------------------------------------------------------------------- /images/cacheFile_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/images/cacheFile_delete.png -------------------------------------------------------------------------------- /images/cacheFile_directory.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/images/cacheFile_directory.gif -------------------------------------------------------------------------------- /images/cacheFile_image.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/images/cacheFile_image.gif -------------------------------------------------------------------------------- /images/cacheFile_video.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potato512/SYCacheFileViewController/7c6f8532b738387bf9c7a285d6004670d59eb076/images/cacheFile_video.gif --------------------------------------------------------------------------------