├── .DS_Store ├── EasyShare.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ ├── WorkspaceSettings.xcsettings │ │ └── swiftpm │ │ │ └── Package.resolved │ └── xcuserdata │ │ └── michaellee.xcuserdatad │ │ ├── IDEFindNavigatorScopes.plist │ │ ├── UserInterfaceState.xcuserstate │ │ └── WorkspaceSettings.xcsettings ├── xcshareddata │ └── xcschemes │ │ ├── EasyShare.xcscheme │ │ └── ShareExtension.xcscheme └── xcuserdata │ └── michaellee.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── EasyShare ├── .DS_Store ├── AppDelegate.swift ├── Assets.xcassets │ ├── .DS_Store │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── new es logo.png │ │ ├── new es logo@0,25x-1.png │ │ ├── new es logo@0,25x-2.png │ │ ├── new es logo@0,25x@0,25x.png │ │ ├── new es logo@0,25x@0,25x@0,25x.png │ │ ├── new es logo@0,25x@0,25x@0,5x-1.png │ │ ├── new es logo@0,25x@0,25x@0,5x.png │ │ ├── new es logo@0,25x@0,5x.png │ │ ├── new es logo@0,5x-2.png │ │ └── new es logo@0,5x-3.png │ ├── Contents.json │ └── Logo.imageset │ │ ├── Contents.json │ │ ├── new es logo.png │ │ ├── new es logo@0,25x.png │ │ └── new es logo@0,5x.png ├── Base.lproj │ └── Main.storyboard ├── DragView.swift ├── EasyShare.entitlements ├── Info.plist ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json ├── Window.swift └── Window.xib ├── EasyShareTests ├── EasyShareTests.swift └── Info.plist ├── EasyShareUITests ├── EasyShareUITests.swift └── Info.plist ├── Extension ├── Base.lproj │ └── ShareViewController.xib ├── Extension.entitlements ├── Info.plist └── ShareViewController.swift ├── README.md ├── README_zh.md ├── ShareExtension ├── .DS_Store ├── Base.lproj │ └── ShareViewController.xib ├── Info.plist ├── Resource │ ├── .DS_Store │ └── wwwroot │ │ ├── ESlogo.png │ │ └── index.html ├── ShareExtension.entitlements ├── ShareServer.swift ├── ShareViewController.swift ├── icon.icns ├── model │ ├── ConfigMap.swift │ └── db │ │ ├── DbHelper.swift │ │ └── dto │ │ ├── ConfigDTO.swift │ │ └── ShareDTO.swift └── utils │ └── DataUtils.swift ├── WX20200505-140330@2x.png ├── WX20200615-235553@2x.png ├── WX20200615-235713@2x.png └── logo.png /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/.DS_Store -------------------------------------------------------------------------------- /EasyShare.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 52; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 906B7534245DF6AE00662E03 /* PerfectHTTPServer in Frameworks */ = {isa = PBXBuildFile; productRef = 906B7533245DF6AE00662E03 /* PerfectHTTPServer */; }; 11 | 90714160245DCC61008D5294 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9071415F245DCC61008D5294 /* AppDelegate.swift */; }; 12 | 90714164245DCC62008D5294 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 90714163245DCC62008D5294 /* Assets.xcassets */; }; 13 | 90714167245DCC62008D5294 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 90714166245DCC62008D5294 /* Preview Assets.xcassets */; }; 14 | 9071416A245DCC62008D5294 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 90714168245DCC62008D5294 /* Main.storyboard */; }; 15 | 90714176245DCC62008D5294 /* EasyShareTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90714175245DCC62008D5294 /* EasyShareTests.swift */; }; 16 | 90714181245DCC62008D5294 /* EasyShareUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90714180245DCC62008D5294 /* EasyShareUITests.swift */; }; 17 | 907B97EC24605F7A00F38E15 /* ShareServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90997479245DDF6900931C1F /* ShareServer.swift */; }; 18 | 908DB5332574C6A8008AF55D /* ESlogo.png in Resources */ = {isa = PBXBuildFile; fileRef = 908DB5322574C6A8008AF55D /* ESlogo.png */; }; 19 | 9096CC71245F14D700AC750B /* SQLiteStORM in Frameworks */ = {isa = PBXBuildFile; productRef = 9096CC70245F14D700AC750B /* SQLiteStORM */; }; 20 | 9096CC78245F18A400AC750B /* ConfigDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC77245F18A400AC750B /* ConfigDTO.swift */; }; 21 | 9096CC7A245F18B700AC750B /* ShareDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC79245F18B700AC750B /* ShareDTO.swift */; }; 22 | 9096CC81245F21D700AC750B /* DbHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC80245F21D700AC750B /* DbHelper.swift */; }; 23 | 9096CC86245F39BE00AC750B /* DataUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC85245F39BE00AC750B /* DataUtils.swift */; }; 24 | 909CBEA42564C3C40046DA74 /* index.html in Resources */ = {isa = PBXBuildFile; fileRef = 909CBEA32564C3C40046DA74 /* index.html */; }; 25 | 90C7A7492460014000F7369C /* ConfigMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC82245F303800AC750B /* ConfigMap.swift */; }; 26 | 90C7A76D2460125100F7369C /* DragView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90C7A76C2460125100F7369C /* DragView.swift */; }; 27 | 90C7A79624605D7300F7369C /* icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 90C7A79524605D7300F7369C /* icon.icns */; }; 28 | 90C7A79824605D7300F7369C /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90C7A79724605D7300F7369C /* ShareViewController.swift */; }; 29 | 90C7A79B24605D7300F7369C /* ShareViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 90C7A79924605D7300F7369C /* ShareViewController.xib */; }; 30 | 90C7A7A024605D7300F7369C /* ShareExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 90C7A79324605D7300F7369C /* ShareExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 31 | 90C7A7A424605D7F00F7369C /* ShareServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90997479245DDF6900931C1F /* ShareServer.swift */; }; 32 | 90C7A7AA24605E2600F7369C /* PerfectHTTPServer in Frameworks */ = {isa = PBXBuildFile; productRef = 90C7A7A924605E2600F7369C /* PerfectHTTPServer */; }; 33 | 90C7A7AC24605E2600F7369C /* SQLiteStORM in Frameworks */ = {isa = PBXBuildFile; productRef = 90C7A7AB24605E2600F7369C /* SQLiteStORM */; }; 34 | 90C7A7AD24605E5500F7369C /* ConfigDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC77245F18A400AC750B /* ConfigDTO.swift */; }; 35 | 90C7A7AE24605E5500F7369C /* ShareDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC79245F18B700AC750B /* ShareDTO.swift */; }; 36 | 90C7A7AF24605E5500F7369C /* DbHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC80245F21D700AC750B /* DbHelper.swift */; }; 37 | 90C7A7B024605E5500F7369C /* ConfigMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC82245F303800AC750B /* ConfigMap.swift */; }; 38 | 90C7A7B124605E5500F7369C /* DataUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC85245F39BE00AC750B /* DataUtils.swift */; }; 39 | 90E808552463B6F70051447E /* Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90E808532463B6F70051447E /* Window.swift */; }; 40 | 90E808562463B6F70051447E /* Window.xib in Resources */ = {isa = PBXBuildFile; fileRef = 90E808542463B6F70051447E /* Window.xib */; }; 41 | /* End PBXBuildFile section */ 42 | 43 | /* Begin PBXContainerItemProxy section */ 44 | 90714172245DCC62008D5294 /* PBXContainerItemProxy */ = { 45 | isa = PBXContainerItemProxy; 46 | containerPortal = 90714154245DCC61008D5294 /* Project object */; 47 | proxyType = 1; 48 | remoteGlobalIDString = 9071415B245DCC61008D5294; 49 | remoteInfo = EasyShare; 50 | }; 51 | 9071417D245DCC62008D5294 /* PBXContainerItemProxy */ = { 52 | isa = PBXContainerItemProxy; 53 | containerPortal = 90714154245DCC61008D5294 /* Project object */; 54 | proxyType = 1; 55 | remoteGlobalIDString = 9071415B245DCC61008D5294; 56 | remoteInfo = EasyShare; 57 | }; 58 | 90C7A79E24605D7300F7369C /* PBXContainerItemProxy */ = { 59 | isa = PBXContainerItemProxy; 60 | containerPortal = 90714154245DCC61008D5294 /* Project object */; 61 | proxyType = 1; 62 | remoteGlobalIDString = 90C7A79224605D7300F7369C; 63 | remoteInfo = ShareExtension; 64 | }; 65 | /* End PBXContainerItemProxy section */ 66 | 67 | /* Begin PBXCopyFilesBuildPhase section */ 68 | 90C7A704245FEE8300F7369C /* Embed App Extensions */ = { 69 | isa = PBXCopyFilesBuildPhase; 70 | buildActionMask = 2147483647; 71 | dstPath = ""; 72 | dstSubfolderSpec = 13; 73 | files = ( 74 | 90C7A7A024605D7300F7369C /* ShareExtension.appex in Embed App Extensions */, 75 | ); 76 | name = "Embed App Extensions"; 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | 90C7A727245FF41300F7369C /* Embed Frameworks */ = { 80 | isa = PBXCopyFilesBuildPhase; 81 | buildActionMask = 2147483647; 82 | dstPath = ""; 83 | dstSubfolderSpec = 10; 84 | files = ( 85 | ); 86 | name = "Embed Frameworks"; 87 | runOnlyForDeploymentPostprocessing = 0; 88 | }; 89 | /* End PBXCopyFilesBuildPhase section */ 90 | 91 | /* Begin PBXFileReference section */ 92 | 9071415C245DCC61008D5294 /* EasyShare.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EasyShare.app; sourceTree = BUILT_PRODUCTS_DIR; }; 93 | 9071415F245DCC61008D5294 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 94 | 90714163245DCC62008D5294 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 95 | 90714166245DCC62008D5294 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 96 | 90714169245DCC62008D5294 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 97 | 9071416B245DCC62008D5294 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 98 | 9071416C245DCC62008D5294 /* EasyShare.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = EasyShare.entitlements; sourceTree = ""; }; 99 | 90714171245DCC62008D5294 /* EasyShareTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EasyShareTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 100 | 90714175245DCC62008D5294 /* EasyShareTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EasyShareTests.swift; sourceTree = ""; }; 101 | 90714177245DCC62008D5294 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 102 | 9071417C245DCC62008D5294 /* EasyShareUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EasyShareUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 103 | 90714180245DCC62008D5294 /* EasyShareUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EasyShareUITests.swift; sourceTree = ""; }; 104 | 90714182245DCC62008D5294 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 105 | 908DB5322574C6A8008AF55D /* ESlogo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ESlogo.png; sourceTree = ""; }; 106 | 9096CC77245F18A400AC750B /* ConfigDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigDTO.swift; sourceTree = ""; }; 107 | 9096CC79245F18B700AC750B /* ShareDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareDTO.swift; sourceTree = ""; }; 108 | 9096CC80245F21D700AC750B /* DbHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DbHelper.swift; sourceTree = ""; }; 109 | 9096CC82245F303800AC750B /* ConfigMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigMap.swift; sourceTree = ""; }; 110 | 9096CC85245F39BE00AC750B /* DataUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataUtils.swift; sourceTree = ""; }; 111 | 90997479245DDF6900931C1F /* ShareServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareServer.swift; sourceTree = ""; }; 112 | 909CBEA32564C3C40046DA74 /* index.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = index.html; sourceTree = ""; }; 113 | 90C7A76C2460125100F7369C /* DragView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DragView.swift; sourceTree = ""; }; 114 | 90C7A79324605D7300F7369C /* ShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 115 | 90C7A79524605D7300F7369C /* icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = icon.icns; sourceTree = ""; }; 116 | 90C7A79724605D7300F7369C /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; }; 117 | 90C7A79A24605D7300F7369C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ShareViewController.xib; sourceTree = ""; }; 118 | 90C7A79C24605D7300F7369C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 119 | 90C7A79D24605D7300F7369C /* ShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ShareExtension.entitlements; sourceTree = ""; }; 120 | 90E808532463B6F70051447E /* Window.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Window.swift; sourceTree = ""; }; 121 | 90E808542463B6F70051447E /* Window.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = Window.xib; sourceTree = ""; }; 122 | /* End PBXFileReference section */ 123 | 124 | /* Begin PBXFrameworksBuildPhase section */ 125 | 90714159245DCC61008D5294 /* Frameworks */ = { 126 | isa = PBXFrameworksBuildPhase; 127 | buildActionMask = 2147483647; 128 | files = ( 129 | 9096CC71245F14D700AC750B /* SQLiteStORM in Frameworks */, 130 | 906B7534245DF6AE00662E03 /* PerfectHTTPServer in Frameworks */, 131 | ); 132 | runOnlyForDeploymentPostprocessing = 0; 133 | }; 134 | 9071416E245DCC62008D5294 /* Frameworks */ = { 135 | isa = PBXFrameworksBuildPhase; 136 | buildActionMask = 2147483647; 137 | files = ( 138 | ); 139 | runOnlyForDeploymentPostprocessing = 0; 140 | }; 141 | 90714179245DCC62008D5294 /* Frameworks */ = { 142 | isa = PBXFrameworksBuildPhase; 143 | buildActionMask = 2147483647; 144 | files = ( 145 | ); 146 | runOnlyForDeploymentPostprocessing = 0; 147 | }; 148 | 90C7A79024605D7300F7369C /* Frameworks */ = { 149 | isa = PBXFrameworksBuildPhase; 150 | buildActionMask = 2147483647; 151 | files = ( 152 | 90C7A7AC24605E2600F7369C /* SQLiteStORM in Frameworks */, 153 | 90C7A7AA24605E2600F7369C /* PerfectHTTPServer in Frameworks */, 154 | ); 155 | runOnlyForDeploymentPostprocessing = 0; 156 | }; 157 | /* End PBXFrameworksBuildPhase section */ 158 | 159 | /* Begin PBXGroup section */ 160 | 90714153245DCC61008D5294 = { 161 | isa = PBXGroup; 162 | children = ( 163 | 9071415E245DCC61008D5294 /* EasyShare */, 164 | 90714174245DCC62008D5294 /* EasyShareTests */, 165 | 9071417F245DCC62008D5294 /* EasyShareUITests */, 166 | 90C7A79424605D7300F7369C /* ShareExtension */, 167 | 9071415D245DCC61008D5294 /* Products */, 168 | 90C7A78524601C1800F7369C /* Frameworks */, 169 | ); 170 | sourceTree = ""; 171 | }; 172 | 9071415D245DCC61008D5294 /* Products */ = { 173 | isa = PBXGroup; 174 | children = ( 175 | 9071415C245DCC61008D5294 /* EasyShare.app */, 176 | 90714171245DCC62008D5294 /* EasyShareTests.xctest */, 177 | 9071417C245DCC62008D5294 /* EasyShareUITests.xctest */, 178 | 90C7A79324605D7300F7369C /* ShareExtension.appex */, 179 | ); 180 | name = Products; 181 | sourceTree = ""; 182 | }; 183 | 9071415E245DCC61008D5294 /* EasyShare */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | 9071415F245DCC61008D5294 /* AppDelegate.swift */, 187 | 90E808532463B6F70051447E /* Window.swift */, 188 | 90E808542463B6F70051447E /* Window.xib */, 189 | 90C7A76C2460125100F7369C /* DragView.swift */, 190 | 90714163245DCC62008D5294 /* Assets.xcassets */, 191 | 90714168245DCC62008D5294 /* Main.storyboard */, 192 | 9071416B245DCC62008D5294 /* Info.plist */, 193 | 9071416C245DCC62008D5294 /* EasyShare.entitlements */, 194 | 90714165245DCC62008D5294 /* Preview Content */, 195 | ); 196 | path = EasyShare; 197 | sourceTree = ""; 198 | }; 199 | 90714165245DCC62008D5294 /* Preview Content */ = { 200 | isa = PBXGroup; 201 | children = ( 202 | 90714166245DCC62008D5294 /* Preview Assets.xcassets */, 203 | ); 204 | path = "Preview Content"; 205 | sourceTree = ""; 206 | }; 207 | 90714174245DCC62008D5294 /* EasyShareTests */ = { 208 | isa = PBXGroup; 209 | children = ( 210 | 90714175245DCC62008D5294 /* EasyShareTests.swift */, 211 | 90714177245DCC62008D5294 /* Info.plist */, 212 | ); 213 | path = EasyShareTests; 214 | sourceTree = ""; 215 | }; 216 | 9071417F245DCC62008D5294 /* EasyShareUITests */ = { 217 | isa = PBXGroup; 218 | children = ( 219 | 90714180245DCC62008D5294 /* EasyShareUITests.swift */, 220 | 90714182245DCC62008D5294 /* Info.plist */, 221 | ); 222 | path = EasyShareUITests; 223 | sourceTree = ""; 224 | }; 225 | 908DB5372574C8E0008AF55D /* wwwroot */ = { 226 | isa = PBXGroup; 227 | children = ( 228 | 908DB5322574C6A8008AF55D /* ESlogo.png */, 229 | 909CBEA32564C3C40046DA74 /* index.html */, 230 | ); 231 | path = wwwroot; 232 | sourceTree = ""; 233 | }; 234 | 9096CC73245F17C100AC750B /* db */ = { 235 | isa = PBXGroup; 236 | children = ( 237 | 9096CC76245F188C00AC750B /* dto */, 238 | 9096CC80245F21D700AC750B /* DbHelper.swift */, 239 | ); 240 | path = db; 241 | sourceTree = ""; 242 | }; 243 | 9096CC76245F188C00AC750B /* dto */ = { 244 | isa = PBXGroup; 245 | children = ( 246 | 9096CC77245F18A400AC750B /* ConfigDTO.swift */, 247 | 9096CC79245F18B700AC750B /* ShareDTO.swift */, 248 | ); 249 | path = dto; 250 | sourceTree = ""; 251 | }; 252 | 909CBEA22564C35C0046DA74 /* Resource */ = { 253 | isa = PBXGroup; 254 | children = ( 255 | 908DB5372574C8E0008AF55D /* wwwroot */, 256 | ); 257 | path = Resource; 258 | sourceTree = ""; 259 | }; 260 | 90C7A7442460010000F7369C /* utils */ = { 261 | isa = PBXGroup; 262 | children = ( 263 | 9096CC85245F39BE00AC750B /* DataUtils.swift */, 264 | ); 265 | path = utils; 266 | sourceTree = ""; 267 | }; 268 | 90C7A7452460010000F7369C /* model */ = { 269 | isa = PBXGroup; 270 | children = ( 271 | 9096CC73245F17C100AC750B /* db */, 272 | 9096CC82245F303800AC750B /* ConfigMap.swift */, 273 | ); 274 | path = model; 275 | sourceTree = ""; 276 | }; 277 | 90C7A78524601C1800F7369C /* Frameworks */ = { 278 | isa = PBXGroup; 279 | children = ( 280 | ); 281 | name = Frameworks; 282 | sourceTree = ""; 283 | }; 284 | 90C7A79424605D7300F7369C /* ShareExtension */ = { 285 | isa = PBXGroup; 286 | children = ( 287 | 909CBEA22564C35C0046DA74 /* Resource */, 288 | 90C7A7452460010000F7369C /* model */, 289 | 90C7A7442460010000F7369C /* utils */, 290 | 90997479245DDF6900931C1F /* ShareServer.swift */, 291 | 90C7A79524605D7300F7369C /* icon.icns */, 292 | 90C7A79724605D7300F7369C /* ShareViewController.swift */, 293 | 90C7A79924605D7300F7369C /* ShareViewController.xib */, 294 | 90C7A79C24605D7300F7369C /* Info.plist */, 295 | 90C7A79D24605D7300F7369C /* ShareExtension.entitlements */, 296 | ); 297 | path = ShareExtension; 298 | sourceTree = ""; 299 | }; 300 | /* End PBXGroup section */ 301 | 302 | /* Begin PBXNativeTarget section */ 303 | 9071415B245DCC61008D5294 /* EasyShare */ = { 304 | isa = PBXNativeTarget; 305 | buildConfigurationList = 90714185245DCC62008D5294 /* Build configuration list for PBXNativeTarget "EasyShare" */; 306 | buildPhases = ( 307 | 90714158245DCC61008D5294 /* Sources */, 308 | 90714159245DCC61008D5294 /* Frameworks */, 309 | 9071415A245DCC61008D5294 /* Resources */, 310 | 90C7A704245FEE8300F7369C /* Embed App Extensions */, 311 | 90C7A727245FF41300F7369C /* Embed Frameworks */, 312 | ); 313 | buildRules = ( 314 | ); 315 | dependencies = ( 316 | 90C7A79F24605D7300F7369C /* PBXTargetDependency */, 317 | ); 318 | name = EasyShare; 319 | packageProductDependencies = ( 320 | 906B7533245DF6AE00662E03 /* PerfectHTTPServer */, 321 | 9096CC70245F14D700AC750B /* SQLiteStORM */, 322 | ); 323 | productName = EasyShare; 324 | productReference = 9071415C245DCC61008D5294 /* EasyShare.app */; 325 | productType = "com.apple.product-type.application"; 326 | }; 327 | 90714170245DCC62008D5294 /* EasyShareTests */ = { 328 | isa = PBXNativeTarget; 329 | buildConfigurationList = 90714188245DCC62008D5294 /* Build configuration list for PBXNativeTarget "EasyShareTests" */; 330 | buildPhases = ( 331 | 9071416D245DCC62008D5294 /* Sources */, 332 | 9071416E245DCC62008D5294 /* Frameworks */, 333 | 9071416F245DCC62008D5294 /* Resources */, 334 | ); 335 | buildRules = ( 336 | ); 337 | dependencies = ( 338 | 90714173245DCC62008D5294 /* PBXTargetDependency */, 339 | ); 340 | name = EasyShareTests; 341 | productName = EasyShareTests; 342 | productReference = 90714171245DCC62008D5294 /* EasyShareTests.xctest */; 343 | productType = "com.apple.product-type.bundle.unit-test"; 344 | }; 345 | 9071417B245DCC62008D5294 /* EasyShareUITests */ = { 346 | isa = PBXNativeTarget; 347 | buildConfigurationList = 9071418B245DCC62008D5294 /* Build configuration list for PBXNativeTarget "EasyShareUITests" */; 348 | buildPhases = ( 349 | 90714178245DCC62008D5294 /* Sources */, 350 | 90714179245DCC62008D5294 /* Frameworks */, 351 | 9071417A245DCC62008D5294 /* Resources */, 352 | ); 353 | buildRules = ( 354 | ); 355 | dependencies = ( 356 | 9071417E245DCC62008D5294 /* PBXTargetDependency */, 357 | ); 358 | name = EasyShareUITests; 359 | productName = EasyShareUITests; 360 | productReference = 9071417C245DCC62008D5294 /* EasyShareUITests.xctest */; 361 | productType = "com.apple.product-type.bundle.ui-testing"; 362 | }; 363 | 90C7A79224605D7300F7369C /* ShareExtension */ = { 364 | isa = PBXNativeTarget; 365 | buildConfigurationList = 90C7A7A124605D7300F7369C /* Build configuration list for PBXNativeTarget "ShareExtension" */; 366 | buildPhases = ( 367 | 90C7A78F24605D7300F7369C /* Sources */, 368 | 90C7A79024605D7300F7369C /* Frameworks */, 369 | 90C7A79124605D7300F7369C /* Resources */, 370 | ); 371 | buildRules = ( 372 | ); 373 | dependencies = ( 374 | 90C7A7A624605E1C00F7369C /* PBXTargetDependency */, 375 | 90C7A7A824605E1C00F7369C /* PBXTargetDependency */, 376 | ); 377 | name = ShareExtension; 378 | packageProductDependencies = ( 379 | 90C7A7A924605E2600F7369C /* PerfectHTTPServer */, 380 | 90C7A7AB24605E2600F7369C /* SQLiteStORM */, 381 | ); 382 | productName = ShareExtension; 383 | productReference = 90C7A79324605D7300F7369C /* ShareExtension.appex */; 384 | productType = "com.apple.product-type.app-extension"; 385 | }; 386 | /* End PBXNativeTarget section */ 387 | 388 | /* Begin PBXProject section */ 389 | 90714154245DCC61008D5294 /* Project object */ = { 390 | isa = PBXProject; 391 | attributes = { 392 | LastSwiftUpdateCheck = 1140; 393 | LastUpgradeCheck = 1140; 394 | ORGANIZATIONNAME = "Michael Lee"; 395 | TargetAttributes = { 396 | 9071415B245DCC61008D5294 = { 397 | CreatedOnToolsVersion = 11.4; 398 | }; 399 | 90714170245DCC62008D5294 = { 400 | CreatedOnToolsVersion = 11.4; 401 | TestTargetID = 9071415B245DCC61008D5294; 402 | }; 403 | 9071417B245DCC62008D5294 = { 404 | CreatedOnToolsVersion = 11.4; 405 | TestTargetID = 9071415B245DCC61008D5294; 406 | }; 407 | 90C7A79224605D7300F7369C = { 408 | CreatedOnToolsVersion = 11.4.1; 409 | }; 410 | }; 411 | }; 412 | buildConfigurationList = 90714157245DCC61008D5294 /* Build configuration list for PBXProject "EasyShare" */; 413 | compatibilityVersion = "Xcode 9.3"; 414 | developmentRegion = en; 415 | hasScannedForEncodings = 0; 416 | knownRegions = ( 417 | en, 418 | Base, 419 | ); 420 | mainGroup = 90714153245DCC61008D5294; 421 | packageReferences = ( 422 | 906B7532245DF6AE00662E03 /* XCRemoteSwiftPackageReference "Perfect-HTTPServer" */, 423 | 9096CC6F245F14D700AC750B /* XCRemoteSwiftPackageReference "SQLite-StORM" */, 424 | ); 425 | productRefGroup = 9071415D245DCC61008D5294 /* Products */; 426 | projectDirPath = ""; 427 | projectRoot = ""; 428 | targets = ( 429 | 9071415B245DCC61008D5294 /* EasyShare */, 430 | 90714170245DCC62008D5294 /* EasyShareTests */, 431 | 9071417B245DCC62008D5294 /* EasyShareUITests */, 432 | 90C7A79224605D7300F7369C /* ShareExtension */, 433 | ); 434 | }; 435 | /* End PBXProject section */ 436 | 437 | /* Begin PBXResourcesBuildPhase section */ 438 | 9071415A245DCC61008D5294 /* Resources */ = { 439 | isa = PBXResourcesBuildPhase; 440 | buildActionMask = 2147483647; 441 | files = ( 442 | 9071416A245DCC62008D5294 /* Main.storyboard in Resources */, 443 | 90714167245DCC62008D5294 /* Preview Assets.xcassets in Resources */, 444 | 90714164245DCC62008D5294 /* Assets.xcassets in Resources */, 445 | 90E808562463B6F70051447E /* Window.xib in Resources */, 446 | ); 447 | runOnlyForDeploymentPostprocessing = 0; 448 | }; 449 | 9071416F245DCC62008D5294 /* Resources */ = { 450 | isa = PBXResourcesBuildPhase; 451 | buildActionMask = 2147483647; 452 | files = ( 453 | ); 454 | runOnlyForDeploymentPostprocessing = 0; 455 | }; 456 | 9071417A245DCC62008D5294 /* Resources */ = { 457 | isa = PBXResourcesBuildPhase; 458 | buildActionMask = 2147483647; 459 | files = ( 460 | ); 461 | runOnlyForDeploymentPostprocessing = 0; 462 | }; 463 | 90C7A79124605D7300F7369C /* Resources */ = { 464 | isa = PBXResourcesBuildPhase; 465 | buildActionMask = 2147483647; 466 | files = ( 467 | 909CBEA42564C3C40046DA74 /* index.html in Resources */, 468 | 90C7A79B24605D7300F7369C /* ShareViewController.xib in Resources */, 469 | 908DB5332574C6A8008AF55D /* ESlogo.png in Resources */, 470 | 90C7A79624605D7300F7369C /* icon.icns in Resources */, 471 | ); 472 | runOnlyForDeploymentPostprocessing = 0; 473 | }; 474 | /* End PBXResourcesBuildPhase section */ 475 | 476 | /* Begin PBXSourcesBuildPhase section */ 477 | 90714158245DCC61008D5294 /* Sources */ = { 478 | isa = PBXSourcesBuildPhase; 479 | buildActionMask = 2147483647; 480 | files = ( 481 | 907B97EC24605F7A00F38E15 /* ShareServer.swift in Sources */, 482 | 90E808552463B6F70051447E /* Window.swift in Sources */, 483 | 9096CC7A245F18B700AC750B /* ShareDTO.swift in Sources */, 484 | 90714160245DCC61008D5294 /* AppDelegate.swift in Sources */, 485 | 9096CC86245F39BE00AC750B /* DataUtils.swift in Sources */, 486 | 9096CC78245F18A400AC750B /* ConfigDTO.swift in Sources */, 487 | 90C7A7492460014000F7369C /* ConfigMap.swift in Sources */, 488 | 9096CC81245F21D700AC750B /* DbHelper.swift in Sources */, 489 | 90C7A76D2460125100F7369C /* DragView.swift in Sources */, 490 | ); 491 | runOnlyForDeploymentPostprocessing = 0; 492 | }; 493 | 9071416D245DCC62008D5294 /* Sources */ = { 494 | isa = PBXSourcesBuildPhase; 495 | buildActionMask = 2147483647; 496 | files = ( 497 | 90714176245DCC62008D5294 /* EasyShareTests.swift in Sources */, 498 | ); 499 | runOnlyForDeploymentPostprocessing = 0; 500 | }; 501 | 90714178245DCC62008D5294 /* Sources */ = { 502 | isa = PBXSourcesBuildPhase; 503 | buildActionMask = 2147483647; 504 | files = ( 505 | 90714181245DCC62008D5294 /* EasyShareUITests.swift in Sources */, 506 | ); 507 | runOnlyForDeploymentPostprocessing = 0; 508 | }; 509 | 90C7A78F24605D7300F7369C /* Sources */ = { 510 | isa = PBXSourcesBuildPhase; 511 | buildActionMask = 2147483647; 512 | files = ( 513 | 90C7A7AD24605E5500F7369C /* ConfigDTO.swift in Sources */, 514 | 90C7A7AE24605E5500F7369C /* ShareDTO.swift in Sources */, 515 | 90C7A7AF24605E5500F7369C /* DbHelper.swift in Sources */, 516 | 90C7A7B024605E5500F7369C /* ConfigMap.swift in Sources */, 517 | 90C7A7B124605E5500F7369C /* DataUtils.swift in Sources */, 518 | 90C7A7A424605D7F00F7369C /* ShareServer.swift in Sources */, 519 | 90C7A79824605D7300F7369C /* ShareViewController.swift in Sources */, 520 | ); 521 | runOnlyForDeploymentPostprocessing = 0; 522 | }; 523 | /* End PBXSourcesBuildPhase section */ 524 | 525 | /* Begin PBXTargetDependency section */ 526 | 90714173245DCC62008D5294 /* PBXTargetDependency */ = { 527 | isa = PBXTargetDependency; 528 | target = 9071415B245DCC61008D5294 /* EasyShare */; 529 | targetProxy = 90714172245DCC62008D5294 /* PBXContainerItemProxy */; 530 | }; 531 | 9071417E245DCC62008D5294 /* PBXTargetDependency */ = { 532 | isa = PBXTargetDependency; 533 | target = 9071415B245DCC61008D5294 /* EasyShare */; 534 | targetProxy = 9071417D245DCC62008D5294 /* PBXContainerItemProxy */; 535 | }; 536 | 90C7A79F24605D7300F7369C /* PBXTargetDependency */ = { 537 | isa = PBXTargetDependency; 538 | target = 90C7A79224605D7300F7369C /* ShareExtension */; 539 | targetProxy = 90C7A79E24605D7300F7369C /* PBXContainerItemProxy */; 540 | }; 541 | 90C7A7A624605E1C00F7369C /* PBXTargetDependency */ = { 542 | isa = PBXTargetDependency; 543 | productRef = 90C7A7A524605E1C00F7369C /* PerfectHTTPServer */; 544 | }; 545 | 90C7A7A824605E1C00F7369C /* PBXTargetDependency */ = { 546 | isa = PBXTargetDependency; 547 | productRef = 90C7A7A724605E1C00F7369C /* SQLiteStORM */; 548 | }; 549 | /* End PBXTargetDependency section */ 550 | 551 | /* Begin PBXVariantGroup section */ 552 | 90714168245DCC62008D5294 /* Main.storyboard */ = { 553 | isa = PBXVariantGroup; 554 | children = ( 555 | 90714169245DCC62008D5294 /* Base */, 556 | ); 557 | name = Main.storyboard; 558 | sourceTree = ""; 559 | }; 560 | 90C7A79924605D7300F7369C /* ShareViewController.xib */ = { 561 | isa = PBXVariantGroup; 562 | children = ( 563 | 90C7A79A24605D7300F7369C /* Base */, 564 | ); 565 | name = ShareViewController.xib; 566 | sourceTree = ""; 567 | }; 568 | /* End PBXVariantGroup section */ 569 | 570 | /* Begin XCBuildConfiguration section */ 571 | 90714183245DCC62008D5294 /* Debug */ = { 572 | isa = XCBuildConfiguration; 573 | buildSettings = { 574 | ALWAYS_SEARCH_USER_PATHS = NO; 575 | CLANG_ANALYZER_NONNULL = YES; 576 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 577 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 578 | CLANG_CXX_LIBRARY = "libc++"; 579 | CLANG_ENABLE_MODULES = YES; 580 | CLANG_ENABLE_OBJC_ARC = YES; 581 | CLANG_ENABLE_OBJC_WEAK = YES; 582 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 583 | CLANG_WARN_BOOL_CONVERSION = YES; 584 | CLANG_WARN_COMMA = YES; 585 | CLANG_WARN_CONSTANT_CONVERSION = YES; 586 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 587 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 588 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 589 | CLANG_WARN_EMPTY_BODY = YES; 590 | CLANG_WARN_ENUM_CONVERSION = YES; 591 | CLANG_WARN_INFINITE_RECURSION = YES; 592 | CLANG_WARN_INT_CONVERSION = YES; 593 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 594 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 595 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 596 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 597 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 598 | CLANG_WARN_STRICT_PROTOTYPES = YES; 599 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 600 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 601 | CLANG_WARN_UNREACHABLE_CODE = YES; 602 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 603 | COPY_PHASE_STRIP = NO; 604 | DEBUG_INFORMATION_FORMAT = dwarf; 605 | ENABLE_STRICT_OBJC_MSGSEND = YES; 606 | ENABLE_TESTABILITY = YES; 607 | GCC_C_LANGUAGE_STANDARD = gnu11; 608 | GCC_DYNAMIC_NO_PIC = NO; 609 | GCC_NO_COMMON_BLOCKS = YES; 610 | GCC_OPTIMIZATION_LEVEL = 0; 611 | GCC_PREPROCESSOR_DEFINITIONS = ( 612 | "DEBUG=1", 613 | "$(inherited)", 614 | ); 615 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 616 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 617 | GCC_WARN_UNDECLARED_SELECTOR = YES; 618 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 619 | GCC_WARN_UNUSED_FUNCTION = YES; 620 | GCC_WARN_UNUSED_VARIABLE = YES; 621 | MACOSX_DEPLOYMENT_TARGET = 10.13; 622 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 623 | MTL_FAST_MATH = YES; 624 | ONLY_ACTIVE_ARCH = YES; 625 | SDKROOT = macosx; 626 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 627 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 628 | }; 629 | name = Debug; 630 | }; 631 | 90714184245DCC62008D5294 /* Release */ = { 632 | isa = XCBuildConfiguration; 633 | buildSettings = { 634 | ALWAYS_SEARCH_USER_PATHS = NO; 635 | CLANG_ANALYZER_NONNULL = YES; 636 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 637 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 638 | CLANG_CXX_LIBRARY = "libc++"; 639 | CLANG_ENABLE_MODULES = YES; 640 | CLANG_ENABLE_OBJC_ARC = YES; 641 | CLANG_ENABLE_OBJC_WEAK = YES; 642 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 643 | CLANG_WARN_BOOL_CONVERSION = YES; 644 | CLANG_WARN_COMMA = YES; 645 | CLANG_WARN_CONSTANT_CONVERSION = YES; 646 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 647 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 648 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 649 | CLANG_WARN_EMPTY_BODY = YES; 650 | CLANG_WARN_ENUM_CONVERSION = YES; 651 | CLANG_WARN_INFINITE_RECURSION = YES; 652 | CLANG_WARN_INT_CONVERSION = YES; 653 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 654 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 655 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 656 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 657 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 658 | CLANG_WARN_STRICT_PROTOTYPES = YES; 659 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 660 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 661 | CLANG_WARN_UNREACHABLE_CODE = YES; 662 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 663 | COPY_PHASE_STRIP = NO; 664 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 665 | ENABLE_NS_ASSERTIONS = NO; 666 | ENABLE_STRICT_OBJC_MSGSEND = YES; 667 | GCC_C_LANGUAGE_STANDARD = gnu11; 668 | GCC_NO_COMMON_BLOCKS = YES; 669 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 670 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 671 | GCC_WARN_UNDECLARED_SELECTOR = YES; 672 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 673 | GCC_WARN_UNUSED_FUNCTION = YES; 674 | GCC_WARN_UNUSED_VARIABLE = YES; 675 | MACOSX_DEPLOYMENT_TARGET = 10.13; 676 | MTL_ENABLE_DEBUG_INFO = NO; 677 | MTL_FAST_MATH = YES; 678 | SDKROOT = macosx; 679 | SWIFT_COMPILATION_MODE = wholemodule; 680 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 681 | }; 682 | name = Release; 683 | }; 684 | 90714186245DCC62008D5294 /* Debug */ = { 685 | isa = XCBuildConfiguration; 686 | buildSettings = { 687 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 688 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 689 | CODE_SIGN_ENTITLEMENTS = EasyShare/EasyShare.entitlements; 690 | CODE_SIGN_IDENTITY = "-"; 691 | CODE_SIGN_STYLE = Automatic; 692 | COMBINE_HIDPI_IMAGES = YES; 693 | CURRENT_PROJECT_VERSION = 10; 694 | DEVELOPMENT_ASSET_PATHS = "\"EasyShare/Preview Content\""; 695 | DEVELOPMENT_TEAM = 5PYBGZXB6L; 696 | ENABLE_HARDENED_RUNTIME = YES; 697 | ENABLE_PREVIEWS = YES; 698 | INFOPLIST_FILE = EasyShare/Info.plist; 699 | LD_RUNPATH_SEARCH_PATHS = ( 700 | "$(inherited)", 701 | "@executable_path/../Frameworks", 702 | ); 703 | MACOSX_DEPLOYMENT_TARGET = 10.13; 704 | MARKETING_VERSION = 1.4; 705 | PRODUCT_BUNDLE_IDENTIFIER = dog.abcd.EasyShare; 706 | PRODUCT_NAME = "$(TARGET_NAME)"; 707 | PROVISIONING_PROFILE_SPECIFIER = ""; 708 | SWIFT_VERSION = 5.0; 709 | }; 710 | name = Debug; 711 | }; 712 | 90714187245DCC62008D5294 /* Release */ = { 713 | isa = XCBuildConfiguration; 714 | buildSettings = { 715 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 716 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 717 | CODE_SIGN_ENTITLEMENTS = EasyShare/EasyShare.entitlements; 718 | CODE_SIGN_IDENTITY = "-"; 719 | CODE_SIGN_STYLE = Automatic; 720 | COMBINE_HIDPI_IMAGES = YES; 721 | CURRENT_PROJECT_VERSION = 10; 722 | DEVELOPMENT_ASSET_PATHS = "\"EasyShare/Preview Content\""; 723 | DEVELOPMENT_TEAM = 5PYBGZXB6L; 724 | ENABLE_HARDENED_RUNTIME = YES; 725 | ENABLE_PREVIEWS = YES; 726 | INFOPLIST_FILE = EasyShare/Info.plist; 727 | LD_RUNPATH_SEARCH_PATHS = ( 728 | "$(inherited)", 729 | "@executable_path/../Frameworks", 730 | ); 731 | MACOSX_DEPLOYMENT_TARGET = 10.13; 732 | MARKETING_VERSION = 1.4; 733 | PRODUCT_BUNDLE_IDENTIFIER = dog.abcd.EasyShare; 734 | PRODUCT_NAME = "$(TARGET_NAME)"; 735 | PROVISIONING_PROFILE_SPECIFIER = ""; 736 | SWIFT_VERSION = 5.0; 737 | }; 738 | name = Release; 739 | }; 740 | 90714189245DCC62008D5294 /* Debug */ = { 741 | isa = XCBuildConfiguration; 742 | buildSettings = { 743 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 744 | BUNDLE_LOADER = "$(TEST_HOST)"; 745 | CODE_SIGN_STYLE = Automatic; 746 | COMBINE_HIDPI_IMAGES = YES; 747 | DEVELOPMENT_TEAM = 5PYBGZXB6L; 748 | INFOPLIST_FILE = EasyShareTests/Info.plist; 749 | LD_RUNPATH_SEARCH_PATHS = ( 750 | "$(inherited)", 751 | "@executable_path/../Frameworks", 752 | "@loader_path/../Frameworks", 753 | ); 754 | MACOSX_DEPLOYMENT_TARGET = 10.15; 755 | PRODUCT_BUNDLE_IDENTIFIER = dog.abcd.EasyShareTests; 756 | PRODUCT_NAME = "$(TARGET_NAME)"; 757 | SWIFT_VERSION = 5.0; 758 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/EasyShare.app/Contents/MacOS/EasyShare"; 759 | }; 760 | name = Debug; 761 | }; 762 | 9071418A245DCC62008D5294 /* Release */ = { 763 | isa = XCBuildConfiguration; 764 | buildSettings = { 765 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 766 | BUNDLE_LOADER = "$(TEST_HOST)"; 767 | CODE_SIGN_STYLE = Automatic; 768 | COMBINE_HIDPI_IMAGES = YES; 769 | DEVELOPMENT_TEAM = 5PYBGZXB6L; 770 | INFOPLIST_FILE = EasyShareTests/Info.plist; 771 | LD_RUNPATH_SEARCH_PATHS = ( 772 | "$(inherited)", 773 | "@executable_path/../Frameworks", 774 | "@loader_path/../Frameworks", 775 | ); 776 | MACOSX_DEPLOYMENT_TARGET = 10.15; 777 | PRODUCT_BUNDLE_IDENTIFIER = dog.abcd.EasyShareTests; 778 | PRODUCT_NAME = "$(TARGET_NAME)"; 779 | SWIFT_VERSION = 5.0; 780 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/EasyShare.app/Contents/MacOS/EasyShare"; 781 | }; 782 | name = Release; 783 | }; 784 | 9071418C245DCC62008D5294 /* Debug */ = { 785 | isa = XCBuildConfiguration; 786 | buildSettings = { 787 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 788 | CODE_SIGN_STYLE = Automatic; 789 | COMBINE_HIDPI_IMAGES = YES; 790 | DEVELOPMENT_TEAM = 5PYBGZXB6L; 791 | INFOPLIST_FILE = EasyShareUITests/Info.plist; 792 | LD_RUNPATH_SEARCH_PATHS = ( 793 | "$(inherited)", 794 | "@executable_path/../Frameworks", 795 | "@loader_path/../Frameworks", 796 | ); 797 | PRODUCT_BUNDLE_IDENTIFIER = dog.abcd.EasyShareUITests; 798 | PRODUCT_NAME = "$(TARGET_NAME)"; 799 | SWIFT_VERSION = 5.0; 800 | TEST_TARGET_NAME = EasyShare; 801 | }; 802 | name = Debug; 803 | }; 804 | 9071418D245DCC62008D5294 /* Release */ = { 805 | isa = XCBuildConfiguration; 806 | buildSettings = { 807 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 808 | CODE_SIGN_STYLE = Automatic; 809 | COMBINE_HIDPI_IMAGES = YES; 810 | DEVELOPMENT_TEAM = 5PYBGZXB6L; 811 | INFOPLIST_FILE = EasyShareUITests/Info.plist; 812 | LD_RUNPATH_SEARCH_PATHS = ( 813 | "$(inherited)", 814 | "@executable_path/../Frameworks", 815 | "@loader_path/../Frameworks", 816 | ); 817 | PRODUCT_BUNDLE_IDENTIFIER = dog.abcd.EasyShareUITests; 818 | PRODUCT_NAME = "$(TARGET_NAME)"; 819 | SWIFT_VERSION = 5.0; 820 | TEST_TARGET_NAME = EasyShare; 821 | }; 822 | name = Release; 823 | }; 824 | 90C7A7A224605D7300F7369C /* Debug */ = { 825 | isa = XCBuildConfiguration; 826 | buildSettings = { 827 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 828 | CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements; 829 | CODE_SIGN_IDENTITY = "-"; 830 | CODE_SIGN_STYLE = Automatic; 831 | COMBINE_HIDPI_IMAGES = YES; 832 | CURRENT_PROJECT_VERSION = 10; 833 | DEVELOPMENT_TEAM = 5PYBGZXB6L; 834 | ENABLE_HARDENED_RUNTIME = YES; 835 | INFOPLIST_FILE = ShareExtension/Info.plist; 836 | LD_RUNPATH_SEARCH_PATHS = ( 837 | "$(inherited)", 838 | "@executable_path/../Frameworks", 839 | "@executable_path/../../../../Frameworks", 840 | ); 841 | MACOSX_DEPLOYMENT_TARGET = 10.13; 842 | MARKETING_VERSION = 1.4; 843 | PRODUCT_BUNDLE_IDENTIFIER = dog.abcd.EasyShare.ShareExtension; 844 | PRODUCT_NAME = "$(TARGET_NAME)"; 845 | SKIP_INSTALL = YES; 846 | SWIFT_VERSION = 5.0; 847 | }; 848 | name = Debug; 849 | }; 850 | 90C7A7A324605D7300F7369C /* Release */ = { 851 | isa = XCBuildConfiguration; 852 | buildSettings = { 853 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 854 | CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtensionRelease.entitlements; 855 | CODE_SIGN_IDENTITY = "-"; 856 | CODE_SIGN_STYLE = Automatic; 857 | COMBINE_HIDPI_IMAGES = YES; 858 | CURRENT_PROJECT_VERSION = 10; 859 | DEVELOPMENT_TEAM = 5PYBGZXB6L; 860 | ENABLE_HARDENED_RUNTIME = YES; 861 | INFOPLIST_FILE = ShareExtension/Info.plist; 862 | LD_RUNPATH_SEARCH_PATHS = ( 863 | "$(inherited)", 864 | "@executable_path/../Frameworks", 865 | "@executable_path/../../../../Frameworks", 866 | ); 867 | MACOSX_DEPLOYMENT_TARGET = 10.13; 868 | MARKETING_VERSION = 1.4; 869 | PRODUCT_BUNDLE_IDENTIFIER = dog.abcd.EasyShare.ShareExtension; 870 | PRODUCT_NAME = "$(TARGET_NAME)"; 871 | SKIP_INSTALL = YES; 872 | SWIFT_VERSION = 5.0; 873 | }; 874 | name = Release; 875 | }; 876 | /* End XCBuildConfiguration section */ 877 | 878 | /* Begin XCConfigurationList section */ 879 | 90714157245DCC61008D5294 /* Build configuration list for PBXProject "EasyShare" */ = { 880 | isa = XCConfigurationList; 881 | buildConfigurations = ( 882 | 90714183245DCC62008D5294 /* Debug */, 883 | 90714184245DCC62008D5294 /* Release */, 884 | ); 885 | defaultConfigurationIsVisible = 0; 886 | defaultConfigurationName = Release; 887 | }; 888 | 90714185245DCC62008D5294 /* Build configuration list for PBXNativeTarget "EasyShare" */ = { 889 | isa = XCConfigurationList; 890 | buildConfigurations = ( 891 | 90714186245DCC62008D5294 /* Debug */, 892 | 90714187245DCC62008D5294 /* Release */, 893 | ); 894 | defaultConfigurationIsVisible = 0; 895 | defaultConfigurationName = Release; 896 | }; 897 | 90714188245DCC62008D5294 /* Build configuration list for PBXNativeTarget "EasyShareTests" */ = { 898 | isa = XCConfigurationList; 899 | buildConfigurations = ( 900 | 90714189245DCC62008D5294 /* Debug */, 901 | 9071418A245DCC62008D5294 /* Release */, 902 | ); 903 | defaultConfigurationIsVisible = 0; 904 | defaultConfigurationName = Release; 905 | }; 906 | 9071418B245DCC62008D5294 /* Build configuration list for PBXNativeTarget "EasyShareUITests" */ = { 907 | isa = XCConfigurationList; 908 | buildConfigurations = ( 909 | 9071418C245DCC62008D5294 /* Debug */, 910 | 9071418D245DCC62008D5294 /* Release */, 911 | ); 912 | defaultConfigurationIsVisible = 0; 913 | defaultConfigurationName = Release; 914 | }; 915 | 90C7A7A124605D7300F7369C /* Build configuration list for PBXNativeTarget "ShareExtension" */ = { 916 | isa = XCConfigurationList; 917 | buildConfigurations = ( 918 | 90C7A7A224605D7300F7369C /* Debug */, 919 | 90C7A7A324605D7300F7369C /* Release */, 920 | ); 921 | defaultConfigurationIsVisible = 0; 922 | defaultConfigurationName = Release; 923 | }; 924 | /* End XCConfigurationList section */ 925 | 926 | /* Begin XCRemoteSwiftPackageReference section */ 927 | 906B7532245DF6AE00662E03 /* XCRemoteSwiftPackageReference "Perfect-HTTPServer" */ = { 928 | isa = XCRemoteSwiftPackageReference; 929 | repositoryURL = "https://github.com/PerfectlySoft/Perfect-HTTPServer.git"; 930 | requirement = { 931 | kind = upToNextMajorVersion; 932 | minimumVersion = 3.0.23; 933 | }; 934 | }; 935 | 9096CC6F245F14D700AC750B /* XCRemoteSwiftPackageReference "SQLite-StORM" */ = { 936 | isa = XCRemoteSwiftPackageReference; 937 | repositoryURL = "https://github.com/SwiftORM/SQLite-StORM.git"; 938 | requirement = { 939 | kind = upToNextMajorVersion; 940 | minimumVersion = 3.1.0; 941 | }; 942 | }; 943 | /* End XCRemoteSwiftPackageReference section */ 944 | 945 | /* Begin XCSwiftPackageProductDependency section */ 946 | 906B7533245DF6AE00662E03 /* PerfectHTTPServer */ = { 947 | isa = XCSwiftPackageProductDependency; 948 | package = 906B7532245DF6AE00662E03 /* XCRemoteSwiftPackageReference "Perfect-HTTPServer" */; 949 | productName = PerfectHTTPServer; 950 | }; 951 | 9096CC70245F14D700AC750B /* SQLiteStORM */ = { 952 | isa = XCSwiftPackageProductDependency; 953 | package = 9096CC6F245F14D700AC750B /* XCRemoteSwiftPackageReference "SQLite-StORM" */; 954 | productName = SQLiteStORM; 955 | }; 956 | 90C7A7A524605E1C00F7369C /* PerfectHTTPServer */ = { 957 | isa = XCSwiftPackageProductDependency; 958 | package = 906B7532245DF6AE00662E03 /* XCRemoteSwiftPackageReference "Perfect-HTTPServer" */; 959 | productName = PerfectHTTPServer; 960 | }; 961 | 90C7A7A724605E1C00F7369C /* SQLiteStORM */ = { 962 | isa = XCSwiftPackageProductDependency; 963 | package = 9096CC6F245F14D700AC750B /* XCRemoteSwiftPackageReference "SQLite-StORM" */; 964 | productName = SQLiteStORM; 965 | }; 966 | 90C7A7A924605E2600F7369C /* PerfectHTTPServer */ = { 967 | isa = XCSwiftPackageProductDependency; 968 | package = 906B7532245DF6AE00662E03 /* XCRemoteSwiftPackageReference "Perfect-HTTPServer" */; 969 | productName = PerfectHTTPServer; 970 | }; 971 | 90C7A7AB24605E2600F7369C /* SQLiteStORM */ = { 972 | isa = XCSwiftPackageProductDependency; 973 | package = 9096CC6F245F14D700AC750B /* XCRemoteSwiftPackageReference "SQLite-StORM" */; 974 | productName = SQLiteStORM; 975 | }; 976 | /* End XCSwiftPackageProductDependency section */ 977 | }; 978 | rootObject = 90714154245DCC61008D5294 /* Project object */; 979 | } 980 | -------------------------------------------------------------------------------- /EasyShare.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /EasyShare.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /EasyShare.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /EasyShare.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "COpenSSL", 6 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-COpenSSL.git", 7 | "state": { 8 | "branch": null, 9 | "revision": "ce3113e159b8c6d8565e5d8db2672b572c81aea9", 10 | "version": "4.0.2" 11 | } 12 | }, 13 | { 14 | "package": "PerfectCRUD", 15 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-CRUD.git", 16 | "state": { 17 | "branch": null, 18 | "revision": "5a947634b7ce0b991e8f455a61ce02449f2e6f36", 19 | "version": "1.2.3" 20 | } 21 | }, 22 | { 23 | "package": "PerfectCrypto", 24 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-Crypto.git", 25 | "state": { 26 | "branch": null, 27 | "revision": "98373fa3a6c3d551e498c1babe4f25f650fa1310", 28 | "version": "3.3.0" 29 | } 30 | }, 31 | { 32 | "package": "PerfectCURL", 33 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-CURL.git", 34 | "state": { 35 | "branch": null, 36 | "revision": "a9f8950554585bd12b9ec24ad4bfbe0b1519e03f", 37 | "version": "3.1.0" 38 | } 39 | }, 40 | { 41 | "package": "PerfectCZlib", 42 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-CZlib-src.git", 43 | "state": { 44 | "branch": null, 45 | "revision": "b63e46909aad937c6434766f8f8c6720d8f3bd05", 46 | "version": "0.0.4" 47 | } 48 | }, 49 | { 50 | "package": "PerfectHTTP", 51 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-HTTP.git", 52 | "state": { 53 | "branch": null, 54 | "revision": "122affd0bb5090c61bdc1e50e7f32ab6457d228e", 55 | "version": "3.3.0" 56 | } 57 | }, 58 | { 59 | "package": "PerfectHTTPServer", 60 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-HTTPServer.git", 61 | "state": { 62 | "branch": null, 63 | "revision": "4843cd54762d59b7e70841663ae561b279b80946", 64 | "version": "3.0.23" 65 | } 66 | }, 67 | { 68 | "package": "cURL", 69 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-libcurl.git", 70 | "state": { 71 | "branch": null, 72 | "revision": "b3d7e65ef5c27c0a027cdc621f34835975301bf1", 73 | "version": "2.1.0" 74 | } 75 | }, 76 | { 77 | "package": "PerfectLogger", 78 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-Logger.git", 79 | "state": { 80 | "branch": null, 81 | "revision": "78f47107c9f7563cf94e3b5d141ca8bf0cc2f995", 82 | "version": "3.3.0" 83 | } 84 | }, 85 | { 86 | "package": "PerfectNet", 87 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-Net.git", 88 | "state": { 89 | "branch": null, 90 | "revision": "d00b2b9f4cccb4c398e1bcf18f767d6b8add6af7", 91 | "version": "3.3.0" 92 | } 93 | }, 94 | { 95 | "package": "PerfectSQLite", 96 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-SQLite.git", 97 | "state": { 98 | "branch": null, 99 | "revision": "420002c79529f8307cf0dda832069a46e466ae82", 100 | "version": "3.1.4" 101 | } 102 | }, 103 | { 104 | "package": "PerfectCSQLite3", 105 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-sqlite3-support.git", 106 | "state": { 107 | "branch": null, 108 | "revision": "64c2bd87e1fd3a41cdeeba073bab794db7e97e42", 109 | "version": "3.1.1" 110 | } 111 | }, 112 | { 113 | "package": "PerfectThread", 114 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-Thread.git", 115 | "state": { 116 | "branch": null, 117 | "revision": "a50b9a33f08fce638f33ae3121613fe499cc23ec", 118 | "version": "3.0.7" 119 | } 120 | }, 121 | { 122 | "package": "PerfectLib", 123 | "repositoryURL": "https://github.com/PerfectlySoft/PerfectLib.git", 124 | "state": { 125 | "branch": null, 126 | "revision": "5a08c2a596df23a3ae30b6ac9cb509a38384166c", 127 | "version": "3.1.4" 128 | } 129 | }, 130 | { 131 | "package": "SQLiteStORM", 132 | "repositoryURL": "https://github.com/SwiftORM/SQLite-StORM.git", 133 | "state": { 134 | "branch": null, 135 | "revision": "dd4cf565ef9ebd7fb2589b64a77e49365f69c681", 136 | "version": "3.1.0" 137 | } 138 | }, 139 | { 140 | "package": "StORM", 141 | "repositoryURL": "https://github.com/SwiftORM/StORM.git", 142 | "state": { 143 | "branch": null, 144 | "revision": "6b29b65bae2b15c7c32c151141f9b3345ec7c881", 145 | "version": "3.3.0" 146 | } 147 | }, 148 | { 149 | "package": "SwiftMoment", 150 | "repositoryURL": "https://github.com/iamjono/SwiftMoment.git", 151 | "state": { 152 | "branch": null, 153 | "revision": "c2ed4248beb6b3b9c93520dd32be0a92f2fee241", 154 | "version": "1.3.0" 155 | } 156 | } 157 | ] 158 | }, 159 | "version": 1 160 | } 161 | -------------------------------------------------------------------------------- /EasyShare.xcodeproj/project.xcworkspace/xcuserdata/michaellee.xcuserdatad/IDEFindNavigatorScopes.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /EasyShare.xcodeproj/project.xcworkspace/xcuserdata/michaellee.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/EasyShare.xcodeproj/project.xcworkspace/xcuserdata/michaellee.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /EasyShare.xcodeproj/project.xcworkspace/xcuserdata/michaellee.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildLocationStyle 6 | UseAppPreferences 7 | CustomBuildLocationType 8 | RelativeToDerivedData 9 | DerivedDataLocationStyle 10 | Default 11 | IssueFilterStyle 12 | ShowActiveSchemeOnly 13 | LiveSourceIssuesEnabled 14 | 15 | ShowSharedSchemesAutomaticallyEnabled 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /EasyShare.xcodeproj/xcshareddata/xcschemes/EasyShare.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 65 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /EasyShare.xcodeproj/xcshareddata/xcschemes/ShareExtension.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 10 | 16 | 22 | 23 | 24 | 30 | 36 | 37 | 38 | 39 | 40 | 45 | 46 | 47 | 48 | 60 | 64 | 65 | 66 | 72 | 73 | 74 | 75 | 82 | 84 | 90 | 91 | 92 | 93 | 95 | 96 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /EasyShare.xcodeproj/xcuserdata/michaellee.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 21 | 22 | 23 | 25 | 37 | 38 | 39 | 41 | 53 | 54 | 55 | 57 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /EasyShare.xcodeproj/xcuserdata/michaellee.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | EasyShare.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | MyPlayground (Playground) 1.xcscheme 13 | 14 | isShown 15 | 16 | orderHint 17 | 3 18 | 19 | MyPlayground (Playground) 2.xcscheme 20 | 21 | isShown 22 | 23 | orderHint 24 | 4 25 | 26 | MyPlayground (Playground).xcscheme 27 | 28 | isShown 29 | 30 | orderHint 31 | 2 32 | 33 | Server.xcscheme_^#shared#^_ 34 | 35 | orderHint 36 | 2 37 | 38 | ShareExtension.xcscheme_^#shared#^_ 39 | 40 | orderHint 41 | 1 42 | 43 | 44 | SuppressBuildableAutocreation 45 | 46 | 9071415B245DCC61008D5294 47 | 48 | primary 49 | 50 | 51 | 90714170245DCC62008D5294 52 | 53 | primary 54 | 55 | 56 | 9071417B245DCC62008D5294 57 | 58 | primary 59 | 60 | 61 | 90C7A79224605D7300F7369C 62 | 63 | primary 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /EasyShare/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/EasyShare/.DS_Store -------------------------------------------------------------------------------- /EasyShare/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // EasyShare 4 | // 5 | // Created by Michael Lee on 2020/5/2. 6 | // Copyright © 2020 Michael Lee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import SwiftUI 11 | import ShareExtension 12 | 13 | @NSApplicationMain 14 | class AppDelegate: NSObject, NSApplicationDelegate { 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | 18 | Window(windowNibName: "Window").showWindow(nil) 19 | } 20 | 21 | func applicationWillTerminate(_ aNotification: Notification) { 22 | // Insert code here to tear down your application 23 | } 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /EasyShare/Assets.xcassets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/EasyShare/Assets.xcassets/.DS_Store -------------------------------------------------------------------------------- /EasyShare/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "new es logo@0,25x@0,25x@0,25x.png", 5 | "idiom" : "mac", 6 | "scale" : "1x", 7 | "size" : "16x16" 8 | }, 9 | { 10 | "filename" : "new es logo@0,25x@0,25x@0,5x-1.png", 11 | "idiom" : "mac", 12 | "scale" : "2x", 13 | "size" : "16x16" 14 | }, 15 | { 16 | "filename" : "new es logo@0,25x@0,25x@0,5x.png", 17 | "idiom" : "mac", 18 | "scale" : "1x", 19 | "size" : "32x32" 20 | }, 21 | { 22 | "filename" : "new es logo@0,25x@0,25x.png", 23 | "idiom" : "mac", 24 | "scale" : "2x", 25 | "size" : "32x32" 26 | }, 27 | { 28 | "filename" : "new es logo@0,25x@0,5x.png", 29 | "idiom" : "mac", 30 | "scale" : "1x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "filename" : "new es logo@0,25x-1.png", 35 | "idiom" : "mac", 36 | "scale" : "2x", 37 | "size" : "128x128" 38 | }, 39 | { 40 | "filename" : "new es logo@0,25x-2.png", 41 | "idiom" : "mac", 42 | "scale" : "1x", 43 | "size" : "256x256" 44 | }, 45 | { 46 | "filename" : "new es logo@0,5x-2.png", 47 | "idiom" : "mac", 48 | "scale" : "2x", 49 | "size" : "256x256" 50 | }, 51 | { 52 | "filename" : "new es logo@0,5x-3.png", 53 | "idiom" : "mac", 54 | "scale" : "1x", 55 | "size" : "512x512" 56 | }, 57 | { 58 | "filename" : "new es logo.png", 59 | "idiom" : "mac", 60 | "scale" : "2x", 61 | "size" : "512x512" 62 | } 63 | ], 64 | "info" : { 65 | "author" : "xcode", 66 | "version" : 1 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo.png -------------------------------------------------------------------------------- /EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x-1.png -------------------------------------------------------------------------------- /EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x-2.png -------------------------------------------------------------------------------- /EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,25x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,25x.png -------------------------------------------------------------------------------- /EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,25x@0,25x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,25x@0,25x.png -------------------------------------------------------------------------------- /EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,25x@0,5x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,25x@0,5x-1.png -------------------------------------------------------------------------------- /EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,25x@0,5x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,25x@0,5x.png -------------------------------------------------------------------------------- /EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,5x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,5x.png -------------------------------------------------------------------------------- /EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,5x-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,5x-2.png -------------------------------------------------------------------------------- /EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,5x-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,5x-3.png -------------------------------------------------------------------------------- /EasyShare/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /EasyShare/Assets.xcassets/Logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "new es logo@0,25x.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "new es logo@0,5x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "new es logo.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /EasyShare/Assets.xcassets/Logo.imageset/new es logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/EasyShare/Assets.xcassets/Logo.imageset/new es logo.png -------------------------------------------------------------------------------- /EasyShare/Assets.xcassets/Logo.imageset/new es logo@0,25x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/EasyShare/Assets.xcassets/Logo.imageset/new es logo@0,25x.png -------------------------------------------------------------------------------- /EasyShare/Assets.xcassets/Logo.imageset/new es logo@0,5x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/EasyShare/Assets.xcassets/Logo.imageset/new es logo@0,5x.png -------------------------------------------------------------------------------- /EasyShare/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 | -------------------------------------------------------------------------------- /EasyShare/DragView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DragView.swift 3 | // EasyShare 4 | // 5 | // Created by Michael Lee on 2020/5/4. 6 | // Copyright © 2020 Michael Lee. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Cocoa 11 | 12 | protocol FileDragDelegate: class { 13 | func didFinishDrag(_ filePath:String) 14 | } 15 | 16 | class DragView: NSView { 17 | weak var delegate: FileDragDelegate? 18 | 19 | override func awakeFromNib() { 20 | super.awakeFromNib() 21 | self.registerForDraggedTypes([ 22 | NSPasteboard.PasteboardType.fileURL, 23 | NSPasteboard.PasteboardType.fileContents 24 | ]) 25 | } 26 | 27 | override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation { 28 | let sourceDragMask = sender.draggingSourceOperationMask 29 | let pboard = sender.draggingPasteboard 30 | let dragTypes = pboard.types! as NSArray 31 | if dragTypes.contains(NSPasteboard.PasteboardType.fileContents) { 32 | if sourceDragMask.contains([.link]){ 33 | return .link 34 | } 35 | if sourceDragMask.contains([.copy]){ 36 | return .copy 37 | } 38 | } 39 | return .generic 40 | } 41 | 42 | override func performDragOperation(_ sender: NSDraggingInfo) -> Bool { 43 | let files = sender.draggingPasteboard.propertyList(forType: NSPasteboard.PasteboardType.fileContents)! as! Array 44 | print(files[0]) 45 | return true 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /EasyShare/EasyShare.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /EasyShare/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2020 Michael Lee. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | NSSupportsAutomaticTermination 32 | 33 | NSSupportsSuddenTermination 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /EasyShare/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /EasyShare/Window.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Window.swift 3 | // EasyShare 4 | // 5 | // Created by Michael Lee on 2020/5/6. 6 | // Copyright © 2020 Michael Lee. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Cocoa 11 | import SwiftUI 12 | 13 | class Window :NSWindowController{ 14 | override func windowDidLoad() { 15 | super.windowDidLoad() 16 | // self.window?.titleVisibility = NSWindow.TitleVisibility.hidden 17 | // self.window?.titlebarAppearsTransparent = true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /EasyShare/Window.xib: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /EasyShareTests/EasyShareTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EasyShareTests.swift 3 | // EasyShareTests 4 | // 5 | // Created by Michael Lee on 2020/5/2. 6 | // Copyright © 2020 Michael Lee. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import EasyShare 11 | 12 | class EasyShareTests: XCTestCase { 13 | 14 | override func setUpWithError() throws { 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDownWithError() throws { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | } 21 | 22 | func testExample() throws { 23 | // This is an example of a functional test case. 24 | // Use XCTAssert and related functions to verify your tests produce the correct results. 25 | } 26 | 27 | func testPerformanceExample() throws { 28 | // This is an example of a performance test case. 29 | self.measure { 30 | // Put the code you want to measure the time of here. 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /EasyShareTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /EasyShareUITests/EasyShareUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EasyShareUITests.swift 3 | // EasyShareUITests 4 | // 5 | // Created by Michael Lee on 2020/5/2. 6 | // Copyright © 2020 Michael Lee. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class EasyShareUITests: XCTestCase { 12 | 13 | override func setUpWithError() throws { 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | 16 | // In UI tests it is usually best to stop immediately when a failure occurs. 17 | continueAfterFailure = false 18 | 19 | // 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. 20 | } 21 | 22 | override func tearDownWithError() throws { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | } 25 | 26 | func testExample() throws { 27 | // UI tests must launch the application that they test. 28 | let app = XCUIApplication() 29 | app.launch() 30 | 31 | // Use recording to get started writing UI tests. 32 | // Use XCTAssert and related functions to verify your tests produce the correct results. 33 | } 34 | 35 | func testLaunchPerformance() throws { 36 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) { 37 | // This measures how long it takes to launch your application. 38 | measure(metrics: [XCTOSSignpostMetric.applicationLaunch]) { 39 | XCUIApplication().launch() 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /EasyShareUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Extension/Base.lproj/ShareViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 30 | 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 | 78 | 79 | -------------------------------------------------------------------------------- /Extension/Extension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Extension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Extension 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIconFile 12 | icon 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | $(PRODUCT_NAME) 19 | CFBundlePackageType 20 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSExtension 28 | 29 | NSExtensionAttributes 30 | 31 | NSExtensionActivationRule 32 | TRUEPREDICATE 33 | 34 | NSExtensionPointIdentifier 35 | com.apple.share-services 36 | NSExtensionPrincipalClass 37 | $(PRODUCT_MODULE_NAME).ShareViewController 38 | 39 | NSHumanReadableCopyright 40 | Copyright © 2020 Michael Lee. All rights reserved. 41 | 42 | 43 | -------------------------------------------------------------------------------- /Extension/ShareViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ShareViewController.swift 3 | // Extension 4 | // 5 | // Created by Michael Lee on 2020/5/4. 6 | // Copyright © 2020 Michael Lee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ShareViewController: NSViewController { 12 | 13 | override var nibName: NSNib.Name? { 14 | return NSNib.Name("ShareViewController") 15 | } 16 | 17 | override func loadView() { 18 | super.loadView() 19 | 20 | // Insert code here to customize the view 21 | let item = self.extensionContext!.inputItems[0] as! NSExtensionItem 22 | if let attachments = item.attachments { 23 | NSLog("Attachments = %@", attachments as NSArray) 24 | } else { 25 | NSLog("No Attachments") 26 | } 27 | } 28 | 29 | @IBAction func send(_ sender: AnyObject?) { 30 | let outputItem = NSExtensionItem() 31 | // Complete implementation by setting the appropriate value on the output item 32 | 33 | let outputItems = [outputItem] 34 | self.extensionContext!.completeRequest(returningItems: outputItems, completionHandler: nil) 35 | } 36 | 37 | @IBAction func cancel(_ sender: AnyObject?) { 38 | let cancelError = NSError(domain: NSCocoaErrorDomain, code: NSUserCancelledError, userInfo: nil) 39 | self.extensionContext!.cancelRequest(withError: cancelError) 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EasyShare [简体中文](README_zh.md) 2 | Easy Share File From Mac To Every Device 3 | 4 | ![logo.png](logo.png) 5 | 6 | ## Install 7 | 8 | Download the release package and unzip it, copy the EasyShare.app into Applications dir. This app is just some tips. 9 | 10 | Open System Preferences -> Extensions -> Share Menu, and select EasyShare. 11 | 12 | ## Use 13 | 14 | Open the finder, select the file you want to share, right-click, then select share -> EasyShare, you will see a QR code on your screen, like this. 15 | 16 | ![WX20200505-140330@2x.png](WX20200505-140330@2x.png) 17 | 18 | Your devices should be connected to the same Wi-Fi. 19 | 20 | Then, you can copy the URL and open it in your browser to download. But, the most convenient way is to use your smartphone to scan this QR code. 21 | 22 | Do not click the `完成` button before the download is completed, otherwise, the link will be disconnected. 23 | 24 | That's all, everything is so easy! 25 | 26 | ## For Pro Man 27 | 28 | The default HTTP port is 12580, if you want to change it, you can search `EasyShare.sqlite` and change something. 29 | 30 | ## Something New 31 | 32 | I found macOS's `ShareExtension` can used in Safari and other browsers. So you can share web pages by `EasyShare` now. Just click the right-top button in Safari, and select `EasyShare`, you will get a QR code, then you can scan it to visit this web page on your smartphone, like this. 33 | 34 | ![WX20200615-235553@2x.png](WX20200615-235553@2x.png) 35 | 36 | ![WX20200615-235713@2x.png](WX20200615-235713@2x.png) 37 | 38 | But I don't know how to get the web page's title, and Apple provides no document. So, let it be. haha :) 39 | 40 | ## One More Thing 41 | 42 | There is a way to send a file from Android to Mac, [Check here for download `AndDrop`](https://play.google.com/store/apps/details?id=com.neure.anddrop). 43 | 44 | 45 | [](https://ko-fi.com/michaellee123) 46 | -------------------------------------------------------------------------------- /README_zh.md: -------------------------------------------------------------------------------- 1 | # EasyShare 2 | 非常简单的从你的Mac分享文件到任何设备 3 | 4 | ![logo.png](logo.png) 5 | 6 | ## 安装 7 | 8 | 下载release里面的文件,并且解压,把EaseShare.app拖进应用目录。这个app打开之后只有一些提示。 9 | 10 | 打开 系统偏好设置 -> 拓展 -> 共享菜单,并且勾选EasyShare。 11 | 12 | ## 使用 13 | 14 | 打开访达,选中你想要分享的文件,右键并选择共享->EasyShare,你就能得到一个像这样的二维码。 15 | 16 | ![WX20200505-140330@2x.png](WX20200505-140330@2x.png) 17 | 18 | 保证你的设备都处于同一个网络下。 19 | 20 | 现在你可以在另一个设备的浏览器打开这个url进行下载了。当然,更方便的办法是,直接拿出手机扫码进浏览器。不要用微信。 21 | 22 | 在下载完成之前不要点`完成`按钮,否则会断开链接。 23 | 24 | 完事儿,就这么简单。 25 | 26 | ## 一些新东西 27 | 28 | 我发现可以在Safari和其他的浏览器里面使用macOS的`ShareExtension`,所以,现在可以使用`EasyShare`来生成二维码,使用手机扫码就可以访问这个网页了。只需要点击Safari右上角的按钮,在选择`EasyShare`就可以了。像这样。 29 | 30 | ![WX20200615-235553@2x.png](WX20200615-235553@2x.png) 31 | 32 | ![WX20200615-235713@2x.png](WX20200615-235713@2x.png) 33 | 34 | 但是我实在不知道怎么获取网页的标题, 并且苹果也没有提供文档。所以就这样吧。 😂 35 | -------------------------------------------------------------------------------- /ShareExtension/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/ShareExtension/.DS_Store -------------------------------------------------------------------------------- /ShareExtension/Base.lproj/ShareViewController.xib: -------------------------------------------------------------------------------- 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 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /ShareExtension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | EasyShare 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | NSExtensionActivationRule 30 | 31 | NSExtensionActivationSupportsAttachmentsWithMaxCount 32 | 1 33 | NSExtensionActivationSupportsAttachmentsWithMinCount 34 | 0 35 | NSExtensionActivationSupportsFileWithMaxCount 36 | 1 37 | NSExtensionActivationSupportsImageWithMaxCount 38 | 1 39 | NSExtensionActivationSupportsMovieWithMaxCount 40 | 1 41 | NSExtensionActivationSupportsWebPageWithMaxCount 42 | 1 43 | NSExtensionActivationSupportsWebURLWithMaxCount 44 | 1 45 | 46 | 47 | NSExtensionMainNibFile 48 | ShareViewController 49 | NSExtensionPointIdentifier 50 | com.apple.share-services 51 | NSExtensionPrincipalClass 52 | $(PRODUCT_MODULE_NAME).ShareViewController 53 | 54 | NSHumanReadableCopyright 55 | Copyright © 2020 Michael Lee. All rights reserved. 56 | 57 | 58 | -------------------------------------------------------------------------------- /ShareExtension/Resource/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/ShareExtension/Resource/.DS_Store -------------------------------------------------------------------------------- /ShareExtension/Resource/wwwroot/ESlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/ShareExtension/Resource/wwwroot/ESlogo.png -------------------------------------------------------------------------------- /ShareExtension/Resource/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Hello Motherfucker 666

4 |
8 | 9 |
10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /ShareExtension/ShareExtension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.assets.movies.read-only 8 | 9 | com.apple.security.assets.music.read-only 10 | 11 | com.apple.security.assets.pictures.read-only 12 | 13 | com.apple.security.automation.apple-events 14 | 15 | com.apple.security.cs.allow-jit 16 | 17 | com.apple.security.files.downloads.read-only 18 | 19 | com.apple.security.files.user-selected.read-only 20 | 21 | com.apple.security.network.client 22 | 23 | com.apple.security.network.server 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ShareExtension/ShareServer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Server.swift 3 | // EasyShare 4 | // 5 | // Created by Michael Lee on 2020/5/3. 6 | // Copyright © 2020 Michael Lee. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import PerfectHTTP 11 | import PerfectLib 12 | import PerfectHTTPServer 13 | import Cocoa 14 | 15 | class ShareServer{ 16 | 17 | static let instance = ShareServer() 18 | 19 | init() { 20 | addApi() 21 | addWeb() 22 | routes.add(api) 23 | routes.add(web) 24 | } 25 | 26 | var state = 0 27 | 28 | var port :UInt16 = 8899 29 | 30 | let queue = DispatchQueue.global() 31 | 32 | var httpServer = HTTPServer() 33 | 34 | var routes = Routes() 35 | 36 | var api = Routes(baseUri: "/api") 37 | 38 | var web = Routes(baseUri: "/web") 39 | 40 | func start(){ 41 | if state == 1 { 42 | return 43 | } 44 | state = 1 45 | httpServer.serverName = "EasyShare" 46 | httpServer.addRoutes(routes) 47 | do{ 48 | try httpServer.serverPort = UInt16(DbHelper.getConfig(key: ConfigMap.port).value) ?? port 49 | }catch{ 50 | httpServer.serverPort = port 51 | } 52 | port = httpServer.serverPort 53 | 54 | queue.async { 55 | do{ 56 | try self.httpServer.start() 57 | }catch{ 58 | self.state = 0 59 | fatalError("\(error)") 60 | } 61 | } 62 | } 63 | 64 | func stop(){ 65 | httpServer.stop() 66 | state = 0 67 | } 68 | 69 | func addApi() { 70 | /// 获取分享详情 71 | api.add(method: .get, uri: "/info/{key}", handler: {request,response in 72 | let key = request.urlVariables["key"] 73 | let share = ShareDTO() 74 | do { 75 | try share.find([("key",key!)]) 76 | }catch{ 77 | do{ 78 | try response.setBody(json: self.createResponseBody(code: 500, message: "key error", data: nil)) 79 | }catch{ 80 | response.setBody(string: "\(error)") 81 | } 82 | response.completed() 83 | return 84 | } 85 | if(share.id == 0){ 86 | do{ 87 | try response.setBody(json: self.createResponseBody(code: 404, message: "key not found", data: nil)) 88 | }catch{ 89 | response.setBody(string: "\(error)") 90 | } 91 | response.completed() 92 | }else{ 93 | do{ 94 | try response.setBody(json: 95 | self.createResponseBody( 96 | code: 200, 97 | message: "success", 98 | data: share.asDataDict())) 99 | }catch{ 100 | response.setBody(string: "\(error)") 101 | } 102 | response.completed() 103 | } 104 | }) 105 | 106 | api.add(method: .get, uri: "/download/{key}", handler: {request,response in 107 | let share = ShareDTO() 108 | let key = request.urlVariables["key"] 109 | do { 110 | try share.find([("key",key!)]) 111 | }catch{ 112 | do{ 113 | try response.setBody(json: self.createResponseBody(code: 500, message: "key error", data: nil)) 114 | }catch{ 115 | response.setBody(string: "\(error)") 116 | } 117 | response.completed() 118 | return 119 | } 120 | 121 | if(share.id == 0){ 122 | do{ 123 | try response.setBody(json: self.createResponseBody(code: 404, message: "key not found", data: nil)) 124 | }catch{ 125 | response.setBody(string: "\(error)") 126 | } 127 | response.completed() 128 | return 129 | } 130 | //重定向 131 | 132 | //获取文件 133 | let file = File(share.path + "/" + share.name) 134 | if(file.exists && !file.isDir){ 135 | do{ 136 | try file.open() 137 | let size = file.size 138 | let contentType = MimeType.forExtension(file.path.filePathExtension) 139 | response.status = .ok 140 | response.isStreaming = true 141 | response.setHeader(.contentType, value: contentType) 142 | response.setHeader(.contentLength, value: "\(size)") 143 | response.setHeader(.acceptRanges, value: "bytes") 144 | response.setHeader(.contentDisposition, value: "attachment;filename=\"\(share.name)\"") 145 | self.pushBody(response: response, file: file) 146 | // try response.appendBody(bytes: file.readSomeBytes(count: size)) 147 | // let handler = StaticFileHandler(documentRoot: share.path) 148 | // request.path = share.name 149 | // handler.handleRequest(request: request, response: response) 150 | }catch{ 151 | response.setBody(string: "\(error)") 152 | response.completed() 153 | } 154 | }else{ 155 | //文件不存在 156 | do{ 157 | try response.setBody(json: self.createResponseBody(code: 404, message: "file not exists", data: nil)) 158 | } catch { 159 | response.setBody(string: "\(error)") 160 | } 161 | response.completed() 162 | } 163 | }) 164 | 165 | api.add(method: .post, uri: "/upload/{key}"){request,response in 166 | if let uploads = request.postFileUploads, uploads.count > 0 { 167 | for upload in uploads{ 168 | let file = File(upload.tmpFileName) 169 | do{ 170 | try file.moveTo(path: "/Users/michaellee/Desktop/upload/"+upload.fileName,overWrite: true) 171 | } catch { 172 | print("\(error)") 173 | } 174 | } 175 | do { 176 | try response.setBody(json: self.createResponseBody(code: 200, message: "上传成功", data: nil)) 177 | } catch { 178 | response.setBody(string: "\(error)") 179 | } 180 | } 181 | response.completed() 182 | } 183 | 184 | } 185 | 186 | func pushBody(response:HTTPResponse,file:File){ 187 | let readSize = 5 * 1024 * 1024//每次读5m 188 | var bytes :[UInt8] 189 | do { 190 | bytes = try file.readSomeBytes(count: readSize) 191 | }catch{ 192 | bytes = [UInt8]() 193 | } 194 | if(bytes.count==0){ 195 | file.close() 196 | response.completed() 197 | return 198 | } 199 | response.appendBody(bytes: bytes) 200 | response.push(callback: { bool in 201 | if(bool){ 202 | self.pushBody(response: response, file: file) 203 | }else{ 204 | file.close() 205 | response.completed(status: HTTPResponseStatus.gatewayTimeout) 206 | } 207 | }) 208 | } 209 | 210 | func addWeb() { 211 | web.add(method: .get, uri: "/**"){request,response in 212 | request.path = request.urlVariables[routeTrailingWildcardKey]! 213 | //allowResponseFilters=true 才能够访问 214 | let handler = StaticFileHandler(documentRoot: Bundle.main.resourcePath! , allowResponseFilters: true) 215 | handler.handleRequest(request: request, response: response) 216 | } 217 | } 218 | 219 | func createResponseBody(code:Int,message:String,data:Any?) -> [String:Any] { 220 | return ["code":code,"message":message,"data":data ?? [String:Any]()] 221 | } 222 | 223 | } 224 | -------------------------------------------------------------------------------- /ShareExtension/ShareViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ShareViewController.swift 3 | // ShareExtension 4 | // 5 | // Created by Michael Lee on 2020/5/4. 6 | // Copyright © 2020 Michael Lee. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import PerfectLib 11 | import SwiftUI 12 | 13 | class ShareViewController: NSViewController { 14 | 15 | @IBOutlet weak var titleCell: NSTextFieldCell! 16 | @IBOutlet weak var imageCell: NSImageCell! 17 | @IBOutlet weak var urlCell: NSTextFieldCell! 18 | 19 | var id = 0 20 | var url = "" 21 | 22 | override var nibName: NSNib.Name? { 23 | return NSNib.Name("ShareViewController") 24 | } 25 | 26 | override func loadView() { 27 | super.loadView() 28 | } 29 | 30 | override func viewDidLoad() { 31 | super.viewDidLoad() 32 | let item = self.extensionContext!.inputItems[0] as! NSExtensionItem 33 | let provider = item.attachments?[0] 34 | provider?.loadItem(forTypeIdentifier: kUTTypeURL as String, options: nil, completionHandler: {data,error in 35 | let nsData = data as! NSData 36 | let url = NSURL(dataRepresentation: nsData as Data, relativeTo: nil) 37 | let path = url.absoluteString 38 | if(path!.starts(with: "file://")){ 39 | self.shareFile(path: url.path!) 40 | }else if(path!.starts(with: "http://") || path!.starts(with: "https://")){ 41 | self.shareWeb(path: path!) 42 | }else{ 43 | self.extensionContext!.completeRequest(returningItems: [NSExtensionItem()], completionHandler: nil) 44 | } 45 | }) 46 | } 47 | 48 | func shareFile(path:String) { 49 | DbHelper.create() 50 | ShareServer.instance.start() 51 | let file = File(path) 52 | if(file.exists){ 53 | let splits = file.path.split(separator: "/") 54 | let name = splits[splits.count-1] 55 | let share = ShareDTO() 56 | share.name = "\(name)" 57 | share.path = file.path.replacingOccurrences(of: "/\(name)", with: "") 58 | share.key = DataUtils.generateKey(name: share.name) 59 | do{ 60 | try share.save{ id in 61 | share.id = id as! Int 62 | self.id = share.id 63 | } 64 | }catch{ 65 | fatalError("\(error)") 66 | } 67 | self.findAllShare() 68 | self.showWindowInfo( 69 | url: "http://\(self.getIFAddresses()[0]):\(ShareServer.instance.port)/api/download/\(share.key)", 70 | title: share.name 71 | ) 72 | }else{ 73 | self.extensionContext!.completeRequest(returningItems: [NSExtensionItem()], completionHandler: nil) 74 | } 75 | } 76 | 77 | func shareWeb(path:String){ 78 | self.showWindowInfo(url: path, title: "我是真的不知道Title怎么获取😅👌") 79 | } 80 | 81 | func showWindowInfo(url:String,title:String) { 82 | self.url = url 83 | self.urlCell.stringValue = url 84 | self.titleCell.stringValue = title 85 | self.imageCell.image = self.generateQRCodeImage(self.url, size: NSSize(width: 600, height: 600)) 86 | } 87 | 88 | @IBAction func copy(_ sender: NSButton) { 89 | let pasteboard = NSPasteboard.general 90 | pasteboard.declareTypes([NSPasteboard.PasteboardType.string], owner: nil) 91 | let b = pasteboard.setString(url, forType: NSPasteboard.PasteboardType.string) 92 | print(b) 93 | } 94 | 95 | @IBAction func send(_ sender: AnyObject?) { 96 | 97 | ShareServer.instance.stop() 98 | let share = ShareDTO() 99 | do{ 100 | try share.delete(id) 101 | }catch{ 102 | NSLog("\(error)") 103 | } 104 | self.extensionContext!.completeRequest(returningItems: [NSExtensionItem()], completionHandler: nil) 105 | } 106 | 107 | func generateQRCodeImage(_ content: String, size: NSSize) -> NSImage?{ 108 | // 创建滤镜 109 | guard let filter = CIFilter(name: "CIQRCodeGenerator") else {return nil} 110 | // 还原滤镜的默认属性 111 | filter.setDefaults() 112 | //1.3 设置生成的二维码的容错率 113 | //value = @"L/M/Q/H" 114 | filter.setValue("L", forKey: "inputCorrectionLevel") 115 | // 设置需要生成的二维码数据 116 | let contentData = content.data(using: String.Encoding.utf8) 117 | filter.setValue(contentData, forKey: "inputMessage") 118 | 119 | 120 | // 从滤镜中取出生成的图片 121 | guard let ciImage = filter.outputImage else {return nil} 122 | 123 | let context = CIContext(options: nil) 124 | let bitmapImage = context.createCGImage(ciImage, from: ciImage.extent) 125 | 126 | let colorSpace = CGColorSpaceCreateDeviceGray() 127 | let bitmapContext = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: 8, bytesPerRow: 0, space: colorSpace, bitmapInfo: CGImageAlphaInfo.none.rawValue) 128 | 129 | //draw image 130 | let scale = min(size.width / ciImage.extent.width, size.height / ciImage.extent.height) 131 | bitmapContext!.interpolationQuality = CGInterpolationQuality.none 132 | bitmapContext?.scaleBy(x: scale, y: scale) 133 | bitmapContext?.draw(bitmapImage!, in: ciImage.extent) 134 | 135 | //保存bitmap到图片 136 | guard let scaledImage = bitmapContext?.makeImage() else {return nil} 137 | 138 | return NSImage(cgImage: scaledImage, size: size) 139 | } 140 | 141 | func getIFAddresses() -> [String] { 142 | var addresses = [String]() 143 | 144 | // Get list of all interfaces on the local machine: 145 | var ifaddr : UnsafeMutablePointer? = nil 146 | if getifaddrs(&ifaddr) == 0 { 147 | 148 | var ptr = ifaddr 149 | while ptr != nil { 150 | let flags = Int32((ptr?.pointee.ifa_flags)!) 151 | var addr = ptr?.pointee.ifa_addr.pointee 152 | 153 | // Check for running IPv4, IPv6 interfaces. Skip the loopback interface. 154 | if (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING) { 155 | if addr?.sa_family == UInt8(AF_INET) && addr?.sa_family != UInt8(AF_INET6) { 156 | 157 | // Convert interface address to a human readable string: 158 | var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST)) 159 | if (getnameinfo(&addr!, socklen_t((addr?.sa_len)!), &hostname, socklen_t(hostname.count), 160 | nil, socklen_t(0), NI_NUMERICHOST) == 0) { 161 | if let address = String(validatingUTF8: hostname) { 162 | addresses.append(address) 163 | } 164 | } 165 | } 166 | } 167 | ptr = ptr?.pointee.ifa_next 168 | } 169 | 170 | freeifaddrs(ifaddr) 171 | } 172 | print("Local IP \(addresses)") 173 | return addresses 174 | } 175 | 176 | func findAllShare(){ 177 | let share = ShareDTO() 178 | do{ 179 | try share.findAll() 180 | let rows = share.rows() 181 | for row in rows{ 182 | print(row.asDataDict()) 183 | } 184 | }catch{ 185 | fatalError("\(error)") 186 | } 187 | } 188 | 189 | } 190 | -------------------------------------------------------------------------------- /ShareExtension/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/ShareExtension/icon.icns -------------------------------------------------------------------------------- /ShareExtension/model/ConfigMap.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConfigMap.swift 3 | // EasyShare 4 | // 5 | // Created by Michael Lee on 2020/5/4. 6 | // Copyright © 2020 Michael Lee. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class ConfigMap{ 12 | /// 端口号 13 | static let port = "port" 14 | } 15 | -------------------------------------------------------------------------------- /ShareExtension/model/db/DbHelper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DbHelper.swift 3 | // EasyShare 4 | // 5 | // Created by Michael Lee on 2020/5/3. 6 | // Copyright © 2020 Michael Lee. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import SQLiteStORM 11 | 12 | class DbHelper{ 13 | static func create() { 14 | SQLiteConnector.db = "./EasyShare.sqlite" 15 | do { 16 | try ConfigDTO().setup() 17 | //设置端口号 18 | let portConfig = ConfigDTO() 19 | portConfig.key = ConfigMap.port 20 | portConfig.value = "12580" 21 | portConfig.remark = "端口号" 22 | try createConfig(config: portConfig) 23 | }catch{ 24 | fatalError("\(error)") 25 | } 26 | do{ 27 | try ShareDTO().setup() 28 | }catch{ 29 | fatalError("\(error)") 30 | } 31 | } 32 | 33 | /// 读取配置 34 | static func getConfig(key:String) throws ->ConfigDTO{ 35 | let config = ConfigDTO() 36 | try config.get(key) 37 | return config 38 | } 39 | 40 | /// 创建配置,如果已经有了就不会再写入了 41 | static func createConfig(config:ConfigDTO) throws { 42 | let createConfig = ConfigDTO() 43 | createConfig.key = config.key 44 | try createConfig.get() 45 | if (createConfig.value.count == 0) { 46 | try config.create() 47 | } 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /ShareExtension/model/db/dto/ConfigDTO.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConfigDTO.swift 3 | // EasyShare 4 | // 5 | // Created by Michael Lee on 2020/5/3. 6 | // Copyright © 2020 Michael Lee. All rights reserved. 7 | // 8 | 9 | import SQLiteStORM 10 | import StORM 11 | 12 | 13 | /// 配置表,key是主键,根据实际需求存储 14 | class ConfigDTO :SQLiteStORM{ 15 | var key:String = "" 16 | var value:String = "" 17 | ///备注 18 | var remark:String = "" 19 | override open func table() -> String { 20 | return "tb_config" 21 | } 22 | 23 | override open func to(_ this: StORMRow) { 24 | key = this.data["key"] as! String 25 | value = this.data["value"] as! String 26 | remark = this.data["remark"] as! String 27 | } 28 | 29 | func rows() -> [ConfigDTO] { 30 | var rows = [ConfigDTO]() 31 | for i in 0.. String { 27 | return "tb_share" 28 | } 29 | 30 | override func to(_ this: StORMRow) { 31 | id = this.data["id"] as! Int 32 | name = this.data["name"] as! String 33 | key = this.data["key"] as! String 34 | path = this.data["path"] as! String 35 | createTime = Int64(this.data["createTime"] as! String)! 36 | } 37 | 38 | func rows() -> [ShareDTO] { 39 | var rows = [ShareDTO]() 40 | for i in 0.. String{ 15 | let md5 = "\(NSDate().timeIntervalSince1970)\(name)".digest(.md5)?.encode(.base64url) 16 | return String(validatingUTF8: md5!) ?? "\(NSDate().timeIntervalSince1970)\(name)" 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /WX20200505-140330@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/WX20200505-140330@2x.png -------------------------------------------------------------------------------- /WX20200615-235553@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/WX20200615-235553@2x.png -------------------------------------------------------------------------------- /WX20200615-235713@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/WX20200615-235713@2x.png -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellee123/EasyShare/a6f6806bf884f3c9f3ef7c2a78cc9fff27cd62f7/logo.png --------------------------------------------------------------------------------