├── .gitignore ├── LICENSE ├── PicU.entitlements ├── PicU.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── PicU.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── Podfile ├── Podfile.lock ├── README.md ├── UPImage ├── AppCache.swift ├── AppConfig.swift ├── AppDelegate.swift ├── AppHelper.swift ├── Assets.xcassets │ ├── 90343Slice 1.imageset │ │ ├── 90343Slice 1.png │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon_128x128.png │ │ ├── Icon_128x128@2x.png │ │ ├── Icon_16x16.png │ │ ├── Icon_16x16@2x.png │ │ ├── Icon_256x256.png │ │ ├── Icon_256x256@2x.png │ │ ├── Icon_32x32.png │ │ ├── Icon_32x32@2x.png │ │ ├── Icon_512x512.png │ │ └── Icon_512x512@2x.png │ ├── Contents.json │ ├── Failure.imageset │ │ ├── Contents.json │ │ ├── Failure.png │ │ ├── Failure@2x.png │ │ └── Failure@3x.png │ ├── Icon_128x128.imageset │ │ ├── Contents.json │ │ ├── Icon_128x128.png │ │ ├── Icon_128x128@2x.png │ │ └── Icon_128x128@3x.png │ ├── Icon_32x32.imageset │ │ ├── Contents.json │ │ ├── Icon_32x32.png │ │ ├── Icon_32x32@2x.png │ │ └── Icon_32x32@3x.png │ ├── StatusIcon.imageset │ │ ├── Combined Shape.png │ │ ├── Combined Shape@2x.png │ │ ├── Combined Shape@3x.png │ │ └── Contents.json │ ├── loading │ │ ├── Contents.json │ │ ├── loading-0.imageset │ │ │ ├── Contents.json │ │ │ ├── loading-0.png │ │ │ └── loading-0@2x.png │ │ ├── loading-1.imageset │ │ │ ├── Contents.json │ │ │ ├── loading-2.png │ │ │ └── loading-2@2x.png │ │ ├── loading-10.imageset │ │ │ ├── Contents.json │ │ │ ├── loading-10.png │ │ │ └── loading-10@2x.png │ │ ├── loading-2.imageset │ │ │ ├── Contents.json │ │ │ ├── loading-1.png │ │ │ └── loading-1@2x.png │ │ ├── loading-3.imageset │ │ │ ├── Contents.json │ │ │ ├── loading-3.png │ │ │ └── loading-3@2x.png │ │ ├── loading-4.imageset │ │ │ ├── Contents.json │ │ │ ├── loading-4.png │ │ │ └── loading-4@2x.png │ │ ├── loading-5.imageset │ │ │ ├── Contents.json │ │ │ ├── loading-5.png │ │ │ └── loading-5@2x.png │ │ ├── loading-6.imageset │ │ │ ├── Contents.json │ │ │ ├── loading-6.png │ │ │ └── loading-6@2x.png │ │ ├── loading-7.imageset │ │ │ ├── Contents.json │ │ │ ├── loading-7.png │ │ │ └── loading-7@2x.png │ │ ├── loading-8.imageset │ │ │ ├── Contents.json │ │ │ ├── loading-8.png │ │ │ └── loading-8@2x.png │ │ └── loading-9.imageset │ │ │ ├── Contents.json │ │ │ ├── loading-9.png │ │ │ └── loading-9@2x.png │ ├── success.imageset │ │ ├── Contents.json │ │ ├── success.png │ │ ├── success@2x.png │ │ └── success@3x.png │ └── upload.imageset │ │ ├── Contents.json │ │ ├── Slice 1.png │ │ └── Slice 1@2x.png ├── DragDestinationView.swift ├── GeneralViewController.swift ├── GeneralViewController.xib ├── ImagePreferencesViewController.swift ├── ImagePreferencesViewController.xib ├── ImageService.swift ├── Info.plist ├── MainMenu.xib ├── OC-birdge.h ├── PasteboardObserver.swift ├── QNConfig.swift ├── QNService.swift └── SMMSService.swift ├── icon.sketch ├── pic └── 2017022646287Icon_128x128@2x.png └── 商店图片.sketch /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | #vscode 31 | 32 | .vscode/ 33 | 34 | # CocoaPods 35 | # 36 | # We recommend against adding the Pods directory to your .gitignore. However 37 | # you should judge for yourself, the pros and cons are mentioned at: 38 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 39 | # 40 | Pods/ 41 | 42 | 43 | # Carthage 44 | # 45 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 46 | # Carthage/Checkouts 47 | 48 | Carthage/Build 49 | 50 | # fastlane 51 | # 52 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 53 | # screenshots whenever they are needed. 54 | # For more information about the recommended setup visit: 55 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 56 | 57 | fastlane/report.xml 58 | fastlane/screenshots 59 | 60 | #Code Injection 61 | # 62 | # After new code Injection tools there's a generated folder /iOSInjectionProject 63 | # https://github.com/johnno1962/injectionforxcode 64 | 65 | iOSInjectionProject/ 66 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 chenxt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PicU.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.network.client 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /PicU.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B44A47A2256D8DA0B03F8237 /* Pods_PicU.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E05A0A741EE20D2780C8F6A /* Pods_PicU.framework */; }; 11 | DD0386E71E123C3E00864E9C /* AppCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0386E61E123C3E00864E9C /* AppCache.swift */; }; 12 | DD369FDB1D3CA0310080C369 /* GeneralViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD369FD91D3CA0310080C369 /* GeneralViewController.swift */; }; 13 | DD369FDC1D3CA0310080C369 /* GeneralViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = DD369FDA1D3CA0310080C369 /* GeneralViewController.xib */; }; 14 | DD373A601E4A0AD0002CC39F /* QNConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD373A5F1E4A0AD0002CC39F /* QNConfig.swift */; }; 15 | DD373A621E4A13ED002CC39F /* AppConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD373A611E4A13ED002CC39F /* AppConfig.swift */; }; 16 | DD4DB49C1D35EDF600FCD47C /* AppHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD4DB49B1D35EDF600FCD47C /* AppHelper.swift */; }; 17 | DD7B7E601D322CC700B68805 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD7B7E5F1D322CC700B68805 /* AppDelegate.swift */; }; 18 | DD7B7E621D322CC700B68805 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DD7B7E611D322CC700B68805 /* Assets.xcassets */; }; 19 | DD7B7E741D322CEE00B68805 /* DragDestinationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD7B7E711D322CEE00B68805 /* DragDestinationView.swift */; }; 20 | DD7B7E781D322D2200B68805 /* ImagePreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD7B7E761D322D2200B68805 /* ImagePreferencesViewController.swift */; }; 21 | DD7B7E791D322D2200B68805 /* ImagePreferencesViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = DD7B7E771D322D2200B68805 /* ImagePreferencesViewController.xib */; }; 22 | DD7B7E7B1D322D7200B68805 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = DD7B7E7A1D322D7200B68805 /* MainMenu.xib */; }; 23 | DD9DCE061E632F63001C0BE5 /* SMMSService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD9DCE051E632F63001C0BE5 /* SMMSService.swift */; }; 24 | DDB6C2311E120378009B7EDD /* QNService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB6C2301E120378009B7EDD /* QNService.swift */; }; 25 | DDC266071E5419B30061F5DA /* ImageService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC266061E5419B30061F5DA /* ImageService.swift */; }; 26 | DDE7BB1F1D3F4295009031F3 /* PasteboardObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE7BB1E1D3F4295009031F3 /* PasteboardObserver.swift */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | 3E05A0A741EE20D2780C8F6A /* Pods_PicU.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PicU.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | 88A8CB4247904D1AAE55DF35 /* Pods-PicU.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PicU.release.xcconfig"; path = "Pods/Target Support Files/Pods-PicU/Pods-PicU.release.xcconfig"; sourceTree = ""; }; 32 | CE95451D6911349713F6C020 /* Pods-PicU.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PicU.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PicU/Pods-PicU.debug.xcconfig"; sourceTree = ""; }; 33 | DD0386E61E123C3E00864E9C /* AppCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppCache.swift; sourceTree = ""; }; 34 | DD369FD91D3CA0310080C369 /* GeneralViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneralViewController.swift; sourceTree = ""; }; 35 | DD369FDA1D3CA0310080C369 /* GeneralViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GeneralViewController.xib; sourceTree = ""; }; 36 | DD373A5F1E4A0AD0002CC39F /* QNConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QNConfig.swift; sourceTree = ""; }; 37 | DD373A611E4A13ED002CC39F /* AppConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppConfig.swift; sourceTree = ""; }; 38 | DD4DB49B1D35EDF600FCD47C /* AppHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppHelper.swift; sourceTree = ""; }; 39 | DD7B7E5C1D322CC700B68805 /* PicU.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PicU.app; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | DD7B7E5F1D322CC700B68805 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 41 | DD7B7E611D322CC700B68805 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 42 | DD7B7E661D322CC700B68805 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 43 | DD7B7E711D322CEE00B68805 /* DragDestinationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DragDestinationView.swift; sourceTree = ""; }; 44 | DD7B7E761D322D2200B68805 /* ImagePreferencesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImagePreferencesViewController.swift; sourceTree = ""; }; 45 | DD7B7E771D322D2200B68805 /* ImagePreferencesViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ImagePreferencesViewController.xib; sourceTree = ""; }; 46 | DD7B7E7A1D322D7200B68805 /* MainMenu.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = ""; }; 47 | DD9DCE051E632F63001C0BE5 /* SMMSService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SMMSService.swift; sourceTree = ""; }; 48 | DDB6C2301E120378009B7EDD /* QNService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QNService.swift; sourceTree = ""; }; 49 | DDC182E91D5C1A6600D40AA3 /* OC-birdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OC-birdge.h"; sourceTree = ""; }; 50 | DDC266061E5419B30061F5DA /* ImageService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageService.swift; sourceTree = ""; }; 51 | DDD7F02D1E6D433700B685D8 /* PicU.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PicU.entitlements; sourceTree = ""; }; 52 | DDE7BB1E1D3F4295009031F3 /* PasteboardObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasteboardObserver.swift; sourceTree = ""; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | DD7B7E591D322CC700B68805 /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | B44A47A2256D8DA0B03F8237 /* Pods_PicU.framework in Frameworks */, 61 | ); 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXFrameworksBuildPhase section */ 65 | 66 | /* Begin PBXGroup section */ 67 | 8678AFDE00AA4AA14BB417A0 /* Pods */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | CE95451D6911349713F6C020 /* Pods-PicU.debug.xcconfig */, 71 | 88A8CB4247904D1AAE55DF35 /* Pods-PicU.release.xcconfig */, 72 | ); 73 | name = Pods; 74 | sourceTree = ""; 75 | }; 76 | DD7B7E531D322CC700B68805 = { 77 | isa = PBXGroup; 78 | children = ( 79 | DDD7F02D1E6D433700B685D8 /* PicU.entitlements */, 80 | DD7B7E5E1D322CC700B68805 /* UPImage */, 81 | DD7B7E5D1D322CC700B68805 /* Products */, 82 | 8678AFDE00AA4AA14BB417A0 /* Pods */, 83 | F5DF376CCCFA2E6993D6955B /* Frameworks */, 84 | ); 85 | sourceTree = ""; 86 | }; 87 | DD7B7E5D1D322CC700B68805 /* Products */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | DD7B7E5C1D322CC700B68805 /* PicU.app */, 91 | ); 92 | name = Products; 93 | sourceTree = ""; 94 | }; 95 | DD7B7E5E1D322CC700B68805 /* UPImage */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | DD369FD91D3CA0310080C369 /* GeneralViewController.swift */, 99 | DD369FDA1D3CA0310080C369 /* GeneralViewController.xib */, 100 | DD7B7E761D322D2200B68805 /* ImagePreferencesViewController.swift */, 101 | DD7B7E771D322D2200B68805 /* ImagePreferencesViewController.xib */, 102 | DD7B7E711D322CEE00B68805 /* DragDestinationView.swift */, 103 | DD7B7E5F1D322CC700B68805 /* AppDelegate.swift */, 104 | DD7B7E7A1D322D7200B68805 /* MainMenu.xib */, 105 | DD7B7E611D322CC700B68805 /* Assets.xcassets */, 106 | DD7B7E661D322CC700B68805 /* Info.plist */, 107 | DD4DB49B1D35EDF600FCD47C /* AppHelper.swift */, 108 | DDE7BB1E1D3F4295009031F3 /* PasteboardObserver.swift */, 109 | DDC182E91D5C1A6600D40AA3 /* OC-birdge.h */, 110 | DD9DCE051E632F63001C0BE5 /* SMMSService.swift */, 111 | DDB6C2301E120378009B7EDD /* QNService.swift */, 112 | DD0386E61E123C3E00864E9C /* AppCache.swift */, 113 | DD373A5F1E4A0AD0002CC39F /* QNConfig.swift */, 114 | DD373A611E4A13ED002CC39F /* AppConfig.swift */, 115 | DDC266061E5419B30061F5DA /* ImageService.swift */, 116 | ); 117 | path = UPImage; 118 | sourceTree = ""; 119 | }; 120 | F5DF376CCCFA2E6993D6955B /* Frameworks */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | 3E05A0A741EE20D2780C8F6A /* Pods_PicU.framework */, 124 | ); 125 | name = Frameworks; 126 | sourceTree = ""; 127 | }; 128 | /* End PBXGroup section */ 129 | 130 | /* Begin PBXNativeTarget section */ 131 | DD7B7E5B1D322CC700B68805 /* PicU */ = { 132 | isa = PBXNativeTarget; 133 | buildConfigurationList = DD7B7E691D322CC700B68805 /* Build configuration list for PBXNativeTarget "PicU" */; 134 | buildPhases = ( 135 | 6A8B62D9AF77E000A69C2630 /* [CP] Check Pods Manifest.lock */, 136 | DD7B7E581D322CC700B68805 /* Sources */, 137 | DD7B7E591D322CC700B68805 /* Frameworks */, 138 | DD7B7E5A1D322CC700B68805 /* Resources */, 139 | 50EC8073D39A9D4A030E7A35 /* [CP] Embed Pods Frameworks */, 140 | ); 141 | buildRules = ( 142 | ); 143 | dependencies = ( 144 | ); 145 | name = PicU; 146 | productName = UPImage; 147 | productReference = DD7B7E5C1D322CC700B68805 /* PicU.app */; 148 | productType = "com.apple.product-type.application"; 149 | }; 150 | /* End PBXNativeTarget section */ 151 | 152 | /* Begin PBXProject section */ 153 | DD7B7E541D322CC700B68805 /* Project object */ = { 154 | isa = PBXProject; 155 | attributes = { 156 | LastSwiftUpdateCheck = 0730; 157 | LastUpgradeCheck = 0730; 158 | ORGANIZATIONNAME = chenxt; 159 | TargetAttributes = { 160 | DD7B7E5B1D322CC700B68805 = { 161 | CreatedOnToolsVersion = 7.3.1; 162 | DevelopmentTeam = 44QSUE25K9; 163 | LastSwiftMigration = 0810; 164 | ProvisioningStyle = Automatic; 165 | SystemCapabilities = { 166 | com.apple.Push = { 167 | enabled = 0; 168 | }; 169 | com.apple.Sandbox = { 170 | enabled = 1; 171 | }; 172 | com.apple.iCloud = { 173 | enabled = 0; 174 | }; 175 | }; 176 | }; 177 | }; 178 | }; 179 | buildConfigurationList = DD7B7E571D322CC700B68805 /* Build configuration list for PBXProject "PicU" */; 180 | compatibilityVersion = "Xcode 3.2"; 181 | developmentRegion = English; 182 | hasScannedForEncodings = 0; 183 | knownRegions = ( 184 | English, 185 | en, 186 | Base, 187 | ); 188 | mainGroup = DD7B7E531D322CC700B68805; 189 | productRefGroup = DD7B7E5D1D322CC700B68805 /* Products */; 190 | projectDirPath = ""; 191 | projectRoot = ""; 192 | targets = ( 193 | DD7B7E5B1D322CC700B68805 /* PicU */, 194 | ); 195 | }; 196 | /* End PBXProject section */ 197 | 198 | /* Begin PBXResourcesBuildPhase section */ 199 | DD7B7E5A1D322CC700B68805 /* Resources */ = { 200 | isa = PBXResourcesBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | DD7B7E621D322CC700B68805 /* Assets.xcassets in Resources */, 204 | DD7B7E791D322D2200B68805 /* ImagePreferencesViewController.xib in Resources */, 205 | DD7B7E7B1D322D7200B68805 /* MainMenu.xib in Resources */, 206 | DD369FDC1D3CA0310080C369 /* GeneralViewController.xib in Resources */, 207 | ); 208 | runOnlyForDeploymentPostprocessing = 0; 209 | }; 210 | /* End PBXResourcesBuildPhase section */ 211 | 212 | /* Begin PBXShellScriptBuildPhase section */ 213 | 50EC8073D39A9D4A030E7A35 /* [CP] Embed Pods Frameworks */ = { 214 | isa = PBXShellScriptBuildPhase; 215 | buildActionMask = 2147483647; 216 | files = ( 217 | ); 218 | inputPaths = ( 219 | "${PODS_ROOT}/Target Support Files/Pods-PicU/Pods-PicU-frameworks.sh", 220 | "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework", 221 | "${BUILT_PRODUCTS_DIR}/HappyDNS/HappyDNS.framework", 222 | "${BUILT_PRODUCTS_DIR}/MASPreferences/MASPreferences.framework", 223 | "${BUILT_PRODUCTS_DIR}/Qiniu/Qiniu.framework", 224 | "${BUILT_PRODUCTS_DIR}/TMCache/TMCache.framework", 225 | ); 226 | name = "[CP] Embed Pods Frameworks"; 227 | outputPaths = ( 228 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework", 229 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/HappyDNS.framework", 230 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MASPreferences.framework", 231 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Qiniu.framework", 232 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TMCache.framework", 233 | ); 234 | runOnlyForDeploymentPostprocessing = 0; 235 | shellPath = /bin/sh; 236 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PicU/Pods-PicU-frameworks.sh\"\n"; 237 | showEnvVarsInLog = 0; 238 | }; 239 | 6A8B62D9AF77E000A69C2630 /* [CP] Check Pods Manifest.lock */ = { 240 | isa = PBXShellScriptBuildPhase; 241 | buildActionMask = 2147483647; 242 | files = ( 243 | ); 244 | inputPaths = ( 245 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 246 | "${PODS_ROOT}/Manifest.lock", 247 | ); 248 | name = "[CP] Check Pods Manifest.lock"; 249 | outputPaths = ( 250 | "$(DERIVED_FILE_DIR)/Pods-PicU-checkManifestLockResult.txt", 251 | ); 252 | runOnlyForDeploymentPostprocessing = 0; 253 | shellPath = /bin/sh; 254 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 255 | showEnvVarsInLog = 0; 256 | }; 257 | /* End PBXShellScriptBuildPhase section */ 258 | 259 | /* Begin PBXSourcesBuildPhase section */ 260 | DD7B7E581D322CC700B68805 /* Sources */ = { 261 | isa = PBXSourcesBuildPhase; 262 | buildActionMask = 2147483647; 263 | files = ( 264 | DD7B7E601D322CC700B68805 /* AppDelegate.swift in Sources */, 265 | DD373A621E4A13ED002CC39F /* AppConfig.swift in Sources */, 266 | DD369FDB1D3CA0310080C369 /* GeneralViewController.swift in Sources */, 267 | DDB6C2311E120378009B7EDD /* QNService.swift in Sources */, 268 | DD7B7E741D322CEE00B68805 /* DragDestinationView.swift in Sources */, 269 | DD9DCE061E632F63001C0BE5 /* SMMSService.swift in Sources */, 270 | DD373A601E4A0AD0002CC39F /* QNConfig.swift in Sources */, 271 | DD4DB49C1D35EDF600FCD47C /* AppHelper.swift in Sources */, 272 | DD7B7E781D322D2200B68805 /* ImagePreferencesViewController.swift in Sources */, 273 | DDC266071E5419B30061F5DA /* ImageService.swift in Sources */, 274 | DDE7BB1F1D3F4295009031F3 /* PasteboardObserver.swift in Sources */, 275 | DD0386E71E123C3E00864E9C /* AppCache.swift in Sources */, 276 | ); 277 | runOnlyForDeploymentPostprocessing = 0; 278 | }; 279 | /* End PBXSourcesBuildPhase section */ 280 | 281 | /* Begin XCBuildConfiguration section */ 282 | DD7B7E671D322CC700B68805 /* Debug */ = { 283 | isa = XCBuildConfiguration; 284 | buildSettings = { 285 | ALWAYS_SEARCH_USER_PATHS = NO; 286 | CLANG_ANALYZER_NONNULL = YES; 287 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 288 | CLANG_CXX_LIBRARY = "libc++"; 289 | CLANG_ENABLE_MODULES = YES; 290 | CLANG_ENABLE_OBJC_ARC = YES; 291 | CLANG_WARN_BOOL_CONVERSION = YES; 292 | CLANG_WARN_CONSTANT_CONVERSION = YES; 293 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 294 | CLANG_WARN_EMPTY_BODY = YES; 295 | CLANG_WARN_ENUM_CONVERSION = YES; 296 | CLANG_WARN_INT_CONVERSION = YES; 297 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 298 | CLANG_WARN_UNREACHABLE_CODE = YES; 299 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 300 | CODE_SIGN_IDENTITY = "-"; 301 | COPY_PHASE_STRIP = NO; 302 | DEBUG_INFORMATION_FORMAT = dwarf; 303 | ENABLE_STRICT_OBJC_MSGSEND = YES; 304 | ENABLE_TESTABILITY = YES; 305 | GCC_C_LANGUAGE_STANDARD = gnu99; 306 | GCC_DYNAMIC_NO_PIC = NO; 307 | GCC_NO_COMMON_BLOCKS = YES; 308 | GCC_OPTIMIZATION_LEVEL = 0; 309 | GCC_PREPROCESSOR_DEFINITIONS = ( 310 | "DEBUG=1", 311 | "$(inherited)", 312 | ); 313 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 314 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 315 | GCC_WARN_UNDECLARED_SELECTOR = YES; 316 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 317 | GCC_WARN_UNUSED_FUNCTION = YES; 318 | GCC_WARN_UNUSED_VARIABLE = YES; 319 | MACOSX_DEPLOYMENT_TARGET = 10.11; 320 | MTL_ENABLE_DEBUG_INFO = YES; 321 | ONLY_ACTIVE_ARCH = YES; 322 | SDKROOT = macosx; 323 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 324 | }; 325 | name = Debug; 326 | }; 327 | DD7B7E681D322CC700B68805 /* Release */ = { 328 | isa = XCBuildConfiguration; 329 | buildSettings = { 330 | ALWAYS_SEARCH_USER_PATHS = NO; 331 | CLANG_ANALYZER_NONNULL = YES; 332 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 333 | CLANG_CXX_LIBRARY = "libc++"; 334 | CLANG_ENABLE_MODULES = YES; 335 | CLANG_ENABLE_OBJC_ARC = YES; 336 | CLANG_WARN_BOOL_CONVERSION = YES; 337 | CLANG_WARN_CONSTANT_CONVERSION = YES; 338 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 339 | CLANG_WARN_EMPTY_BODY = YES; 340 | CLANG_WARN_ENUM_CONVERSION = YES; 341 | CLANG_WARN_INT_CONVERSION = YES; 342 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 343 | CLANG_WARN_UNREACHABLE_CODE = YES; 344 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 345 | CODE_SIGN_IDENTITY = "-"; 346 | COPY_PHASE_STRIP = NO; 347 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 348 | ENABLE_NS_ASSERTIONS = NO; 349 | ENABLE_STRICT_OBJC_MSGSEND = YES; 350 | GCC_C_LANGUAGE_STANDARD = gnu99; 351 | GCC_NO_COMMON_BLOCKS = YES; 352 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 353 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 354 | GCC_WARN_UNDECLARED_SELECTOR = YES; 355 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 356 | GCC_WARN_UNUSED_FUNCTION = YES; 357 | GCC_WARN_UNUSED_VARIABLE = YES; 358 | MACOSX_DEPLOYMENT_TARGET = 10.11; 359 | MTL_ENABLE_DEBUG_INFO = NO; 360 | SDKROOT = macosx; 361 | }; 362 | name = Release; 363 | }; 364 | DD7B7E6A1D322CC700B68805 /* Debug */ = { 365 | isa = XCBuildConfiguration; 366 | baseConfigurationReference = CE95451D6911349713F6C020 /* Pods-PicU.debug.xcconfig */; 367 | buildSettings = { 368 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 369 | CODE_SIGN_ENTITLEMENTS = PicU.entitlements; 370 | CODE_SIGN_IDENTITY = "Mac Developer"; 371 | "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Mac Developer"; 372 | COMBINE_HIDPI_IMAGES = YES; 373 | CURRENT_PROJECT_VERSION = 1; 374 | DEVELOPMENT_TEAM = 44QSUE25K9; 375 | INFOPLIST_FILE = UPImage/Info.plist; 376 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 377 | MACOSX_DEPLOYMENT_TARGET = 10.13; 378 | MARKETING_VERSION = 1.6; 379 | OTHER_CODE_SIGN_FLAGS = "--deep"; 380 | OTHER_SWIFT_FLAGS = "$(inherited) -D DEBUG"; 381 | PRODUCT_BUNDLE_IDENTIFIER = com.chenxtdo.upi; 382 | PRODUCT_NAME = PicU; 383 | PROVISIONING_PROFILE = ""; 384 | PROVISIONING_PROFILE_SPECIFIER = ""; 385 | SWIFT_OBJC_BRIDGING_HEADER = "UPImage/OC-birdge.h"; 386 | SWIFT_VERSION = 5.0; 387 | }; 388 | name = Debug; 389 | }; 390 | DD7B7E6B1D322CC700B68805 /* Release */ = { 391 | isa = XCBuildConfiguration; 392 | baseConfigurationReference = 88A8CB4247904D1AAE55DF35 /* Pods-PicU.release.xcconfig */; 393 | buildSettings = { 394 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 395 | CODE_SIGN_ENTITLEMENTS = PicU.entitlements; 396 | CODE_SIGN_IDENTITY = "Mac Developer"; 397 | "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Mac Developer"; 398 | COMBINE_HIDPI_IMAGES = YES; 399 | CURRENT_PROJECT_VERSION = 1; 400 | DEVELOPMENT_TEAM = 44QSUE25K9; 401 | INFOPLIST_FILE = UPImage/Info.plist; 402 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 403 | MACOSX_DEPLOYMENT_TARGET = 10.13; 404 | MARKETING_VERSION = 1.6; 405 | OTHER_CODE_SIGN_FLAGS = "--deep"; 406 | PRODUCT_BUNDLE_IDENTIFIER = com.chenxtdo.upi; 407 | PRODUCT_NAME = PicU; 408 | PROVISIONING_PROFILE = ""; 409 | PROVISIONING_PROFILE_SPECIFIER = ""; 410 | SWIFT_OBJC_BRIDGING_HEADER = "UPImage/OC-birdge.h"; 411 | SWIFT_VERSION = 5.0; 412 | }; 413 | name = Release; 414 | }; 415 | /* End XCBuildConfiguration section */ 416 | 417 | /* Begin XCConfigurationList section */ 418 | DD7B7E571D322CC700B68805 /* Build configuration list for PBXProject "PicU" */ = { 419 | isa = XCConfigurationList; 420 | buildConfigurations = ( 421 | DD7B7E671D322CC700B68805 /* Debug */, 422 | DD7B7E681D322CC700B68805 /* Release */, 423 | ); 424 | defaultConfigurationIsVisible = 0; 425 | defaultConfigurationName = Release; 426 | }; 427 | DD7B7E691D322CC700B68805 /* Build configuration list for PBXNativeTarget "PicU" */ = { 428 | isa = XCConfigurationList; 429 | buildConfigurations = ( 430 | DD7B7E6A1D322CC700B68805 /* Debug */, 431 | DD7B7E6B1D322CC700B68805 /* Release */, 432 | ); 433 | defaultConfigurationIsVisible = 0; 434 | defaultConfigurationName = Release; 435 | }; 436 | /* End XCConfigurationList section */ 437 | }; 438 | rootObject = DD7B7E541D322CC700B68805 /* Project object */; 439 | } 440 | -------------------------------------------------------------------------------- /PicU.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PicU.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /PicU.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | use_frameworks! 3 | 4 | def pods 5 | pod "Qiniu", "~> 7.2" 6 | pod 'MASPreferences' 7 | pod 'AFNetworking' 8 | pod 'TMCache' 9 | end 10 | 11 | target ‘PicU’ do 12 | pods 13 | end 14 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AFNetworking (3.2.1): 3 | - AFNetworking/NSURLSession (= 3.2.1) 4 | - AFNetworking/Reachability (= 3.2.1) 5 | - AFNetworking/Security (= 3.2.1) 6 | - AFNetworking/Serialization (= 3.2.1) 7 | - AFNetworking/UIKit (= 3.2.1) 8 | - AFNetworking/NSURLSession (3.2.1): 9 | - AFNetworking/Reachability 10 | - AFNetworking/Security 11 | - AFNetworking/Serialization 12 | - AFNetworking/Reachability (3.2.1) 13 | - AFNetworking/Security (3.2.1) 14 | - AFNetworking/Serialization (3.2.1) 15 | - HappyDNS (0.3.14) 16 | - MASPreferences (1.3) 17 | - Qiniu (7.2.4): 18 | - HappyDNS (~> 0.3) 19 | - TMCache (2.1.0) 20 | 21 | DEPENDENCIES: 22 | - AFNetworking 23 | - MASPreferences 24 | - Qiniu (~> 7.2) 25 | - TMCache 26 | 27 | SPEC REPOS: 28 | https://github.com/CocoaPods/Specs.git: 29 | - AFNetworking 30 | - HappyDNS 31 | - MASPreferences 32 | - Qiniu 33 | - TMCache 34 | 35 | SPEC CHECKSUMS: 36 | AFNetworking: b6f891fdfaed196b46c7a83cf209e09697b94057 37 | HappyDNS: dc6a164ee81979093123c241c6353bcf0218add6 38 | MASPreferences: c08b8622dd17b47da87669e741efd7c92e970e8c 39 | Qiniu: 65384bca1cdb0480a68d9b9b8f54db53418c0355 40 | TMCache: 95ebcc9b3c7e90fb5fd8fc3036cba3aa781c9bed 41 | 42 | PODFILE CHECKSUM: 118dcfb5abd42130dde389f59bb2b387ee43dbb4 43 | 44 | COCOAPODS: 1.8.4 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # PicU 3 | 4 |

5 | 6 | PicU 7 | 8 |

9 | 10 |

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |

19 | 20 | PicU is a tool for Mac, that can easily upload picture to [QNServer](http://www.qiniu.com/) and save a markdown link in the clipboard. 21 | 22 | ## Features 23 | 24 | - [x] Drag a picture to PicU status menu icon for uploading picture. 25 | - [x] Copy a image in the clipboard,click PicU status menu icon for uploading pictrue.(Hot Key CMD+U) 26 | - [x] Upload automatically,when you copy picture.(open auto upload). 27 | - [x] Save five pictures of historical links. 28 | - [x] Markdown link or common http link. 29 | - [x] Custom QNServer. 30 | - [x] Default sm.ms Server 31 | 32 | ## Next Steps 33 | 34 | - Custom quality of the picture. 35 | - More custom servers for picture. 36 | 37 | ## Download 38 | 39 | [Releases](https://github.com/chenxtdo/UPImageMacApp/releases) 40 | 41 | 42 | 43 | ## License 44 | 45 | PicU is released under the MIT license.See LICENSE for details. 46 | 47 | -------------------------------------------------------------------------------- /UPImage/AppCache.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppCache.swift 3 | // U图床 4 | // 5 | // Created by Pro.chen on 27/12/2016. 6 | // Copyright © 2016 chenxt. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import TMCache 11 | 12 | protocol DiskCache { 13 | 14 | } 15 | extension DiskCache where Self : NSCoding{ 16 | func setInCache(_ key:String){ 17 | let cacheDir = NSHomeDirectory() + "/Documents"; 18 | TMCache(name: "picCache", rootPath: cacheDir).setObject(self, forKey: key); 19 | } 20 | static func getInCahce(_ key:String)->Self?{ 21 | let cacheDir = NSHomeDirectory() + "/Documents"; 22 | return TMCache(name: "picCache", rootPath: cacheDir).object(forKey: key) as? Self; 23 | } 24 | } 25 | 26 | class AppCache: NSObject{ 27 | static let shared = AppCache() 28 | var imagesCacheArr: [[String: AnyObject]] = Array() 29 | var appConfig : AppConfig! 30 | var qnConfig : QNConfig! 31 | fileprivate override init() { 32 | super.init() 33 | if let ac = AppConfig.getInCahce("appConfig") { 34 | appConfig = ac; 35 | }else{ 36 | appConfig = AppConfig(); 37 | } 38 | 39 | if appConfig.useDefServer { 40 | qnConfig = nil; 41 | } 42 | else { 43 | qnConfig = QNConfig.getInCahce("QN_Use_Config") 44 | } 45 | } 46 | func adduploadImageToCache(_ dic: [String: AnyObject]) { 47 | if imagesCacheArr.count < 5 { 48 | imagesCacheArr.append(dic) 49 | TMCache.shared().setObject(imagesCacheArr as NSCoding?, forKey: "imageCache") 50 | } else { 51 | imagesCacheArr.remove(at: 0) 52 | imagesCacheArr.append(dic) 53 | TMCache.shared().setObject(imagesCacheArr as NSCoding?, forKey: "imageCache") 54 | } 55 | } 56 | 57 | 58 | 59 | 60 | 61 | } 62 | -------------------------------------------------------------------------------- /UPImage/AppConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppConfig.swift 3 | // U图床 4 | // 5 | // Created by Pro.chen on 07/02/2017. 6 | // Copyright © 2017 chenxt. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | enum LinkType : Int { 12 | case url = 0 13 | case markdown = 1 14 | static func getLink(path:String,type:LinkType) -> String{ 15 | let name = NSString(string: path).lastPathComponent 16 | switch type { 17 | case .markdown: 18 | return "![" + name + "](" + path + ")" 19 | // return "![" + name + "](" + path + mark + ")" 20 | case .url: 21 | return path 22 | } 23 | } 24 | } 25 | 26 | class AppConfig: NSObject ,NSCoding ,DiskCache{ 27 | var linkType : LinkType = .url //链接模式 28 | var autoUp : Bool = false //是否自动上传 29 | var useDefServer : Bool = true //是否配置好 , true 未配置, false 已配置 30 | 31 | 32 | func encode(with aCoder: NSCoder) { 33 | 34 | aCoder.encode(linkType.rawValue.description, forKey: "linkType") 35 | if autoUp { 36 | aCoder.encode("1", forKey: "autoUp") 37 | } else { 38 | aCoder.encode("0", forKey: "autoUp") 39 | } 40 | if useDefServer { 41 | aCoder.encode("1", forKey: "useDefServer") 42 | } else { 43 | aCoder.encode("0", forKey: "useDefServer") 44 | } 45 | 46 | } 47 | 48 | required init?(coder aDecoder: NSCoder) { 49 | guard let _ = aDecoder.decodeObject(forKey: "linkType") else { 50 | return nil 51 | } 52 | autoUp = Bool(NSNumber(value: Int(aDecoder.decodeObject(forKey: "autoUp") as! String)!)) 53 | linkType = LinkType(rawValue: Int(aDecoder.decodeObject(forKey: "linkType") as! String)! )! 54 | useDefServer = Bool(NSNumber(value: Int(aDecoder.decodeObject(forKey: "useDefServer") as! String)!)) 55 | super.init() 56 | } 57 | override init() { 58 | super.init(); 59 | setInCache("appConfig"); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /UPImage/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // UPImage 4 | // 5 | // Created by Pro.chen on 16/7/10. 6 | // Copyright © 2016年 chenxt. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import MASPreferences 11 | import TMCache 12 | import Carbon 13 | 14 | 15 | 16 | var appDelegate: NSObject? 17 | 18 | var statusItem: NSStatusItem! 19 | 20 | 21 | 22 | @NSApplicationMain 23 | class AppDelegate: NSObject, NSApplicationDelegate { 24 | 25 | 26 | @IBOutlet weak var MarkdownItem: NSMenuItem! 27 | @IBOutlet weak var window: NSWindow! 28 | @IBOutlet weak var statusMenu: NSMenu! 29 | @IBOutlet weak var cacheImageMenu: NSMenu! 30 | @IBOutlet weak var autoUpItem: NSMenuItem! 31 | @IBOutlet weak var uploadMenuItem: NSMenuItem! 32 | @IBOutlet weak var cacheImageMenuItem: NSMenuItem! 33 | 34 | let pasteboardObserver = PasteboardObserver() 35 | lazy var preferencesWindowController: NSWindowController = { 36 | let imageViewController = ImagePreferencesViewController() 37 | let generalViewController = GeneralViewController() 38 | let controllers = [imageViewController] 39 | let wc = MASPreferencesWindowController(viewControllers: controllers, title: "设置") 40 | imageViewController.window = wc.window 41 | return wc 42 | }() 43 | 44 | func applicationDidFinishLaunching(_ aNotification: Notification) { 45 | registerHotKeys() 46 | initApp() 47 | } 48 | 49 | func initApp() { 50 | switch AppCache.shared.appConfig.linkType { 51 | case .markdown: 52 | MarkdownItem.state = NSControl.StateValue(rawValue: 1) 53 | case .url: 54 | MarkdownItem.state = NSControl.StateValue(rawValue: 0) 55 | } 56 | 57 | 58 | 59 | pasteboardObserver.addSubscriber(self) 60 | 61 | if AppCache.shared.appConfig.autoUp { 62 | pasteboardObserver.startObserving() 63 | autoUpItem.state = NSControl.StateValue(rawValue: 1) 64 | } 65 | 66 | NotificationCenter.default.addObserver(self, selector: #selector(notification), name: NSNotification.Name(rawValue: "MarkdownState"), object: nil) 67 | window.center() 68 | appDelegate = self 69 | statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength) 70 | let statusBarButton = DragDestinationView(frame: (statusItem.button?.bounds)!) 71 | statusItem.button?.superview?.addSubview(statusBarButton, positioned: .below, relativeTo: statusItem.button) 72 | let iconImage = NSImage(named: "StatusIcon") 73 | iconImage?.isTemplate = true 74 | statusItem.button?.image = iconImage 75 | statusItem.button?.action = #selector(showMenu) 76 | statusItem.button?.target = self 77 | } 78 | 79 | @objc func notification(_ notification: Notification) { 80 | MarkdownItem.state = NSControl.StateValue(rawValue: Int(truncating: (notification.object as AnyObject) as! NSNumber)) 81 | } 82 | 83 | func applicationWillTerminate(_ aNotification: Notification) { 84 | // Insert code here to tear down your application 85 | AppCache.shared.appConfig.setInCache("appConfig") 86 | } 87 | 88 | @objc func showMenu() { 89 | let pboard = NSPasteboard.general 90 | let files: NSArray? = pboard.propertyList(forType: NSPasteboard.PasteboardType(rawValue: "NSFilenamesPboardType")) as? NSArray 91 | if let files = files { 92 | let i = NSImage(contentsOfFile: files.firstObject as! String) 93 | i?.scalingImage() 94 | uploadMenuItem.image = i 95 | } else { 96 | let i = NSImage(pasteboard: pboard) 97 | i?.scalingImage() 98 | uploadMenuItem.image = i 99 | } 100 | let object = TMCache.shared().object(forKey: "imageCache") 101 | if let obj = object as? [[String: AnyObject]] { 102 | AppCache.shared.imagesCacheArr = obj 103 | } 104 | cacheImageMenuItem.submenu = makeCacheImageMenu(AppCache.shared.imagesCacheArr) 105 | statusItem.popUpMenu(statusMenu) 106 | } 107 | 108 | @IBAction func statusMenuClicked(_ sender: NSMenuItem) { 109 | switch sender.tag { 110 | // 上传 111 | case 1: 112 | let pboard = NSPasteboard.general 113 | ImageService.shared.uploadImg(pboard) 114 | // 设置 115 | case 2: 116 | preferencesWindowController.showWindow(nil) 117 | preferencesWindowController.window?.center() 118 | NSApp.activate(ignoringOtherApps: true) 119 | case 3: 120 | // 退出 121 | NSApp.terminate(nil) 122 | //帮助 123 | case 5: 124 | break 125 | //自动上传 126 | case 6: 127 | sender.state = NSControl.StateValue(rawValue: 1 - sender.state.rawValue); 128 | AppCache.shared.appConfig.autoUp = sender.state.rawValue == 1 ? true : false 129 | AppCache.shared.appConfig.autoUp ? pasteboardObserver.startObserving() : pasteboardObserver.stopObserving() 130 | AppCache.shared.appConfig.setInCache("appConfig") 131 | //切换markdown 132 | case 7: 133 | sender.state = NSControl.StateValue(rawValue: 1 - sender.state.rawValue) 134 | AppCache.shared.appConfig.linkType = LinkType(rawValue: sender.state.rawValue)! 135 | guard let imagesCache = AppCache.shared.imagesCacheArr.last else { 136 | return 137 | } 138 | let picUrl = imagesCache["url"] as! String 139 | NSPasteboard.general.setString(LinkType.getLink(path: picUrl, type: AppCache.shared.appConfig.linkType), forType: NSPasteboard.PasteboardType.string) 140 | AppCache.shared.appConfig.setInCache("appConfig") 141 | default: 142 | break 143 | } 144 | 145 | } 146 | 147 | @IBAction func btnClick(_ sender: NSButton) { 148 | switch sender.tag { 149 | case 1: 150 | NSWorkspace.shared.open(URL(string: "http://blog.lzqup.com/tools/2016/07/10/Tools-UPImage.html")!) 151 | self.window.close() 152 | case 2: 153 | self.window.close() 154 | 155 | default: 156 | break 157 | } 158 | } 159 | 160 | func makeCacheImageMenu(_ imagesArr: [[String: AnyObject]]) -> NSMenu { 161 | let menu = NSMenu() 162 | if imagesArr.count == 0 { 163 | let item = NSMenuItem(title: "没有历史", action: nil, keyEquivalent: "") 164 | menu.addItem(item) 165 | } else { 166 | for index in 0.. Bool { 192 | return true 193 | } 194 | 195 | override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) { 196 | 197 | 198 | } 199 | 200 | func pasteboardChanged(_ pasteboard: NSPasteboard) { 201 | ImageService.shared.uploadImg(pasteboard) 202 | 203 | } 204 | 205 | func registerHotKeys() { 206 | 207 | var gMyHotKeyRef: EventHotKeyRef? = nil 208 | var gMyHotKeyIDU = EventHotKeyID() 209 | var gMyHotKeyIDM = EventHotKeyID() 210 | var eventType = EventTypeSpec() 211 | 212 | eventType.eventClass = OSType(kEventClassKeyboard) 213 | eventType.eventKind = OSType(kEventHotKeyPressed) 214 | gMyHotKeyIDU.signature = OSType(32) 215 | gMyHotKeyIDU.id = UInt32(kVK_ANSI_U); 216 | gMyHotKeyIDM.signature = OSType(46); 217 | gMyHotKeyIDM.id = UInt32(kVK_ANSI_M); 218 | 219 | RegisterEventHotKey(UInt32(kVK_ANSI_U), UInt32(cmdKey), gMyHotKeyIDU, GetApplicationEventTarget(), 0, &gMyHotKeyRef) 220 | 221 | RegisterEventHotKey(UInt32(kVK_ANSI_M), UInt32(controlKey), gMyHotKeyIDM, GetApplicationEventTarget(), 0, &gMyHotKeyRef) 222 | 223 | // Install handler. 224 | InstallEventHandler(GetApplicationEventTarget(), { (nextHanlder, theEvent, userData) -> OSStatus in 225 | var hkCom = EventHotKeyID() 226 | GetEventParameter(theEvent, EventParamName(kEventParamDirectObject), EventParamType(typeEventHotKeyID), nil, MemoryLayout.size, nil, &hkCom) 227 | switch hkCom.id { 228 | case UInt32(kVK_ANSI_U): 229 | let pboard = NSPasteboard.general 230 | ImageService.shared.uploadImg(pboard) 231 | case UInt32(kVK_ANSI_M): 232 | 233 | AppCache.shared.appConfig.linkType = LinkType(rawValue: 1 - AppCache.shared.appConfig.linkType.rawValue)! 234 | print(AppCache.shared.appConfig.linkType.rawValue) 235 | NotificationCenter.default.post(name: Notification.Name(rawValue: "MarkdownState"), object: AppCache.shared.appConfig.linkType.rawValue) 236 | guard let imagesCache = AppCache.shared.imagesCacheArr.last else { 237 | return 33 238 | } 239 | NSPasteboard.general.clearContents() 240 | let picUrl = imagesCache["url"] as! String 241 | NSPasteboard.general.setString(LinkType.getLink(path: picUrl, type: AppCache.shared.appConfig.linkType), forType: NSPasteboard.PasteboardType.string) 242 | 243 | 244 | default: 245 | break 246 | } 247 | 248 | return 33 249 | /// Check that hkCom in indeed your hotkey ID and handle it. 250 | }, 1, &eventType, nil, nil) 251 | 252 | } 253 | 254 | } 255 | 256 | -------------------------------------------------------------------------------- /UPImage/AppHelper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppHelper.swift 3 | // U图床 4 | // 5 | // Created by Pro.chen on 16/7/13. 6 | // Copyright © 2016年 chenxt. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import AppKit 11 | import TMCache 12 | 13 | 14 | public enum Result { 15 | case success(Value) 16 | case failure(Value) 17 | 18 | public func Success( success: (_ value: Value) -> Void) -> Result { 19 | switch self { 20 | case .success(let value): 21 | success(value) 22 | default: 23 | break 24 | } 25 | 26 | return self 27 | } 28 | 29 | public func Failure( failure: (_ error: Value) -> Void) -> Result { 30 | switch self { 31 | case .failure(let error): 32 | failure(error) 33 | default: 34 | break 35 | } 36 | return self 37 | } 38 | 39 | } 40 | 41 | extension NSImage { 42 | 43 | func scalingImage() { 44 | let sW = self.size.width 45 | let sH = self.size.height 46 | let nW: CGFloat = 100 47 | let nH = nW * sH / sW 48 | self.size = CGSize(width: nW, height: nH) 49 | } 50 | 51 | } 52 | 53 | 54 | 55 | func NotificationMessage(_ message: String, informative: String? = nil, isSuccess: Bool = false) { 56 | 57 | let notification = NSUserNotification() 58 | let notificationCenter = NSUserNotificationCenter.default 59 | notificationCenter.delegate = appDelegate as? NSUserNotificationCenterDelegate 60 | notification.title = message 61 | notification.informativeText = informative 62 | if isSuccess { 63 | notification.contentImage = NSImage(named: "success") 64 | notification.informativeText = "链接已经保存在剪贴板里,可以直接粘贴" 65 | } else { 66 | notification.contentImage = NSImage(named: "Failure") 67 | } 68 | 69 | notification.soundName = NSUserNotificationDefaultSoundName; 70 | notificationCenter.scheduleNotification(notification) 71 | 72 | } 73 | 74 | func arc() -> UInt32 { return arc4random() % 100000 } 75 | 76 | func timeInterval() -> Int { 77 | 78 | return Int(Date(timeIntervalSinceNow: 0).timeIntervalSince1970) 79 | } 80 | 81 | func getDateString() -> String { 82 | let dateformatter = DateFormatter() 83 | dateformatter.dateFormat = "YYYYMMdd" 84 | let dataString = dateformatter.string(from: Date(timeInterval: 0, since: Date())) 85 | return dataString 86 | } 87 | 88 | func checkImageFile(_ pboard: NSPasteboard) -> Bool { 89 | guard let pasteboard = pboard.propertyList(forType: NSPasteboard.PasteboardType(rawValue: "NSFilenamesPboardType")) as? NSArray, 90 | let path = pasteboard[0] as? String 91 | else { return false } 92 | 93 | let image = NSImage(contentsOfFile: path) 94 | guard let _ = image else { 95 | return false 96 | } 97 | return true 98 | } 99 | 100 | func getImageType(_ data: Data) -> String { 101 | var c: uint8 = 0 102 | data.copyBytes(to: &c, count: 1) 103 | switch c { 104 | case 0xFF: 105 | return ".jpeg" 106 | case 0x89: 107 | return ".png" 108 | case 0x49: 109 | return ".tiff" 110 | case 0x4D: 111 | return ".tiff" 112 | case 0x52: 113 | guard data.count > 12, let str = String(data: data.subdata(in: 0..<13), encoding: .ascii), str.hasPrefix("RIFF"), str.hasPrefix("WEBP") else { 114 | return "" 115 | } 116 | return ".webp" 117 | default: 118 | return "" 119 | } 120 | } 121 | 122 | private let pngHeader: [UInt8] = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A] 123 | private let jpgHeaderSOI: [UInt8] = [0xFF, 0xD8] 124 | private let jpgHeaderIF: [UInt8] = [0xFF] 125 | private let gifHeader: [UInt8] = [0x47, 0x49, 0x46] 126 | 127 | enum ImageFormat : String { 128 | case unknown = "" 129 | case png = ".png" 130 | case jpeg = ".jpg" 131 | case gif = ".gif" 132 | } 133 | 134 | extension Data { 135 | var imageFormat: ImageFormat { 136 | var buffer = [UInt8](repeating: 0, count: 8) 137 | (self as NSData).getBytes(&buffer, length: 8) 138 | if buffer == pngHeader { 139 | return .png 140 | } else if buffer[0] == jpgHeaderSOI[0] && 141 | buffer[1] == jpgHeaderSOI[1] && 142 | buffer[2] == jpgHeaderIF[0] 143 | { 144 | return .jpeg 145 | } else if buffer[0] == gifHeader[0] && 146 | buffer[1] == gifHeader[1] && 147 | buffer[2] == gifHeader[2] 148 | { 149 | return .gif 150 | } 151 | 152 | return .unknown 153 | } 154 | } 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/90343Slice 1.imageset/90343Slice 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/90343Slice 1.imageset/90343Slice 1.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/90343Slice 1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "90343Slice 1.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "Icon_16x16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "Icon_16x16@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "Icon_32x32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "Icon_32x32@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "Icon_128x128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "Icon_128x128@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "Icon_256x256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "Icon_256x256@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "Icon_512x512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "Icon_512x512@2x.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/AppIcon.appiconset/Icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/AppIcon.appiconset/Icon_128x128.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/AppIcon.appiconset/Icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/AppIcon.appiconset/Icon_128x128@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/AppIcon.appiconset/Icon_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/AppIcon.appiconset/Icon_16x16.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/AppIcon.appiconset/Icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/AppIcon.appiconset/Icon_16x16@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/AppIcon.appiconset/Icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/AppIcon.appiconset/Icon_256x256.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/AppIcon.appiconset/Icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/AppIcon.appiconset/Icon_256x256@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/AppIcon.appiconset/Icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/AppIcon.appiconset/Icon_32x32.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/AppIcon.appiconset/Icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/AppIcon.appiconset/Icon_32x32@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/AppIcon.appiconset/Icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/AppIcon.appiconset/Icon_512x512.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/AppIcon.appiconset/Icon_512x512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/AppIcon.appiconset/Icon_512x512@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/Failure.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Failure.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Failure@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Failure@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/Failure.imageset/Failure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/Failure.imageset/Failure.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/Failure.imageset/Failure@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/Failure.imageset/Failure@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/Failure.imageset/Failure@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/Failure.imageset/Failure@3x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/Icon_128x128.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Icon_128x128.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Icon_128x128@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Icon_128x128@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/Icon_128x128.imageset/Icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/Icon_128x128.imageset/Icon_128x128.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/Icon_128x128.imageset/Icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/Icon_128x128.imageset/Icon_128x128@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/Icon_128x128.imageset/Icon_128x128@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/Icon_128x128.imageset/Icon_128x128@3x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/Icon_32x32.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Icon_32x32.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Icon_32x32@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Icon_32x32@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/Icon_32x32.imageset/Icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/Icon_32x32.imageset/Icon_32x32.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/Icon_32x32.imageset/Icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/Icon_32x32.imageset/Icon_32x32@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/Icon_32x32.imageset/Icon_32x32@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/Icon_32x32.imageset/Icon_32x32@3x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/StatusIcon.imageset/Combined Shape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/StatusIcon.imageset/Combined Shape.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/StatusIcon.imageset/Combined Shape@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/StatusIcon.imageset/Combined Shape@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/StatusIcon.imageset/Combined Shape@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/StatusIcon.imageset/Combined Shape@3x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/StatusIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Combined Shape.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Combined Shape@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Combined Shape@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-0.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "loading-0.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "loading-0@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-0.imageset/loading-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-0.imageset/loading-0.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-0.imageset/loading-0@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-0.imageset/loading-0@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "loading-2.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "loading-2@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-1.imageset/loading-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-1.imageset/loading-2.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-1.imageset/loading-2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-1.imageset/loading-2@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-10.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "loading-10.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "loading-10@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-10.imageset/loading-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-10.imageset/loading-10.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-10.imageset/loading-10@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-10.imageset/loading-10@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "loading-1.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "loading-1@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-2.imageset/loading-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-2.imageset/loading-1.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-2.imageset/loading-1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-2.imageset/loading-1@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "loading-3.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "loading-3@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-3.imageset/loading-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-3.imageset/loading-3.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-3.imageset/loading-3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-3.imageset/loading-3@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-4.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "loading-4.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "loading-4@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-4.imageset/loading-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-4.imageset/loading-4.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-4.imageset/loading-4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-4.imageset/loading-4@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-5.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "loading-5.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "loading-5@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-5.imageset/loading-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-5.imageset/loading-5.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-5.imageset/loading-5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-5.imageset/loading-5@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-6.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "loading-6.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "loading-6@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-6.imageset/loading-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-6.imageset/loading-6.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-6.imageset/loading-6@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-6.imageset/loading-6@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-7.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "loading-7.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "loading-7@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-7.imageset/loading-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-7.imageset/loading-7.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-7.imageset/loading-7@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-7.imageset/loading-7@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-8.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "loading-8.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "loading-8@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-8.imageset/loading-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-8.imageset/loading-8.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-8.imageset/loading-8@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-8.imageset/loading-8@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-9.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "loading-9.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "loading-9@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-9.imageset/loading-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-9.imageset/loading-9.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/loading/loading-9.imageset/loading-9@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/loading/loading-9.imageset/loading-9@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/success.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "success.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "success@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "success@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/success.imageset/success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/success.imageset/success.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/success.imageset/success@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/success.imageset/success@2x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/success.imageset/success@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/success.imageset/success@3x.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/upload.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Slice 1.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Slice 1@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/upload.imageset/Slice 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/upload.imageset/Slice 1.png -------------------------------------------------------------------------------- /UPImage/Assets.xcassets/upload.imageset/Slice 1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/UPImage/Assets.xcassets/upload.imageset/Slice 1@2x.png -------------------------------------------------------------------------------- /UPImage/DragDestinationView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DragDestinationView.swift 3 | // UPImage 4 | // 5 | // Created by Pro.chen on 16/7/9. 6 | // Copyright © 2016年 chenxt. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class DragDestinationView: NSView { 12 | 13 | override func draw(_ dirtyRect: NSRect) { 14 | super.draw(dirtyRect) 15 | 16 | // Drawing code here. 17 | } 18 | 19 | override init(frame frameRect: NSRect) { 20 | super.init(frame: frameRect) 21 | // 注册接受文件拖入的类型 22 | registerForDraggedTypes([kUTTypeFileURL as NSPasteboard.PasteboardType]) 23 | 24 | } 25 | 26 | required init?(coder: NSCoder) { 27 | fatalError("init(coder:) has not been implemented") 28 | } 29 | 30 | override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation { 31 | let pboard = sender.draggingPasteboard 32 | 33 | if checkImageFile(pboard) { 34 | statusItem.button?.image = NSImage(named: "upload") 35 | statusItem.button?.image?.isTemplate = true 36 | 37 | return NSDragOperation.copy 38 | } else { 39 | return NSDragOperation() 40 | } 41 | } 42 | 43 | override func draggingExited(_ sender: NSDraggingInfo?) { 44 | statusItem.button?.image = NSImage(named: "StatusIcon") 45 | statusItem.button?.image?.isTemplate = true 46 | } 47 | 48 | override func prepareForDragOperation(_ sender: NSDraggingInfo) -> Bool { 49 | let pboard = sender.draggingPasteboard 50 | return checkImageFile(pboard) 51 | } 52 | 53 | override func performDragOperation(_ sender: NSDraggingInfo) -> Bool { 54 | let pboard = sender.draggingPasteboard 55 | ImageService.shared.uploadImg(pboard) 56 | return true 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /UPImage/GeneralViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GeneralViewController.swift 3 | // U图床 4 | // 5 | // Created by Pro.chen on 7/18/16. 6 | // Copyright © 2016 chenxt. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import MASPreferences 11 | 12 | 13 | class GeneralViewController: NSViewController, MASPreferencesViewController { 14 | var viewIdentifier: String = "general" 15 | var toolbarItemLabel: String? { get { return "基本" } } 16 | var toolbarItemImage: NSImage? { get { return NSImage(named: NSImage.preferencesGeneralName) } } 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /UPImage/GeneralViewController.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 | -------------------------------------------------------------------------------- /UPImage/ImagePreferencesViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImagePreferencesViewController.swift 3 | // imageUpload 4 | // 5 | // Created by Pro.chen on 16/7/8. 6 | // Copyright © 2016年 chenxt. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import MASPreferences 11 | 12 | class ImagePreferencesViewController: NSViewController, MASPreferencesViewController { 13 | var viewIdentifier: String = "image" 14 | var toolbarItemLabel: String? { get { return "图床" } } 15 | var toolbarItemImage: NSImage? { get { return NSImage(named: NSImage.userName) } } 16 | var window: NSWindow? 17 | @IBOutlet weak var statusLabel: NSTextField! 18 | @IBOutlet weak var accessKeyTextField: NSTextField! 19 | @IBOutlet weak var secretKeyTextField: NSTextField! 20 | @IBOutlet weak var bucketTextField: NSTextField! 21 | @IBOutlet weak var urlPrefixTextField: NSTextField! 22 | @IBOutlet weak var checkButton: NSButton! 23 | @IBOutlet weak var markTextField: NSTextField! 24 | @IBOutlet weak var QNZonePopButton: NSPopUpButton! 25 | 26 | override func viewDidLoad() { 27 | super.viewDidLoad() 28 | 29 | 30 | guard let qc = AppCache.shared.qnConfig else{ 31 | QNZonePopButton.selectItem(withTag: 1) 32 | statusLabel.cell?.title = "请配置图床" 33 | return 34 | } 35 | statusLabel.cell?.title = "配置成功。" 36 | statusLabel.textColor = .magenta 37 | QNZonePopButton.selectItem(withTag: qc.zone); 38 | accessKeyTextField.cell?.title = qc.accessKey; 39 | secretKeyTextField.cell?.title = qc.secretKey; 40 | bucketTextField.cell?.title = qc.scope; 41 | urlPrefixTextField.cell?.title = qc.picUrlPrefix; 42 | markTextField.cell?.title = qc.mark; 43 | 44 | 45 | 46 | } 47 | @IBAction func setDefault(_ sender: AnyObject) { 48 | AppCache.shared.appConfig.useDefServer = true 49 | statusLabel.cell?.title = "目前使用默认图床" 50 | // statusLabel.textColor = .red 51 | // AppCache.shared.appConfig.setInCache("appConfig") 52 | 53 | } 54 | 55 | @IBAction func selectQNZone(_ sender: NSMenuItem) { 56 | 57 | 58 | QNZonePopButton.select(sender); 59 | 60 | } 61 | 62 | 63 | 64 | @IBAction func setQiniuConfig(_ sender: AnyObject) { 65 | if (accessKeyTextField.cell?.title.count == 0 || 66 | secretKeyTextField.cell?.title.count == 0 || 67 | bucketTextField.cell?.title.count == 0 || 68 | urlPrefixTextField.cell?.title.count == 0) { 69 | showAlert("有配置信息未填写", informative: "请仔细填写") 70 | return 71 | } 72 | 73 | urlPrefixTextField.cell?.title = (urlPrefixTextField.cell?.title.replacingOccurrences(of: " ", with: ""))! 74 | 75 | if !(urlPrefixTextField.cell?.title.hasPrefix("http://"))! && !(urlPrefixTextField.cell?.title.hasPrefix("https://"))! { 76 | urlPrefixTextField.cell?.title = "http://" + (urlPrefixTextField.cell?.title)! 77 | } 78 | 79 | if !(urlPrefixTextField.cell?.title.hasSuffix("/"))! { 80 | urlPrefixTextField.cell?.title = (urlPrefixTextField.cell?.title)! + "/" 81 | } 82 | 83 | let ack = (accessKeyTextField.cell?.title)! 84 | let sek = (secretKeyTextField.cell?.title)! 85 | let bck = (bucketTextField.cell?.title)! 86 | let qnConfig = QNConfig(picUrlPrefix: (urlPrefixTextField.cell?.title)!, accessKey: ack, scope: bck, secretKey: sek, mark: (markTextField.cell?.title)!, zone: (QNZonePopButton.selectedItem?.tag)!) 87 | checkButton.title = "验证中" 88 | checkButton.isEnabled = false 89 | QNService.shared.register(config:qnConfig) 90 | QNService.shared.createToken() 91 | QNService.shared.verifyQNConfig(zone: QNZonePopButton.selectedItem?.tag){ [weak self] (result) in 92 | self?.checkButton.isEnabled = true 93 | self?.checkButton.title = "验证配置" 94 | result.Success(success: {_ in 95 | self?.statusLabel.cell?.title = "配置成功。" 96 | self?.statusLabel.textColor = .magenta 97 | self?.showAlert("验证成功", informative: "配置成功。") 98 | qnConfig.setInCache("QN_Use_Config"); 99 | AppCache.shared.qnConfig = qnConfig; 100 | AppCache.shared.appConfig.useDefServer = false 101 | AppCache.shared.appConfig.setInCache("appConfig") 102 | }).Failure(failure: { _ in 103 | self?.showAlert("验证失败", informative: "验证失败,请仔细填写信息。") 104 | }) 105 | } 106 | } 107 | 108 | func showAlert(_ message: String, informative: String) { 109 | let arlert = NSAlert() 110 | arlert.messageText = message 111 | arlert.informativeText = informative 112 | arlert.addButton(withTitle: "确定") 113 | arlert.icon = message == "验证成功" ? NSImage(named: "Icon_32x32") : NSImage(named: "Failure") 114 | arlert.beginSheetModal(for: self.window!, completionHandler: { (response) in 115 | 116 | }) 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /UPImage/ImagePreferencesViewController.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 | 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 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | -------------------------------------------------------------------------------- /UPImage/ImageService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageService.swift 3 | // U图床 4 | // 5 | // Created by Pro.chen on 15/02/2017. 6 | // Copyright © 2017 chenxt. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ImageService: NSObject { 12 | static let shared = ImageService() 13 | public func uploadImg(_ pboard: NSPasteboard) { 14 | let files: NSArray? = pboard.propertyList(forType: NSPasteboard.PasteboardType(rawValue: "NSFilenamesPboardType")) as? NSArray 15 | var data : Data? 16 | statusItem.button?.image = NSImage(named: "loading-\(0)") 17 | statusItem.button?.image?.isTemplate = true 18 | if let files = files { 19 | guard let _ = NSImage(contentsOfFile: files.firstObject as! String) else { 20 | return 21 | } 22 | data = NSData(contentsOfFile: files.firstObject as! String) as Data? 23 | } 24 | else { 25 | guard let type = pboard.pasteboardItems?.first?.types.first else { 26 | return 27 | } 28 | 29 | // guard ["public.tiff","public.png"].contains(type as! String) else { 30 | // return 31 | // } 32 | data = (pboard.pasteboardItems?.first?.data(forType: type)) 33 | guard let _ = NSImage(data: data!) else { 34 | return 35 | } 36 | } 37 | //进行格式转换 38 | if data?.imageFormat == .unknown { 39 | let imageRep = NSBitmapImageRep(data: data!) 40 | 41 | data = imageRep?.representation(using: .png, properties: [NSBitmapImageRep.PropertyKey.compressionMethod: ""]) 42 | // data = (imageRep?.representation(using: .PNG, properties: ["":""]))! 43 | } 44 | 45 | if AppCache.shared.appConfig.useDefServer{ 46 | SMMSService.shared.uploadImage(data!) 47 | }else{ 48 | QNService.shared.QiniuSDKUpload(data) 49 | } 50 | // 51 | 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /UPImage/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | zh_CN 7 | CFBundleDisplayName 8 | PicU 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIconFile 12 | 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | PicU 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | $(MARKETING_VERSION) 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | $(CURRENT_PROJECT_VERSION) 27 | LSApplicationCategoryType 28 | public.app-category.productivity 29 | LSMinimumSystemVersion 30 | $(MACOSX_DEPLOYMENT_TARGET) 31 | LSUIElement 32 | 33 | NSHumanReadableCopyright 34 | Copyright © 2017年 chenxt. All rights reserved. 35 | NSMainNibFile 36 | MainMenu 37 | NSPrincipalClass 38 | NSApplication 39 | 40 | 41 | -------------------------------------------------------------------------------- /UPImage/MainMenu.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 | 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 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | Default 546 | 547 | 548 | 549 | 550 | 551 | 552 | Left to Right 553 | 554 | 555 | 556 | 557 | 558 | 559 | Right to Left 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | Default 571 | 572 | 573 | 574 | 575 | 576 | 577 | Left to Right 578 | 579 | 580 | 581 | 582 | 583 | 584 | Right to Left 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 721 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | -------------------------------------------------------------------------------- /UPImage/OC-birdge.h: -------------------------------------------------------------------------------- 1 | // 2 | // OC-birdge.h 3 | // U图床 4 | // 5 | // Created by Pro.chen on 16/8/11. 6 | // Copyright © 2016年 chenxt. All rights reserved. 7 | // 8 | 9 | #ifndef OC_birdge_h 10 | #define OC_birdge_h 11 | 12 | 13 | #import 14 | 15 | #endif /* OC_birdge_h */ 16 | -------------------------------------------------------------------------------- /UPImage/PasteboardObserver.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasteboardObserver.swift 3 | // U图床 4 | // 5 | // Created by Pro.chen on 7/20/16. 6 | // Copyright © 2016 chenxt. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @objc protocol PasteboardObserverSubscriber: NSObjectProtocol { 12 | 13 | func pasteboardChanged(_ pasteboard: NSPasteboard) 14 | 15 | } 16 | 17 | enum PasteboardObserverState { 18 | case disabled 19 | case enabled 20 | case paused 21 | } 22 | 23 | class PasteboardObserver: NSObject { 24 | var pasteboard: NSPasteboard = NSPasteboard.general 25 | 26 | var subscribers: NSMutableSet = NSMutableSet() 27 | var serialQueue: DispatchQueue = DispatchQueue(label: "org.okolodev.PrettyPasteboard", attributes: []) 28 | var changeCount: Int = -1 29 | var state: PasteboardObserverState = PasteboardObserverState.disabled 30 | 31 | override init() { 32 | super.init() 33 | } 34 | 35 | deinit { 36 | self.stopObserving() 37 | self.removeSubscribers() 38 | } 39 | 40 | // Observing 41 | 42 | func startObserving() { 43 | DispatchQueue.global(priority: DispatchQueue.GlobalQueuePriority.default).async(execute: { () -> Void in 44 | self.changeState(PasteboardObserverState.enabled) 45 | self.observerLoop() 46 | }); 47 | } 48 | 49 | func stopObserving() { 50 | self.changeState(PasteboardObserverState.disabled) 51 | } 52 | 53 | func pauseObserving() { 54 | self.changeState(PasteboardObserverState.paused) 55 | } 56 | 57 | func continueObserving() { 58 | if (self.state == PasteboardObserverState.paused) { 59 | self.changeCount = self.pasteboard.changeCount; 60 | self.state = PasteboardObserverState.enabled 61 | } 62 | } 63 | 64 | func observerLoop() { 65 | while self.isEnabled() { 66 | usleep(250000) 67 | let countEquals = self.changeCount == self.pasteboard.changeCount 68 | if countEquals { 69 | continue 70 | } 71 | 72 | self.changeCount = self.pasteboard.changeCount 73 | self.pasteboardContentChanged() 74 | } 75 | } 76 | 77 | func pasteboardContentChanged() { 78 | self.pauseObserving() 79 | for anySubscriber in self.subscribers { 80 | if let subscriber = anySubscriber as? PasteboardObserverSubscriber { 81 | subscriber.pasteboardChanged(self.pasteboard) 82 | } 83 | } 84 | self.continueObserving() 85 | } 86 | 87 | func changeState(_ newState: PasteboardObserverState) { 88 | self.serialQueue.sync(execute: { () -> Void in 89 | self.state = newState; 90 | }); 91 | } 92 | 93 | func isEnabled() -> Bool { 94 | return self.state == PasteboardObserverState.enabled; 95 | } 96 | 97 | // Subscribers 98 | 99 | func addSubscriber(_ subscriber: PasteboardObserverSubscriber) { 100 | self.subscribers.add(subscriber) 101 | } 102 | 103 | func removeSubscribers() { 104 | self.subscribers.removeAllObjects() 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /UPImage/QNConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // QNConfig.swift 3 | // U图床 4 | // 5 | // Created by Pro.chen on 07/02/2017. 6 | // Copyright © 2017 chenxt. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import TMCache 11 | 12 | class QNConfig: NSObject,NSCoding,DiskCache { 13 | var picUrlPrefix : String! 14 | var accessKey: String! 15 | var scope:String! 16 | var secretKey:String! 17 | var mark:String! 18 | var zone:Int! 19 | 20 | func encode(with aCoder: NSCoder) { 21 | aCoder.encode(picUrlPrefix, forKey: "picUrlPrefix") 22 | aCoder.encode(accessKey, forKey: "accessKey") 23 | aCoder.encode(scope, forKey: "scope") 24 | aCoder.encode(secretKey, forKey: "secretKey") 25 | aCoder.encode(mark, forKey: "mark") 26 | aCoder.encode(zone, forKey: "zone") 27 | } 28 | 29 | required init?(coder aDecoder: NSCoder) { 30 | super.init() 31 | picUrlPrefix = aDecoder.decodeObject(forKey: "picUrlPrefix") as! String 32 | accessKey = aDecoder.decodeObject(forKey: "accessKey") as! String 33 | scope = aDecoder.decodeObject(forKey: "scope") as! String 34 | secretKey = aDecoder.decodeObject(forKey: "secretKey") as! String 35 | mark = aDecoder.decodeObject(forKey: "mark") as! String 36 | zone = aDecoder.decodeObject(forKey: "zone") as! Int 37 | } 38 | 39 | init(picUrlPrefix:String,accessKey:String,scope:String,secretKey:String,mark:String,zone:Int) { 40 | self.picUrlPrefix = picUrlPrefix; 41 | self.accessKey = accessKey; 42 | self.scope = scope; 43 | self.secretKey = secretKey; 44 | self.mark = mark; 45 | self.zone = zone; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /UPImage/QNService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageServer.swift 3 | // U图床 4 | // 5 | // Created by Pro.chen on 27/12/2016. 6 | // Copyright © 2016 chenxt. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Qiniu 11 | 12 | class QNService: NSObject { 13 | 14 | static let shared = QNService() 15 | fileprivate var scope : String! 16 | fileprivate var accessKey: String! 17 | fileprivate var secretKey: String! 18 | fileprivate var liveTime: Int! 19 | fileprivate var QNToken : String! 20 | var upManager :QNUploadManager! 21 | var picUrlPrefix : String! 22 | var mark: String! 23 | 24 | fileprivate override init() { 25 | super.init() 26 | } 27 | 28 | class func initQNManager(_ zoneType : Int) -> QNUploadManager { 29 | let config = QNConfiguration.build({ (builder: QNConfigurationBuilder?) in 30 | var zone : QNFixedZone! 31 | switch zoneType { 32 | case 1: 33 | zone = QNFixedZone.zone0() //华东 34 | case 2: 35 | zone = QNFixedZone.zone1() //华北 36 | case 3: 37 | zone = QNFixedZone.zone2() //华南 38 | case 4: 39 | zone = QNFixedZone.zoneNa0() //北美 40 | default: 41 | zone = QNFixedZone.zone0() 42 | } 43 | builder?.setZone(zone); 44 | 45 | }) 46 | 47 | let manager = QNUploadManager(configuration: config); 48 | 49 | return manager!; 50 | } 51 | 52 | public func register( config:QNConfig,liveTime:Int = 5 ){ 53 | self.scope = config.scope; 54 | self.accessKey = config.accessKey; 55 | self.secretKey = config.secretKey; 56 | self.liveTime = liveTime; 57 | } 58 | 59 | 60 | public func createToken(){ 61 | let authInfo :[String:Any] = ["scope":scope,"deadline" : Int(Date().timeIntervalSince1970) + liveTime * 24 * 3600]; 62 | var jsonData = Data() 63 | do { 64 | try jsonData = JSONSerialization.data(withJSONObject: authInfo, options: .prettyPrinted); 65 | } 66 | catch{ 67 | 68 | } 69 | let encodedString = self.urlSafeBase64Encode(data: jsonData); 70 | let encodedSignedString = HMACSHA1(key: secretKey, text: encodedString); 71 | let token = accessKey + ":" + encodedSignedString + ":" + encodedString; 72 | QNToken = token; 73 | 74 | } 75 | 76 | fileprivate func urlSafeBase64Encode(data:Data) -> String{ 77 | var base64 = data.base64EncodedString(); 78 | base64 = base64.replacingOccurrences(of: "+", with: "-"); 79 | base64 = base64.replacingOccurrences(of: "/", with: "_"); 80 | return base64 81 | } 82 | 83 | fileprivate func HMACSHA1(key:String , text:String) -> String{ 84 | let cKey = key.cString(using: .utf8); 85 | let cData = text.cString(using: .utf8); 86 | let ckeyLen = key.lengthOfBytes(using: .utf8) 87 | let cDataLen = text.lengthOfBytes(using: .utf8); 88 | let cHMAC = UnsafeMutablePointer.allocate(capacity: Int(CC_SHA1_DIGEST_LENGTH)) 89 | CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA1), cKey, ckeyLen, cData, cDataLen, cHMAC); 90 | let HMAC = Data.init(bytes: cHMAC, count: Int(CC_SHA1_DIGEST_LENGTH)); 91 | let hash = urlSafeBase64Encode(data: HMAC) 92 | return hash; 93 | } 94 | 95 | public func verifyQNConfig(zone:Int? ,completion: @escaping (Result) -> Void){ 96 | upManager = QNService.initQNManager(zone ?? 1); 97 | 98 | upManager.put("Hello, World!".data(using: .utf8), key: "Hello", token: QNToken, complete: { (info, key, resp) in 99 | guard let _ = info, let _ = resp else { 100 | completion(.failure(nil)) 101 | return 102 | } 103 | completion(.success(nil)) 104 | }, option: nil) 105 | } 106 | 107 | 108 | 109 | } 110 | 111 | // MARK: - 七牛服务,上传图片 112 | extension QNService{ 113 | 114 | public func QiniuSDKUpload(_ data: Data?) { 115 | guard let qc = AppCache.shared.qnConfig else{ 116 | NotificationMessage("上传图片失败", informative: "请在设置中配置图床") 117 | return 118 | } 119 | upManager = QNService.initQNManager(qc.zone); 120 | picUrlPrefix = qc.picUrlPrefix; 121 | mark = qc.mark; 122 | register(config: qc) 123 | createToken() 124 | let token = QNToken 125 | let opt = QNUploadOption(progressHandler: { (key, percent) in 126 | statusItem.button?.image = NSImage(named: "loading-\(Int(percent*10))") 127 | statusItem.button?.image?.isTemplate = true 128 | }) 129 | let hanlder: (QNResponseInfo?, String?, [AnyHashable : Any]?, NSImage) -> () = { (info, key, resp, image) in 130 | statusItem.button?.image = NSImage(named: "StatusIcon") 131 | statusItem.button?.image?.isTemplate = true 132 | guard let _ = info, let _ = resp else { 133 | NotificationMessage("上传图片失败", informative: "可能是配置信息错误,或者是Token过去。请仔细检查配置信息,或重新上传") 134 | return 135 | } 136 | NotificationMessage("上传图片成功", isSuccess: true) 137 | NSPasteboard.general.clearContents() 138 | NSPasteboard.general 139 | let picUrl = self.picUrlPrefix + key! 140 | let picUrlS = LinkType.getLink(path:picUrl,type:AppCache.shared.appConfig.linkType); 141 | NSPasteboard.general.setString(picUrlS, forType: NSPasteboard.PasteboardType.string) 142 | let cacheDic: [String: AnyObject] = ["image": image, "url": picUrl as AnyObject] 143 | AppCache.shared.adduploadImageToCache(cacheDic) 144 | } 145 | if let data = data { 146 | let fileName = getDateString() + "\(timeInterval())" + "\(arc())" + data.imageFormat.rawValue 147 | upManager.put(data, key: fileName, token: token, complete: { (info, key, resp) in 148 | hanlder(info, key, resp, NSImage(data: data)!) 149 | }, option: opt) 150 | } 151 | } 152 | } 153 | 154 | 155 | -------------------------------------------------------------------------------- /UPImage/SMMSService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SMMSService.swift 3 | // PicU 4 | // 5 | // Created by Pro.chen on 26/02/2017. 6 | // Copyright © 2017 chenxt. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import AFNetworking 11 | 12 | class SMMSService: NSObject { 13 | static let shared = SMMSService() 14 | let api = "https://sm.ms/api/upload"; 15 | 16 | 17 | func uploadImage(_ data: Data){ 18 | 19 | var type = ""; 20 | switch data.imageFormat { 21 | case .gif: 22 | type = "image/gif" 23 | case .jpeg: 24 | type = "image/jpeg" 25 | case .png: 26 | type = "image/png" 27 | case .unknown: 28 | type = "image/jpeg" 29 | 30 | } 31 | 32 | let fileName = getDateString() + "\(timeInterval())" + "\(arc())" + data.imageFormat.rawValue 33 | 34 | let manager = AFHTTPSessionManager(); 35 | 36 | manager.post(api, parameters: nil, constructingBodyWith: { (formData) in 37 | formData.appendPart(withFileData: data, name: "smfile", fileName: fileName, mimeType: type) 38 | }, progress: { (progress) in 39 | statusItem.button?.image = NSImage(named: "loading-\(Int(progress.fractionCompleted*10))") 40 | statusItem.button?.image?.isTemplate = true 41 | }, success: { (URLSessionDataTask, responseObject) in 42 | statusItem.button?.image = NSImage(named: "StatusIcon") 43 | statusItem.button?.image?.isTemplate = true 44 | let re = responseObject as! [String:AnyObject]; 45 | guard let url = re["data"]!.value(forKey: "url") as? String else{ 46 | return 47 | } 48 | NotificationMessage("上传图片成功", isSuccess: true) 49 | NSPasteboard.general.clearContents() 50 | NSPasteboard.general 51 | let picUrl = url; 52 | let picUrlS = LinkType.getLink(path:picUrl,type:AppCache.shared.appConfig.linkType); 53 | NSPasteboard.general.setString(picUrlS, forType: NSPasteboard.PasteboardType.string) 54 | let cacheDic: [String: AnyObject] = ["image": NSImage(data: data)!, "url": picUrl as AnyObject] 55 | AppCache.shared.adduploadImageToCache(cacheDic) 56 | }) { (URLSessionDataTask, error) in 57 | statusItem.button?.image = NSImage(named: "StatusIcon") 58 | statusItem.button?.image?.isTemplate = true 59 | print(error); 60 | } 61 | 62 | } 63 | 64 | 65 | } 66 | -------------------------------------------------------------------------------- /icon.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/icon.sketch -------------------------------------------------------------------------------- /pic/2017022646287Icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/pic/2017022646287Icon_128x128@2x.png -------------------------------------------------------------------------------- /商店图片.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxtdo/UPImageMacApp/2c3e85aa48ef47c9be5575e2b6cfeb82da687605/商店图片.sketch --------------------------------------------------------------------------------