";
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 |
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 ""
19 | // return ""
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 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
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 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
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 |
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 |
750 |
751 |
757 |
758 |
761 |
762 |
768 |
769 |
775 |
776 |
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
--------------------------------------------------------------------------------