├── .gitignore ├── MKDocumentProvider ├── MKDocumentProvider.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── MKDocumentProvider │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── MKDocumentProvider.entitlements │ ├── ViewController.h │ ├── ViewController.m │ └── main.m ├── MKDocumentProviderDemo │ ├── Base.lproj │ │ └── MainInterface.storyboard │ ├── DocumentPickerViewController.h │ ├── DocumentPickerViewController.m │ ├── Info.plist │ └── MKDocumentProviderDemo.entitlements └── MKDocumentProviderDemoFileProvider │ ├── FileProvider.h │ ├── FileProvider.m │ ├── Info.plist │ └── MKDocumentProviderDemoFileProvider.entitlements ├── MKTextEdit ├── MKTextEdit.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── MKTextEdit │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── MKTextEdit.entitlements │ ├── ViewController.h │ ├── ViewController.m │ └── main.m └── README.md /.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 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | # Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | 55 | #Code Injection 56 | # 57 | # After new code Injection tools there's a generated folder /iOSInjectionProject 58 | # https://github.com/johnno1962/injectionforxcode 59 | 60 | iOSInjectionProject/ 61 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProvider.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | FB0C9DB81D22512500E5DBF4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FB0C9DB71D22512500E5DBF4 /* main.m */; }; 11 | FB0C9DBB1D22512500E5DBF4 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FB0C9DBA1D22512500E5DBF4 /* AppDelegate.m */; }; 12 | FB0C9DBE1D22512500E5DBF4 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FB0C9DBD1D22512500E5DBF4 /* ViewController.m */; }; 13 | FB0C9DC11D22512500E5DBF4 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB0C9DBF1D22512500E5DBF4 /* Main.storyboard */; }; 14 | FB0C9DC31D22512500E5DBF4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FB0C9DC21D22512500E5DBF4 /* Assets.xcassets */; }; 15 | FB0C9DC61D22512500E5DBF4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB0C9DC41D22512500E5DBF4 /* LaunchScreen.storyboard */; }; 16 | FB0C9DD71D22517F00E5DBF4 /* DocumentPickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FB0C9DD61D22517F00E5DBF4 /* DocumentPickerViewController.m */; }; 17 | FB0C9DDA1D22517F00E5DBF4 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB0C9DD81D22517F00E5DBF4 /* MainInterface.storyboard */; }; 18 | FB0C9DE61D22517F00E5DBF4 /* FileProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = FB0C9DE51D22517F00E5DBF4 /* FileProvider.m */; }; 19 | FB0C9DEA1D22517F00E5DBF4 /* MKDocumentProviderDemoFileProvider.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = FB0C9DE01D22517F00E5DBF4 /* MKDocumentProviderDemoFileProvider.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 20 | FB0C9DED1D22517F00E5DBF4 /* MKDocumentProviderDemo.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = FB0C9DD11D22517F00E5DBF4 /* MKDocumentProviderDemo.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 21 | FB0C9DF61D237AE000E5DBF4 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB0C9DF51D237AE000E5DBF4 /* MobileCoreServices.framework */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | FB0C9DE81D22517F00E5DBF4 /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = FB0C9DAB1D22512500E5DBF4 /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = FB0C9DDF1D22517F00E5DBF4; 30 | remoteInfo = MKDocumentProviderDemoFileProvider; 31 | }; 32 | FB0C9DEB1D22517F00E5DBF4 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = FB0C9DAB1D22512500E5DBF4 /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = FB0C9DD01D22517F00E5DBF4; 37 | remoteInfo = MKDocumentProviderDemo; 38 | }; 39 | FB0C9E391D23CAE600E5DBF4 /* PBXContainerItemProxy */ = { 40 | isa = PBXContainerItemProxy; 41 | containerPortal = FB0C9E351D23CAE600E5DBF4 /* MKTextEdit.xcodeproj */; 42 | proxyType = 2; 43 | remoteGlobalIDString = FB0C9E011D23CA9600E5DBF4; 44 | remoteInfo = MKTextEdit; 45 | }; 46 | /* End PBXContainerItemProxy section */ 47 | 48 | /* Begin PBXCopyFilesBuildPhase section */ 49 | FB0C9DF41D22517F00E5DBF4 /* Embed App Extensions */ = { 50 | isa = PBXCopyFilesBuildPhase; 51 | buildActionMask = 2147483647; 52 | dstPath = ""; 53 | dstSubfolderSpec = 13; 54 | files = ( 55 | FB0C9DEA1D22517F00E5DBF4 /* MKDocumentProviderDemoFileProvider.appex in Embed App Extensions */, 56 | FB0C9DED1D22517F00E5DBF4 /* MKDocumentProviderDemo.appex in Embed App Extensions */, 57 | ); 58 | name = "Embed App Extensions"; 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXCopyFilesBuildPhase section */ 62 | 63 | /* Begin PBXFileReference section */ 64 | FB0C9DB31D22512500E5DBF4 /* MKDocumentProvider.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MKDocumentProvider.app; sourceTree = BUILT_PRODUCTS_DIR; }; 65 | FB0C9DB71D22512500E5DBF4 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 66 | FB0C9DB91D22512500E5DBF4 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 67 | FB0C9DBA1D22512500E5DBF4 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 68 | FB0C9DBC1D22512500E5DBF4 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 69 | FB0C9DBD1D22512500E5DBF4 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 70 | FB0C9DC01D22512500E5DBF4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 71 | FB0C9DC21D22512500E5DBF4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 72 | FB0C9DC51D22512500E5DBF4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 73 | FB0C9DC71D22512500E5DBF4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 74 | FB0C9DD11D22517F00E5DBF4 /* MKDocumentProviderDemo.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MKDocumentProviderDemo.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 75 | FB0C9DD41D22517F00E5DBF4 /* MKDocumentProviderDemo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = MKDocumentProviderDemo.entitlements; sourceTree = ""; }; 76 | FB0C9DD51D22517F00E5DBF4 /* DocumentPickerViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DocumentPickerViewController.h; sourceTree = ""; }; 77 | FB0C9DD61D22517F00E5DBF4 /* DocumentPickerViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DocumentPickerViewController.m; sourceTree = ""; }; 78 | FB0C9DD91D22517F00E5DBF4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; }; 79 | FB0C9DDB1D22517F00E5DBF4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 80 | FB0C9DE01D22517F00E5DBF4 /* MKDocumentProviderDemoFileProvider.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MKDocumentProviderDemoFileProvider.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 81 | FB0C9DE31D22517F00E5DBF4 /* MKDocumentProviderDemoFileProvider.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = MKDocumentProviderDemoFileProvider.entitlements; sourceTree = ""; }; 82 | FB0C9DE41D22517F00E5DBF4 /* FileProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FileProvider.h; sourceTree = ""; }; 83 | FB0C9DE51D22517F00E5DBF4 /* FileProvider.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FileProvider.m; sourceTree = ""; }; 84 | FB0C9DE71D22517F00E5DBF4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 85 | FB0C9DF51D237AE000E5DBF4 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; }; 86 | FB0C9DF71D237DAA00E5DBF4 /* MKDocumentProvider.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = MKDocumentProvider.entitlements; sourceTree = ""; }; 87 | FB0C9E351D23CAE600E5DBF4 /* MKTextEdit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MKTextEdit.xcodeproj; path = ../MKTextEdit/MKTextEdit.xcodeproj; sourceTree = ""; }; 88 | /* End PBXFileReference section */ 89 | 90 | /* Begin PBXFrameworksBuildPhase section */ 91 | FB0C9DB01D22512500E5DBF4 /* Frameworks */ = { 92 | isa = PBXFrameworksBuildPhase; 93 | buildActionMask = 2147483647; 94 | files = ( 95 | ); 96 | runOnlyForDeploymentPostprocessing = 0; 97 | }; 98 | FB0C9DCE1D22517F00E5DBF4 /* Frameworks */ = { 99 | isa = PBXFrameworksBuildPhase; 100 | buildActionMask = 2147483647; 101 | files = ( 102 | FB0C9DF61D237AE000E5DBF4 /* MobileCoreServices.framework in Frameworks */, 103 | ); 104 | runOnlyForDeploymentPostprocessing = 0; 105 | }; 106 | FB0C9DDD1D22517F00E5DBF4 /* Frameworks */ = { 107 | isa = PBXFrameworksBuildPhase; 108 | buildActionMask = 2147483647; 109 | files = ( 110 | ); 111 | runOnlyForDeploymentPostprocessing = 0; 112 | }; 113 | /* End PBXFrameworksBuildPhase section */ 114 | 115 | /* Begin PBXGroup section */ 116 | FB0C9DAA1D22512500E5DBF4 = { 117 | isa = PBXGroup; 118 | children = ( 119 | FB0C9E351D23CAE600E5DBF4 /* MKTextEdit.xcodeproj */, 120 | FB0C9DB51D22512500E5DBF4 /* MKDocumentProvider */, 121 | FB0C9DD21D22517F00E5DBF4 /* MKDocumentProviderDemo */, 122 | FB0C9DE11D22517F00E5DBF4 /* MKDocumentProviderDemoFileProvider */, 123 | FB0C9DB41D22512500E5DBF4 /* Products */, 124 | ); 125 | sourceTree = ""; 126 | }; 127 | FB0C9DB41D22512500E5DBF4 /* Products */ = { 128 | isa = PBXGroup; 129 | children = ( 130 | FB0C9DB31D22512500E5DBF4 /* MKDocumentProvider.app */, 131 | FB0C9DD11D22517F00E5DBF4 /* MKDocumentProviderDemo.appex */, 132 | FB0C9DE01D22517F00E5DBF4 /* MKDocumentProviderDemoFileProvider.appex */, 133 | ); 134 | name = Products; 135 | sourceTree = ""; 136 | }; 137 | FB0C9DB51D22512500E5DBF4 /* MKDocumentProvider */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | FB0C9DF71D237DAA00E5DBF4 /* MKDocumentProvider.entitlements */, 141 | FB0C9DB91D22512500E5DBF4 /* AppDelegate.h */, 142 | FB0C9DBA1D22512500E5DBF4 /* AppDelegate.m */, 143 | FB0C9DBC1D22512500E5DBF4 /* ViewController.h */, 144 | FB0C9DBD1D22512500E5DBF4 /* ViewController.m */, 145 | FB0C9DBF1D22512500E5DBF4 /* Main.storyboard */, 146 | FB0C9DC21D22512500E5DBF4 /* Assets.xcassets */, 147 | FB0C9DC41D22512500E5DBF4 /* LaunchScreen.storyboard */, 148 | FB0C9DC71D22512500E5DBF4 /* Info.plist */, 149 | FB0C9DB61D22512500E5DBF4 /* Supporting Files */, 150 | ); 151 | path = MKDocumentProvider; 152 | sourceTree = ""; 153 | }; 154 | FB0C9DB61D22512500E5DBF4 /* Supporting Files */ = { 155 | isa = PBXGroup; 156 | children = ( 157 | FB0C9DF51D237AE000E5DBF4 /* MobileCoreServices.framework */, 158 | FB0C9DB71D22512500E5DBF4 /* main.m */, 159 | ); 160 | name = "Supporting Files"; 161 | sourceTree = ""; 162 | }; 163 | FB0C9DD21D22517F00E5DBF4 /* MKDocumentProviderDemo */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | FB0C9DD51D22517F00E5DBF4 /* DocumentPickerViewController.h */, 167 | FB0C9DD61D22517F00E5DBF4 /* DocumentPickerViewController.m */, 168 | FB0C9DD81D22517F00E5DBF4 /* MainInterface.storyboard */, 169 | FB0C9DDB1D22517F00E5DBF4 /* Info.plist */, 170 | FB0C9DD31D22517F00E5DBF4 /* Supporting Files */, 171 | ); 172 | path = MKDocumentProviderDemo; 173 | sourceTree = ""; 174 | }; 175 | FB0C9DD31D22517F00E5DBF4 /* Supporting Files */ = { 176 | isa = PBXGroup; 177 | children = ( 178 | FB0C9DD41D22517F00E5DBF4 /* MKDocumentProviderDemo.entitlements */, 179 | ); 180 | name = "Supporting Files"; 181 | sourceTree = ""; 182 | }; 183 | FB0C9DE11D22517F00E5DBF4 /* MKDocumentProviderDemoFileProvider */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | FB0C9DE41D22517F00E5DBF4 /* FileProvider.h */, 187 | FB0C9DE51D22517F00E5DBF4 /* FileProvider.m */, 188 | FB0C9DE71D22517F00E5DBF4 /* Info.plist */, 189 | FB0C9DE21D22517F00E5DBF4 /* Supporting Files */, 190 | ); 191 | path = MKDocumentProviderDemoFileProvider; 192 | sourceTree = ""; 193 | }; 194 | FB0C9DE21D22517F00E5DBF4 /* Supporting Files */ = { 195 | isa = PBXGroup; 196 | children = ( 197 | FB0C9DE31D22517F00E5DBF4 /* MKDocumentProviderDemoFileProvider.entitlements */, 198 | ); 199 | name = "Supporting Files"; 200 | sourceTree = ""; 201 | }; 202 | FB0C9E361D23CAE600E5DBF4 /* Products */ = { 203 | isa = PBXGroup; 204 | children = ( 205 | FB0C9E3A1D23CAE600E5DBF4 /* MKTextEdit.app */, 206 | ); 207 | name = Products; 208 | sourceTree = ""; 209 | }; 210 | /* End PBXGroup section */ 211 | 212 | /* Begin PBXNativeTarget section */ 213 | FB0C9DB21D22512500E5DBF4 /* MKDocumentProvider */ = { 214 | isa = PBXNativeTarget; 215 | buildConfigurationList = FB0C9DCA1D22512500E5DBF4 /* Build configuration list for PBXNativeTarget "MKDocumentProvider" */; 216 | buildPhases = ( 217 | FB0C9DAF1D22512500E5DBF4 /* Sources */, 218 | FB0C9DB01D22512500E5DBF4 /* Frameworks */, 219 | FB0C9DB11D22512500E5DBF4 /* Resources */, 220 | FB0C9DF41D22517F00E5DBF4 /* Embed App Extensions */, 221 | ); 222 | buildRules = ( 223 | ); 224 | dependencies = ( 225 | FB0C9DE91D22517F00E5DBF4 /* PBXTargetDependency */, 226 | FB0C9DEC1D22517F00E5DBF4 /* PBXTargetDependency */, 227 | ); 228 | name = MKDocumentProvider; 229 | productName = MKDocumentProvider; 230 | productReference = FB0C9DB31D22512500E5DBF4 /* MKDocumentProvider.app */; 231 | productType = "com.apple.product-type.application"; 232 | }; 233 | FB0C9DD01D22517F00E5DBF4 /* MKDocumentProviderDemo */ = { 234 | isa = PBXNativeTarget; 235 | buildConfigurationList = FB0C9DF11D22517F00E5DBF4 /* Build configuration list for PBXNativeTarget "MKDocumentProviderDemo" */; 236 | buildPhases = ( 237 | FB0C9DCD1D22517F00E5DBF4 /* Sources */, 238 | FB0C9DCE1D22517F00E5DBF4 /* Frameworks */, 239 | FB0C9DCF1D22517F00E5DBF4 /* Resources */, 240 | ); 241 | buildRules = ( 242 | ); 243 | dependencies = ( 244 | ); 245 | name = MKDocumentProviderDemo; 246 | productName = MKDocumentProviderDemo; 247 | productReference = FB0C9DD11D22517F00E5DBF4 /* MKDocumentProviderDemo.appex */; 248 | productType = "com.apple.product-type.app-extension"; 249 | }; 250 | FB0C9DDF1D22517F00E5DBF4 /* MKDocumentProviderDemoFileProvider */ = { 251 | isa = PBXNativeTarget; 252 | buildConfigurationList = FB0C9DEE1D22517F00E5DBF4 /* Build configuration list for PBXNativeTarget "MKDocumentProviderDemoFileProvider" */; 253 | buildPhases = ( 254 | FB0C9DDC1D22517F00E5DBF4 /* Sources */, 255 | FB0C9DDD1D22517F00E5DBF4 /* Frameworks */, 256 | FB0C9DDE1D22517F00E5DBF4 /* Resources */, 257 | ); 258 | buildRules = ( 259 | ); 260 | dependencies = ( 261 | ); 262 | name = MKDocumentProviderDemoFileProvider; 263 | productName = MKDocumentProviderDemoFileProvider; 264 | productReference = FB0C9DE01D22517F00E5DBF4 /* MKDocumentProviderDemoFileProvider.appex */; 265 | productType = "com.apple.product-type.app-extension"; 266 | }; 267 | /* End PBXNativeTarget section */ 268 | 269 | /* Begin PBXProject section */ 270 | FB0C9DAB1D22512500E5DBF4 /* Project object */ = { 271 | isa = PBXProject; 272 | attributes = { 273 | LastUpgradeCheck = 0730; 274 | ORGANIZATIONNAME = Donlinks; 275 | TargetAttributes = { 276 | FB0C9DB21D22512500E5DBF4 = { 277 | CreatedOnToolsVersion = 7.3.1; 278 | DevelopmentTeam = DM7XAFH5UF; 279 | SystemCapabilities = { 280 | com.apple.ApplicationGroups.iOS = { 281 | enabled = 1; 282 | }; 283 | com.apple.iCloud = { 284 | enabled = 1; 285 | }; 286 | }; 287 | }; 288 | FB0C9DD01D22517F00E5DBF4 = { 289 | CreatedOnToolsVersion = 7.3.1; 290 | DevelopmentTeam = DM7XAFH5UF; 291 | }; 292 | FB0C9DDF1D22517F00E5DBF4 = { 293 | CreatedOnToolsVersion = 7.3.1; 294 | DevelopmentTeam = DM7XAFH5UF; 295 | }; 296 | }; 297 | }; 298 | buildConfigurationList = FB0C9DAE1D22512500E5DBF4 /* Build configuration list for PBXProject "MKDocumentProvider" */; 299 | compatibilityVersion = "Xcode 3.2"; 300 | developmentRegion = English; 301 | hasScannedForEncodings = 0; 302 | knownRegions = ( 303 | en, 304 | Base, 305 | ); 306 | mainGroup = FB0C9DAA1D22512500E5DBF4; 307 | productRefGroup = FB0C9DB41D22512500E5DBF4 /* Products */; 308 | projectDirPath = ""; 309 | projectReferences = ( 310 | { 311 | ProductGroup = FB0C9E361D23CAE600E5DBF4 /* Products */; 312 | ProjectRef = FB0C9E351D23CAE600E5DBF4 /* MKTextEdit.xcodeproj */; 313 | }, 314 | ); 315 | projectRoot = ""; 316 | targets = ( 317 | FB0C9DB21D22512500E5DBF4 /* MKDocumentProvider */, 318 | FB0C9DD01D22517F00E5DBF4 /* MKDocumentProviderDemo */, 319 | FB0C9DDF1D22517F00E5DBF4 /* MKDocumentProviderDemoFileProvider */, 320 | ); 321 | }; 322 | /* End PBXProject section */ 323 | 324 | /* Begin PBXReferenceProxy section */ 325 | FB0C9E3A1D23CAE600E5DBF4 /* MKTextEdit.app */ = { 326 | isa = PBXReferenceProxy; 327 | fileType = wrapper.application; 328 | path = MKTextEdit.app; 329 | remoteRef = FB0C9E391D23CAE600E5DBF4 /* PBXContainerItemProxy */; 330 | sourceTree = BUILT_PRODUCTS_DIR; 331 | }; 332 | /* End PBXReferenceProxy section */ 333 | 334 | /* Begin PBXResourcesBuildPhase section */ 335 | FB0C9DB11D22512500E5DBF4 /* Resources */ = { 336 | isa = PBXResourcesBuildPhase; 337 | buildActionMask = 2147483647; 338 | files = ( 339 | FB0C9DC61D22512500E5DBF4 /* LaunchScreen.storyboard in Resources */, 340 | FB0C9DC31D22512500E5DBF4 /* Assets.xcassets in Resources */, 341 | FB0C9DC11D22512500E5DBF4 /* Main.storyboard in Resources */, 342 | ); 343 | runOnlyForDeploymentPostprocessing = 0; 344 | }; 345 | FB0C9DCF1D22517F00E5DBF4 /* Resources */ = { 346 | isa = PBXResourcesBuildPhase; 347 | buildActionMask = 2147483647; 348 | files = ( 349 | FB0C9DDA1D22517F00E5DBF4 /* MainInterface.storyboard in Resources */, 350 | ); 351 | runOnlyForDeploymentPostprocessing = 0; 352 | }; 353 | FB0C9DDE1D22517F00E5DBF4 /* Resources */ = { 354 | isa = PBXResourcesBuildPhase; 355 | buildActionMask = 2147483647; 356 | files = ( 357 | ); 358 | runOnlyForDeploymentPostprocessing = 0; 359 | }; 360 | /* End PBXResourcesBuildPhase section */ 361 | 362 | /* Begin PBXSourcesBuildPhase section */ 363 | FB0C9DAF1D22512500E5DBF4 /* Sources */ = { 364 | isa = PBXSourcesBuildPhase; 365 | buildActionMask = 2147483647; 366 | files = ( 367 | FB0C9DBE1D22512500E5DBF4 /* ViewController.m in Sources */, 368 | FB0C9DBB1D22512500E5DBF4 /* AppDelegate.m in Sources */, 369 | FB0C9DB81D22512500E5DBF4 /* main.m in Sources */, 370 | ); 371 | runOnlyForDeploymentPostprocessing = 0; 372 | }; 373 | FB0C9DCD1D22517F00E5DBF4 /* Sources */ = { 374 | isa = PBXSourcesBuildPhase; 375 | buildActionMask = 2147483647; 376 | files = ( 377 | FB0C9DD71D22517F00E5DBF4 /* DocumentPickerViewController.m in Sources */, 378 | ); 379 | runOnlyForDeploymentPostprocessing = 0; 380 | }; 381 | FB0C9DDC1D22517F00E5DBF4 /* Sources */ = { 382 | isa = PBXSourcesBuildPhase; 383 | buildActionMask = 2147483647; 384 | files = ( 385 | FB0C9DE61D22517F00E5DBF4 /* FileProvider.m in Sources */, 386 | ); 387 | runOnlyForDeploymentPostprocessing = 0; 388 | }; 389 | /* End PBXSourcesBuildPhase section */ 390 | 391 | /* Begin PBXTargetDependency section */ 392 | FB0C9DE91D22517F00E5DBF4 /* PBXTargetDependency */ = { 393 | isa = PBXTargetDependency; 394 | target = FB0C9DDF1D22517F00E5DBF4 /* MKDocumentProviderDemoFileProvider */; 395 | targetProxy = FB0C9DE81D22517F00E5DBF4 /* PBXContainerItemProxy */; 396 | }; 397 | FB0C9DEC1D22517F00E5DBF4 /* PBXTargetDependency */ = { 398 | isa = PBXTargetDependency; 399 | target = FB0C9DD01D22517F00E5DBF4 /* MKDocumentProviderDemo */; 400 | targetProxy = FB0C9DEB1D22517F00E5DBF4 /* PBXContainerItemProxy */; 401 | }; 402 | /* End PBXTargetDependency section */ 403 | 404 | /* Begin PBXVariantGroup section */ 405 | FB0C9DBF1D22512500E5DBF4 /* Main.storyboard */ = { 406 | isa = PBXVariantGroup; 407 | children = ( 408 | FB0C9DC01D22512500E5DBF4 /* Base */, 409 | ); 410 | name = Main.storyboard; 411 | sourceTree = ""; 412 | }; 413 | FB0C9DC41D22512500E5DBF4 /* LaunchScreen.storyboard */ = { 414 | isa = PBXVariantGroup; 415 | children = ( 416 | FB0C9DC51D22512500E5DBF4 /* Base */, 417 | ); 418 | name = LaunchScreen.storyboard; 419 | sourceTree = ""; 420 | }; 421 | FB0C9DD81D22517F00E5DBF4 /* MainInterface.storyboard */ = { 422 | isa = PBXVariantGroup; 423 | children = ( 424 | FB0C9DD91D22517F00E5DBF4 /* Base */, 425 | ); 426 | name = MainInterface.storyboard; 427 | sourceTree = ""; 428 | }; 429 | /* End PBXVariantGroup section */ 430 | 431 | /* Begin XCBuildConfiguration section */ 432 | FB0C9DC81D22512500E5DBF4 /* Debug */ = { 433 | isa = XCBuildConfiguration; 434 | buildSettings = { 435 | ALWAYS_SEARCH_USER_PATHS = NO; 436 | CLANG_ANALYZER_NONNULL = YES; 437 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 438 | CLANG_CXX_LIBRARY = "libc++"; 439 | CLANG_ENABLE_MODULES = YES; 440 | CLANG_ENABLE_OBJC_ARC = YES; 441 | CLANG_WARN_BOOL_CONVERSION = YES; 442 | CLANG_WARN_CONSTANT_CONVERSION = YES; 443 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 444 | CLANG_WARN_EMPTY_BODY = YES; 445 | CLANG_WARN_ENUM_CONVERSION = YES; 446 | CLANG_WARN_INT_CONVERSION = YES; 447 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 448 | CLANG_WARN_UNREACHABLE_CODE = YES; 449 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 450 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 451 | COPY_PHASE_STRIP = NO; 452 | DEBUG_INFORMATION_FORMAT = dwarf; 453 | ENABLE_STRICT_OBJC_MSGSEND = YES; 454 | ENABLE_TESTABILITY = YES; 455 | GCC_C_LANGUAGE_STANDARD = gnu99; 456 | GCC_DYNAMIC_NO_PIC = NO; 457 | GCC_NO_COMMON_BLOCKS = YES; 458 | GCC_OPTIMIZATION_LEVEL = 0; 459 | GCC_PREPROCESSOR_DEFINITIONS = ( 460 | "DEBUG=1", 461 | "$(inherited)", 462 | ); 463 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 464 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 465 | GCC_WARN_UNDECLARED_SELECTOR = YES; 466 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 467 | GCC_WARN_UNUSED_FUNCTION = YES; 468 | GCC_WARN_UNUSED_VARIABLE = YES; 469 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 470 | MTL_ENABLE_DEBUG_INFO = YES; 471 | ONLY_ACTIVE_ARCH = YES; 472 | SDKROOT = iphoneos; 473 | }; 474 | name = Debug; 475 | }; 476 | FB0C9DC91D22512500E5DBF4 /* Release */ = { 477 | isa = XCBuildConfiguration; 478 | buildSettings = { 479 | ALWAYS_SEARCH_USER_PATHS = NO; 480 | CLANG_ANALYZER_NONNULL = YES; 481 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 482 | CLANG_CXX_LIBRARY = "libc++"; 483 | CLANG_ENABLE_MODULES = YES; 484 | CLANG_ENABLE_OBJC_ARC = YES; 485 | CLANG_WARN_BOOL_CONVERSION = YES; 486 | CLANG_WARN_CONSTANT_CONVERSION = YES; 487 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 488 | CLANG_WARN_EMPTY_BODY = YES; 489 | CLANG_WARN_ENUM_CONVERSION = YES; 490 | CLANG_WARN_INT_CONVERSION = YES; 491 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 492 | CLANG_WARN_UNREACHABLE_CODE = YES; 493 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 494 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 495 | COPY_PHASE_STRIP = NO; 496 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 497 | ENABLE_NS_ASSERTIONS = NO; 498 | ENABLE_STRICT_OBJC_MSGSEND = YES; 499 | GCC_C_LANGUAGE_STANDARD = gnu99; 500 | GCC_NO_COMMON_BLOCKS = YES; 501 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 502 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 503 | GCC_WARN_UNDECLARED_SELECTOR = YES; 504 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 505 | GCC_WARN_UNUSED_FUNCTION = YES; 506 | GCC_WARN_UNUSED_VARIABLE = YES; 507 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 508 | MTL_ENABLE_DEBUG_INFO = NO; 509 | SDKROOT = iphoneos; 510 | VALIDATE_PRODUCT = YES; 511 | }; 512 | name = Release; 513 | }; 514 | FB0C9DCB1D22512500E5DBF4 /* Debug */ = { 515 | isa = XCBuildConfiguration; 516 | buildSettings = { 517 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 518 | CODE_SIGN_ENTITLEMENTS = MKDocumentProvider/MKDocumentProvider.entitlements; 519 | CODE_SIGN_IDENTITY = "iPhone Developer"; 520 | INFOPLIST_FILE = MKDocumentProvider/Info.plist; 521 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 522 | PRODUCT_BUNDLE_IDENTIFIER = com.donlinks.MKDocumentProvider; 523 | PRODUCT_NAME = "$(TARGET_NAME)"; 524 | }; 525 | name = Debug; 526 | }; 527 | FB0C9DCC1D22512500E5DBF4 /* Release */ = { 528 | isa = XCBuildConfiguration; 529 | buildSettings = { 530 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 531 | CODE_SIGN_ENTITLEMENTS = MKDocumentProvider/MKDocumentProvider.entitlements; 532 | CODE_SIGN_IDENTITY = "iPhone Developer"; 533 | INFOPLIST_FILE = MKDocumentProvider/Info.plist; 534 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 535 | PRODUCT_BUNDLE_IDENTIFIER = com.donlinks.MKDocumentProvider; 536 | PRODUCT_NAME = "$(TARGET_NAME)"; 537 | }; 538 | name = Release; 539 | }; 540 | FB0C9DEF1D22517F00E5DBF4 /* Debug */ = { 541 | isa = XCBuildConfiguration; 542 | buildSettings = { 543 | CODE_SIGN_ENTITLEMENTS = MKDocumentProviderDemoFileProvider/MKDocumentProviderDemoFileProvider.entitlements; 544 | CODE_SIGN_IDENTITY = "iPhone Developer"; 545 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 546 | INFOPLIST_FILE = MKDocumentProviderDemoFileProvider/Info.plist; 547 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; 548 | PRODUCT_BUNDLE_IDENTIFIER = com.donlinks.MKDocumentProvider.MKDocumentProviderDemoFileProvider; 549 | PRODUCT_NAME = "$(TARGET_NAME)"; 550 | PROVISIONING_PROFILE = ""; 551 | SKIP_INSTALL = YES; 552 | }; 553 | name = Debug; 554 | }; 555 | FB0C9DF01D22517F00E5DBF4 /* Release */ = { 556 | isa = XCBuildConfiguration; 557 | buildSettings = { 558 | CODE_SIGN_ENTITLEMENTS = MKDocumentProviderDemoFileProvider/MKDocumentProviderDemoFileProvider.entitlements; 559 | CODE_SIGN_IDENTITY = "iPhone Developer"; 560 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 561 | INFOPLIST_FILE = MKDocumentProviderDemoFileProvider/Info.plist; 562 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; 563 | PRODUCT_BUNDLE_IDENTIFIER = com.donlinks.MKDocumentProvider.MKDocumentProviderDemoFileProvider; 564 | PRODUCT_NAME = "$(TARGET_NAME)"; 565 | PROVISIONING_PROFILE = ""; 566 | SKIP_INSTALL = YES; 567 | }; 568 | name = Release; 569 | }; 570 | FB0C9DF21D22517F00E5DBF4 /* Debug */ = { 571 | isa = XCBuildConfiguration; 572 | buildSettings = { 573 | CODE_SIGN_ENTITLEMENTS = MKDocumentProviderDemo/MKDocumentProviderDemo.entitlements; 574 | CODE_SIGN_IDENTITY = "iPhone Developer"; 575 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 576 | INFOPLIST_FILE = MKDocumentProviderDemo/Info.plist; 577 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; 578 | PRODUCT_BUNDLE_IDENTIFIER = com.donlinks.MKDocumentProvider.MKDocumentProviderDemo; 579 | PRODUCT_NAME = "$(TARGET_NAME)"; 580 | PROVISIONING_PROFILE = ""; 581 | SKIP_INSTALL = YES; 582 | }; 583 | name = Debug; 584 | }; 585 | FB0C9DF31D22517F00E5DBF4 /* Release */ = { 586 | isa = XCBuildConfiguration; 587 | buildSettings = { 588 | CODE_SIGN_ENTITLEMENTS = MKDocumentProviderDemo/MKDocumentProviderDemo.entitlements; 589 | CODE_SIGN_IDENTITY = "iPhone Developer"; 590 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 591 | INFOPLIST_FILE = MKDocumentProviderDemo/Info.plist; 592 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; 593 | PRODUCT_BUNDLE_IDENTIFIER = com.donlinks.MKDocumentProvider.MKDocumentProviderDemo; 594 | PRODUCT_NAME = "$(TARGET_NAME)"; 595 | PROVISIONING_PROFILE = ""; 596 | SKIP_INSTALL = YES; 597 | }; 598 | name = Release; 599 | }; 600 | /* End XCBuildConfiguration section */ 601 | 602 | /* Begin XCConfigurationList section */ 603 | FB0C9DAE1D22512500E5DBF4 /* Build configuration list for PBXProject "MKDocumentProvider" */ = { 604 | isa = XCConfigurationList; 605 | buildConfigurations = ( 606 | FB0C9DC81D22512500E5DBF4 /* Debug */, 607 | FB0C9DC91D22512500E5DBF4 /* Release */, 608 | ); 609 | defaultConfigurationIsVisible = 0; 610 | defaultConfigurationName = Release; 611 | }; 612 | FB0C9DCA1D22512500E5DBF4 /* Build configuration list for PBXNativeTarget "MKDocumentProvider" */ = { 613 | isa = XCConfigurationList; 614 | buildConfigurations = ( 615 | FB0C9DCB1D22512500E5DBF4 /* Debug */, 616 | FB0C9DCC1D22512500E5DBF4 /* Release */, 617 | ); 618 | defaultConfigurationIsVisible = 0; 619 | defaultConfigurationName = Release; 620 | }; 621 | FB0C9DEE1D22517F00E5DBF4 /* Build configuration list for PBXNativeTarget "MKDocumentProviderDemoFileProvider" */ = { 622 | isa = XCConfigurationList; 623 | buildConfigurations = ( 624 | FB0C9DEF1D22517F00E5DBF4 /* Debug */, 625 | FB0C9DF01D22517F00E5DBF4 /* Release */, 626 | ); 627 | defaultConfigurationIsVisible = 0; 628 | defaultConfigurationName = Release; 629 | }; 630 | FB0C9DF11D22517F00E5DBF4 /* Build configuration list for PBXNativeTarget "MKDocumentProviderDemo" */ = { 631 | isa = XCConfigurationList; 632 | buildConfigurations = ( 633 | FB0C9DF21D22517F00E5DBF4 /* Debug */, 634 | FB0C9DF31D22517F00E5DBF4 /* Release */, 635 | ); 636 | defaultConfigurationIsVisible = 0; 637 | defaultConfigurationName = Release; 638 | }; 639 | /* End XCConfigurationList section */ 640 | }; 641 | rootObject = FB0C9DAB1D22512500E5DBF4 /* Project object */; 642 | } 643 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProvider.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProvider/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // MKDocumentProvider 4 | // 5 | // Created by DONLINKS on 16/6/28. 6 | // Copyright © 2016年 Donlinks. 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 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProvider/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // MKDocumentProvider 4 | // 5 | // Created by DONLINKS on 16/6/28. 6 | // Copyright © 2016年 Donlinks. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // 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. 25 | // 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. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // 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. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // 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. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProvider/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 | } -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProvider/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 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProvider/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 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProvider/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 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProvider/MKDocumentProvider.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.icloud-container-identifiers 6 | 7 | iCloud.$(CFBundleIdentifier) 8 | 9 | com.apple.developer.icloud-services 10 | 11 | CloudDocuments 12 | 13 | com.apple.developer.ubiquity-container-identifiers 14 | 15 | iCloud.$(CFBundleIdentifier) 16 | 17 | com.apple.developer.ubiquity-kvstore-identifier 18 | $(TeamIdentifierPrefix)$(CFBundleIdentifier) 19 | com.apple.security.application-groups 20 | 21 | group.com.donlinks.MKDocumentProvider 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProvider/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // MKDocumentProvider 4 | // 5 | // Created by DONLINKS on 16/6/28. 6 | // Copyright © 2016年 Donlinks. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProvider/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // MKDocumentProvider 4 | // 5 | // Created by DONLINKS on 16/6/28. 6 | // Copyright © 2016年 Donlinks. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | #define APP_GROUP_ID @"group.com.donlinks.MKDocumentProvider" 12 | #define APP_FILE_NAME @"File Provider Storage/MKFile" 13 | 14 | #define CellIdentifier @"cellIde" 15 | 16 | @interface ViewController () 17 | 18 | @end 19 | 20 | @implementation ViewController 21 | { 22 | NSArray *fileNamesArray; 23 | 24 | __weak IBOutlet UITableView *fileTableView; 25 | 26 | NSString *storagePath; 27 | } 28 | 29 | - (void)viewDidLoad { 30 | [super viewDidLoad]; 31 | 32 | storagePath = [self storagePath]; 33 | 34 | //第一次启动先写入一些文件到共享容器 35 | [self writeFirstFileToShare]; 36 | 37 | [self loadData]; 38 | } 39 | 40 | #pragma mark - 获取共享容器文件夹路径 41 | - (NSString *)storagePath { 42 | NSURL *groupURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:APP_GROUP_ID]; 43 | NSString *groupPath = [groupURL path]; 44 | NSString *_storagePath = [groupPath stringByAppendingPathComponent:APP_FILE_NAME]; 45 | NSFileManager *fileManager = [NSFileManager defaultManager]; 46 | if (![fileManager fileExistsAtPath:_storagePath]) { 47 | [fileManager createDirectoryAtPath:_storagePath withIntermediateDirectories:NO attributes:nil error:nil]; 48 | } 49 | return _storagePath; 50 | } 51 | 52 | - (void)writeFirstFileToShare{ 53 | 54 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 55 | BOOL isOpened = [[defaults objectForKey:@"isOpened"] boolValue]; 56 | if(!isOpened){ 57 | [defaults setObject:@(YES) forKey:@"isOpened"]; 58 | 59 | NSString *file1Cont = @"Hello every one. I'm M0nk1y. My site: http://mkapple.cn"; 60 | NSString *file2Cont = @"new File2:"; 61 | 62 | [file1Cont writeToFile:[storagePath stringByAppendingPathComponent:@"File1.text"] atomically:YES encoding:NSUTF8StringEncoding error:nil]; 63 | [file2Cont writeToFile:[storagePath stringByAppendingPathComponent:@"File2.text"] atomically:YES encoding:NSUTF8StringEncoding error:nil]; 64 | } 65 | } 66 | 67 | - (void)loadData 68 | { 69 | fileNamesArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:storagePath error:nil]; 70 | [fileTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CellIdentifier]; 71 | [fileTableView reloadData]; 72 | } 73 | 74 | #pragma mark - UITableViewDelegate 75 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 76 | { 77 | return fileNamesArray.count; 78 | } 79 | 80 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 81 | { 82 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 83 | cell.textLabel.text = fileNamesArray[indexPath.row]; 84 | return cell; 85 | } 86 | 87 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 88 | { 89 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 90 | 91 | NSString *docFilePath = [storagePath stringByAppendingPathComponent: fileNamesArray[indexPath.row]]; 92 | NSString *fileContent = [[NSString alloc] initWithContentsOfFile:docFilePath encoding:NSUTF8StringEncoding error:nil]; 93 | 94 | UIViewController *viewCtrl = [UIViewController new]; 95 | 96 | UITextView *textView = [[UITextView alloc] initWithFrame:viewCtrl.view.bounds]; 97 | textView.text = fileContent; 98 | [viewCtrl.view addSubview:textView]; 99 | 100 | [self.navigationController pushViewController:viewCtrl animated:YES]; 101 | 102 | } 103 | 104 | @end 105 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProvider/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // MKDocumentProvider 4 | // 5 | // Created by DONLINKS on 16/6/28. 6 | // Copyright © 2016年 Donlinks. 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 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProviderDemo/Base.lproj/MainInterface.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 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProviderDemo/DocumentPickerViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DocumentPickerViewController.h 3 | // MKDocumentProviderDemo 4 | // 5 | // Created by DONLINKS on 16/6/28. 6 | // Copyright © 2016年 Donlinks. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DocumentPickerViewController : UIDocumentPickerExtensionViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProviderDemo/DocumentPickerViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DocumentPickerViewController.m 3 | // MKDocumentProviderDemo 4 | // 5 | // Created by DONLINKS on 16/6/28. 6 | // Copyright © 2016年 Donlinks. All rights reserved. 7 | // 8 | 9 | #import "DocumentPickerViewController.h" 10 | 11 | #define APP_GROUP_ID @"group.com.donlinks.MKDocumentProvider" 12 | #define APP_FILE_NAME @"MKFile" 13 | 14 | #define CellIdentifier @"cellIde" 15 | 16 | @interface DocumentPickerViewController () 17 | 18 | @end 19 | 20 | @implementation DocumentPickerViewController 21 | { 22 | NSArray *fileNamesArray; 23 | NSString *storagePath; 24 | 25 | __weak IBOutlet UITableView *itemsTableView; 26 | } 27 | 28 | -(void)viewDidLoad 29 | { 30 | [super viewDidLoad]; 31 | 32 | [itemsTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CellIdentifier]; 33 | itemsTableView.backgroundColor = [UIColor whiteColor]; 34 | } 35 | 36 | - (void)loadData{ 37 | NSFileManager *fileMgr = [NSFileManager defaultManager]; 38 | storagePath = [[self.documentStorageURL path] stringByAppendingPathComponent:APP_FILE_NAME]; 39 | fileNamesArray = [fileMgr contentsOfDirectoryAtPath:storagePath error:nil]; 40 | [itemsTableView reloadData]; 41 | } 42 | 43 | -(void)prepareForPresentationInMode:(UIDocumentPickerMode)mode { 44 | 45 | switch (mode) { 46 | case UIDocumentPickerModeImport: 47 | { 48 | self.navigationItem.title = @"请选择导入文件"; 49 | } 50 | break; 51 | case UIDocumentPickerModeOpen: 52 | { 53 | self.navigationItem.title = @"请选择打开文件"; 54 | } 55 | break; 56 | 57 | case UIDocumentPickerModeExportToService: 58 | { 59 | self.navigationItem.title = @"导出文件"; 60 | } 61 | break; 62 | case UIDocumentPickerModeMoveToService: 63 | { 64 | self.navigationItem.title = @"移动文件"; 65 | } 66 | default: 67 | break; 68 | } 69 | 70 | [self loadData]; 71 | } 72 | 73 | #pragma mark - UITableViewDelegate 74 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 75 | { 76 | return fileNamesArray.count; 77 | } 78 | 79 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 80 | { 81 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 82 | cell.textLabel.text = fileNamesArray[indexPath.row]; 83 | return cell; 84 | } 85 | 86 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 87 | { 88 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 89 | if(self.documentPickerMode == UIDocumentPickerModeExportToService || 90 | self.documentPickerMode == UIDocumentPickerModeMoveToService){ 91 | return; 92 | } 93 | // NSString *filePath = [storagePath stringByAppendingPathComponent: @"fileNotExist.txt"]; 94 | NSString *filePath = [storagePath stringByAppendingPathComponent: fileNamesArray[indexPath.row]]; 95 | NSURL *fileURL = [NSURL fileURLWithPath: filePath]; 96 | [self dismissGrantingAccessToURL: fileURL]; 97 | } 98 | 99 | - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section 100 | { 101 | if(self.documentPickerMode == UIDocumentPickerModeExportToService || 102 | self.documentPickerMode == UIDocumentPickerModeMoveToService){ 103 | 104 | NSString *btnTitle = @"导出到这里"; 105 | if(self.documentPickerMode == UIDocumentPickerModeMoveToService){ 106 | btnTitle = @"移动到这里"; 107 | } 108 | 109 | UIView *tableFootView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44)]; 110 | UIButton *btn = [[UIButton alloc] initWithFrame:tableFootView.bounds]; 111 | [btn setTitle:btnTitle forState:UIControlStateNormal]; 112 | [btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 113 | [btn addTarget:self action:@selector(exportFile) forControlEvents:UIControlEventTouchUpInside]; 114 | [tableFootView addSubview:btn]; 115 | return tableFootView; 116 | } 117 | return nil; 118 | } 119 | 120 | - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section 121 | { 122 | return 44; 123 | } 124 | 125 | #pragma mark - exportFile 126 | - (void)exportFile 127 | { 128 | NSURL *originalURL = self.originalURL; 129 | NSString *fileName = [originalURL lastPathComponent]; 130 | NSString *exportFilePath = [storagePath stringByAppendingPathComponent: fileName]; 131 | 132 | //1. 获取安全访问权限 133 | BOOL access = [originalURL startAccessingSecurityScopedResource]; 134 | 135 | if(access){ 136 | //2. 通过文件协调器访问读取该文件 137 | NSFileCoordinator *fileCoordinator = [NSFileCoordinator new]; 138 | NSError *error = nil; 139 | [fileCoordinator coordinateReadingItemAtURL:originalURL options:NSFileCoordinatorReadingWithoutChanges error:&error byAccessor:^(NSURL * _Nonnull newURL) { 140 | 141 | //3.保存文件到共享容器 142 | [self saveFileFromURL:newURL toFileURL: [NSURL fileURLWithPath:exportFilePath]]; 143 | }]; 144 | 145 | } 146 | 147 | //4. 停止安全访问权限 148 | [originalURL stopAccessingSecurityScopedResource]; 149 | } 150 | 151 | #pragma mark - saveFile 152 | - (void)saveFileFromURL:(NSURL *)fileURL toFileURL:(NSURL *)toFileURL 153 | { 154 | NSString *fileName = [fileURL lastPathComponent]; 155 | 156 | void (^saveBlock)(NSString *) = ^(NSString *newFileName){ 157 | NSString *fileCont = [NSString stringWithContentsOfURL:fileURL encoding:NSUTF8StringEncoding error:nil]; 158 | NSURL *saveURL = [toFileURL URLByDeletingLastPathComponent]; 159 | NSURL *newFileURL = [saveURL URLByAppendingPathComponent: newFileName]; 160 | if([fileCont writeToURL:newFileURL atomically:YES encoding:NSUTF8StringEncoding error:nil]){ 161 | [self dismissGrantingAccessToURL: newFileURL]; 162 | }else{ 163 | NSLog(@"保存失败"); 164 | } 165 | }; 166 | 167 | if([fileNamesArray containsObject:fileName]){ 168 | UIAlertController *alertCtrl = [UIAlertController alertControllerWithTitle:@"是否覆盖已有文件" message:nil preferredStyle:UIAlertControllerStyleAlert]; 169 | [alertCtrl addAction: [UIAlertAction actionWithTitle:@"覆盖" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 170 | saveBlock(fileName); 171 | }]]; 172 | 173 | [alertCtrl addAction: [UIAlertAction actionWithTitle:@"更名保存" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 174 | saveBlock([self getOneSuitableFileName:fileName index:2]); 175 | }]]; 176 | [self presentViewController:alertCtrl animated:YES completion:nil]; 177 | 178 | return; 179 | } 180 | 181 | saveBlock(fileName); 182 | } 183 | 184 | - (NSString *)getOneSuitableFileName:(NSString *)originalName index:(NSInteger)index{ 185 | NSString *pathExtension = [originalName pathExtension]; 186 | NSString *fileNameNoExtension = [originalName stringByDeletingPathExtension]; 187 | fileNameNoExtension = [NSString stringWithFormat:@"%@(%@)", fileNameNoExtension, @(index)]; 188 | NSString *newFileName = [fileNameNoExtension stringByAppendingPathExtension: pathExtension]; 189 | if([fileNamesArray containsObject: newFileName]){ 190 | return [self getOneSuitableFileName:originalName index:index+1]; 191 | }else{ 192 | return newFileName; 193 | } 194 | } 195 | 196 | @end 197 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProviderDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MKDocumentProviderDemo 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | UIDocumentPickerModes 30 | 31 | UIDocumentPickerModeImport 32 | UIDocumentPickerModeOpen 33 | UIDocumentPickerModeExportToService 34 | UIDocumentPickerModeMoveToService 35 | 36 | UIDocumentPickerSupportedFileTypes 37 | 38 | public.content 39 | 40 | 41 | NSExtensionMainStoryboard 42 | MainInterface 43 | NSExtensionPointIdentifier 44 | com.apple.fileprovider-ui 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProviderDemo/MKDocumentProviderDemo.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.donlinks.MKDocumentProvider 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProviderDemoFileProvider/FileProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // FileProvider.h 3 | // MKDocumentProviderDemoFileProvider 4 | // 5 | // Created by DONLINKS on 16/6/28. 6 | // Copyright © 2016年 Donlinks. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FileProvider : NSFileProviderExtension 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProviderDemoFileProvider/FileProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // FileProvider.m 3 | // MKDocumentProviderDemoFileProvider 4 | // 5 | // Created by DONLINKS on 16/6/28. 6 | // Copyright © 2016年 Donlinks. All rights reserved. 7 | // 8 | 9 | #import "FileProvider.h" 10 | #import 11 | 12 | @interface FileProvider () 13 | 14 | @end 15 | 16 | @implementation FileProvider 17 | 18 | - (NSFileCoordinator *)fileCoordinator { 19 | NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; 20 | [fileCoordinator setPurposeIdentifier:[self providerIdentifier]]; 21 | return fileCoordinator; 22 | } 23 | 24 | - (instancetype)init { 25 | self = [super init]; 26 | if (self) { 27 | [self.fileCoordinator coordinateWritingItemAtURL:[self documentStorageURL] options:0 error:nil byAccessor:^(NSURL *newURL) { 28 | // ensure the documentStorageURL actually exists 29 | NSError *error = nil; 30 | [[NSFileManager defaultManager] createDirectoryAtURL:newURL withIntermediateDirectories:YES attributes:nil error:&error]; 31 | }]; 32 | } 33 | return self; 34 | } 35 | 36 | - (void)providePlaceholderAtURL:(NSURL *)url completionHandler:(void (^)(NSError *error))completionHandler { 37 | // Should call + writePlaceholderAtURL:withMetadata:error: with the placeholder URL, then call the completion handler with the error if applicable. 38 | NSString *fileName = [url lastPathComponent]; 39 | 40 | NSURL *placeholderURL = [NSFileProviderExtension placeholderURLForURL:[self.documentStorageURL URLByAppendingPathComponent:fileName]]; 41 | 42 | // TODO: get file size for file at from model 43 | NSUInteger fileSize = 0; 44 | NSDictionary* metadata = @{ NSURLFileSizeKey : @(fileSize)}; 45 | [NSFileProviderExtension writePlaceholderAtURL:placeholderURL withMetadata:metadata error:NULL]; 46 | 47 | if (completionHandler) { 48 | completionHandler(nil); 49 | } 50 | } 51 | 52 | //文件保护,文件不存在则创建新文件 53 | - (void)startProvidingItemAtURL:(NSURL *)url completionHandler:(void (^)(NSError *))completionHandler { 54 | NSError* error = nil; 55 | __block NSError* fileError = nil; 56 | 57 | NSFileManager *fileMgr = [NSFileManager defaultManager]; 58 | NSString *filePath = [url path]; 59 | if([fileMgr fileExistsAtPath:filePath]){ //1 60 | //文件已存在,返回 61 | completionHandler(error); 62 | return; 63 | } 64 | 65 | //文件不存在,创建新文件,并写入url 66 | NSData *fileData = [@"新建文件:" dataUsingEncoding:NSUTF8StringEncoding]; //2 67 | 68 | [self.fileCoordinator coordinateWritingItemAtURL:url options:NSFileCoordinatorWritingForReplacing error:&error byAccessor:^(NSURL *newURL) { 69 | [fileData writeToURL:newURL options:0 error:&fileError]; //3 70 | }]; 71 | 72 | if (error!=nil) { 73 | completionHandler(error); 74 | } else { 75 | completionHandler(fileError); 76 | } 77 | } 78 | 79 | 80 | - (void)itemChangedAtURL:(NSURL *)url { 81 | // Called at some point after the file has changed; the provider may then trigger an upload 82 | 83 | // TODO: mark file at as needing an update in the model; kick off update process 84 | NSLog(@"Item changed at URL %@", url); 85 | } 86 | 87 | - (void)stopProvidingItemAtURL:(NSURL *)url { 88 | // Called after the last claim to the file has been released. At this point, it is safe for the file provider to remove the content file. 89 | // Care should be taken that the corresponding placeholder file stays behind after the content file has been deleted. 90 | 91 | [self.fileCoordinator coordinateWritingItemAtURL:url options:NSFileCoordinatorWritingForDeleting error:NULL byAccessor:^(NSURL *newURL) { 92 | [[NSFileManager defaultManager] removeItemAtURL:newURL error:NULL]; 93 | }]; 94 | 95 | [self providePlaceholderAtURL:url completionHandler:^(NSError * __nullable error) { 96 | // TODO: handle any error, do any necessary cleanup 97 | }]; 98 | } 99 | 100 | @end 101 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProviderDemoFileProvider/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MKDocumentProviderDemoFileProvider 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | NSExtension 26 | 27 | NSExtensionFileProviderDocumentGroup 28 | group.com.donlinks.MKDocumentProvider 29 | NSExtensionPointIdentifier 30 | com.apple.fileprovider-nonui 31 | NSExtensionPrincipalClass 32 | FileProvider 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /MKDocumentProvider/MKDocumentProviderDemoFileProvider/MKDocumentProviderDemoFileProvider.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.donlinks.MKDocumentProvider 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MKTextEdit/MKTextEdit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | FB0C9E061D23CA9600E5DBF4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FB0C9E051D23CA9600E5DBF4 /* main.m */; }; 11 | FB0C9E091D23CA9600E5DBF4 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FB0C9E081D23CA9600E5DBF4 /* AppDelegate.m */; }; 12 | FB0C9E0C1D23CA9600E5DBF4 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FB0C9E0B1D23CA9600E5DBF4 /* ViewController.m */; }; 13 | FB0C9E0F1D23CA9600E5DBF4 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB0C9E0D1D23CA9600E5DBF4 /* Main.storyboard */; }; 14 | FB0C9E111D23CA9600E5DBF4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FB0C9E101D23CA9600E5DBF4 /* Assets.xcassets */; }; 15 | FB0C9E141D23CA9600E5DBF4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB0C9E121D23CA9600E5DBF4 /* LaunchScreen.storyboard */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | FB0C9E011D23CA9600E5DBF4 /* MKTextEdit.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MKTextEdit.app; sourceTree = BUILT_PRODUCTS_DIR; }; 20 | FB0C9E051D23CA9600E5DBF4 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 21 | FB0C9E071D23CA9600E5DBF4 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 22 | FB0C9E081D23CA9600E5DBF4 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 23 | FB0C9E0A1D23CA9600E5DBF4 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 24 | FB0C9E0B1D23CA9600E5DBF4 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 25 | FB0C9E0E1D23CA9600E5DBF4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 26 | FB0C9E101D23CA9600E5DBF4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 27 | FB0C9E131D23CA9600E5DBF4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 28 | FB0C9E151D23CA9600E5DBF4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 29 | FB0C9E3B1D23CBE800E5DBF4 /* MKTextEdit.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = MKTextEdit.entitlements; sourceTree = ""; }; 30 | /* End PBXFileReference section */ 31 | 32 | /* Begin PBXFrameworksBuildPhase section */ 33 | FB0C9DFE1D23CA9600E5DBF4 /* Frameworks */ = { 34 | isa = PBXFrameworksBuildPhase; 35 | buildActionMask = 2147483647; 36 | files = ( 37 | ); 38 | runOnlyForDeploymentPostprocessing = 0; 39 | }; 40 | /* End PBXFrameworksBuildPhase section */ 41 | 42 | /* Begin PBXGroup section */ 43 | FB0C9DF81D23CA9600E5DBF4 = { 44 | isa = PBXGroup; 45 | children = ( 46 | FB0C9E031D23CA9600E5DBF4 /* MKTextEdit */, 47 | FB0C9E021D23CA9600E5DBF4 /* Products */, 48 | ); 49 | sourceTree = ""; 50 | }; 51 | FB0C9E021D23CA9600E5DBF4 /* Products */ = { 52 | isa = PBXGroup; 53 | children = ( 54 | FB0C9E011D23CA9600E5DBF4 /* MKTextEdit.app */, 55 | ); 56 | name = Products; 57 | sourceTree = ""; 58 | }; 59 | FB0C9E031D23CA9600E5DBF4 /* MKTextEdit */ = { 60 | isa = PBXGroup; 61 | children = ( 62 | FB0C9E3B1D23CBE800E5DBF4 /* MKTextEdit.entitlements */, 63 | FB0C9E071D23CA9600E5DBF4 /* AppDelegate.h */, 64 | FB0C9E081D23CA9600E5DBF4 /* AppDelegate.m */, 65 | FB0C9E0A1D23CA9600E5DBF4 /* ViewController.h */, 66 | FB0C9E0B1D23CA9600E5DBF4 /* ViewController.m */, 67 | FB0C9E0D1D23CA9600E5DBF4 /* Main.storyboard */, 68 | FB0C9E101D23CA9600E5DBF4 /* Assets.xcassets */, 69 | FB0C9E121D23CA9600E5DBF4 /* LaunchScreen.storyboard */, 70 | FB0C9E151D23CA9600E5DBF4 /* Info.plist */, 71 | FB0C9E041D23CA9600E5DBF4 /* Supporting Files */, 72 | ); 73 | path = MKTextEdit; 74 | sourceTree = ""; 75 | }; 76 | FB0C9E041D23CA9600E5DBF4 /* Supporting Files */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | FB0C9E051D23CA9600E5DBF4 /* main.m */, 80 | ); 81 | name = "Supporting Files"; 82 | sourceTree = ""; 83 | }; 84 | /* End PBXGroup section */ 85 | 86 | /* Begin PBXNativeTarget section */ 87 | FB0C9E001D23CA9600E5DBF4 /* MKTextEdit */ = { 88 | isa = PBXNativeTarget; 89 | buildConfigurationList = FB0C9E181D23CA9600E5DBF4 /* Build configuration list for PBXNativeTarget "MKTextEdit" */; 90 | buildPhases = ( 91 | FB0C9DFD1D23CA9600E5DBF4 /* Sources */, 92 | FB0C9DFE1D23CA9600E5DBF4 /* Frameworks */, 93 | FB0C9DFF1D23CA9600E5DBF4 /* Resources */, 94 | ); 95 | buildRules = ( 96 | ); 97 | dependencies = ( 98 | ); 99 | name = MKTextEdit; 100 | productName = MKTextEdit; 101 | productReference = FB0C9E011D23CA9600E5DBF4 /* MKTextEdit.app */; 102 | productType = "com.apple.product-type.application"; 103 | }; 104 | /* End PBXNativeTarget section */ 105 | 106 | /* Begin PBXProject section */ 107 | FB0C9DF91D23CA9600E5DBF4 /* Project object */ = { 108 | isa = PBXProject; 109 | attributes = { 110 | LastUpgradeCheck = 0730; 111 | ORGANIZATIONNAME = Donlinks; 112 | TargetAttributes = { 113 | FB0C9E001D23CA9600E5DBF4 = { 114 | CreatedOnToolsVersion = 7.3.1; 115 | DevelopmentTeam = DM7XAFH5UF; 116 | SystemCapabilities = { 117 | com.apple.iCloud = { 118 | enabled = 1; 119 | }; 120 | }; 121 | }; 122 | }; 123 | }; 124 | buildConfigurationList = FB0C9DFC1D23CA9600E5DBF4 /* Build configuration list for PBXProject "MKTextEdit" */; 125 | compatibilityVersion = "Xcode 3.2"; 126 | developmentRegion = English; 127 | hasScannedForEncodings = 0; 128 | knownRegions = ( 129 | en, 130 | Base, 131 | ); 132 | mainGroup = FB0C9DF81D23CA9600E5DBF4; 133 | productRefGroup = FB0C9E021D23CA9600E5DBF4 /* Products */; 134 | projectDirPath = ""; 135 | projectRoot = ""; 136 | targets = ( 137 | FB0C9E001D23CA9600E5DBF4 /* MKTextEdit */, 138 | ); 139 | }; 140 | /* End PBXProject section */ 141 | 142 | /* Begin PBXResourcesBuildPhase section */ 143 | FB0C9DFF1D23CA9600E5DBF4 /* Resources */ = { 144 | isa = PBXResourcesBuildPhase; 145 | buildActionMask = 2147483647; 146 | files = ( 147 | FB0C9E141D23CA9600E5DBF4 /* LaunchScreen.storyboard in Resources */, 148 | FB0C9E111D23CA9600E5DBF4 /* Assets.xcassets in Resources */, 149 | FB0C9E0F1D23CA9600E5DBF4 /* Main.storyboard in Resources */, 150 | ); 151 | runOnlyForDeploymentPostprocessing = 0; 152 | }; 153 | /* End PBXResourcesBuildPhase section */ 154 | 155 | /* Begin PBXSourcesBuildPhase section */ 156 | FB0C9DFD1D23CA9600E5DBF4 /* Sources */ = { 157 | isa = PBXSourcesBuildPhase; 158 | buildActionMask = 2147483647; 159 | files = ( 160 | FB0C9E0C1D23CA9600E5DBF4 /* ViewController.m in Sources */, 161 | FB0C9E091D23CA9600E5DBF4 /* AppDelegate.m in Sources */, 162 | FB0C9E061D23CA9600E5DBF4 /* main.m in Sources */, 163 | ); 164 | runOnlyForDeploymentPostprocessing = 0; 165 | }; 166 | /* End PBXSourcesBuildPhase section */ 167 | 168 | /* Begin PBXVariantGroup section */ 169 | FB0C9E0D1D23CA9600E5DBF4 /* Main.storyboard */ = { 170 | isa = PBXVariantGroup; 171 | children = ( 172 | FB0C9E0E1D23CA9600E5DBF4 /* Base */, 173 | ); 174 | name = Main.storyboard; 175 | sourceTree = ""; 176 | }; 177 | FB0C9E121D23CA9600E5DBF4 /* LaunchScreen.storyboard */ = { 178 | isa = PBXVariantGroup; 179 | children = ( 180 | FB0C9E131D23CA9600E5DBF4 /* Base */, 181 | ); 182 | name = LaunchScreen.storyboard; 183 | sourceTree = ""; 184 | }; 185 | /* End PBXVariantGroup section */ 186 | 187 | /* Begin XCBuildConfiguration section */ 188 | FB0C9E161D23CA9600E5DBF4 /* Debug */ = { 189 | isa = XCBuildConfiguration; 190 | buildSettings = { 191 | ALWAYS_SEARCH_USER_PATHS = NO; 192 | CLANG_ANALYZER_NONNULL = YES; 193 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 194 | CLANG_CXX_LIBRARY = "libc++"; 195 | CLANG_ENABLE_MODULES = YES; 196 | CLANG_ENABLE_OBJC_ARC = YES; 197 | CLANG_WARN_BOOL_CONVERSION = YES; 198 | CLANG_WARN_CONSTANT_CONVERSION = YES; 199 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 200 | CLANG_WARN_EMPTY_BODY = YES; 201 | CLANG_WARN_ENUM_CONVERSION = YES; 202 | CLANG_WARN_INT_CONVERSION = YES; 203 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 204 | CLANG_WARN_UNREACHABLE_CODE = YES; 205 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 206 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 207 | COPY_PHASE_STRIP = NO; 208 | DEBUG_INFORMATION_FORMAT = dwarf; 209 | ENABLE_STRICT_OBJC_MSGSEND = YES; 210 | ENABLE_TESTABILITY = YES; 211 | GCC_C_LANGUAGE_STANDARD = gnu99; 212 | GCC_DYNAMIC_NO_PIC = NO; 213 | GCC_NO_COMMON_BLOCKS = YES; 214 | GCC_OPTIMIZATION_LEVEL = 0; 215 | GCC_PREPROCESSOR_DEFINITIONS = ( 216 | "DEBUG=1", 217 | "$(inherited)", 218 | ); 219 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 220 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 221 | GCC_WARN_UNDECLARED_SELECTOR = YES; 222 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 223 | GCC_WARN_UNUSED_FUNCTION = YES; 224 | GCC_WARN_UNUSED_VARIABLE = YES; 225 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 226 | MTL_ENABLE_DEBUG_INFO = YES; 227 | ONLY_ACTIVE_ARCH = YES; 228 | SDKROOT = iphoneos; 229 | }; 230 | name = Debug; 231 | }; 232 | FB0C9E171D23CA9600E5DBF4 /* Release */ = { 233 | isa = XCBuildConfiguration; 234 | buildSettings = { 235 | ALWAYS_SEARCH_USER_PATHS = NO; 236 | CLANG_ANALYZER_NONNULL = YES; 237 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 238 | CLANG_CXX_LIBRARY = "libc++"; 239 | CLANG_ENABLE_MODULES = YES; 240 | CLANG_ENABLE_OBJC_ARC = YES; 241 | CLANG_WARN_BOOL_CONVERSION = YES; 242 | CLANG_WARN_CONSTANT_CONVERSION = YES; 243 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 244 | CLANG_WARN_EMPTY_BODY = YES; 245 | CLANG_WARN_ENUM_CONVERSION = YES; 246 | CLANG_WARN_INT_CONVERSION = YES; 247 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 248 | CLANG_WARN_UNREACHABLE_CODE = YES; 249 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 250 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 251 | COPY_PHASE_STRIP = NO; 252 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 253 | ENABLE_NS_ASSERTIONS = NO; 254 | ENABLE_STRICT_OBJC_MSGSEND = YES; 255 | GCC_C_LANGUAGE_STANDARD = gnu99; 256 | GCC_NO_COMMON_BLOCKS = YES; 257 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 258 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 259 | GCC_WARN_UNDECLARED_SELECTOR = YES; 260 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 261 | GCC_WARN_UNUSED_FUNCTION = YES; 262 | GCC_WARN_UNUSED_VARIABLE = YES; 263 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 264 | MTL_ENABLE_DEBUG_INFO = NO; 265 | SDKROOT = iphoneos; 266 | VALIDATE_PRODUCT = YES; 267 | }; 268 | name = Release; 269 | }; 270 | FB0C9E191D23CA9600E5DBF4 /* Debug */ = { 271 | isa = XCBuildConfiguration; 272 | buildSettings = { 273 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 274 | CODE_SIGN_ENTITLEMENTS = MKTextEdit/MKTextEdit.entitlements; 275 | INFOPLIST_FILE = MKTextEdit/Info.plist; 276 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 277 | PRODUCT_BUNDLE_IDENTIFIER = com.donlinks.MKTextEdit; 278 | PRODUCT_NAME = "$(TARGET_NAME)"; 279 | }; 280 | name = Debug; 281 | }; 282 | FB0C9E1A1D23CA9600E5DBF4 /* Release */ = { 283 | isa = XCBuildConfiguration; 284 | buildSettings = { 285 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 286 | CODE_SIGN_ENTITLEMENTS = MKTextEdit/MKTextEdit.entitlements; 287 | INFOPLIST_FILE = MKTextEdit/Info.plist; 288 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 289 | PRODUCT_BUNDLE_IDENTIFIER = com.donlinks.MKTextEdit; 290 | PRODUCT_NAME = "$(TARGET_NAME)"; 291 | }; 292 | name = Release; 293 | }; 294 | /* End XCBuildConfiguration section */ 295 | 296 | /* Begin XCConfigurationList section */ 297 | FB0C9DFC1D23CA9600E5DBF4 /* Build configuration list for PBXProject "MKTextEdit" */ = { 298 | isa = XCConfigurationList; 299 | buildConfigurations = ( 300 | FB0C9E161D23CA9600E5DBF4 /* Debug */, 301 | FB0C9E171D23CA9600E5DBF4 /* Release */, 302 | ); 303 | defaultConfigurationIsVisible = 0; 304 | defaultConfigurationName = Release; 305 | }; 306 | FB0C9E181D23CA9600E5DBF4 /* Build configuration list for PBXNativeTarget "MKTextEdit" */ = { 307 | isa = XCConfigurationList; 308 | buildConfigurations = ( 309 | FB0C9E191D23CA9600E5DBF4 /* Debug */, 310 | FB0C9E1A1D23CA9600E5DBF4 /* Release */, 311 | ); 312 | defaultConfigurationIsVisible = 0; 313 | defaultConfigurationName = Release; 314 | }; 315 | /* End XCConfigurationList section */ 316 | }; 317 | rootObject = FB0C9DF91D23CA9600E5DBF4 /* Project object */; 318 | } 319 | -------------------------------------------------------------------------------- /MKTextEdit/MKTextEdit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MKTextEdit/MKTextEdit/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // MKTextEdit 4 | // 5 | // Created by DONLINKS on 16/6/29. 6 | // Copyright © 2016年 Donlinks. 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 | -------------------------------------------------------------------------------- /MKTextEdit/MKTextEdit/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // MKTextEdit 4 | // 5 | // Created by DONLINKS on 16/6/29. 6 | // Copyright © 2016年 Donlinks. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // 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. 25 | // 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. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // 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. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // 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. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /MKTextEdit/MKTextEdit/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 | } -------------------------------------------------------------------------------- /MKTextEdit/MKTextEdit/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 | -------------------------------------------------------------------------------- /MKTextEdit/MKTextEdit/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 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /MKTextEdit/MKTextEdit/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 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /MKTextEdit/MKTextEdit/MKTextEdit.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.icloud-container-identifiers 6 | 7 | iCloud.$(CFBundleIdentifier) 8 | 9 | com.apple.developer.icloud-services 10 | 11 | CloudDocuments 12 | 13 | com.apple.developer.ubiquity-container-identifiers 14 | 15 | iCloud.$(CFBundleIdentifier) 16 | 17 | com.apple.developer.ubiquity-kvstore-identifier 18 | $(TeamIdentifierPrefix)$(CFBundleIdentifier) 19 | 20 | 21 | -------------------------------------------------------------------------------- /MKTextEdit/MKTextEdit/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // MKTextEdit 4 | // 5 | // Created by DONLINKS on 16/6/29. 6 | // Copyright © 2016年 Donlinks. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /MKTextEdit/MKTextEdit/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // MKDocumentProvider 4 | // 5 | // Created by DONLINKS on 16/6/28. 6 | // Copyright © 2016年 Donlinks. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | //缓存文件路径 12 | #define CachesFilePath ([NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]) 13 | 14 | @interface ViewController () 15 | 16 | @end 17 | 18 | @implementation ViewController 19 | { 20 | __weak IBOutlet UITextField *titleTextField; 21 | __weak IBOutlet UITextView *contTextView; 22 | __weak IBOutlet UIActivityIndicatorView *activityView; 23 | 24 | __weak IBOutlet UIBarButtonItem *moveBtnItem; 25 | __weak IBOutlet UIBarButtonItem *exportBtnItem; 26 | __weak IBOutlet UIBarButtonItem *saveBtnItem; 27 | 28 | NSString *currentFileName; 29 | UIDocumentPickerMode documentPickerMode; 30 | 31 | NSURL *lastURL; 32 | } 33 | - (void)viewDidLoad { 34 | [super viewDidLoad]; 35 | } 36 | 37 | #pragma mark - 新建文件 38 | - (IBAction)newFile:(id)sender{ 39 | titleTextField.enabled = YES; 40 | 41 | documentPickerMode = 0; 42 | lastURL = nil; 43 | 44 | currentFileName = @"新建文件.txt"; 45 | titleTextField.text = currentFileName; 46 | 47 | [titleTextField becomeFirstResponder]; 48 | [self refreshBtnStatue]; 49 | } 50 | 51 | #pragma mark - 打开文件 52 | - (IBAction)open:(id)sender { 53 | titleTextField.enabled = NO; 54 | documentPickerMode = UIDocumentPickerModeOpen; 55 | [self displayDocumentPickerWithURIs:@[@"public.text", @"public.content"]]; 56 | } 57 | 58 | #pragma mark - 导入文件 59 | - (IBAction)import:(id)sender { 60 | //导入情况下,导入的文件会放在应用的临时文件目录里 61 | titleTextField.enabled = NO; 62 | documentPickerMode = UIDocumentPickerModeImport; 63 | [self displayDocumentPickerWithURIs:@[@"public.text", @"public.content"]]; 64 | } 65 | 66 | #pragma mark - 移动文件 67 | - (IBAction)move:(id)sender { 68 | [self modify:nil]; 69 | documentPickerMode = UIDocumentPickerModeMoveToService; 70 | NSURL *fileURL = [NSURL fileURLWithPath: [CachesFilePath stringByAppendingPathComponent: currentFileName]]; 71 | [self displayDocumentPickerWithURL:fileURL]; 72 | } 73 | 74 | #pragma mark - 导出文件 75 | - (IBAction)export:(id)sender { 76 | //1. 保存缓存文件 77 | [self modify:nil]; 78 | documentPickerMode = UIDocumentPickerModeExportToService; 79 | NSURL *fileURL = [NSURL fileURLWithPath: [CachesFilePath stringByAppendingPathComponent: currentFileName]]; 80 | 81 | //2.打开文件选择器 82 | [self displayDocumentPickerWithURL:fileURL]; 83 | } 84 | 85 | #pragma mark - 修改文件 86 | - (IBAction)modify:(id)sender { 87 | 88 | if(currentFileName.length > 0){ 89 | if(![currentFileName isEqualToString: titleTextField.text]){ 90 | //删除缓存中旧文件 91 | [self deleteLocalCachesData:currentFileName]; 92 | currentFileName = titleTextField.text; 93 | } 94 | NSString *content = contTextView.text; 95 | 96 | if([self saveLocalCachesCont:content fileName: currentFileName]){ 97 | NSLog(@"保存成功"); 98 | } 99 | 100 | if(documentPickerMode == UIDocumentPickerModeOpen){ 101 | //打开模式下,保存在文件打开的地址 102 | //1.通过文件协调器写入文件 103 | NSFileCoordinator *fileCoorDinator = [NSFileCoordinator new]; 104 | NSError *error = nil; 105 | [fileCoorDinator coordinateWritingItemAtURL:lastURL 106 | options:NSFileCoordinatorWritingForReplacing 107 | error:&error 108 | byAccessor:^(NSURL * _Nonnull newURL) { 109 | 110 | //2.获取安全访问权限 111 | BOOL access = [newURL startAccessingSecurityScopedResource]; 112 | 113 | //3.写入数据 114 | if(access && [content writeToURL:newURL atomically:YES encoding:NSUTF8StringEncoding error:nil]){ 115 | NSLog(@"保存原文件成功"); 116 | } 117 | 118 | //4.停止安全访问权限 119 | [newURL stopAccessingSecurityScopedResource]; 120 | }]; 121 | } 122 | 123 | } 124 | 125 | } 126 | 127 | - (void)displayDocumentPickerWithURL:(NSURL *)url { 128 | UIDocumentMenuViewController *importMenu = [[UIDocumentMenuViewController alloc] initWithURL:url inMode:documentPickerMode]; 129 | importMenu.delegate = self; 130 | [self presentViewController:importMenu animated:YES completion:nil]; 131 | } 132 | 133 | - (void)displayDocumentPickerWithURIs:(NSArray *)UTIs { 134 | UIDocumentMenuViewController *importMenu = [[UIDocumentMenuViewController alloc] initWithDocumentTypes:UTIs inMode:documentPickerMode]; 135 | importMenu.delegate = self; 136 | [self presentViewController:importMenu animated:YES completion:nil]; 137 | } 138 | 139 | #pragma mark - UIDocumentMenuDelegate 140 | -(void)documentMenu:(UIDocumentMenuViewController *)documentMenu didPickDocumentPicker:(UIDocumentPickerViewController *)documentPicker 141 | { 142 | documentPicker.delegate = self; 143 | [self presentViewController:documentPicker animated:YES completion:nil]; 144 | } 145 | 146 | #pragma mark - UIDocumentPickerDelegate 147 | -(void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url 148 | { 149 | lastURL = url; 150 | [controller dismissViewControllerAnimated:YES completion:nil]; 151 | switch (controller.documentPickerMode) { 152 | case UIDocumentPickerModeImport: 153 | { 154 | [self refreshBtnStatue]; 155 | [self importFile: url]; 156 | } 157 | break; 158 | case UIDocumentPickerModeOpen: 159 | { 160 | [self refreshBtnStatue]; 161 | [self openFile: url]; 162 | } 163 | break; 164 | case UIDocumentPickerModeExportToService: 165 | { 166 | NSLog(@"保存到此位置:%@", url); 167 | } 168 | break; 169 | case UIDocumentPickerModeMoveToService: 170 | { 171 | //可以删除本地对应的文件 172 | NSLog(@"移动到此位置:%@", url); 173 | } 174 | break; 175 | 176 | default: 177 | break; 178 | } 179 | } 180 | 181 | - (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller 182 | { 183 | [controller dismissViewControllerAnimated:YES completion:nil]; 184 | } 185 | 186 | - (void)importFile:(NSURL *)url 187 | { 188 | [activityView startAnimating]; 189 | 190 | //1.通过文件协调工具来得到新的文件地址,以此得到文件保护功能 191 | NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil]; 192 | [fileCoordinator coordinateReadingItemAtURL:url options:NSFileCoordinatorReadingWithoutChanges error:nil byAccessor:^(NSURL * _Nonnull newURL) { 193 | [activityView stopAnimating]; 194 | 195 | //2.直接读取文件 196 | NSString *fileName = [newURL lastPathComponent]; 197 | NSString *contStr = [NSString stringWithContentsOfURL:newURL encoding:NSUTF8StringEncoding error:nil]; 198 | 199 | //3.把数据保存在本地缓存 200 | [self saveLocalCachesCont:contStr fileName:fileName]; 201 | 202 | //4.显示数据 203 | currentFileName = fileName; 204 | titleTextField.text = fileName; 205 | contTextView.text = contStr; 206 | 207 | }]; 208 | } 209 | 210 | - (void)openFile:(NSURL *)url 211 | { 212 | //1.获取文件授权 213 | BOOL accessing = [url startAccessingSecurityScopedResource]; 214 | 215 | if(accessing){ 216 | [activityView startAnimating]; 217 | 218 | //2.通过文件协调器读取文件地址 219 | NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil]; 220 | [fileCoordinator coordinateReadingItemAtURL:url 221 | options:NSFileCoordinatorReadingWithoutChanges 222 | error:nil 223 | byAccessor:^(NSURL * _Nonnull newURL) { 224 | 225 | [activityView stopAnimating]; 226 | 227 | //3.读取文件协调器提供的新地址里的数据 228 | NSString *fileName = [newURL lastPathComponent]; 229 | NSString *contStr = [NSString stringWithContentsOfURL:newURL encoding:NSUTF8StringEncoding error:nil]; 230 | 231 | //4.把数据保存在本地缓存 232 | [self saveLocalCachesCont:contStr fileName:fileName]; 233 | 234 | //5.显示数据 235 | currentFileName = fileName; 236 | titleTextField.text = fileName; 237 | contTextView.text = contStr; 238 | }]; 239 | 240 | } 241 | 242 | //6.停止授权 243 | [url stopAccessingSecurityScopedResource]; 244 | } 245 | 246 | //把文件保存在本地缓存 247 | - (BOOL)saveLocalCachesCont:(NSString *)cont fileName:(NSString *)fileName 248 | { 249 | NSString *filePath = [CachesFilePath stringByAppendingPathComponent: fileName]; 250 | return [cont writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil]; 251 | } 252 | 253 | - (void)deleteLocalCachesData:(NSString *)fileName 254 | { 255 | NSFileManager *fileMgr = [NSFileManager defaultManager]; 256 | NSString *filePath = [CachesFilePath stringByAppendingPathComponent: fileName]; 257 | if([fileMgr fileExistsAtPath:filePath]){ 258 | [fileMgr removeItemAtPath:filePath error:nil]; 259 | } 260 | } 261 | 262 | - (void)refreshBtnStatue{ 263 | moveBtnItem.enabled = YES; 264 | exportBtnItem.enabled = YES; 265 | saveBtnItem.enabled = YES; 266 | } 267 | 268 | - (void)didReceiveMemoryWarning { 269 | [super didReceiveMemoryWarning]; 270 | // Dispose of any resources that can be recreated. 271 | } 272 | 273 | @end 274 | -------------------------------------------------------------------------------- /MKTextEdit/MKTextEdit/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // MKTextEdit 4 | // 5 | // Created by DONLINKS on 16/6/29. 6 | // Copyright © 2016年 Donlinks. 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MKDocumentProvider 2 | Document Provider extension Demo 3 | 4 | [这里是详细说明](http://mkapple.cn/2016/07/01/DocumentProvider) 5 | --------------------------------------------------------------------------------