diff --git a/LaunchHelper/LaunchHelper.xcodeproj/project.pbxproj b/LaunchHelper/LaunchHelper.xcodeproj/project.pbxproj new file mode 100644 index 0000000..898023d --- /dev/null +++ b/LaunchHelper/LaunchHelper.xcodeproj/project.pbxproj @@ -0,0 +1,295 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 9B6BF93F1E27B1F10061B9A7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B6BF93E1E27B1F10061B9A7 /* AppDelegate.swift */; }; + 9B6BF9411E27B1F10061B9A7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9B6BF9401E27B1F10061B9A7 /* Assets.xcassets */; }; + 9B6BF9441E27B1F10061B9A7 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B6BF9421E27B1F10061B9A7 /* MainMenu.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 9B6BF93B1E27B1F10061B9A7 /* LaunchHelper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LaunchHelper.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 9B6BF93E1E27B1F10061B9A7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 9B6BF9401E27B1F10061B9A7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 9B6BF9431E27B1F10061B9A7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 9B6BF9451E27B1F10061B9A7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 9B6BF9381E27B1F10061B9A7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9B6BF9321E27B1F10061B9A7 = { + isa = PBXGroup; + children = ( + 9B6BF93D1E27B1F10061B9A7 /* LaunchHelper */, + 9B6BF93C1E27B1F10061B9A7 /* Products */, + ); + sourceTree = ""; + }; + 9B6BF93C1E27B1F10061B9A7 /* Products */ = { + isa = PBXGroup; + children = ( + 9B6BF93B1E27B1F10061B9A7 /* LaunchHelper.app */, + ); + name = Products; + sourceTree = ""; + }; + 9B6BF93D1E27B1F10061B9A7 /* LaunchHelper */ = { + isa = PBXGroup; + children = ( + 9B6BF93E1E27B1F10061B9A7 /* AppDelegate.swift */, + 9B6BF9401E27B1F10061B9A7 /* Assets.xcassets */, + 9B6BF9421E27B1F10061B9A7 /* MainMenu.xib */, + 9B6BF9451E27B1F10061B9A7 /* Info.plist */, + ); + path = LaunchHelper; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 9B6BF93A1E27B1F10061B9A7 /* LaunchHelper */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9B6BF9481E27B1F10061B9A7 /* Build configuration list for PBXNativeTarget "LaunchHelper" */; + buildPhases = ( + 9B6BF9371E27B1F10061B9A7 /* Sources */, + 9B6BF9381E27B1F10061B9A7 /* Frameworks */, + 9B6BF9391E27B1F10061B9A7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = LaunchHelper; + productName = LaunchHelper; + productReference = 9B6BF93B1E27B1F10061B9A7 /* LaunchHelper.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 9B6BF9331E27B1F10061B9A7 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0820; + LastUpgradeCheck = 0820; + ORGANIZATIONNAME = qiuyuzhou; + TargetAttributes = { + 9B6BF93A1E27B1F10061B9A7 = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = S878RH3PA8; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 9B6BF9361E27B1F10061B9A7 /* Build configuration list for PBXProject "LaunchHelper" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 9B6BF9321E27B1F10061B9A7; + productRefGroup = 9B6BF93C1E27B1F10061B9A7 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 9B6BF93A1E27B1F10061B9A7 /* LaunchHelper */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 9B6BF9391E27B1F10061B9A7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9B6BF9411E27B1F10061B9A7 /* Assets.xcassets in Resources */, + 9B6BF9441E27B1F10061B9A7 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 9B6BF9371E27B1F10061B9A7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9B6BF93F1E27B1F10061B9A7 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 9B6BF9421E27B1F10061B9A7 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 9B6BF9431E27B1F10061B9A7 /* Base */, + ); + name = MainMenu.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 9B6BF9461E27B1F10061B9A7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 9B6BF9471E27B1F10061B9A7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + }; + name = Release; + }; + 9B6BF9491E27B1F10061B9A7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = S878RH3PA8; + INFOPLIST_FILE = LaunchHelper/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.qiuyuzhou.ShadowsocksX-NG.LaunchHelper"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 9B6BF94A1E27B1F10061B9A7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = S878RH3PA8; + INFOPLIST_FILE = LaunchHelper/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.qiuyuzhou.ShadowsocksX-NG.LaunchHelper"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 9B6BF9361E27B1F10061B9A7 /* Build configuration list for PBXProject "LaunchHelper" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9B6BF9461E27B1F10061B9A7 /* Debug */, + 9B6BF9471E27B1F10061B9A7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9B6BF9481E27B1F10061B9A7 /* Build configuration list for PBXNativeTarget "LaunchHelper" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9B6BF9491E27B1F10061B9A7 /* Debug */, + 9B6BF94A1E27B1F10061B9A7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 9B6BF9331E27B1F10061B9A7 /* Project object */; +} diff --git a/LaunchHelper/LaunchHelper/AppDelegate.swift b/LaunchHelper/LaunchHelper/AppDelegate.swift new file mode 100644 index 0000000..14f7bed --- /dev/null +++ b/LaunchHelper/LaunchHelper/AppDelegate.swift @@ -0,0 +1,48 @@ +// +// AppDelegate.swift +// LaunchHelper +// +// Created by 邱宇舟 on 2017/1/12. +// Copyright © 2017年 qiuyuzhou. All rights reserved. +// + +import Cocoa + +@NSApplicationMain +class AppDelegate: NSObject, NSApplicationDelegate { + + @IBOutlet weak var window: NSWindow! + + + func applicationDidFinishLaunching(_ aNotification: Notification) { + // Insert code here to initialize your application + let mainBundleId = "com.qiuyuzhou.ShadowsocksX-NG" + var alreadyRunning = false; + for app in NSWorkspace.shared().runningApplications { + if app.bundleIdentifier == mainBundleId { + alreadyRunning = true + break + } + } + + if (!alreadyRunning) { + let helperPath: NSString = Bundle.main.bundlePath as NSString; + var pathComponents = helperPath.pathComponents; + pathComponents.removeLast(3); + let mainBundlePath = NSString.path(withComponents: pathComponents); + + if !NSWorkspace.shared().launchApplication(mainBundlePath) { + NSLog("Launch app \(mainBundleId) failed.") + } +// if !NSWorkspace.shared().launchApplication("/Applications/ShadowsocksX-NG.app") { +// NSLog("Launch app \(mainBundleId) failed.") +// } + } + NSApp.terminate(nil); + } + + func applicationWillTerminate(_ aNotification: Notification) { + // Insert code here to tear down your application + } +} + diff --git a/LaunchHelper/LaunchHelper/Assets.xcassets/AppIcon.appiconset/Contents.json b/LaunchHelper/LaunchHelper/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2db2b1c --- /dev/null +++ b/LaunchHelper/LaunchHelper/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,58 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/LaunchHelper/LaunchHelper/Base.lproj/MainMenu.xib b/LaunchHelper/LaunchHelper/Base.lproj/MainMenu.xib new file mode 100644 index 0000000..ddb5c97 --- /dev/null +++ b/LaunchHelper/LaunchHelper/Base.lproj/MainMenu.xib @@ -0,0 +1,679 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LaunchHelper/LaunchHelper/Info.plist b/LaunchHelper/LaunchHelper/Info.plist new file mode 100644 index 0000000..909b70e --- /dev/null +++ b/LaunchHelper/LaunchHelper/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSBackgroundOnly + + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2017年 qiuyuzhou. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/Podfile b/Podfile index 58e3edb..7f52142 100644 --- a/Podfile +++ b/Podfile @@ -6,7 +6,7 @@ target 'ShadowsocksX-NG' do use_frameworks! # Pods for ShadowsocksX-NG - pod 'Alamofire', '~> 4.0.1' + pod 'Alamofire', '~> 4.2.0' pod "GCDWebServer", "~> 3.0" target 'ShadowsocksX-NGTests' do diff --git a/Podfile.lock b/Podfile.lock index d1abbe2..539ffd5 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,20 +1,20 @@ PODS: - - Alamofire (4.0.1) + - Alamofire (4.2.0) - BRLOptionParser (0.3.1) - GCDWebServer (3.3.3): - GCDWebServer/Core (= 3.3.3) - GCDWebServer/Core (3.3.3) DEPENDENCIES: - - Alamofire (~> 4.0.1) + - Alamofire (~> 4.2.0) - BRLOptionParser (~> 0.3.1) - GCDWebServer (~> 3.0) SPEC CHECKSUMS: - Alamofire: 7682d43245de14874acd142ec137b144aa1dd335 + Alamofire: aa2e09d871c9160ac53c90e83c68064a94e3dfbe BRLOptionParser: a03256a8ff003ca1f5376c55f55f210e085a3958 GCDWebServer: 1c39a1f0763e4eb492bee021e4270fce097d3555 -PODFILE CHECKSUM: e675030dbd86de38216dc6c44e64ca1458be94bc +PODFILE CHECKSUM: d717746ef98bb719d87cee4fc334a392005fd32e -COCOAPODS: 1.0.1 +COCOAPODS: 1.2.0.beta.1 diff --git a/Pods/Alamofire/README.md b/Pods/Alamofire/README.md index bfaed03..f16157e 100644 --- a/Pods/Alamofire/README.md +++ b/Pods/Alamofire/README.md @@ -55,8 +55,8 @@ In order to keep Alamofire focused specifically on core networking implementatio ## Requirements -- iOS 9.0+ / macOS 10.11+ / tvOS 9.0+ / watchOS 2.0+ -- Xcode 8.0+ +- iOS 8.0+ / macOS 10.10+ / tvOS 9.0+ / watchOS 2.0+ +- Xcode 8.1+ - Swift 3.0+ ## Migration Guides @@ -130,13 +130,13 @@ If you prefer not to use either of the aforementioned dependency managers, you c - Open up Terminal, `cd` into your top-level project directory, and run the following command "if" your project is not initialized as a git repository: -```bash + ```bash $ git init ``` - Add Alamofire as a git [submodule](http://git-scm.com/docs/git-submodule) by running the following command: -```bash + ```bash $ git submodule add https://github.com/Alamofire/Alamofire.git ``` @@ -158,7 +158,7 @@ $ git submodule add https://github.com/Alamofire/Alamofire.git - And that's it! -> The `Alamofire.framework` is automagically added as a target dependency, linked framework and embedded framework in a copy files build phase which is all you need to build on the simulator and a device. + > The `Alamofire.framework` is automagically added as a target dependency, linked framework and embedded framework in a copy files build phase which is all you need to build on the simulator and a device. --- @@ -199,7 +199,7 @@ Alamofire contains five different response handlers by default including: // Response Handler - Unserialized Response func response( queue: DispatchQueue?, - completionHandler: @escaping (DefaultDownloadResponse) -> Void) + completionHandler: @escaping (DefaultDataResponse) -> Void) -> Self // Response Data Handler - Serialized into Data @@ -240,7 +240,7 @@ The `response` handler does NOT evaluate any of the response data. It merely for Alamofire.request("https://httpbin.org/get").response { response in print("Request: \(response.request)") print("Response: \(response.response)") - print("Error: \(response.data)") + print("Error: \(response.error)") if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) { print("Data: \(utf8Text)") @@ -331,7 +331,7 @@ By default, Alamofire treats any completed request to be successful, regardless Alamofire.request("https://httpbin.org/get") .validate(statusCode: 200..<300) .validate(contentType: ["application/json"]) - .response { response in + .responseData { response in switch response.result { case .success: print("Validation Successful") @@ -360,7 +360,7 @@ Alamofire.request("https://httpbin.org/get").validate().responseJSON { response Response Caching is handled on the system framework level by [`URLCache`](https://developer.apple.com/reference/foundation/urlcache). It provides a composite in-memory and on-disk cache and lets you manipulate the sizes of both the in-memory and on-disk portions. -> By default, Alamofire leverages the shared `URLCache`. In order to customize it, see the [Session Manager Configurations](#session-manager-configurations) section. +> By default, Alamofire leverages the shared `URLCache`. In order to customize it, see the [Session Manager Configurations](#session-manager) section. ### HTTP Methods @@ -520,7 +520,7 @@ Alamofire.request("https://httpbin.org/headers", headers: headers).responseJSON } ``` -> For HTTP headers that do not change, it is recommended to set them on the `URLSessionConfiguration` so they are automatically applied to any `URLSessionTask` created by the underlying `URLSession`. For more information, see the [Session Manager Configurations](#session-manager-configurations) section. +> For HTTP headers that do not change, it is recommended to set them on the `URLSessionConfiguration` so they are automatically applied to any `URLSessionTask` created by the underlying `URLSession`. For more information, see the [Session Manager Configurations](#session-manager) section. The default Alamofire `SessionManager` provides a default set of headers for every `Request`. These include: @@ -528,7 +528,7 @@ The default Alamofire `SessionManager` provides a default set of headers for eve - `Accept-Language`, which defaults to up to the top 6 preferred languages on the system, formatted like `en;q=1.0`, per [RFC 7231 §5.3.5](https://tools.ietf.org/html/rfc7231#section-5.3.5). - `User-Agent`, which contains versioning information about the current app. For example: `iOS Example/1.0 (com.alamofire.iOS-Example; build:1; iOS 10.0.0) Alamofire/4.0.0`, per [RFC 7231 §5.5.3](https://tools.ietf.org/html/rfc7231#section-5.5.3). -If you need to customize these headers, a custom `URLSessionManagerConfiguration` should be created, the `defaultHTTPHeaders` property updated and the configuration applied to a new `SessionManager` instance. +If you need to customize these headers, a custom `URLSessionConfiguration` should be created, the `defaultHTTPHeaders` property updated and the configuration applied to a new `SessionManager` instance. ### Authentication @@ -603,7 +603,7 @@ Alamofire.download("https://httpbin.org/image/png").responseData { response in } ``` -> The `Alamofire.download` APIs should also be used if you need to download data while your app is in the background. For more information, please see the [Session Manager Configurations](#session-manager-configurations) section. +> The `Alamofire.download` APIs should also be used if you need to download data while your app is in the background. For more information, please see the [Session Manager Configurations](#session-manager) section. #### Download File Destination @@ -623,7 +623,7 @@ let destination: DownloadRequest.DownloadFileDestination = { _, _ in Alamofire.download(urlString, to: destination).response { response in print(response) - if response.result.isSuccess, let imagePath = response.destinationURL?.path { + if response.error == nil, let imagePath = response.destinationURL?.path { let image = UIImage(contentsOfFile: imagePath) } } @@ -672,6 +672,8 @@ Alamofire.download("https://httpbin.org/image/png") If a `DownloadRequest` is cancelled or interrupted, the underlying URL session may generate resume data for the active `DownloadRequest`. If this happens, the resume data can be re-used to restart the `DownloadRequest` where it left off. The resume data can be accessed through the download response, then reused when trying to restart the request. +> **IMPORTANT:** On the latest release of all the Apple platforms (iOS 10, macOS 10.12, tvOS 10, watchOS 3), `resumeData` is broken on background URL session configurations. There's an underlying bug in the `resumeData` generation logic where the data is written incorrectly and will always fail to resume the download. For more information about the bug and possible workarounds, please see this Stack Overflow [post](http://stackoverflow.com/a/39347461/1342462). + ```swift class ImageRequestor { private var resumeData: Data? @@ -711,7 +713,7 @@ class ImageRequestor { When sending relatively small amounts of data to a server using JSON or URL encoded parameters, the `Alamofire.request` APIs are usually sufficient. If you need to send much larger amounts of data from a file URL or an `InputStream`, then the `Alamofire.upload` APIs are what you want to use. -> The `Alamofire.upload` APIs should also be used if you need to upload data while your app is in the background. For more information, please see the [Session Manager Configurations](#session-manager-configurations) section. +> The `Alamofire.upload` APIs should also be used if you need to upload data while your app is in the background. For more information, please see the [Session Manager Configurations](#session-manager) section. #### Uploading Data @@ -1289,8 +1291,12 @@ class OAuth2Handler: RequestAdapter, RequestRetrier { .responseJSON { [weak self] response in guard let strongSelf = self else { return } - if let json = response.result.value as? [String: String] { - completion(true, json["access_token"], json["refresh_token"]) + if + let json = response.result.value as? [String: Any], + let accessToken = json["access_token"] as? String, + let refreshToken = json["refresh_token"] as? String + { + completion(true, accessToken, refreshToken) } else { completion(false, nil, nil) } diff --git a/Pods/Alamofire/Source/AFError.swift b/Pods/Alamofire/Source/AFError.swift index 82e8a25..f047695 100644 --- a/Pods/Alamofire/Source/AFError.swift +++ b/Pods/Alamofire/Source/AFError.swift @@ -132,6 +132,16 @@ public enum AFError: Error { case responseSerializationFailed(reason: ResponseSerializationFailureReason) } +// MARK: - Adapt Error + +struct AdaptError: Error { + let error: Error +} + +extension Error { + var underlyingAdaptError: Error? { return (self as? AdaptError)?.error } +} + // MARK: - Error Booleans extension AFError { diff --git a/Pods/Alamofire/Source/Alamofire.swift b/Pods/Alamofire/Source/Alamofire.swift index 7566587..86d54d8 100644 --- a/Pods/Alamofire/Source/Alamofire.swift +++ b/Pods/Alamofire/Source/Alamofire.swift @@ -222,6 +222,13 @@ public func download( /// If `destination` is not specified, the contents will remain in the temporary location determined by the /// underlying URL session. /// +/// On the latest release of all the Apple platforms (iOS 10, macOS 10.12, tvOS 10, watchOS 3), `resumeData` is broken +/// on background URL session configurations. There's an underlying bug in the `resumeData` generation logic where the +/// data is written incorrectly and will always fail to resume the download. For more information about the bug and +/// possible workarounds, please refer to the following Stack Overflow post: +/// +/// - http://stackoverflow.com/a/39347461/1342462 +/// /// - parameter resumeData: The resume data. This is an opaque data blob produced by `URLSessionDownloadTask` /// when a task is cancelled. See `URLSession -downloadTask(withResumeData:)` for additional /// information. @@ -435,6 +442,7 @@ public func upload( /// /// - returns: The created `StreamRequest`. @discardableResult +@available(iOS 9.0, macOS 10.11, tvOS 9.0, *) public func stream(withHostName hostName: String, port: Int) -> StreamRequest { return SessionManager.default.stream(withHostName: hostName, port: port) } @@ -449,6 +457,7 @@ public func stream(withHostName hostName: String, port: Int) -> StreamRequest { /// /// - returns: The created `StreamRequest`. @discardableResult +@available(iOS 9.0, macOS 10.11, tvOS 9.0, *) public func stream(with netService: NetService) -> StreamRequest { return SessionManager.default.stream(with: netService) } diff --git a/Pods/Alamofire/Source/ParameterEncoding.swift b/Pods/Alamofire/Source/ParameterEncoding.swift index 42b5b2d..242f6a8 100644 --- a/Pods/Alamofire/Source/ParameterEncoding.swift +++ b/Pods/Alamofire/Source/ParameterEncoding.swift @@ -199,7 +199,39 @@ public struct URLEncoding: ParameterEncoding { var allowedCharacterSet = CharacterSet.urlQueryAllowed allowedCharacterSet.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)") - return string.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? string + var escaped = "" + + //========================================================================================================== + // + // Batching is required for escaping due to an internal bug in iOS 8.1 and 8.2. Encoding more than a few + // hundred Chinese characters causes various malloc error crashes. To avoid this issue until iOS 8 is no + // longer supported, batching MUST be used for encoding. This introduces roughly a 20% overhead. For more + // info, please refer to: + // + // - https://github.com/Alamofire/Alamofire/issues/206 + // + //========================================================================================================== + + if #available(iOS 8.3, *) { + escaped = string.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? string + } else { + let batchSize = 50 + var index = string.startIndex + + while index != string.endIndex { + let startIndex = index + let endIndex = string.index(index, offsetBy: batchSize, limitedBy: string.endIndex) ?? string.endIndex + let range = startIndex.. String { @@ -289,6 +321,34 @@ public struct JSONEncoding: ParameterEncoding { return urlRequest } + + /// Creates a URL request by encoding the JSON object and setting the resulting data on the HTTP body. + /// + /// - parameter urlRequest: The request to apply the JSON object to. + /// - parameter jsonObject: The JSON object to apply to the request. + /// + /// - throws: An `Error` if the encoding process encounters an error. + /// + /// - returns: The encoded request. + public func encode(_ urlRequest: URLRequestConvertible, withJSONObject jsonObject: Any? = nil) throws -> URLRequest { + var urlRequest = try urlRequest.asURLRequest() + + guard let jsonObject = jsonObject else { return urlRequest } + + do { + let data = try JSONSerialization.data(withJSONObject: jsonObject, options: options) + + if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil { + urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") + } + + urlRequest.httpBody = data + } catch { + throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error)) + } + + return urlRequest + } } // MARK: - diff --git a/Pods/Alamofire/Source/Request.swift b/Pods/Alamofire/Source/Request.swift index 85eb869..8714928 100644 --- a/Pods/Alamofire/Source/Request.swift +++ b/Pods/Alamofire/Source/Request.swift @@ -110,6 +110,9 @@ open class Request { /// The response received from the server, if any. open var response: HTTPURLResponse? { return task?.response as? HTTPURLResponse } + /// The number of times the request has been retried. + open internal(set) var retryCount: UInt = 0 + let originalTask: TaskConvertible? var startTime: CFAbsoluteTime? @@ -351,13 +354,25 @@ open class DataRequest: Request { let urlRequest: URLRequest func task(session: URLSession, adapter: RequestAdapter?, queue: DispatchQueue) throws -> URLSessionTask { - let urlRequest = try self.urlRequest.adapt(using: adapter) - return queue.syncResult { session.dataTask(with: urlRequest) } + do { + let urlRequest = try self.urlRequest.adapt(using: adapter) + return queue.syncResult { session.dataTask(with: urlRequest) } + } catch { + throw AdaptError(error: error) + } } } // MARK: Properties + /// The request sent or to be sent to the server. + open override var request: URLRequest? { + if let request = super.request { return request } + if let requestable = originalTask as? Requestable { return requestable.urlRequest } + + return nil + } + /// The progress of fetching the response data from the server for the request. open var progress: Progress { return dataDelegate.progress } @@ -438,22 +453,37 @@ open class DownloadRequest: Request { case resumeData(Data) func task(session: URLSession, adapter: RequestAdapter?, queue: DispatchQueue) throws -> URLSessionTask { - let task: URLSessionTask + do { + let task: URLSessionTask - switch self { - case let .request(urlRequest): - let urlRequest = try urlRequest.adapt(using: adapter) - task = queue.syncResult { session.downloadTask(with: urlRequest) } - case let .resumeData(resumeData): - task = queue.syncResult { session.downloadTask(withResumeData: resumeData) } + switch self { + case let .request(urlRequest): + let urlRequest = try urlRequest.adapt(using: adapter) + task = queue.syncResult { session.downloadTask(with: urlRequest) } + case let .resumeData(resumeData): + task = queue.syncResult { session.downloadTask(withResumeData: resumeData) } + } + + return task + } catch { + throw AdaptError(error: error) } - - return task } } // MARK: Properties + /// The request sent or to be sent to the server. + open override var request: URLRequest? { + if let request = super.request { return request } + + if let downloadable = originalTask as? Downloadable, case let .request(urlRequest) = downloadable { + return urlRequest + } + + return nil + } + /// The resume data of the underlying download task if available after a failure. open var resumeData: Data? { return downloadDelegate.resumeData } @@ -471,7 +501,7 @@ open class DownloadRequest: Request { NotificationCenter.default.post( name: Notification.Name.Task.DidCancel, object: self, - userInfo: [Notification.Key.Task: task] + userInfo: [Notification.Key.Task: task as Any] ) } @@ -528,26 +558,42 @@ open class UploadRequest: DataRequest { case stream(InputStream, URLRequest) func task(session: URLSession, adapter: RequestAdapter?, queue: DispatchQueue) throws -> URLSessionTask { - let task: URLSessionTask + do { + let task: URLSessionTask - switch self { - case let .data(data, urlRequest): - let urlRequest = try urlRequest.adapt(using: adapter) - task = queue.syncResult { session.uploadTask(with: urlRequest, from: data) } - case let .file(url, urlRequest): - let urlRequest = try urlRequest.adapt(using: adapter) - task = queue.syncResult { session.uploadTask(with: urlRequest, fromFile: url) } - case let .stream(_, urlRequest): - let urlRequest = try urlRequest.adapt(using: adapter) - task = queue.syncResult { session.uploadTask(withStreamedRequest: urlRequest) } + switch self { + case let .data(data, urlRequest): + let urlRequest = try urlRequest.adapt(using: adapter) + task = queue.syncResult { session.uploadTask(with: urlRequest, from: data) } + case let .file(url, urlRequest): + let urlRequest = try urlRequest.adapt(using: adapter) + task = queue.syncResult { session.uploadTask(with: urlRequest, fromFile: url) } + case let .stream(_, urlRequest): + let urlRequest = try urlRequest.adapt(using: adapter) + task = queue.syncResult { session.uploadTask(withStreamedRequest: urlRequest) } + } + + return task + } catch { + throw AdaptError(error: error) } - - return task } } // MARK: Properties + /// The request sent or to be sent to the server. + open override var request: URLRequest? { + if let request = super.request { return request } + + guard let uploadable = originalTask as? Uploadable else { return nil } + + switch uploadable { + case .data(_, let urlRequest), .file(_, let urlRequest), .stream(_, let urlRequest): + return urlRequest + } + } + /// The progress of uploading the payload to the server for the upload request. open var uploadProgress: Progress { return uploadDelegate.uploadProgress } @@ -577,6 +623,7 @@ open class UploadRequest: DataRequest { #if !os(watchOS) /// Specific type of `Request` that manages an underlying `URLSessionStreamTask`. +@available(iOS 9.0, macOS 10.11, tvOS 9.0, *) open class StreamRequest: Request { enum Streamable: TaskConvertible { case stream(hostName: String, port: Int) diff --git a/Pods/Alamofire/Source/Response.swift b/Pods/Alamofire/Source/Response.swift index f80779c..ba45f6b 100644 --- a/Pods/Alamofire/Source/Response.swift +++ b/Pods/Alamofire/Source/Response.swift @@ -38,13 +38,17 @@ public struct DefaultDataResponse { /// The error encountered while executing or validating the request. public let error: Error? + /// The timeline of the complete lifecycle of the request. + public let timeline: Timeline + var _metrics: AnyObject? - init(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) { + init(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?, timeline: Timeline = Timeline()) { self.request = request self.response = response self.data = data self.error = error + self.timeline = timeline } } @@ -64,7 +68,7 @@ public struct DataResponse { /// The result of response serialization. public let result: Result - /// The timeline of the complete lifecycle of the `Request`. + /// The timeline of the complete lifecycle of the request. public let timeline: Timeline var _metrics: AnyObject? @@ -139,6 +143,9 @@ public struct DefaultDownloadResponse { /// The error encountered while executing or validating the request. public let error: Error? + /// The timeline of the complete lifecycle of the request. + public let timeline: Timeline + var _metrics: AnyObject? init( @@ -147,7 +154,8 @@ public struct DefaultDownloadResponse { temporaryURL: URL?, destinationURL: URL?, resumeData: Data?, - error: Error?) + error: Error?, + timeline: Timeline = Timeline()) { self.request = request self.response = response @@ -155,6 +163,7 @@ public struct DefaultDownloadResponse { self.destinationURL = destinationURL self.resumeData = resumeData self.error = error + self.timeline = timeline } } diff --git a/Pods/Alamofire/Source/ResponseSerialization.swift b/Pods/Alamofire/Source/ResponseSerialization.swift index 0bbb373..47780fd 100644 --- a/Pods/Alamofire/Source/ResponseSerialization.swift +++ b/Pods/Alamofire/Source/ResponseSerialization.swift @@ -84,6 +84,22 @@ public struct DownloadResponseSerializer: DownloadResponseSerializerProto } } +// MARK: - Timeline + +extension Request { + var timeline: Timeline { + let requestCompletedTime = self.endTime ?? CFAbsoluteTimeGetCurrent() + let initialResponseTime = self.delegate.initialResponseTime ?? requestCompletedTime + + return Timeline( + requestStartTime: self.startTime ?? CFAbsoluteTimeGetCurrent(), + initialResponseTime: initialResponseTime, + requestCompletedTime: requestCompletedTime, + serializationCompletedTime: CFAbsoluteTimeGetCurrent() + ) + } +} + // MARK: - Default extension DataRequest { @@ -101,7 +117,8 @@ extension DataRequest { request: self.request, response: self.response, data: self.delegate.data, - error: self.delegate.error + error: self.delegate.error, + timeline: self.timeline ) dataResponse.add(self.delegate.metrics) @@ -136,22 +153,12 @@ extension DataRequest { self.delegate.error ) - let requestCompletedTime = self.endTime ?? CFAbsoluteTimeGetCurrent() - let initialResponseTime = self.delegate.initialResponseTime ?? requestCompletedTime - - let timeline = Timeline( - requestStartTime: self.startTime ?? CFAbsoluteTimeGetCurrent(), - initialResponseTime: initialResponseTime, - requestCompletedTime: requestCompletedTime, - serializationCompletedTime: CFAbsoluteTimeGetCurrent() - ) - var dataResponse = DataResponse( request: self.request, response: self.response, data: self.delegate.data, result: result, - timeline: timeline + timeline: self.timeline ) dataResponse.add(self.delegate.metrics) @@ -184,7 +191,8 @@ extension DownloadRequest { temporaryURL: self.downloadDelegate.temporaryURL, destinationURL: self.downloadDelegate.destinationURL, resumeData: self.downloadDelegate.resumeData, - error: self.downloadDelegate.error + error: self.downloadDelegate.error, + timeline: self.timeline ) downloadResponse.add(self.delegate.metrics) @@ -219,16 +227,6 @@ extension DownloadRequest { self.downloadDelegate.error ) - let requestCompletedTime = self.endTime ?? CFAbsoluteTimeGetCurrent() - let initialResponseTime = self.delegate.initialResponseTime ?? requestCompletedTime - - let timeline = Timeline( - requestStartTime: self.startTime ?? CFAbsoluteTimeGetCurrent(), - initialResponseTime: initialResponseTime, - requestCompletedTime: requestCompletedTime, - serializationCompletedTime: CFAbsoluteTimeGetCurrent() - ) - var downloadResponse = DownloadResponse( request: self.request, response: self.response, @@ -236,7 +234,7 @@ extension DownloadRequest { destinationURL: self.downloadDelegate.destinationURL, resumeData: self.downloadDelegate.resumeData, result: result, - timeline: timeline + timeline: self.timeline ) downloadResponse.add(self.delegate.metrics) diff --git a/Pods/Alamofire/Source/SessionDelegate.swift b/Pods/Alamofire/Source/SessionDelegate.swift index 4549731..f40bf89 100644 --- a/Pods/Alamofire/Source/SessionDelegate.swift +++ b/Pods/Alamofire/Source/SessionDelegate.swift @@ -108,16 +108,53 @@ open class SessionDelegate: NSObject { #if !os(watchOS) /// Overrides default behavior for URLSessionStreamDelegate method `urlSession(_:readClosedFor:)`. - open var streamTaskReadClosed: ((URLSession, URLSessionStreamTask) -> Void)? + @available(iOS 9.0, macOS 10.11, tvOS 9.0, *) + open var streamTaskReadClosed: ((URLSession, URLSessionStreamTask) -> Void)? { + get { + return _streamTaskReadClosed as? (URLSession, URLSessionStreamTask) -> Void + } + set { + _streamTaskReadClosed = newValue + } + } /// Overrides default behavior for URLSessionStreamDelegate method `urlSession(_:writeClosedFor:)`. - open var streamTaskWriteClosed: ((URLSession, URLSessionStreamTask) -> Void)? + @available(iOS 9.0, macOS 10.11, tvOS 9.0, *) + open var streamTaskWriteClosed: ((URLSession, URLSessionStreamTask) -> Void)? { + get { + return _streamTaskWriteClosed as? (URLSession, URLSessionStreamTask) -> Void + } + set { + _streamTaskWriteClosed = newValue + } + } /// Overrides default behavior for URLSessionStreamDelegate method `urlSession(_:betterRouteDiscoveredFor:)`. - open var streamTaskBetterRouteDiscovered: ((URLSession, URLSessionStreamTask) -> Void)? + @available(iOS 9.0, macOS 10.11, tvOS 9.0, *) + open var streamTaskBetterRouteDiscovered: ((URLSession, URLSessionStreamTask) -> Void)? { + get { + return _streamTaskBetterRouteDiscovered as? (URLSession, URLSessionStreamTask) -> Void + } + set { + _streamTaskBetterRouteDiscovered = newValue + } + } /// Overrides default behavior for URLSessionStreamDelegate method `urlSession(_:streamTask:didBecome:outputStream:)`. - open var streamTaskDidBecomeInputAndOutputStreams: ((URLSession, URLSessionStreamTask, InputStream, OutputStream) -> Void)? + @available(iOS 9.0, macOS 10.11, tvOS 9.0, *) + open var streamTaskDidBecomeInputAndOutputStreams: ((URLSession, URLSessionStreamTask, InputStream, OutputStream) -> Void)? { + get { + return _streamTaskDidBecomeInputStream as? (URLSession, URLSessionStreamTask, InputStream, OutputStream) -> Void + } + set { + _streamTaskDidBecomeInputStream = newValue + } + } + + var _streamTaskReadClosed: Any? + var _streamTaskWriteClosed: Any? + var _streamTaskBetterRouteDiscovered: Any? + var _streamTaskDidBecomeInputStream: Any? #endif @@ -166,17 +203,19 @@ open class SessionDelegate: NSObject { #endif #if !os(watchOS) - switch selector { - case #selector(URLSessionStreamDelegate.urlSession(_:readClosedFor:)): - return streamTaskReadClosed != nil - case #selector(URLSessionStreamDelegate.urlSession(_:writeClosedFor:)): - return streamTaskWriteClosed != nil - case #selector(URLSessionStreamDelegate.urlSession(_:betterRouteDiscoveredFor:)): - return streamTaskBetterRouteDiscovered != nil - case #selector(URLSessionStreamDelegate.urlSession(_:streamTask:didBecome:outputStream:)): - return streamTaskDidBecomeInputAndOutputStreams != nil - default: - break + if #available(iOS 9.0, macOS 10.11, tvOS 9.0, *) { + switch selector { + case #selector(URLSessionStreamDelegate.urlSession(_:readClosedFor:)): + return streamTaskReadClosed != nil + case #selector(URLSessionStreamDelegate.urlSession(_:writeClosedFor:)): + return streamTaskWriteClosed != nil + case #selector(URLSessionStreamDelegate.urlSession(_:betterRouteDiscoveredFor:)): + return streamTaskBetterRouteDiscovered != nil + case #selector(URLSessionStreamDelegate.urlSession(_:streamTask:didBecome:outputStream:)): + return streamTaskDidBecomeInputAndOutputStreams != nil + default: + break + } } #endif @@ -637,6 +676,7 @@ extension SessionDelegate: URLSessionDownloadDelegate { #if !os(watchOS) +@available(iOS 9.0, macOS 10.11, tvOS 9.0, *) extension SessionDelegate: URLSessionStreamDelegate { /// Tells the delegate that the read side of the connection has been closed. /// diff --git a/Pods/Alamofire/Source/SessionManager.swift b/Pods/Alamofire/Source/SessionManager.swift index 1363125..2984033 100644 --- a/Pods/Alamofire/Source/SessionManager.swift +++ b/Pods/Alamofire/Source/SessionManager.swift @@ -231,12 +231,14 @@ open class SessionManager { headers: HTTPHeaders? = nil) -> DataRequest { + var originalRequest: URLRequest? + do { - let urlRequest = try URLRequest(url: url, method: method, headers: headers) - let encodedURLRequest = try encoding.encode(urlRequest, with: parameters) + originalRequest = try URLRequest(url: url, method: method, headers: headers) + let encodedURLRequest = try encoding.encode(originalRequest!, with: parameters) return request(encodedURLRequest) } catch { - return request(failedWith: error) + return request(originalRequest, failedWith: error) } } @@ -248,9 +250,11 @@ open class SessionManager { /// /// - returns: The created `DataRequest`. open func request(_ urlRequest: URLRequestConvertible) -> DataRequest { + var originalRequest: URLRequest? + do { - let originalRequest = try urlRequest.asURLRequest() - let originalTask = DataRequest.Requestable(urlRequest: originalRequest) + originalRequest = try urlRequest.asURLRequest() + let originalTask = DataRequest.Requestable(urlRequest: originalRequest!) let task = try originalTask.task(session: session, adapter: adapter, queue: queue) let request = DataRequest(session: session, requestTask: .data(originalTask, task)) @@ -261,15 +265,29 @@ open class SessionManager { return request } catch { - return request(failedWith: error) + return request(originalRequest, failedWith: error) } } // MARK: Private - Request Implementation - private func request(failedWith error: Error) -> DataRequest { - let request = DataRequest(session: session, requestTask: .data(nil, nil), error: error) - if startRequestsImmediately { request.resume() } + private func request(_ urlRequest: URLRequest?, failedWith error: Error) -> DataRequest { + var requestTask: Request.RequestTask = .data(nil, nil) + + if let urlRequest = urlRequest { + let originalTask = DataRequest.Requestable(urlRequest: urlRequest) + requestTask = .data(originalTask, nil) + } + + let underlyingError = error.underlyingAdaptError ?? error + let request = DataRequest(session: session, requestTask: requestTask, error: underlyingError) + + if let retrier = retrier, error is AdaptError { + allowRetrier(retrier, toRetry: request, with: underlyingError) + } else { + if startRequestsImmediately { request.resume() } + } + return request } @@ -308,7 +326,7 @@ open class SessionManager { let encodedURLRequest = try encoding.encode(urlRequest, with: parameters) return download(encodedURLRequest, to: destination) } catch { - return download(failedWith: error) + return download(nil, to: destination, failedWith: error) } } @@ -334,7 +352,7 @@ open class SessionManager { let urlRequest = try urlRequest.asURLRequest() return download(.request(urlRequest), to: destination) } catch { - return download(failedWith: error) + return download(nil, to: destination, failedWith: error) } } @@ -348,6 +366,13 @@ open class SessionManager { /// /// If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned. /// + /// On the latest release of all the Apple platforms (iOS 10, macOS 10.12, tvOS 10, watchOS 3), `resumeData` is broken + /// on background URL session configurations. There's an underlying bug in the `resumeData` generation logic where the + /// data is written incorrectly and will always fail to resume the download. For more information about the bug and + /// possible workarounds, please refer to the following Stack Overflow post: + /// + /// - http://stackoverflow.com/a/39347461/1342462 + /// /// - parameter resumeData: The resume data. This is an opaque data blob produced by `URLSessionDownloadTask` /// when a task is cancelled. See `URLSession -downloadTask(withResumeData:)` for /// additional information. @@ -372,23 +397,43 @@ open class SessionManager { { do { let task = try downloadable.task(session: session, adapter: adapter, queue: queue) - let request = DownloadRequest(session: session, requestTask: .download(downloadable, task)) + let download = DownloadRequest(session: session, requestTask: .download(downloadable, task)) - request.downloadDelegate.destination = destination + download.downloadDelegate.destination = destination - delegate[task] = request + delegate[task] = download - if startRequestsImmediately { request.resume() } + if startRequestsImmediately { download.resume() } - return request + return download } catch { - return download(failedWith: error) + return download(downloadable, to: destination, failedWith: error) } } - private func download(failedWith error: Error) -> DownloadRequest { - let download = DownloadRequest(session: session, requestTask: .download(nil, nil), error: error) - if startRequestsImmediately { download.resume() } + private func download( + _ downloadable: DownloadRequest.Downloadable?, + to destination: DownloadRequest.DownloadFileDestination?, + failedWith error: Error) + -> DownloadRequest + { + var downloadTask: Request.RequestTask = .download(nil, nil) + + if let downloadable = downloadable { + downloadTask = .download(downloadable, nil) + } + + let underlyingError = error.underlyingAdaptError ?? error + + let download = DownloadRequest(session: session, requestTask: downloadTask, error: underlyingError) + download.downloadDelegate.destination = destination + + if let retrier = retrier, error is AdaptError { + allowRetrier(retrier, toRetry: download, with: underlyingError) + } else { + if startRequestsImmediately { download.resume() } + } + return download } @@ -418,7 +463,7 @@ open class SessionManager { let urlRequest = try URLRequest(url: url, method: method, headers: headers) return upload(fileURL, with: urlRequest) } catch { - return upload(failedWith: error) + return upload(nil, failedWith: error) } } @@ -436,7 +481,7 @@ open class SessionManager { let urlRequest = try urlRequest.asURLRequest() return upload(.file(fileURL, urlRequest)) } catch { - return upload(failedWith: error) + return upload(nil, failedWith: error) } } @@ -464,7 +509,7 @@ open class SessionManager { let urlRequest = try URLRequest(url: url, method: method, headers: headers) return upload(data, with: urlRequest) } catch { - return upload(failedWith: error) + return upload(nil, failedWith: error) } } @@ -482,7 +527,7 @@ open class SessionManager { let urlRequest = try urlRequest.asURLRequest() return upload(.data(data, urlRequest)) } catch { - return upload(failedWith: error) + return upload(nil, failedWith: error) } } @@ -510,7 +555,7 @@ open class SessionManager { let urlRequest = try URLRequest(url: url, method: method, headers: headers) return upload(stream, with: urlRequest) } catch { - return upload(failedWith: error) + return upload(nil, failedWith: error) } } @@ -528,7 +573,7 @@ open class SessionManager { let urlRequest = try urlRequest.asURLRequest() return upload(.stream(stream, urlRequest)) } catch { - return upload(failedWith: error) + return upload(nil, failedWith: error) } } @@ -614,6 +659,8 @@ open class SessionManager { let formData = MultipartFormData() multipartFormData(formData) + var tempFileURL: URL? + do { var urlRequestWithContentType = try urlRequest.asURLRequest() urlRequestWithContentType.setValue(formData.contentType, forHTTPHeaderField: "Content-Type") @@ -637,6 +684,8 @@ open class SessionManager { let fileName = UUID().uuidString let fileURL = directoryURL.appendingPathComponent(fileName) + tempFileURL = fileURL + var directoryError: Error? // Create directory inside serial queue to ensure two threads don't do this in parallel @@ -652,16 +701,37 @@ open class SessionManager { try formData.writeEncodedData(to: fileURL) + let upload = self.upload(fileURL, with: urlRequestWithContentType) + + // Cleanup the temp file once the upload is complete + upload.delegate.queue.addOperation { + do { + try FileManager.default.removeItem(at: fileURL) + } catch { + // No-op + } + } + DispatchQueue.main.async { let encodingResult = MultipartFormDataEncodingResult.success( - request: self.upload(fileURL, with: urlRequestWithContentType), + request: upload, streamingFromDisk: true, streamFileURL: fileURL ) + encodingCompletion?(encodingResult) } } } catch { + // Cleanup the temp file in the event that the multipart form data encoding failed + if let tempFileURL = tempFileURL { + do { + try FileManager.default.removeItem(at: tempFileURL) + } catch { + // No-op + } + } + DispatchQueue.main.async { encodingCompletion?(.failure(error)) } } } @@ -684,13 +754,26 @@ open class SessionManager { return upload } catch { - return upload(failedWith: error) + return upload(uploadable, failedWith: error) } } - private func upload(failedWith error: Error) -> UploadRequest { - let upload = UploadRequest(session: session, requestTask: .upload(nil, nil), error: error) - if startRequestsImmediately { upload.resume() } + private func upload(_ uploadable: UploadRequest.Uploadable?, failedWith error: Error) -> UploadRequest { + var uploadTask: Request.RequestTask = .upload(nil, nil) + + if let uploadable = uploadable { + uploadTask = .upload(uploadable, nil) + } + + let underlyingError = error.underlyingAdaptError ?? error + let upload = UploadRequest(session: session, requestTask: uploadTask, error: underlyingError) + + if let retrier = retrier, error is AdaptError { + allowRetrier(retrier, toRetry: upload, with: underlyingError) + } else { + if startRequestsImmediately { upload.resume() } + } + return upload } @@ -709,6 +792,7 @@ open class SessionManager { /// /// - returns: The created `StreamRequest`. @discardableResult + @available(iOS 9.0, macOS 10.11, tvOS 9.0, *) open func stream(withHostName hostName: String, port: Int) -> StreamRequest { return stream(.stream(hostName: hostName, port: port)) } @@ -723,12 +807,14 @@ open class SessionManager { /// /// - returns: The created `StreamRequest`. @discardableResult + @available(iOS 9.0, macOS 10.11, tvOS 9.0, *) open func stream(with netService: NetService) -> StreamRequest { return stream(.netService(netService)) } // MARK: Private - Stream Implementation + @available(iOS 9.0, macOS 10.11, tvOS 9.0, *) private func stream(_ streamable: StreamRequest.Streamable) -> StreamRequest { do { let task = try streamable.task(session: session, adapter: adapter, queue: queue) @@ -744,6 +830,7 @@ open class SessionManager { } } + @available(iOS 9.0, macOS 10.11, tvOS 9.0, *) private func stream(failedWith error: Error) -> StreamRequest { let stream = StreamRequest(session: session, requestTask: .stream(nil, nil), error: error) if startRequestsImmediately { stream.resume() } @@ -762,6 +849,7 @@ open class SessionManager { request.delegate.task = task // resets all task delegate data + request.retryCount += 1 request.startTime = CFAbsoluteTimeGetCurrent() request.endTime = nil @@ -769,8 +857,31 @@ open class SessionManager { return true } catch { - request.delegate.error = error + request.delegate.error = error.underlyingAdaptError ?? error return false } } + + private func allowRetrier(_ retrier: RequestRetrier, toRetry request: Request, with error: Error) { + DispatchQueue.utility.async { [weak self] in + guard let strongSelf = self else { return } + + retrier.should(strongSelf, retry: request, with: error) { shouldRetry, timeDelay in + guard let strongSelf = self else { return } + + guard shouldRetry else { + if strongSelf.startRequestsImmediately { request.resume() } + return + } + + let retrySucceeded = strongSelf.retry(request) + + if retrySucceeded, let task = request.task { + strongSelf.delegate[task] = request + } else { + if strongSelf.startRequestsImmediately { request.resume() } + } + } + } + } } diff --git a/Pods/Alamofire/Source/TaskDelegate.swift b/Pods/Alamofire/Source/TaskDelegate.swift index 4a10b65..d4fd216 100644 --- a/Pods/Alamofire/Source/TaskDelegate.swift +++ b/Pods/Alamofire/Source/TaskDelegate.swift @@ -33,13 +33,16 @@ open class TaskDelegate: NSObject { /// The serial operation queue used to execute all operations after the task completes. open let queue: OperationQueue + /// The data returned by the server. + public var data: Data? { return nil } + + /// The error generated throughout the lifecyle of the task. + public var error: Error? + var task: URLSessionTask? { didSet { reset() } } - var data: Data? { return nil } - var error: Error? - var initialResponseTime: CFAbsoluteTime? var credential: URLCredential? var metrics: AnyObject? // URLSessionTaskMetrics @@ -331,29 +334,30 @@ class DownloadTaskDelegate: TaskDelegate, URLSessionDownloadDelegate { { temporaryURL = location - if let destination = destination { - let result = destination(location, downloadTask.response as! HTTPURLResponse) - let destination = result.destinationURL - let options = result.options + guard + let destination = destination, + let response = downloadTask.response as? HTTPURLResponse + else { return } - do { - destinationURL = destination + let result = destination(location, response) + let destinationURL = result.destinationURL + let options = result.options - if options.contains(.removePreviousFile) { - if FileManager.default.fileExists(atPath: destination.path) { - try FileManager.default.removeItem(at: destination) - } - } + self.destinationURL = destinationURL - if options.contains(.createIntermediateDirectories) { - let directory = destination.deletingLastPathComponent() - try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true, attributes: nil) - } - - try FileManager.default.moveItem(at: location, to: destination) - } catch { - self.error = error + do { + if options.contains(.removePreviousFile), FileManager.default.fileExists(atPath: destinationURL.path) { + try FileManager.default.removeItem(at: destinationURL) } + + if options.contains(.createIntermediateDirectories) { + let directory = destinationURL.deletingLastPathComponent() + try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true) + } + + try FileManager.default.moveItem(at: location, to: destinationURL) + } catch { + self.error = error } } diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index d1abbe2..539ffd5 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -1,20 +1,20 @@ PODS: - - Alamofire (4.0.1) + - Alamofire (4.2.0) - BRLOptionParser (0.3.1) - GCDWebServer (3.3.3): - GCDWebServer/Core (= 3.3.3) - GCDWebServer/Core (3.3.3) DEPENDENCIES: - - Alamofire (~> 4.0.1) + - Alamofire (~> 4.2.0) - BRLOptionParser (~> 0.3.1) - GCDWebServer (~> 3.0) SPEC CHECKSUMS: - Alamofire: 7682d43245de14874acd142ec137b144aa1dd335 + Alamofire: aa2e09d871c9160ac53c90e83c68064a94e3dfbe BRLOptionParser: a03256a8ff003ca1f5376c55f55f210e085a3958 GCDWebServer: 1c39a1f0763e4eb492bee021e4270fce097d3555 -PODFILE CHECKSUM: e675030dbd86de38216dc6c44e64ca1458be94bc +PODFILE CHECKSUM: d717746ef98bb719d87cee4fc334a392005fd32e -COCOAPODS: 1.0.1 +COCOAPODS: 1.2.0.beta.1 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index 13063d4..be653d2 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -7,92 +7,92 @@ objects = { /* Begin PBXBuildFile section */ - 00C1D4F2B49242121D01C05655377D07 /* GCDWebServerMultiPartFormRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = EAEC4F2E970093B9815E645E63781C40 /* GCDWebServerMultiPartFormRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 06BA2F5A0BF79A08FA2DAB3E0FFD5498 /* BRLOptionParser-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 052330BD03A0DFCDEFF81F8EC5BFEB02 /* BRLOptionParser-dummy.m */; }; - 06CE205FB95B45D7ED260AFD00AC79DD /* GCDWebServerErrorResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B884322F7F32E5886E831225EF61A24 /* GCDWebServerErrorResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 0C1B4E9FFB8B81E8833A3BAD537B1990 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B556C66780BC3D0BECF011EAF49ECB /* Notifications.swift */; }; - 12118C354EFA36292F82A8D0CFCE45B2 /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = 781B71F26694E106B9C6014A4D828CFE /* Request.swift */; }; - 15660F7531C71B00780160E7BC3A75EF /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 35133A1ADAD65BF87962F819AF44834C /* Cocoa.framework */; }; - 1B72926422971A05A1038FEF1F10DA23 /* GCDWebServerFileResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = D35A95B17B77B37E12236498D60B8478 /* GCDWebServerFileResponse.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 1BF86805992CFF0188743FC58574A612 /* GCDWebServerResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 7EA43A03295E967E8CE48DC3D41B1FB1 /* GCDWebServerResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1DBE01B20E03413F5811A7E58EB649BD /* GCDWebServerFileResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = EB10970D56AE3E8EC08A3B6CB0ECF896 /* GCDWebServerFileResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 2659AF88A6232000AB5213D46D90BF57 /* GCDWebServer-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 675C317EFB4447DD15024A74FF8C9E6C /* GCDWebServer-dummy.m */; }; - 2D93C03399B11DAF5988CEC6E4EDDE50 /* Pods-ShadowsocksX-NG-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 24B01D81E3D7058FA14A053EC19874D0 /* Pods-ShadowsocksX-NG-dummy.m */; }; - 2FD4F69F155869816E3568D2C0A328CD /* GCDWebServerDataResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = BE05C895D7CA02C6123697B3944C59D3 /* GCDWebServerDataResponse.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 34FDA8A310469061BC207ED84D065BBC /* GCDWebServerFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = A2AB24692BC4901FA1B8CD5A65C8AA62 /* GCDWebServerFunctions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 3982B850C43B41BA6D25F440F0412E9B /* Timeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2E64BA5DE520D1FF8D157D1948EF678 /* Timeline.swift */; }; - 44550BF1A67A522A640A51B30DB21069 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 35133A1ADAD65BF87962F819AF44834C /* Cocoa.framework */; }; - 44D5C1A62CB2C6B4C3BC022D80F843D1 /* GCDWebServerRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4DE2F9318899EC55FF739F09547B9F /* GCDWebServerRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 466989E9288E7804B50D2D9FDCAD8F19 /* BRLOptionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4461C7BE603BCBC96BA24E3E752C6AC0 /* BRLOptionParser.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4718BD505162FA674C844F282A692E90 /* GCDWebServerRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BD69E62A30DA9C6468DE578D50E5FB0 /* GCDWebServerRequest.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 4C505B10F8DCBA352FA9EF4514D0AC12 /* Pods-ShadowsocksX-NG-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A9EC2BB1EC6484018A5EB4B9B2C231 /* Pods-ShadowsocksX-NG-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5183D0C1CC83750A1ADE57A638E7F456 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 71153E50563B065484D16F662AD08EDB /* SystemConfiguration.framework */; }; - 53F30F986D39FC6EBE468697B2494ED5 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 35133A1ADAD65BF87962F819AF44834C /* Cocoa.framework */; }; - 59B57964B1FD13F37637947C46E77EA0 /* GCDWebServerConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C6F72ED24E84D8DC9445729D927B6E8 /* GCDWebServerConnection.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 5FAE6F4952486D7B0087309AA2F25DB0 /* GCDWebServerConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 150AAAC15A441418AEA6DFBF159FBEA0 /* GCDWebServerConnection.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 62143065F94E53F437DCE5D7A998D66D /* AFError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D86AC40F610A78D1B5E5AC9528E70ADB /* AFError.swift */; }; - 64EFFC6E05B9CACD03418CEF01429883 /* GCDWebServerFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CD28F4DA9E9FD6CDF59B9183753B0AD /* GCDWebServerFunctions.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 6B25647E430E216994070188D9E2CFF8 /* GCDWebServerDataRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 056695931D97F3BAC1F31181094FF7F0 /* GCDWebServerDataRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6D2CA7708E200C89F0DAD24F88680D46 /* GCDWebServerHTTPStatusCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = D9D61BAD16772ED8DBCD878F6BBF7025 /* GCDWebServerHTTPStatusCodes.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 743CC8268943E23DB0EADC8614FEE9BA /* GCDWebServerURLEncodedFormRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 56CBA6D73D3D0B47B5D2DCA98FD3514E /* GCDWebServerURLEncodedFormRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 749BEB3F21EAFA6D78F5631312D2C7E6 /* GCDWebServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 057330267A99F07C8ADE6135AA1F622F /* GCDWebServer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 7CA5A9BA5246FDA8227233E310029392 /* Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8D592A9C0AE4B6C90789AFF29DF516 /* Alamofire.swift */; }; - 7D747500B9BEC95D4FA0FEA5BFA6D4D4 /* GCDWebServerFileRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = D7C15E08E56E065130F76FC8DC8C8619 /* GCDWebServerFileRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8316EC11EB8EF857FC8AC924FF540076 /* GCDWebServerErrorResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CC694BC2D5AA3651FE2946D4032D0F5 /* GCDWebServerErrorResponse.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 86ED08F33B7D357932A9AB743E9D9EA7 /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC11D9EFE483BFE3E6CC4AC3CCC0E8D7 /* Response.swift */; }; - 8A400F495FB328F47971CEFD020BE9CB /* GCDWebServerStreamedResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 65715F792D70CDE4E67F1EB98531E233 /* GCDWebServerStreamedResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8B2C601594F026DF642B1F06A77C4CBB /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 35133A1ADAD65BF87962F819AF44834C /* Cocoa.framework */; }; - 8D463A0A4C65C02FDD5211F0F3C6F8B8 /* Alamofire-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 383ADB6B629F7BC3B7FB986648404A88 /* Alamofire-dummy.m */; }; - 907AB123FBC8BC9340D5B7350CE828DF /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3565E299C44D10C2D206FDCD078A0008 /* SessionDelegate.swift */; }; - 936C4E5402529DF91047CB9B84C5C281 /* GCDWebServerURLEncodedFormRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C6444C9A87ED6919A7864A0C9D70A4C /* GCDWebServerURLEncodedFormRequest.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 9469DF81ECB494E84675969B5E13374C /* Alamofire-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = BB1A40A42CB3E3DE3C7FB21A038462FD /* Alamofire-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 946AF936A5472D7D7EF243D3399A2D44 /* GCDWebServerResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 432FFBD34AE4D6FE11F7562A7B2E2DF6 /* GCDWebServerResponse.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 976C070668BB589ABDB7498633967223 /* GCDWebServerStreamedResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 41B03492069EA8D52FDD5E9F8CC3749D /* GCDWebServerStreamedResponse.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 9B0EB35B7EB06524DBD6B46D15F9E55B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 35133A1ADAD65BF87962F819AF44834C /* Cocoa.framework */; }; - A79AC30123B0C2177D67F6ED6A1B3215 /* SessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 352C9ACA5D14E48B378FF32021EAD9B4 /* SessionManager.swift */; }; - A7AF534B31209659ED4C123BC4D32A31 /* GCDWebServerFileRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 9564AF1CDDA43CCBDDB1A7A9D41FD163 /* GCDWebServerFileRequest.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - AA5A24F29D4D8831ED55AB74A2F17A71 /* GCDWebServerDataResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = B49FCFC5427009EB0DE924D8E6689486 /* GCDWebServerDataResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AF158CAAF4DD319009AFC855DC995D90 /* ParameterEncoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = C83162C9BDFB3C0617CF191D660EC2DA /* ParameterEncoding.swift */; }; - AFC0F5A350E42EDD292F2B499C13FBFD /* GCDWebServerMultiPartFormRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 5BF25F29EE771444894D4B4BD6A5094A /* GCDWebServerMultiPartFormRequest.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - B117FB3C5DADAA39C6FE0B2E2E0FD8F8 /* GCDWebServerDataRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = E02D3FE330950F96E4826E6785950F95 /* GCDWebServerDataRequest.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - B8154C96802336E5DDA5CEE97C3180A0 /* ResponseSerialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11B6EC5B2B4F6B09E9967325BF493C9D /* ResponseSerialization.swift */; }; - C0AEA97E7684DDAD56998C0AE198A433 /* ServerTrustPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193AA1B44C4CB1CFCCEDD6C9741F5211 /* ServerTrustPolicy.swift */; }; - C40F70E70A1D2FAEBFEFE14958C47FBE /* GCDWebServer-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = F5FCCAE1F4AE542376E5F228D7463E4F /* GCDWebServer-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C434F05C1EE617DA4557EF41FBE55B3E /* Pods-proxy_conf_helper-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = CE50445A73ECB9A2ED31A6FF93D45808 /* Pods-proxy_conf_helper-dummy.m */; }; - C7A3408350643ADE1018826C766EE356 /* MultipartFormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C4A7AA3B3DD74EDA43165A42745D1A /* MultipartFormData.swift */; }; - CF7724A299AEAFFC9CF29DE6124520E3 /* Pods-ShadowsocksX-NGTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = D7E8128F302CF60BEF206008CE11F6D3 /* Pods-ShadowsocksX-NGTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DE37CE3D218BBE39543E834E7BFA857C /* GCDWebServerPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = CA78677B47A82041B6A0C96CE51F76C2 /* GCDWebServerPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DF1BBF94997A2F4248B42B25EA919EC2 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1673CAE4B8238FFD59A792823A36A9DF /* Result.swift */; }; - E1F583CB4A68A928CD197250AA752926 /* TaskDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C058E7895E0BD655DB18CD87B39658B /* TaskDelegate.swift */; }; - E2A1C34237B4E928E5F85C097F4C2551 /* DispatchQueue+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2625C48AD777A2B7E26D2A80E9CD94E7 /* DispatchQueue+Alamofire.swift */; }; - E59BF19C0AFA68B741552319FC478C7B /* NetworkReachabilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7E6D819AE4FECE3068ED91259133EAC /* NetworkReachabilityManager.swift */; }; - F06A7AC16F49B8271D54543DB8F29199 /* GCDWebServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3490D661D0DB72BC3A5F94A1C6AE083C /* GCDWebServer.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - F2D887DA7E26C2F5533160A074B05EF0 /* BRLOptionParser.m in Sources */ = {isa = PBXBuildFile; fileRef = BAA6E2FFB996A81C9D31918A563B43FB /* BRLOptionParser.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - F3F3FD9096F43B73CBB52EF0E1CCF73E /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 35133A1ADAD65BF87962F819AF44834C /* Cocoa.framework */; }; - F976934F1E382AAA9975FC9E3F439B50 /* Pods-ShadowsocksX-NGTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46662EB64876AD1C891F548C69A89E89 /* Pods-ShadowsocksX-NGTests-dummy.m */; }; - FFFDD494EE6D1B83DDAF5F2721F685A6 /* Validation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6648A20B97426F9940955502FA6FF042 /* Validation.swift */; }; + 008D88E94858B0B8190DD42951253AD2 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F07CBE6988BD391FE7A0AE9BAA63882 /* Cocoa.framework */; }; + 015A2D47B6DA8E170E4E64108EC177CA /* GCDWebServerFileRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = D7C15E08E56E065130F76FC8DC8C8619 /* GCDWebServerFileRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 03810806C0578A750613717248DC37CC /* GCDWebServerPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = CA78677B47A82041B6A0C96CE51F76C2 /* GCDWebServerPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0551162B7568A0F3028CF7CE13E9C1C7 /* GCDWebServerURLEncodedFormRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C6444C9A87ED6919A7864A0C9D70A4C /* GCDWebServerURLEncodedFormRequest.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 098AA417A5494FC829E777DC5CF06ECC /* GCDWebServerURLEncodedFormRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 56CBA6D73D3D0B47B5D2DCA98FD3514E /* GCDWebServerURLEncodedFormRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0A402C97D8A2855E4F69D8E2BFEE752E /* BRLOptionParser.m in Sources */ = {isa = PBXBuildFile; fileRef = BAA6E2FFB996A81C9D31918A563B43FB /* BRLOptionParser.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 0B8140968914C908CFB4949F67745DD7 /* GCDWebServerFileResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = EB10970D56AE3E8EC08A3B6CB0ECF896 /* GCDWebServerFileResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0EC1F64B51A455E18896FCB15AE297F7 /* Pods-ShadowsocksX-NG-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A9EC2BB1EC6484018A5EB4B9B2C231 /* Pods-ShadowsocksX-NG-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 10EB23E9ECC4B33E16933BB1EA560B6A /* Timeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2E64BA5DE520D1FF8D157D1948EF678 /* Timeline.swift */; }; + 1568BC317134F1902AB76EE65E0A18CE /* GCDWebServerDataResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = B49FCFC5427009EB0DE924D8E6689486 /* GCDWebServerDataResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1AB0577134E333EA71DCCE332191A260 /* Pods-ShadowsocksX-NGTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 46662EB64876AD1C891F548C69A89E89 /* Pods-ShadowsocksX-NGTests-dummy.m */; }; + 1B9EDEDC964E6B08F78920B4F4B9DB84 /* Alamofire-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = BB1A40A42CB3E3DE3C7FB21A038462FD /* Alamofire-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1EF1D9B948C91F3CAD0F2998F3765D8B /* GCDWebServerErrorResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B884322F7F32E5886E831225EF61A24 /* GCDWebServerErrorResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2527F62CEADDA5CE60852E0C067D3438 /* GCDWebServerResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 7EA43A03295E967E8CE48DC3D41B1FB1 /* GCDWebServerResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2545E11592C408516EA9AC047FFD47FD /* BRLOptionParser-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 052330BD03A0DFCDEFF81F8EC5BFEB02 /* BRLOptionParser-dummy.m */; }; + 286A79B0F2405FD08804042FE30407B1 /* GCDWebServerMultiPartFormRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 5BF25F29EE771444894D4B4BD6A5094A /* GCDWebServerMultiPartFormRequest.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 2DBAC0452D6B85DF3E41E3AEFB4EEC16 /* Pods-ShadowsocksX-NGTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = D7E8128F302CF60BEF206008CE11F6D3 /* Pods-ShadowsocksX-NGTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 30E2A73CDE464DC6C23D3524F07FBB9F /* GCDWebServer-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = F5FCCAE1F4AE542376E5F228D7463E4F /* GCDWebServer-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 33669A1E8FF6BB34131FB94871DDF908 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F07CBE6988BD391FE7A0AE9BAA63882 /* Cocoa.framework */; }; + 35B3DA850A250223EE5CEB9DB04D1FC4 /* GCDWebServerResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 432FFBD34AE4D6FE11F7562A7B2E2DF6 /* GCDWebServerResponse.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 3626B94094672CB1C9DEA32B9F9502E1 /* TaskDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C058E7895E0BD655DB18CD87B39658B /* TaskDelegate.swift */; }; + 36E0FA5FE4424D20F0215B1C2CD85D90 /* GCDWebServerRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4DE2F9318899EC55FF739F09547B9F /* GCDWebServerRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 382EEA9832CF0E0860B998EAD0EE66E1 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49E50A971405B804294572CAAD1D1F90 /* SystemConfiguration.framework */; }; + 3DD0362B0B6B939B5D087A150121A4B1 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F07CBE6988BD391FE7A0AE9BAA63882 /* Cocoa.framework */; }; + 3E715DFE443524EB6ADE892E4A676224 /* GCDWebServerMultiPartFormRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = EAEC4F2E970093B9815E645E63781C40 /* GCDWebServerMultiPartFormRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 48FE45BD7BF4ABB32A024550ED96B4C6 /* GCDWebServerStreamedResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 41B03492069EA8D52FDD5E9F8CC3749D /* GCDWebServerStreamedResponse.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 4EDE49009B5B68074CD71F8B362F0DDC /* GCDWebServerDataRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 056695931D97F3BAC1F31181094FF7F0 /* GCDWebServerDataRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5387216E723A3C68E851CA15573CDD71 /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = 781B71F26694E106B9C6014A4D828CFE /* Request.swift */; }; + 53D63A17DB43C044EFBAA17337600276 /* GCDWebServerRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BD69E62A30DA9C6468DE578D50E5FB0 /* GCDWebServerRequest.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 5BCD116D40D884DF5E2F4DDC9E3AD53A /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F07CBE6988BD391FE7A0AE9BAA63882 /* Cocoa.framework */; }; + 61200D01A1855D7920CEF835C8BE00B0 /* DispatchQueue+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2625C48AD777A2B7E26D2A80E9CD94E7 /* DispatchQueue+Alamofire.swift */; }; + 62F65AD8DC4F0F9610F4B8B4738EC094 /* ServerTrustPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193AA1B44C4CB1CFCCEDD6C9741F5211 /* ServerTrustPolicy.swift */; }; + 66AD0D86950A5C05121AE482F5257717 /* GCDWebServerConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 150AAAC15A441418AEA6DFBF159FBEA0 /* GCDWebServerConnection.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6C62ACD1AF9B80626023D3E654D3E77B /* GCDWebServerStreamedResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 65715F792D70CDE4E67F1EB98531E233 /* GCDWebServerStreamedResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7B5FE28C7EA4122B0598738E54DBEBD8 /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3565E299C44D10C2D206FDCD078A0008 /* SessionDelegate.swift */; }; + 7B70A32CB535894B889DC0400D0DE4B5 /* GCDWebServerDataRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = E02D3FE330950F96E4826E6785950F95 /* GCDWebServerDataRequest.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 7C46C6DFBF9F5A96C6BCE1C93052B63D /* GCDWebServerHTTPStatusCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = D9D61BAD16772ED8DBCD878F6BBF7025 /* GCDWebServerHTTPStatusCodes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7D8CC01E8C9EFFF9F4D65406CDE0AB66 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1673CAE4B8238FFD59A792823A36A9DF /* Result.swift */; }; + 886E89D85907BBD7A8C8BAA088D23E3D /* GCDWebServerFileResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = D35A95B17B77B37E12236498D60B8478 /* GCDWebServerFileResponse.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 9B622302DDDA1881AC9ABA9EA4C81564 /* BRLOptionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4461C7BE603BCBC96BA24E3E752C6AC0 /* BRLOptionParser.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9DB91F7B392D045AB8451F515D20D649 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F07CBE6988BD391FE7A0AE9BAA63882 /* Cocoa.framework */; }; + 9ED2BB2981896E0A39EFA365503F58CE /* AFError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D86AC40F610A78D1B5E5AC9528E70ADB /* AFError.swift */; }; + A2A6F71B727312BD45CC7A4AAD7B0AB7 /* NetworkReachabilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7E6D819AE4FECE3068ED91259133EAC /* NetworkReachabilityManager.swift */; }; + A9EEEA7477981DEEBC72432DE9990A4B /* Alamofire-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 383ADB6B629F7BC3B7FB986648404A88 /* Alamofire-dummy.m */; }; + ADE45FBACDF07286A544DC20605FE624 /* Pods-proxy_conf_helper-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = CE50445A73ECB9A2ED31A6FF93D45808 /* Pods-proxy_conf_helper-dummy.m */; }; + AE1EF48399533730D0066E04B22CA2D6 /* SessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 352C9ACA5D14E48B378FF32021EAD9B4 /* SessionManager.swift */; }; + B65FCF589DA398C3EFE0128064E510EC /* MultipartFormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C4A7AA3B3DD74EDA43165A42745D1A /* MultipartFormData.swift */; }; + B7EF65DA3A34ABF3B41F50ADCD198BDC /* GCDWebServerFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = A2AB24692BC4901FA1B8CD5A65C8AA62 /* GCDWebServerFunctions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BBEFE2F9CEB73DC7BD97FFA66A0D9D4F /* Validation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6648A20B97426F9940955502FA6FF042 /* Validation.swift */; }; + BE5C67A07E289FE1F9BE27335B159997 /* ParameterEncoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = C83162C9BDFB3C0617CF191D660EC2DA /* ParameterEncoding.swift */; }; + C96E54153198E59FF0F8B9F7408523E0 /* GCDWebServerDataResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = BE05C895D7CA02C6123697B3944C59D3 /* GCDWebServerDataResponse.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + CB6D60925223897FFA2662667DF83E8A /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC11D9EFE483BFE3E6CC4AC3CCC0E8D7 /* Response.swift */; }; + CD97073476795E5EAA07C91A7F7890D2 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F07CBE6988BD391FE7A0AE9BAA63882 /* Cocoa.framework */; }; + D2B04C075D6CA6AF10C35D8BF7DEF0D3 /* GCDWebServerFileRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 9564AF1CDDA43CCBDDB1A7A9D41FD163 /* GCDWebServerFileRequest.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + D63E514E26A060F7C90A92AE8E9B49F9 /* GCDWebServer-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 675C317EFB4447DD15024A74FF8C9E6C /* GCDWebServer-dummy.m */; }; + D7524216B4C0994A50624825DFB7CB6B /* GCDWebServerConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C6F72ED24E84D8DC9445729D927B6E8 /* GCDWebServerConnection.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + E62DD91C60246BD1E4E8A0AF5D7BF0E7 /* GCDWebServerErrorResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CC694BC2D5AA3651FE2946D4032D0F5 /* GCDWebServerErrorResponse.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + E9E49601CF0FCF90E3E962F5DDEFD115 /* Pods-ShadowsocksX-NG-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 24B01D81E3D7058FA14A053EC19874D0 /* Pods-ShadowsocksX-NG-dummy.m */; }; + EA6D2E46B967F447FFC46520EC328B5E /* GCDWebServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 057330267A99F07C8ADE6135AA1F622F /* GCDWebServer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EFD264FC408EBF3BA2528E70B08DDD94 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B556C66780BC3D0BECF011EAF49ECB /* Notifications.swift */; }; + F359857602B1D4C91B4AC3D1A2CDFE1B /* GCDWebServerFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CD28F4DA9E9FD6CDF59B9183753B0AD /* GCDWebServerFunctions.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + F6BECD98B97CBFEBE2C96F0E9E72A6C0 /* ResponseSerialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11B6EC5B2B4F6B09E9967325BF493C9D /* ResponseSerialization.swift */; }; + F8B3D3092ED0417E8CDF32033F6122F5 /* Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8D592A9C0AE4B6C90789AFF29DF516 /* Alamofire.swift */; }; + FBF219CBB84DD6F373B818708C889C9D /* GCDWebServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3490D661D0DB72BC3A5F94A1C6AE083C /* GCDWebServer.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 73C64E43E31999AF7C2B373FA34C2235 /* PBXContainerItemProxy */ = { + 408240F5321FFD1270C133C590B77FEC /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; - remoteGlobalIDString = 79C040AFDDCE1BCBF6D8B5EB0B85887F; + remoteGlobalIDString = 88E9EC28B8B46C3631E6B242B50F4442; remoteInfo = Alamofire; }; - E895AA04EEFEDDCA3F15E606C7C3C10A /* PBXContainerItemProxy */ = { + 7D7286FD822FB02FEAECE006469945BB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; - remoteGlobalIDString = 8DADB076AFECDBAADF5E2B19FB72188A; + remoteGlobalIDString = 5B8B0ED1046111D92895FC95F12DBC10; remoteInfo = GCDWebServer; }; - F1C53463E9DF7371C2384C5C32B425B6 /* PBXContainerItemProxy */ = { + FDE579D9762D0D9F86EDB1DE6EADE62F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; - remoteGlobalIDString = 7AD154F318B10A340D705FD3003EAAC6; + remoteGlobalIDString = 3CB2B8006B2B1ACAF9ADCA1DC82E2290; remoteInfo = BRLOptionParser; }; /* End PBXContainerItemProxy section */ @@ -123,7 +123,6 @@ 2D644FB3545AF46CBD6ED919703E7147 /* Alamofire-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-prefix.pch"; sourceTree = ""; }; 3358F45A5BEC1A7F725167CD1969EDC8 /* Pods-ShadowsocksX-NG-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-ShadowsocksX-NG-acknowledgements.markdown"; sourceTree = ""; }; 3490D661D0DB72BC3A5F94A1C6AE083C /* GCDWebServer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GCDWebServer.m; path = GCDWebServer/Core/GCDWebServer.m; sourceTree = ""; }; - 35133A1ADAD65BF87962F819AF44834C /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; }; 352C9ACA5D14E48B378FF32021EAD9B4 /* SessionManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionManager.swift; path = Source/SessionManager.swift; sourceTree = ""; }; 3565E299C44D10C2D206FDCD078A0008 /* SessionDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDelegate.swift; path = Source/SessionDelegate.swift; sourceTree = ""; }; 383ADB6B629F7BC3B7FB986648404A88 /* Alamofire-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Alamofire-dummy.m"; sourceTree = ""; }; @@ -131,6 +130,7 @@ 432FFBD34AE4D6FE11F7562A7B2E2DF6 /* GCDWebServerResponse.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GCDWebServerResponse.m; path = GCDWebServer/Core/GCDWebServerResponse.m; sourceTree = ""; }; 4461C7BE603BCBC96BA24E3E752C6AC0 /* BRLOptionParser.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BRLOptionParser.h; path = BRLOptionParser/BRLOptionParser.h; sourceTree = ""; }; 46662EB64876AD1C891F548C69A89E89 /* Pods-ShadowsocksX-NGTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-ShadowsocksX-NGTests-dummy.m"; sourceTree = ""; }; + 49E50A971405B804294572CAAD1D1F90 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; }; 4BD69E62A30DA9C6468DE578D50E5FB0 /* GCDWebServerRequest.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GCDWebServerRequest.m; path = GCDWebServer/Core/GCDWebServerRequest.m; sourceTree = ""; }; 52F51F94701ABD692BFFC9F92AE2E115 /* Pods-ShadowsocksX-NG-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-ShadowsocksX-NG-acknowledgements.plist"; sourceTree = ""; }; 56CBA6D73D3D0B47B5D2DCA98FD3514E /* GCDWebServerURLEncodedFormRequest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerURLEncodedFormRequest.h; path = GCDWebServer/Requests/GCDWebServerURLEncodedFormRequest.h; sourceTree = ""; }; @@ -142,7 +142,6 @@ 65715F792D70CDE4E67F1EB98531E233 /* GCDWebServerStreamedResponse.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerStreamedResponse.h; path = GCDWebServer/Responses/GCDWebServerStreamedResponse.h; sourceTree = ""; }; 6648A20B97426F9940955502FA6FF042 /* Validation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Validation.swift; path = Source/Validation.swift; sourceTree = ""; }; 675C317EFB4447DD15024A74FF8C9E6C /* GCDWebServer-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "GCDWebServer-dummy.m"; sourceTree = ""; }; - 71153E50563B065484D16F662AD08EDB /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; }; 781B71F26694E106B9C6014A4D828CFE /* Request.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Request.swift; path = Source/Request.swift; sourceTree = ""; }; 78FDF9432C1735D2CE78FC0BBD37B6D3 /* GCDWebServer.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = GCDWebServer.modulemap; sourceTree = ""; }; 7B884322F7F32E5886E831225EF61A24 /* GCDWebServerErrorResponse.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerErrorResponse.h; path = GCDWebServer/Responses/GCDWebServerErrorResponse.h; sourceTree = ""; }; @@ -159,6 +158,7 @@ 98522BF2EB25C0255284080F9CA3E195 /* Pods-ShadowsocksX-NG.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ShadowsocksX-NG.debug.xcconfig"; sourceTree = ""; }; 9B8B5CBA357BDB968C73E8F58DFBC74C /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 9BA2A0099476E08B6CC8026BDF0C603E /* Pods-ShadowsocksX-NGTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ShadowsocksX-NGTests.debug.xcconfig"; sourceTree = ""; }; + 9F07CBE6988BD391FE7A0AE9BAA63882 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; }; A2AB24692BC4901FA1B8CD5A65C8AA62 /* GCDWebServerFunctions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerFunctions.h; path = GCDWebServer/Core/GCDWebServerFunctions.h; sourceTree = ""; }; A5055B8EFFFBEDE50909E935D4BCA446 /* Pods-proxy_conf_helper.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-proxy_conf_helper.release.xcconfig"; sourceTree = ""; }; A51D2862E977EC32406F9AB39ECEC3BF /* GCDWebServer-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GCDWebServer-prefix.pch"; sourceTree = ""; }; @@ -199,67 +199,58 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 644D7073D43F0C3168D56462D23A1E62 /* Frameworks */ = { + 6E7F016811926ED895957BC5F8CE3ACA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9B0EB35B7EB06524DBD6B46D15F9E55B /* Cocoa.framework in Frameworks */, + 5BCD116D40D884DF5E2F4DDC9E3AD53A /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 86631BCDD6995CFD2A8A7716F3673282 /* Frameworks */ = { + 7E718F9F87ABFC0EC82CF710FAF92DC4 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F3F3FD9096F43B73CBB52EF0E1CCF73E /* Cocoa.framework in Frameworks */, + 33669A1E8FF6BB34131FB94871DDF908 /* Cocoa.framework in Frameworks */, + 382EEA9832CF0E0860B998EAD0EE66E1 /* SystemConfiguration.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - AB147E21E0AB36B5E26650D526EE24B0 /* Frameworks */ = { + B14D21A682C80219D90189FAC9A7DDDF /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8B2C601594F026DF642B1F06A77C4CBB /* Cocoa.framework in Frameworks */, + 9DB91F7B392D045AB8451F515D20D649 /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - B301BDF47623A07531A7025565B54DC5 /* Frameworks */ = { + BC15E0C98F4999B51186E4915D7B5660 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 15660F7531C71B00780160E7BC3A75EF /* Cocoa.framework in Frameworks */, - 5183D0C1CC83750A1ADE57A638E7F456 /* SystemConfiguration.framework in Frameworks */, + CD97073476795E5EAA07C91A7F7890D2 /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - C81A3D9DE7D5F1A9FD254497C673A6BA /* Frameworks */ = { + BFC962BBCB4EEE8B8C42B979F2D19C34 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 44550BF1A67A522A640A51B30DB21069 /* Cocoa.framework in Frameworks */, + 3DD0362B0B6B939B5D087A150121A4B1 /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - F0EA5BEE5D5781833D5031FB44647FD1 /* Frameworks */ = { + C8718142612A4E100493606F033235C0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 53F30F986D39FC6EBE468697B2494ED5 /* Cocoa.framework in Frameworks */, + 008D88E94858B0B8190DD42951253AD2 /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 009866DA8729A04594F6795F91341C8C /* OS X */ = { - isa = PBXGroup; - children = ( - 35133A1ADAD65BF87962F819AF44834C /* Cocoa.framework */, - 71153E50563B065484D16F662AD08EDB /* SystemConfiguration.framework */, - ); - name = "OS X"; - sourceTree = ""; - }; 07568FCBBF071BD2EE0E5EBA001A4712 /* Pods-ShadowsocksX-NGTests */ = { isa = PBXGroup; children = ( @@ -313,6 +304,15 @@ path = BRLOptionParser; sourceTree = ""; }; + 648D916E57015940B3943E2D877A7EFA /* OS X */ = { + isa = PBXGroup; + children = ( + 9F07CBE6988BD391FE7A0AE9BAA63882 /* Cocoa.framework */, + 49E50A971405B804294572CAAD1D1F90 /* SystemConfiguration.framework */, + ); + name = "OS X"; + sourceTree = ""; + }; 785842678515C4CDC9428DD20DCD752D /* Targets Support Files */ = { isa = PBXGroup; children = ( @@ -457,7 +457,7 @@ D648CE86F139C7CCFD55D5B8A03BE74B /* Frameworks */ = { isa = PBXGroup; children = ( - 009866DA8729A04594F6795F91341C8C /* OS X */, + 648D916E57015940B3943E2D877A7EFA /* OS X */, ); name = Frameworks; sourceTree = ""; @@ -484,139 +484,88 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 0F8EA6AC53B53E6057C6A19C165F84D7 /* Headers */ = { + 49E47E8FB0395F70E77651B02346BF41 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 4C505B10F8DCBA352FA9EF4514D0AC12 /* Pods-ShadowsocksX-NG-umbrella.h in Headers */, + 2DBAC0452D6B85DF3E41E3AEFB4EEC16 /* Pods-ShadowsocksX-NGTests-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 0FC6EB28B2F6E2A523EE04368E3DC5F7 /* Headers */ = { + 6B9981C9382CA48E42CADD9274429C8D /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - CF7724A299AEAFFC9CF29DE6124520E3 /* Pods-ShadowsocksX-NGTests-umbrella.h in Headers */, + 30E2A73CDE464DC6C23D3524F07FBB9F /* GCDWebServer-umbrella.h in Headers */, + EA6D2E46B967F447FFC46520EC328B5E /* GCDWebServer.h in Headers */, + 66AD0D86950A5C05121AE482F5257717 /* GCDWebServerConnection.h in Headers */, + 4EDE49009B5B68074CD71F8B362F0DDC /* GCDWebServerDataRequest.h in Headers */, + 1568BC317134F1902AB76EE65E0A18CE /* GCDWebServerDataResponse.h in Headers */, + 1EF1D9B948C91F3CAD0F2998F3765D8B /* GCDWebServerErrorResponse.h in Headers */, + 015A2D47B6DA8E170E4E64108EC177CA /* GCDWebServerFileRequest.h in Headers */, + 0B8140968914C908CFB4949F67745DD7 /* GCDWebServerFileResponse.h in Headers */, + B7EF65DA3A34ABF3B41F50ADCD198BDC /* GCDWebServerFunctions.h in Headers */, + 7C46C6DFBF9F5A96C6BCE1C93052B63D /* GCDWebServerHTTPStatusCodes.h in Headers */, + 3E715DFE443524EB6ADE892E4A676224 /* GCDWebServerMultiPartFormRequest.h in Headers */, + 03810806C0578A750613717248DC37CC /* GCDWebServerPrivate.h in Headers */, + 36E0FA5FE4424D20F0215B1C2CD85D90 /* GCDWebServerRequest.h in Headers */, + 2527F62CEADDA5CE60852E0C067D3438 /* GCDWebServerResponse.h in Headers */, + 6C62ACD1AF9B80626023D3E654D3E77B /* GCDWebServerStreamedResponse.h in Headers */, + 098AA417A5494FC829E777DC5CF06ECC /* GCDWebServerURLEncodedFormRequest.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 121728020127207BFCA6A27073898473 /* Headers */ = { + B4002B6E97835FDCCAA5963EFE09A3E0 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 466989E9288E7804B50D2D9FDCAD8F19 /* BRLOptionParser.h in Headers */, + 1B9EDEDC964E6B08F78920B4F4B9DB84 /* Alamofire-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - D9BF5E3F1B461B3BD89FA515D5D28535 /* Headers */ = { + D6D75A22098E62174AFAD752CA5F6BEC /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - C40F70E70A1D2FAEBFEFE14958C47FBE /* GCDWebServer-umbrella.h in Headers */, - 749BEB3F21EAFA6D78F5631312D2C7E6 /* GCDWebServer.h in Headers */, - 5FAE6F4952486D7B0087309AA2F25DB0 /* GCDWebServerConnection.h in Headers */, - 6B25647E430E216994070188D9E2CFF8 /* GCDWebServerDataRequest.h in Headers */, - AA5A24F29D4D8831ED55AB74A2F17A71 /* GCDWebServerDataResponse.h in Headers */, - 06CE205FB95B45D7ED260AFD00AC79DD /* GCDWebServerErrorResponse.h in Headers */, - 7D747500B9BEC95D4FA0FEA5BFA6D4D4 /* GCDWebServerFileRequest.h in Headers */, - 1DBE01B20E03413F5811A7E58EB649BD /* GCDWebServerFileResponse.h in Headers */, - 34FDA8A310469061BC207ED84D065BBC /* GCDWebServerFunctions.h in Headers */, - 6D2CA7708E200C89F0DAD24F88680D46 /* GCDWebServerHTTPStatusCodes.h in Headers */, - 00C1D4F2B49242121D01C05655377D07 /* GCDWebServerMultiPartFormRequest.h in Headers */, - DE37CE3D218BBE39543E834E7BFA857C /* GCDWebServerPrivate.h in Headers */, - 44D5C1A62CB2C6B4C3BC022D80F843D1 /* GCDWebServerRequest.h in Headers */, - 1BF86805992CFF0188743FC58574A612 /* GCDWebServerResponse.h in Headers */, - 8A400F495FB328F47971CEFD020BE9CB /* GCDWebServerStreamedResponse.h in Headers */, - 743CC8268943E23DB0EADC8614FEE9BA /* GCDWebServerURLEncodedFormRequest.h in Headers */, + 9B622302DDDA1881AC9ABA9EA4C81564 /* BRLOptionParser.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - EFDF3B631BBB965A372347705CA14854 /* Headers */ = { + F52931F6A771F68236D6B3E7B0F95DD8 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 9469DF81ECB494E84675969B5E13374C /* Alamofire-umbrella.h in Headers */, + 0EC1F64B51A455E18896FCB15AE297F7 /* Pods-ShadowsocksX-NG-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 3F0FDAFB5467946C22EE9F2EC643E2B0 /* Pods-proxy_conf_helper */ = { + 05800FAF969AA3CD7F8AEB1C36988B53 /* Pods-proxy_conf_helper */ = { isa = PBXNativeTarget; - buildConfigurationList = F1E46DE142216CD3C0327D20F3073961 /* Build configuration list for PBXNativeTarget "Pods-proxy_conf_helper" */; + buildConfigurationList = 246647E8AB354727F9ECD0879805161F /* Build configuration list for PBXNativeTarget "Pods-proxy_conf_helper" */; buildPhases = ( - 4EAA284BFC07AC421BF366F1EB9B757F /* Sources */, - F0EA5BEE5D5781833D5031FB44647FD1 /* Frameworks */, + B8B68DF2BFB4B345BDF00E3B4B94B92C /* Sources */, + BFC962BBCB4EEE8B8C42B979F2D19C34 /* Frameworks */, ); buildRules = ( ); dependencies = ( - 7C10FF72EF971F45066B238F3B2BCDC2 /* PBXTargetDependency */, + 7C03549F53DE7DA200E36C0642A79977 /* PBXTargetDependency */, ); name = "Pods-proxy_conf_helper"; productName = "Pods-proxy_conf_helper"; productReference = D534FA8B75596A674095DAA7CA3B08D1 /* libPods-proxy_conf_helper.a */; productType = "com.apple.product-type.library.static"; }; - 79C040AFDDCE1BCBF6D8B5EB0B85887F /* Alamofire */ = { + 339CC546E4A1696296EFEDC2FA79ADE0 /* Pods-ShadowsocksX-NGTests */ = { isa = PBXNativeTarget; - buildConfigurationList = 3CFB42910790CF0BDBCCEBAACD6B9367 /* Build configuration list for PBXNativeTarget "Alamofire" */; + buildConfigurationList = 78B338CAC10BFFE58C0DE5D189212D60 /* Build configuration list for PBXNativeTarget "Pods-ShadowsocksX-NGTests" */; buildPhases = ( - 120C4E824DDCCA024C170A491FF221A5 /* Sources */, - 86631BCDD6995CFD2A8A7716F3673282 /* Frameworks */, - EFDF3B631BBB965A372347705CA14854 /* Headers */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Alamofire; - productName = Alamofire; - productReference = BA947346171BBF9CB75B49AF462D0A14 /* Alamofire.framework */; - productType = "com.apple.product-type.framework"; - }; - 7AD154F318B10A340D705FD3003EAAC6 /* BRLOptionParser */ = { - isa = PBXNativeTarget; - buildConfigurationList = 0174BA27A62F6F29EEDC03CA3FB0A9C4 /* Build configuration list for PBXNativeTarget "BRLOptionParser" */; - buildPhases = ( - 53EDB8E624E634651BB754FE71BCB15E /* Sources */, - AB147E21E0AB36B5E26650D526EE24B0 /* Frameworks */, - 121728020127207BFCA6A27073898473 /* Headers */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = BRLOptionParser; - productName = BRLOptionParser; - productReference = 5E949AC812278EA6428E8B1B3F4567E5 /* libBRLOptionParser.a */; - productType = "com.apple.product-type.library.static"; - }; - 8DADB076AFECDBAADF5E2B19FB72188A /* GCDWebServer */ = { - isa = PBXNativeTarget; - buildConfigurationList = 16ED0890B237DF1B16DA47D0E14DB4DD /* Build configuration list for PBXNativeTarget "GCDWebServer" */; - buildPhases = ( - 5761E9EE01E570A31C13FCC75B0E3EB0 /* Sources */, - B301BDF47623A07531A7025565B54DC5 /* Frameworks */, - D9BF5E3F1B461B3BD89FA515D5D28535 /* Headers */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = GCDWebServer; - productName = GCDWebServer; - productReference = 29F1D38D8FBC1D989199E905EA6CA548 /* GCDWebServer.framework */; - productType = "com.apple.product-type.framework"; - }; - 9D7253CF594B2D7CB8127F7CCAFF916F /* Pods-ShadowsocksX-NGTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 757EEB566CE14B3A8210DD4A32EBDD7A /* Build configuration list for PBXNativeTarget "Pods-ShadowsocksX-NGTests" */; - buildPhases = ( - 11900A69B6F5C76B91A40DD81CC30137 /* Sources */, - C81A3D9DE7D5F1A9FD254497C673A6BA /* Frameworks */, - 0FC6EB28B2F6E2A523EE04368E3DC5F7 /* Headers */, + AFD9223E8E59CD878E1C56F1407DA2C8 /* Sources */, + BC15E0C98F4999B51186E4915D7B5660 /* Frameworks */, + 49E47E8FB0395F70E77651B02346BF41 /* Headers */, ); buildRules = ( ); @@ -627,25 +576,76 @@ productReference = A628D7F35A0F9EBD66407BDCC9C92D20 /* Pods_ShadowsocksX_NGTests.framework */; productType = "com.apple.product-type.framework"; }; - F69966EE760BB16DE7009DBE04D8B18D /* Pods-ShadowsocksX-NG */ = { + 3CB2B8006B2B1ACAF9ADCA1DC82E2290 /* BRLOptionParser */ = { isa = PBXNativeTarget; - buildConfigurationList = 4AC88E06DEFEEDAF5DAA6F0F774D05D4 /* Build configuration list for PBXNativeTarget "Pods-ShadowsocksX-NG" */; + buildConfigurationList = 4B561109B4C51E9DC9F5F27E9C033405 /* Build configuration list for PBXNativeTarget "BRLOptionParser" */; buildPhases = ( - 9C086154608D1205F5A92B4645B6E785 /* Sources */, - 644D7073D43F0C3168D56462D23A1E62 /* Frameworks */, - 0F8EA6AC53B53E6057C6A19C165F84D7 /* Headers */, + 2899546AD56DA12F9B03BC5050860413 /* Sources */, + C8718142612A4E100493606F033235C0 /* Frameworks */, + D6D75A22098E62174AFAD752CA5F6BEC /* Headers */, ); buildRules = ( ); dependencies = ( - 54F37EFBCE086D0667D0893860A8BEC4 /* PBXTargetDependency */, - 2E540C786B1F4BF64B47EA0B320C67F2 /* PBXTargetDependency */, + ); + name = BRLOptionParser; + productName = BRLOptionParser; + productReference = 5E949AC812278EA6428E8B1B3F4567E5 /* libBRLOptionParser.a */; + productType = "com.apple.product-type.library.static"; + }; + 5B8B0ED1046111D92895FC95F12DBC10 /* GCDWebServer */ = { + isa = PBXNativeTarget; + buildConfigurationList = 010811070A86F912EA0CD2BB98136CD9 /* Build configuration list for PBXNativeTarget "GCDWebServer" */; + buildPhases = ( + 81F40976E91E102E115D6BE30CCC18E9 /* Sources */, + 7E718F9F87ABFC0EC82CF710FAF92DC4 /* Frameworks */, + 6B9981C9382CA48E42CADD9274429C8D /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GCDWebServer; + productName = GCDWebServer; + productReference = 29F1D38D8FBC1D989199E905EA6CA548 /* GCDWebServer.framework */; + productType = "com.apple.product-type.framework"; + }; + 76AB1BA247F8CB57FCB2BA6577D40FE6 /* Pods-ShadowsocksX-NG */ = { + isa = PBXNativeTarget; + buildConfigurationList = BFE80AF401A02D5658D84A694BE7A3CE /* Build configuration list for PBXNativeTarget "Pods-ShadowsocksX-NG" */; + buildPhases = ( + D58B98E801980FD3514B9C96F2FEBA64 /* Sources */, + 6E7F016811926ED895957BC5F8CE3ACA /* Frameworks */, + F52931F6A771F68236D6B3E7B0F95DD8 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + 49BA5C047101B8A959AF5E17B7DBCDD4 /* PBXTargetDependency */, + 3C89DE54CAB947747F7F2F6907F40D6E /* PBXTargetDependency */, ); name = "Pods-ShadowsocksX-NG"; productName = "Pods-ShadowsocksX-NG"; productReference = FB6A7098E32F88CAD8F6D0BB8E334D4C /* Pods_ShadowsocksX_NG.framework */; productType = "com.apple.product-type.framework"; }; + 88E9EC28B8B46C3631E6B242B50F4442 /* Alamofire */ = { + isa = PBXNativeTarget; + buildConfigurationList = 419E5D95491847CD79841B971A8A3277 /* Build configuration list for PBXNativeTarget "Alamofire" */; + buildPhases = ( + 32B9974868188C4803318E36329C87FE /* Sources */, + B14D21A682C80219D90189FAC9A7DDDF /* Frameworks */, + B4002B6E97835FDCCAA5963EFE09A3E0 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Alamofire; + productName = Alamofire; + productReference = BA947346171BBF9CB75B49AF462D0A14 /* Alamofire.framework */; + productType = "com.apple.product-type.framework"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -653,15 +653,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0730; - LastUpgradeCheck = 0700; - TargetAttributes = { - 79C040AFDDCE1BCBF6D8B5EB0B85887F = { - LastSwiftMigration = 0800; - }; - F69966EE760BB16DE7009DBE04D8B18D = { - LastSwiftMigration = 0800; - }; - }; + LastUpgradeCheck = 0810; }; buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; compatibilityVersion = "Xcode 3.2"; @@ -675,125 +667,249 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 79C040AFDDCE1BCBF6D8B5EB0B85887F /* Alamofire */, - 7AD154F318B10A340D705FD3003EAAC6 /* BRLOptionParser */, - 8DADB076AFECDBAADF5E2B19FB72188A /* GCDWebServer */, - 3F0FDAFB5467946C22EE9F2EC643E2B0 /* Pods-proxy_conf_helper */, - F69966EE760BB16DE7009DBE04D8B18D /* Pods-ShadowsocksX-NG */, - 9D7253CF594B2D7CB8127F7CCAFF916F /* Pods-ShadowsocksX-NGTests */, + 88E9EC28B8B46C3631E6B242B50F4442 /* Alamofire */, + 3CB2B8006B2B1ACAF9ADCA1DC82E2290 /* BRLOptionParser */, + 5B8B0ED1046111D92895FC95F12DBC10 /* GCDWebServer */, + 05800FAF969AA3CD7F8AEB1C36988B53 /* Pods-proxy_conf_helper */, + 76AB1BA247F8CB57FCB2BA6577D40FE6 /* Pods-ShadowsocksX-NG */, + 339CC546E4A1696296EFEDC2FA79ADE0 /* Pods-ShadowsocksX-NGTests */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ - 11900A69B6F5C76B91A40DD81CC30137 /* Sources */ = { + 2899546AD56DA12F9B03BC5050860413 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - F976934F1E382AAA9975FC9E3F439B50 /* Pods-ShadowsocksX-NGTests-dummy.m in Sources */, + 2545E11592C408516EA9AC047FFD47FD /* BRLOptionParser-dummy.m in Sources */, + 0A402C97D8A2855E4F69D8E2BFEE752E /* BRLOptionParser.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 120C4E824DDCCA024C170A491FF221A5 /* Sources */ = { + 32B9974868188C4803318E36329C87FE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 62143065F94E53F437DCE5D7A998D66D /* AFError.swift in Sources */, - 8D463A0A4C65C02FDD5211F0F3C6F8B8 /* Alamofire-dummy.m in Sources */, - 7CA5A9BA5246FDA8227233E310029392 /* Alamofire.swift in Sources */, - E2A1C34237B4E928E5F85C097F4C2551 /* DispatchQueue+Alamofire.swift in Sources */, - C7A3408350643ADE1018826C766EE356 /* MultipartFormData.swift in Sources */, - E59BF19C0AFA68B741552319FC478C7B /* NetworkReachabilityManager.swift in Sources */, - 0C1B4E9FFB8B81E8833A3BAD537B1990 /* Notifications.swift in Sources */, - AF158CAAF4DD319009AFC855DC995D90 /* ParameterEncoding.swift in Sources */, - 12118C354EFA36292F82A8D0CFCE45B2 /* Request.swift in Sources */, - 86ED08F33B7D357932A9AB743E9D9EA7 /* Response.swift in Sources */, - B8154C96802336E5DDA5CEE97C3180A0 /* ResponseSerialization.swift in Sources */, - DF1BBF94997A2F4248B42B25EA919EC2 /* Result.swift in Sources */, - C0AEA97E7684DDAD56998C0AE198A433 /* ServerTrustPolicy.swift in Sources */, - 907AB123FBC8BC9340D5B7350CE828DF /* SessionDelegate.swift in Sources */, - A79AC30123B0C2177D67F6ED6A1B3215 /* SessionManager.swift in Sources */, - E1F583CB4A68A928CD197250AA752926 /* TaskDelegate.swift in Sources */, - 3982B850C43B41BA6D25F440F0412E9B /* Timeline.swift in Sources */, - FFFDD494EE6D1B83DDAF5F2721F685A6 /* Validation.swift in Sources */, + 9ED2BB2981896E0A39EFA365503F58CE /* AFError.swift in Sources */, + A9EEEA7477981DEEBC72432DE9990A4B /* Alamofire-dummy.m in Sources */, + F8B3D3092ED0417E8CDF32033F6122F5 /* Alamofire.swift in Sources */, + 61200D01A1855D7920CEF835C8BE00B0 /* DispatchQueue+Alamofire.swift in Sources */, + B65FCF589DA398C3EFE0128064E510EC /* MultipartFormData.swift in Sources */, + A2A6F71B727312BD45CC7A4AAD7B0AB7 /* NetworkReachabilityManager.swift in Sources */, + EFD264FC408EBF3BA2528E70B08DDD94 /* Notifications.swift in Sources */, + BE5C67A07E289FE1F9BE27335B159997 /* ParameterEncoding.swift in Sources */, + 5387216E723A3C68E851CA15573CDD71 /* Request.swift in Sources */, + CB6D60925223897FFA2662667DF83E8A /* Response.swift in Sources */, + F6BECD98B97CBFEBE2C96F0E9E72A6C0 /* ResponseSerialization.swift in Sources */, + 7D8CC01E8C9EFFF9F4D65406CDE0AB66 /* Result.swift in Sources */, + 62F65AD8DC4F0F9610F4B8B4738EC094 /* ServerTrustPolicy.swift in Sources */, + 7B5FE28C7EA4122B0598738E54DBEBD8 /* SessionDelegate.swift in Sources */, + AE1EF48399533730D0066E04B22CA2D6 /* SessionManager.swift in Sources */, + 3626B94094672CB1C9DEA32B9F9502E1 /* TaskDelegate.swift in Sources */, + 10EB23E9ECC4B33E16933BB1EA560B6A /* Timeline.swift in Sources */, + BBEFE2F9CEB73DC7BD97FFA66A0D9D4F /* Validation.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4EAA284BFC07AC421BF366F1EB9B757F /* Sources */ = { + 81F40976E91E102E115D6BE30CCC18E9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C434F05C1EE617DA4557EF41FBE55B3E /* Pods-proxy_conf_helper-dummy.m in Sources */, + D63E514E26A060F7C90A92AE8E9B49F9 /* GCDWebServer-dummy.m in Sources */, + FBF219CBB84DD6F373B818708C889C9D /* GCDWebServer.m in Sources */, + D7524216B4C0994A50624825DFB7CB6B /* GCDWebServerConnection.m in Sources */, + 7B70A32CB535894B889DC0400D0DE4B5 /* GCDWebServerDataRequest.m in Sources */, + C96E54153198E59FF0F8B9F7408523E0 /* GCDWebServerDataResponse.m in Sources */, + E62DD91C60246BD1E4E8A0AF5D7BF0E7 /* GCDWebServerErrorResponse.m in Sources */, + D2B04C075D6CA6AF10C35D8BF7DEF0D3 /* GCDWebServerFileRequest.m in Sources */, + 886E89D85907BBD7A8C8BAA088D23E3D /* GCDWebServerFileResponse.m in Sources */, + F359857602B1D4C91B4AC3D1A2CDFE1B /* GCDWebServerFunctions.m in Sources */, + 286A79B0F2405FD08804042FE30407B1 /* GCDWebServerMultiPartFormRequest.m in Sources */, + 53D63A17DB43C044EFBAA17337600276 /* GCDWebServerRequest.m in Sources */, + 35B3DA850A250223EE5CEB9DB04D1FC4 /* GCDWebServerResponse.m in Sources */, + 48FE45BD7BF4ABB32A024550ED96B4C6 /* GCDWebServerStreamedResponse.m in Sources */, + 0551162B7568A0F3028CF7CE13E9C1C7 /* GCDWebServerURLEncodedFormRequest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 53EDB8E624E634651BB754FE71BCB15E /* Sources */ = { + AFD9223E8E59CD878E1C56F1407DA2C8 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 06BA2F5A0BF79A08FA2DAB3E0FFD5498 /* BRLOptionParser-dummy.m in Sources */, - F2D887DA7E26C2F5533160A074B05EF0 /* BRLOptionParser.m in Sources */, + 1AB0577134E333EA71DCCE332191A260 /* Pods-ShadowsocksX-NGTests-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 5761E9EE01E570A31C13FCC75B0E3EB0 /* Sources */ = { + B8B68DF2BFB4B345BDF00E3B4B94B92C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 2659AF88A6232000AB5213D46D90BF57 /* GCDWebServer-dummy.m in Sources */, - F06A7AC16F49B8271D54543DB8F29199 /* GCDWebServer.m in Sources */, - 59B57964B1FD13F37637947C46E77EA0 /* GCDWebServerConnection.m in Sources */, - B117FB3C5DADAA39C6FE0B2E2E0FD8F8 /* GCDWebServerDataRequest.m in Sources */, - 2FD4F69F155869816E3568D2C0A328CD /* GCDWebServerDataResponse.m in Sources */, - 8316EC11EB8EF857FC8AC924FF540076 /* GCDWebServerErrorResponse.m in Sources */, - A7AF534B31209659ED4C123BC4D32A31 /* GCDWebServerFileRequest.m in Sources */, - 1B72926422971A05A1038FEF1F10DA23 /* GCDWebServerFileResponse.m in Sources */, - 64EFFC6E05B9CACD03418CEF01429883 /* GCDWebServerFunctions.m in Sources */, - AFC0F5A350E42EDD292F2B499C13FBFD /* GCDWebServerMultiPartFormRequest.m in Sources */, - 4718BD505162FA674C844F282A692E90 /* GCDWebServerRequest.m in Sources */, - 946AF936A5472D7D7EF243D3399A2D44 /* GCDWebServerResponse.m in Sources */, - 976C070668BB589ABDB7498633967223 /* GCDWebServerStreamedResponse.m in Sources */, - 936C4E5402529DF91047CB9B84C5C281 /* GCDWebServerURLEncodedFormRequest.m in Sources */, + ADE45FBACDF07286A544DC20605FE624 /* Pods-proxy_conf_helper-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 9C086154608D1205F5A92B4645B6E785 /* Sources */ = { + D58B98E801980FD3514B9C96F2FEBA64 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 2D93C03399B11DAF5988CEC6E4EDDE50 /* Pods-ShadowsocksX-NG-dummy.m in Sources */, + E9E49601CF0FCF90E3E962F5DDEFD115 /* Pods-ShadowsocksX-NG-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 2E540C786B1F4BF64B47EA0B320C67F2 /* PBXTargetDependency */ = { + 3C89DE54CAB947747F7F2F6907F40D6E /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = GCDWebServer; - target = 8DADB076AFECDBAADF5E2B19FB72188A /* GCDWebServer */; - targetProxy = E895AA04EEFEDDCA3F15E606C7C3C10A /* PBXContainerItemProxy */; + target = 5B8B0ED1046111D92895FC95F12DBC10 /* GCDWebServer */; + targetProxy = 7D7286FD822FB02FEAECE006469945BB /* PBXContainerItemProxy */; }; - 54F37EFBCE086D0667D0893860A8BEC4 /* PBXTargetDependency */ = { + 49BA5C047101B8A959AF5E17B7DBCDD4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Alamofire; - target = 79C040AFDDCE1BCBF6D8B5EB0B85887F /* Alamofire */; - targetProxy = 73C64E43E31999AF7C2B373FA34C2235 /* PBXContainerItemProxy */; + target = 88E9EC28B8B46C3631E6B242B50F4442 /* Alamofire */; + targetProxy = 408240F5321FFD1270C133C590B77FEC /* PBXContainerItemProxy */; }; - 7C10FF72EF971F45066B238F3B2BCDC2 /* PBXTargetDependency */ = { + 7C03549F53DE7DA200E36C0642A79977 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = BRLOptionParser; - target = 7AD154F318B10A340D705FD3003EAAC6 /* BRLOptionParser */; - targetProxy = F1C53463E9DF7371C2384C5C32B425B6 /* PBXContainerItemProxy */; + target = 3CB2B8006B2B1ACAF9ADCA1DC82E2290 /* BRLOptionParser */; + targetProxy = FDE579D9762D0D9F86EDB1DE6EADE62F /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 179A484411D601715E6EB758424482A4 /* Release */ = { + 02E195CBAB30A9CBC71B668C0E2C5F60 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = C18C5D68D2A979595D2A50A1D65A8AF2 /* Alamofire.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_VERSION = A; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/Alamofire/Alamofire-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Alamofire/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.10; + MODULEMAP_FILE = "Target Support Files/Alamofire/Alamofire.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = Alamofire; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 09AC259EF48E4803CFA133821B50928D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F67191B1F87DA238C4D87250DFBE43DD /* Pods-ShadowsocksX-NGTests.release.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_VERSION = A; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-ShadowsocksX-NGTests/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MODULEMAP_FILE = "Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_ShadowsocksX_NGTests; + SDKROOT = macosx; + SKIP_INSTALL = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 2A0A67E0E8A2EA509035561EE4AFB8EB /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A5055B8EFFFBEDE50909E935D4BCA446 /* Pods-proxy_conf_helper.release.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + EXECUTABLE_PREFIX = lib; + GCC_NO_COMMON_BLOCKS = YES; + MACH_O_TYPE = staticlib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + SKIP_INSTALL = YES; + }; + name = Release; + }; + 454A1980F630934367D478DF55211291 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C12AC1F78F621586EC3C233BD8CF4BE0 /* BRLOptionParser.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + EXECUTABLE_PREFIX = lib; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/BRLOptionParser/BRLOptionParser-prefix.pch"; + MACOSX_DEPLOYMENT_TARGET = 10.7; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = macosx; + }; + name = Release; + }; + 581B7E690A5A7F5E7DF616728F5651C1 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C18C5D68D2A979595D2A50A1D65A8AF2 /* Alamofire.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -808,7 +924,7 @@ INFOPLIST_FILE = "Target Support Files/Alamofire/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.10; MODULEMAP_FILE = "Target Support Files/Alamofire/Alamofire.modulemap"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = Alamofire; @@ -820,42 +936,7 @@ }; name = Release; }; - 46F4EEF8E3C7148427E518702ACE51CA /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 089EB7E66F64D3A19BB7681AFCE91031 /* Pods-ShadowsocksX-NG.release.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - FRAMEWORK_VERSION = A; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "Target Support Files/Pods-ShadowsocksX-NG/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MACOSX_DEPLOYMENT_TARGET = 10.11; - MODULEMAP_FILE = "Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.modulemap"; - MTL_ENABLE_DEBUG_INFO = NO; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = Pods_ShadowsocksX_NG; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 4888EEFBEA04FABA2120470F4B676BBD /* Release */ = { + 5D622BA00757EC20ADAD24C580904C04 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -869,13 +950,18 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGNING_REQUIRED = NO; COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "POD_CONFIGURATION_RELEASE=1", "$(inherited)", @@ -886,24 +972,87 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; STRIP_INSTALLED_PRODUCT = NO; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SYMROOT = "${SRCROOT}/../build"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 4F25746D417AD7959CEFE5D13B9045BF /* Debug */ = { + 81B74614E7B351BBFADF2489179A00EE /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C12AC1F78F621586EC3C233BD8CF4BE0 /* BRLOptionParser.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + EXECUTABLE_PREFIX = lib; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/BRLOptionParser/BRLOptionParser-prefix.pch"; + MACOSX_DEPLOYMENT_TARGET = 10.7; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = macosx; + }; + name = Debug; + }; + 85EFB31300ECD852FAD5DE392B6CDD3A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 24BCEE536E19B38E28CE6933A0D49A2D /* GCDWebServer.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_VERSION = A; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/GCDWebServer/GCDWebServer-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/GCDWebServer/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.7; + MODULEMAP_FILE = "Target Support Files/GCDWebServer/GCDWebServer.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = GCDWebServer; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 87B437463CE3AEA04B9E52EC25693B5B /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 054C3E84057CD06DB85D99E7AD207F48 /* Pods-proxy_conf_helper.debug.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; EXECUTABLE_PREFIX = lib; GCC_NO_COMMON_BLOCKS = YES; MACH_O_TYPE = staticlib; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = YES; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; @@ -915,267 +1064,7 @@ }; name = Debug; }; - 66E018521CC39B874E17650E877662C0 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9BA2A0099476E08B6CC8026BDF0C603E /* Pods-ShadowsocksX-NGTests.debug.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - FRAMEWORK_VERSION = A; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "Target Support Files/Pods-ShadowsocksX-NGTests/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MACOSX_DEPLOYMENT_TARGET = 10.11; - MODULEMAP_FILE = "Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests.modulemap"; - MTL_ENABLE_DEBUG_INFO = YES; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = Pods_ShadowsocksX_NGTests; - SDKROOT = macosx; - SKIP_INSTALL = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 6C331DEA6276195F599807BBC932074D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 98522BF2EB25C0255284080F9CA3E195 /* Pods-ShadowsocksX-NG.debug.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - FRAMEWORK_VERSION = A; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "Target Support Files/Pods-ShadowsocksX-NG/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MACOSX_DEPLOYMENT_TARGET = 10.11; - MODULEMAP_FILE = "Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.modulemap"; - MTL_ENABLE_DEBUG_INFO = YES; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = Pods_ShadowsocksX_NG; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 92B477579DE5EFCC17E358B57A3A599E /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = C12AC1F78F621586EC3C233BD8CF4BE0 /* BRLOptionParser.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - EXECUTABLE_PREFIX = lib; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREFIX_HEADER = "Target Support Files/BRLOptionParser/BRLOptionParser-prefix.pch"; - MACOSX_DEPLOYMENT_TARGET = 10.7; - MTL_ENABLE_DEBUG_INFO = YES; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_NAME = "$(TARGET_NAME)"; - PUBLIC_HEADERS_FOLDER_PATH = ""; - SDKROOT = macosx; - }; - name = Debug; - }; - 94D9BC00EEB34DA6CE7149B77BCFB946 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 24BCEE536E19B38E28CE6933A0D49A2D /* GCDWebServer.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - FRAMEWORK_VERSION = A; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREFIX_HEADER = "Target Support Files/GCDWebServer/GCDWebServer-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/GCDWebServer/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.7; - MODULEMAP_FILE = "Target Support Files/GCDWebServer/GCDWebServer.modulemap"; - MTL_ENABLE_DEBUG_INFO = YES; - PRODUCT_NAME = GCDWebServer; - SDKROOT = macosx; - SKIP_INSTALL = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 9825B7CD16B076B290073DADEE5E3AEE /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = A5055B8EFFFBEDE50909E935D4BCA446 /* Pods-proxy_conf_helper.release.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - EXECUTABLE_PREFIX = lib; - GCC_NO_COMMON_BLOCKS = YES; - MACH_O_TYPE = staticlib; - MACOSX_DEPLOYMENT_TARGET = 10.10; - MTL_ENABLE_DEBUG_INFO = NO; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SKIP_INSTALL = YES; - }; - name = Release; - }; - 9B688665FDF44A7A81FB65791A544010 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 24BCEE536E19B38E28CE6933A0D49A2D /* GCDWebServer.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - FRAMEWORK_VERSION = A; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREFIX_HEADER = "Target Support Files/GCDWebServer/GCDWebServer-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/GCDWebServer/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.7; - MODULEMAP_FILE = "Target Support Files/GCDWebServer/GCDWebServer.modulemap"; - MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_NAME = GCDWebServer; - SDKROOT = macosx; - SKIP_INSTALL = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - B9E2E17CACCD9DB6ACE1EE1508A63590 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = C12AC1F78F621586EC3C233BD8CF4BE0 /* BRLOptionParser.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - EXECUTABLE_PREFIX = lib; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREFIX_HEADER = "Target Support Files/BRLOptionParser/BRLOptionParser-prefix.pch"; - MACOSX_DEPLOYMENT_TARGET = 10.7; - MTL_ENABLE_DEBUG_INFO = NO; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_NAME = "$(TARGET_NAME)"; - PUBLIC_HEADERS_FOLDER_PATH = ""; - SDKROOT = macosx; - }; - name = Release; - }; - BA46F8D5DD91E1BC7016CD04C4BDF87E /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = C18C5D68D2A979595D2A50A1D65A8AF2 /* Alamofire.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - FRAMEWORK_VERSION = A; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREFIX_HEADER = "Target Support Files/Alamofire/Alamofire-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/Alamofire/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.11; - MODULEMAP_FILE = "Target Support Files/Alamofire/Alamofire.modulemap"; - MTL_ENABLE_DEBUG_INFO = YES; - PRODUCT_NAME = Alamofire; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - BD0EE8DAC69BCFCB8E530D37B3D16A7A /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = F67191B1F87DA238C4D87250DFBE43DD /* Pods-ShadowsocksX-NGTests.release.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - FRAMEWORK_VERSION = A; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "Target Support Files/Pods-ShadowsocksX-NGTests/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MACOSX_DEPLOYMENT_TARGET = 10.11; - MODULEMAP_FILE = "Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests.modulemap"; - MTL_ENABLE_DEBUG_INFO = NO; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = Pods_ShadowsocksX_NGTests; - SDKROOT = macosx; - SKIP_INSTALL = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - DA2E206EB90DF75A25332AE4AA713F31 /* Debug */ = { + AB74B5E09B30AE94F1D9671501EA01E8 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -1189,14 +1078,19 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGNING_REQUIRED = NO; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "POD_CONFIGURATION_DEBUG=1", @@ -1210,30 +1104,177 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.11; ONLY_ACTIVE_ARCH = YES; + PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; STRIP_INSTALLED_PRODUCT = NO; SYMROOT = "${SRCROOT}/../build"; }; name = Debug; }; + BF053C260AA01D48984E55F5E6765FA3 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 089EB7E66F64D3A19BB7681AFCE91031 /* Pods-ShadowsocksX-NG.release.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_VERSION = A; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-ShadowsocksX-NG/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MODULEMAP_FILE = "Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_ShadowsocksX_NG; + SDKROOT = macosx; + SKIP_INSTALL = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + D13D4430BCE0A99C4D768DB5B9EAFAB4 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9BA2A0099476E08B6CC8026BDF0C603E /* Pods-ShadowsocksX-NGTests.debug.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_VERSION = A; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-ShadowsocksX-NGTests/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MODULEMAP_FILE = "Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_ShadowsocksX_NGTests; + SDKROOT = macosx; + SKIP_INSTALL = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + DB48EB34699C1507919A42A6EC412706 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 98522BF2EB25C0255284080F9CA3E195 /* Pods-ShadowsocksX-NG.debug.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_VERSION = A; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-ShadowsocksX-NG/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MODULEMAP_FILE = "Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_ShadowsocksX_NG; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + EEC1F7D47739588099958DDE9B22FEEB /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 24BCEE536E19B38E28CE6933A0D49A2D /* GCDWebServer.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_VERSION = A; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/GCDWebServer/GCDWebServer-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/GCDWebServer/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.7; + MODULEMAP_FILE = "Target Support Files/GCDWebServer/GCDWebServer.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = GCDWebServer; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 0174BA27A62F6F29EEDC03CA3FB0A9C4 /* Build configuration list for PBXNativeTarget "BRLOptionParser" */ = { + 010811070A86F912EA0CD2BB98136CD9 /* Build configuration list for PBXNativeTarget "GCDWebServer" */ = { isa = XCConfigurationList; buildConfigurations = ( - 92B477579DE5EFCC17E358B57A3A599E /* Debug */, - B9E2E17CACCD9DB6ACE1EE1508A63590 /* Release */, + EEC1F7D47739588099958DDE9B22FEEB /* Debug */, + 85EFB31300ECD852FAD5DE392B6CDD3A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 16ED0890B237DF1B16DA47D0E14DB4DD /* Build configuration list for PBXNativeTarget "GCDWebServer" */ = { + 246647E8AB354727F9ECD0879805161F /* Build configuration list for PBXNativeTarget "Pods-proxy_conf_helper" */ = { isa = XCConfigurationList; buildConfigurations = ( - 94D9BC00EEB34DA6CE7149B77BCFB946 /* Debug */, - 9B688665FDF44A7A81FB65791A544010 /* Release */, + 87B437463CE3AEA04B9E52EC25693B5B /* Debug */, + 2A0A67E0E8A2EA509035561EE4AFB8EB /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -1241,44 +1282,44 @@ 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { isa = XCConfigurationList; buildConfigurations = ( - DA2E206EB90DF75A25332AE4AA713F31 /* Debug */, - 4888EEFBEA04FABA2120470F4B676BBD /* Release */, + AB74B5E09B30AE94F1D9671501EA01E8 /* Debug */, + 5D622BA00757EC20ADAD24C580904C04 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 3CFB42910790CF0BDBCCEBAACD6B9367 /* Build configuration list for PBXNativeTarget "Alamofire" */ = { + 419E5D95491847CD79841B971A8A3277 /* Build configuration list for PBXNativeTarget "Alamofire" */ = { isa = XCConfigurationList; buildConfigurations = ( - BA46F8D5DD91E1BC7016CD04C4BDF87E /* Debug */, - 179A484411D601715E6EB758424482A4 /* Release */, + 02E195CBAB30A9CBC71B668C0E2C5F60 /* Debug */, + 581B7E690A5A7F5E7DF616728F5651C1 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4AC88E06DEFEEDAF5DAA6F0F774D05D4 /* Build configuration list for PBXNativeTarget "Pods-ShadowsocksX-NG" */ = { + 4B561109B4C51E9DC9F5F27E9C033405 /* Build configuration list for PBXNativeTarget "BRLOptionParser" */ = { isa = XCConfigurationList; buildConfigurations = ( - 6C331DEA6276195F599807BBC932074D /* Debug */, - 46F4EEF8E3C7148427E518702ACE51CA /* Release */, + 81B74614E7B351BBFADF2489179A00EE /* Debug */, + 454A1980F630934367D478DF55211291 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 757EEB566CE14B3A8210DD4A32EBDD7A /* Build configuration list for PBXNativeTarget "Pods-ShadowsocksX-NGTests" */ = { + 78B338CAC10BFFE58C0DE5D189212D60 /* Build configuration list for PBXNativeTarget "Pods-ShadowsocksX-NGTests" */ = { isa = XCConfigurationList; buildConfigurations = ( - 66E018521CC39B874E17650E877662C0 /* Debug */, - BD0EE8DAC69BCFCB8E530D37B3D16A7A /* Release */, + D13D4430BCE0A99C4D768DB5B9EAFAB4 /* Debug */, + 09AC259EF48E4803CFA133821B50928D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - F1E46DE142216CD3C0327D20F3073961 /* Build configuration list for PBXNativeTarget "Pods-proxy_conf_helper" */ = { + BFE80AF401A02D5658D84A694BE7A3CE /* Build configuration list for PBXNativeTarget "Pods-ShadowsocksX-NG" */ = { isa = XCConfigurationList; buildConfigurations = ( - 4F25746D417AD7959CEFE5D13B9045BF /* Debug */, - 9825B7CD16B076B290073DADEE5E3AEE /* Release */, + DB48EB34699C1507919A42A6EC412706 /* Debug */, + BF053C260AA01D48984E55F5E6765FA3 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Pods/Target Support Files/Alamofire/Alamofire-prefix.pch b/Pods/Target Support Files/Alamofire/Alamofire-prefix.pch index b9c163b..082f8af 100644 --- a/Pods/Target Support Files/Alamofire/Alamofire-prefix.pch +++ b/Pods/Target Support Files/Alamofire/Alamofire-prefix.pch @@ -1,4 +1,12 @@ #ifdef __OBJC__ #import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif #endif diff --git a/Pods/Target Support Files/Alamofire/Alamofire-umbrella.h b/Pods/Target Support Files/Alamofire/Alamofire-umbrella.h index 17f78f7..c83c1a5 100644 --- a/Pods/Target Support Files/Alamofire/Alamofire-umbrella.h +++ b/Pods/Target Support Files/Alamofire/Alamofire-umbrella.h @@ -1,4 +1,14 @@ +#ifdef __OBJC__ #import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif FOUNDATION_EXPORT double AlamofireVersionNumber; diff --git a/Pods/Target Support Files/Alamofire/Alamofire.xcconfig b/Pods/Target Support Files/Alamofire/Alamofire.xcconfig index 572419f..a7c04ce 100644 --- a/Pods/Target Support Files/Alamofire/Alamofire.xcconfig +++ b/Pods/Target Support Files/Alamofire/Alamofire.xcconfig @@ -6,5 +6,6 @@ OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/Alamofire PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES diff --git a/Pods/Target Support Files/Alamofire/Info.plist b/Pods/Target Support Files/Alamofire/Info.plist index b672cd7..6631be7 100644 --- a/Pods/Target Support Files/Alamofire/Info.plist +++ b/Pods/Target Support Files/Alamofire/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 4.0.1 + 4.2.0 CFBundleSignature ???? CFBundleVersion diff --git a/Pods/Target Support Files/BRLOptionParser/BRLOptionParser-prefix.pch b/Pods/Target Support Files/BRLOptionParser/BRLOptionParser-prefix.pch index b9c163b..082f8af 100644 --- a/Pods/Target Support Files/BRLOptionParser/BRLOptionParser-prefix.pch +++ b/Pods/Target Support Files/BRLOptionParser/BRLOptionParser-prefix.pch @@ -1,4 +1,12 @@ #ifdef __OBJC__ #import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif #endif diff --git a/Pods/Target Support Files/BRLOptionParser/BRLOptionParser.xcconfig b/Pods/Target Support Files/BRLOptionParser/BRLOptionParser.xcconfig index 1660b8d..3784c02 100644 --- a/Pods/Target Support Files/BRLOptionParser/BRLOptionParser.xcconfig +++ b/Pods/Target Support Files/BRLOptionParser/BRLOptionParser.xcconfig @@ -4,5 +4,6 @@ HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Priva PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/BRLOptionParser PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES diff --git a/Pods/Target Support Files/GCDWebServer/GCDWebServer-prefix.pch b/Pods/Target Support Files/GCDWebServer/GCDWebServer-prefix.pch index b9c163b..082f8af 100644 --- a/Pods/Target Support Files/GCDWebServer/GCDWebServer-prefix.pch +++ b/Pods/Target Support Files/GCDWebServer/GCDWebServer-prefix.pch @@ -1,4 +1,12 @@ #ifdef __OBJC__ #import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif #endif diff --git a/Pods/Target Support Files/GCDWebServer/GCDWebServer-umbrella.h b/Pods/Target Support Files/GCDWebServer/GCDWebServer-umbrella.h index 98a7e7b..e7ae400 100644 --- a/Pods/Target Support Files/GCDWebServer/GCDWebServer-umbrella.h +++ b/Pods/Target Support Files/GCDWebServer/GCDWebServer-umbrella.h @@ -1,4 +1,14 @@ +#ifdef __OBJC__ #import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif #import "GCDWebServer.h" #import "GCDWebServerConnection.h" diff --git a/Pods/Target Support Files/GCDWebServer/GCDWebServer.xcconfig b/Pods/Target Support Files/GCDWebServer/GCDWebServer.xcconfig index 9fd1848..7dbb43b 100644 --- a/Pods/Target Support Files/GCDWebServer/GCDWebServer.xcconfig +++ b/Pods/Target Support Files/GCDWebServer/GCDWebServer.xcconfig @@ -6,5 +6,6 @@ OTHER_LDFLAGS = -l"z" -framework "SystemConfiguration" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/GCDWebServer PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES diff --git a/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-acknowledgements.plist b/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-acknowledgements.plist index 4293969..fb52059 100644 --- a/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-acknowledgements.plist +++ b/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-acknowledgements.plist @@ -34,6 +34,8 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + License + MIT Title Alamofire Type @@ -66,6 +68,8 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + License + BSD Title GCDWebServer Type diff --git a/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-frameworks.sh b/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-frameworks.sh index 6b1dedf..a7f5302 100755 --- a/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-frameworks.sh +++ b/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-frameworks.sh @@ -59,8 +59,13 @@ code_sign_if_enabled() { if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then # Use the current code_sign_identitiy echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" - echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" - /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1"" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" fi } @@ -91,3 +96,6 @@ if [[ "$CONFIGURATION" == "Release" ]]; then install_framework "$BUILT_PRODUCTS_DIR/Alamofire/Alamofire.framework" install_framework "$BUILT_PRODUCTS_DIR/GCDWebServer/GCDWebServer.framework" fi +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-resources.sh b/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-resources.sh index 0a15615..4602c68 100755 --- a/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-resources.sh +++ b/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-resources.sh @@ -18,17 +18,14 @@ case "${TARGETED_DEVICE_FAMILY}" in 2) TARGET_DEVICE_ARGS="--target-device ipad" ;; + 3) + TARGET_DEVICE_ARGS="--target-device tv" + ;; *) TARGET_DEVICE_ARGS="--target-device mac" ;; esac -realpath() { - DIRECTORY="$(cd "${1%/*}" && pwd)" - FILENAME="${1##*/}" - echo "$DIRECTORY/$FILENAME" -} - install_resource() { if [[ "$1" = /* ]] ; then @@ -70,7 +67,7 @@ EOM xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" ;; *.xcassets) - ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH") + ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") ;; *) @@ -93,7 +90,7 @@ then # Find all other xcassets (this unfortunately includes those of path pods and other targets). OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) while read line; do - if [[ $line != "`realpath $PODS_ROOT`*" ]]; then + if [[ $line != "${PODS_ROOT}*" ]]; then XCASSET_FILES+=("$line") fi done <<<"$OTHER_XCASSETS" diff --git a/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-umbrella.h b/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-umbrella.h index b67da16..9422e61 100644 --- a/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-umbrella.h +++ b/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-umbrella.h @@ -1,4 +1,14 @@ +#ifdef __OBJC__ #import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif FOUNDATION_EXPORT double Pods_ShadowsocksX_NGVersionNumber; diff --git a/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.debug.xcconfig b/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.debug.xcconfig index d9b9254..a07111d 100644 --- a/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.debug.xcconfig +++ b/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.debug.xcconfig @@ -1,5 +1,5 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES CODE_SIGN_IDENTITY = -EMBEDDED_CONTENT_CONTAINS_SWIFT = YES FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Alamofire" "$PODS_CONFIGURATION_BUILD_DIR/GCDWebServer" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/Frameworks' diff --git a/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.release.xcconfig b/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.release.xcconfig index d9b9254..a07111d 100644 --- a/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.release.xcconfig +++ b/Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.release.xcconfig @@ -1,5 +1,5 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES CODE_SIGN_IDENTITY = -EMBEDDED_CONTENT_CONTAINS_SWIFT = YES FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Alamofire" "$PODS_CONFIGURATION_BUILD_DIR/GCDWebServer" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/Frameworks' diff --git a/Pods/Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests-frameworks.sh b/Pods/Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests-frameworks.sh index 893c16a..d839f60 100755 --- a/Pods/Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests-frameworks.sh +++ b/Pods/Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests-frameworks.sh @@ -59,8 +59,13 @@ code_sign_if_enabled() { if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then # Use the current code_sign_identitiy echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" - echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" - /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1"" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" fi } @@ -82,3 +87,6 @@ strip_invalid_archs() { fi } +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/Pods/Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests-resources.sh b/Pods/Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests-resources.sh index 0a15615..4602c68 100755 --- a/Pods/Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests-resources.sh +++ b/Pods/Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests-resources.sh @@ -18,17 +18,14 @@ case "${TARGETED_DEVICE_FAMILY}" in 2) TARGET_DEVICE_ARGS="--target-device ipad" ;; + 3) + TARGET_DEVICE_ARGS="--target-device tv" + ;; *) TARGET_DEVICE_ARGS="--target-device mac" ;; esac -realpath() { - DIRECTORY="$(cd "${1%/*}" && pwd)" - FILENAME="${1##*/}" - echo "$DIRECTORY/$FILENAME" -} - install_resource() { if [[ "$1" = /* ]] ; then @@ -70,7 +67,7 @@ EOM xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" ;; *.xcassets) - ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH") + ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") ;; *) @@ -93,7 +90,7 @@ then # Find all other xcassets (this unfortunately includes those of path pods and other targets). OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) while read line; do - if [[ $line != "`realpath $PODS_ROOT`*" ]]; then + if [[ $line != "${PODS_ROOT}*" ]]; then XCASSET_FILES+=("$line") fi done <<<"$OTHER_XCASSETS" diff --git a/Pods/Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests-umbrella.h b/Pods/Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests-umbrella.h index b3d635a..6531c0d 100644 --- a/Pods/Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests-umbrella.h +++ b/Pods/Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests-umbrella.h @@ -1,4 +1,14 @@ +#ifdef __OBJC__ #import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif FOUNDATION_EXPORT double Pods_ShadowsocksX_NGTestsVersionNumber; diff --git a/Pods/Target Support Files/Pods-proxy_conf_helper/Pods-proxy_conf_helper-acknowledgements.plist b/Pods/Target Support Files/Pods-proxy_conf_helper/Pods-proxy_conf_helper-acknowledgements.plist index 42b0d2c..db98090 100644 --- a/Pods/Target Support Files/Pods-proxy_conf_helper/Pods-proxy_conf_helper-acknowledgements.plist +++ b/Pods/Target Support Files/Pods-proxy_conf_helper/Pods-proxy_conf_helper-acknowledgements.plist @@ -16,7 +16,7 @@ FooterText (The MIT License) -Copyright © 2013-2015 Stephen Celis (<stephen@stephencelis.com>) +Copyright © 2013-2015 Stephen Celis (<stephen@stephencelis.com>) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -37,6 +37,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + License + MIT Title BRLOptionParser Type diff --git a/Pods/Target Support Files/Pods-proxy_conf_helper/Pods-proxy_conf_helper-frameworks.sh b/Pods/Target Support Files/Pods-proxy_conf_helper/Pods-proxy_conf_helper-frameworks.sh index 893c16a..d839f60 100755 --- a/Pods/Target Support Files/Pods-proxy_conf_helper/Pods-proxy_conf_helper-frameworks.sh +++ b/Pods/Target Support Files/Pods-proxy_conf_helper/Pods-proxy_conf_helper-frameworks.sh @@ -59,8 +59,13 @@ code_sign_if_enabled() { if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then # Use the current code_sign_identitiy echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" - echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" - /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1"" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" fi } @@ -82,3 +87,6 @@ strip_invalid_archs() { fi } +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/Pods/Target Support Files/Pods-proxy_conf_helper/Pods-proxy_conf_helper-resources.sh b/Pods/Target Support Files/Pods-proxy_conf_helper/Pods-proxy_conf_helper-resources.sh index 0a15615..4602c68 100755 --- a/Pods/Target Support Files/Pods-proxy_conf_helper/Pods-proxy_conf_helper-resources.sh +++ b/Pods/Target Support Files/Pods-proxy_conf_helper/Pods-proxy_conf_helper-resources.sh @@ -18,17 +18,14 @@ case "${TARGETED_DEVICE_FAMILY}" in 2) TARGET_DEVICE_ARGS="--target-device ipad" ;; + 3) + TARGET_DEVICE_ARGS="--target-device tv" + ;; *) TARGET_DEVICE_ARGS="--target-device mac" ;; esac -realpath() { - DIRECTORY="$(cd "${1%/*}" && pwd)" - FILENAME="${1##*/}" - echo "$DIRECTORY/$FILENAME" -} - install_resource() { if [[ "$1" = /* ]] ; then @@ -70,7 +67,7 @@ EOM xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" ;; *.xcassets) - ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH") + ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") ;; *) @@ -93,7 +90,7 @@ then # Find all other xcassets (this unfortunately includes those of path pods and other targets). OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) while read line; do - if [[ $line != "`realpath $PODS_ROOT`*" ]]; then + if [[ $line != "${PODS_ROOT}*" ]]; then XCASSET_FILES+=("$line") fi done <<<"$OTHER_XCASSETS" diff --git a/README.md b/README.md index dee24b9..e0bc131 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,8 @@ So after you quit the app, the ss-local maybe be still running. Added a manual mode which won't configure the system proxy settings. Then you could configure your apps to use socks5 proxy manual. +Added global Keyboard shortcut + + P to switch between `global` mode and `auto` mode. + ## Contributing Contributions must be available on a separately named branch based on the latest version of the main branch develop. diff --git a/ShadowsocksX-NG.xcodeproj/project.pbxproj b/ShadowsocksX-NG.xcodeproj/project.pbxproj index 2a78063..d04cf9c 100755 --- a/ShadowsocksX-NG.xcodeproj/project.pbxproj +++ b/ShadowsocksX-NG.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 08FCA0FF1E24BE1A0070984F /* example-gui-config.json in Resources */ = {isa = PBXBuildFile; fileRef = 08FCA0FE1E24BE1A0070984F /* example-gui-config.json */; }; 258E511BA910B0521B24DAB8 /* Pods_ShadowsocksX_NG.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 283ED1A8E9B711AC65670031 /* Pods_ShadowsocksX_NG.framework */; }; 9B07EFA71D048BBB0052D9DF /* ss-local in Resources */ = {isa = PBXBuildFile; fileRef = 9B07EFA61D048BBB0052D9DF /* ss-local */; }; 9B07EFAC1D048E880052D9DF /* menu_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9B07EFA81D048E880052D9DF /* menu_icon@2x.png */; }; @@ -35,6 +36,15 @@ 9B3FFF4C1D09D8F70019A709 /* install_helper.sh in Resources */ = {isa = PBXBuildFile; fileRef = 9B3FFF4B1D09D8F70019A709 /* install_helper.sh */; }; 9B3FFF4F1D09D9D50019A709 /* ProxyConfHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B3FFF4E1D09D9D50019A709 /* ProxyConfHelper.m */; }; 9B3FFF541D09E2D10019A709 /* proxy_conf_helper in Resources */ = {isa = PBXBuildFile; fileRef = 9B3FFF441D09CD3B0019A709 /* proxy_conf_helper */; }; + 9B6BF9521E27B23F0061B9A7 /* LaunchHelper.app in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9B6BF9501E27B1F20061B9A7 /* LaunchHelper.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 9B6BF9541E27B2570061B9A7 /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B6BF9531E27B2570061B9A7 /* ServiceManagement.framework */; }; + 9B9CBCA61E25E1DB00FC61AA /* KcptunProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B9CBCA51E25E1DB00FC61AA /* KcptunProfile.swift */; }; + 9B9CBCA81E26312E00FC61AA /* install_kcptun.sh in Resources */ = {isa = PBXBuildFile; fileRef = 9B9CBCA71E26310E00FC61AA /* install_kcptun.sh */; }; + 9B9CBCAA1E2633CB00FC61AA /* kcptun_client in Resources */ = {isa = PBXBuildFile; fileRef = 9B9CBCA91E2633CB00FC61AA /* kcptun_client */; }; + 9B9CBCAF1E263B1600FC61AA /* libpcre.1.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 9B9CBCAD1E263A6600FC61AA /* libpcre.1.dylib */; }; + 9B9CBCB31E26452500FC61AA /* reload_conf_kcptun.sh in Resources */ = {isa = PBXBuildFile; fileRef = 9B9CBCB21E26452500FC61AA /* reload_conf_kcptun.sh */; }; + 9B9CBCB41E26453C00FC61AA /* start_kcptun.sh in Resources */ = {isa = PBXBuildFile; fileRef = 9B9CBCB01E2644DC00FC61AA /* start_kcptun.sh */; }; + 9B9CBCB51E26453C00FC61AA /* stop_kcptun.sh in Resources */ = {isa = PBXBuildFile; fileRef = 9B9CBCB11E26450D00FC61AA /* stop_kcptun.sh */; }; 9BA04B231D23D5A5005AAD7F /* ProxyConfTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BA04B221D23D5A5005AAD7F /* ProxyConfTool.m */; }; 9BA04B261D24044D005AAD7F /* ProxyPreferencesController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BA04B241D24044D005AAD7F /* ProxyPreferencesController.swift */; }; 9BB706A71D1B982300551F0E /* SWBApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BB706A51D1B982300551F0E /* SWBApplication.m */; }; @@ -59,6 +69,7 @@ C6E28E951DA79705004F8330 /* HTTPPreferencesWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = C6E28E971DA79705004F8330 /* HTTPPreferencesWindowController.xib */; }; C8E42A6C1D4F270A0074C7EA /* UserRulesController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E42A6A1D4F270A0074C7EA /* UserRulesController.swift */; }; C8E42A6E1D4F2CAF0074C7EA /* UserRulesController.xib in Resources */ = {isa = PBXBuildFile; fileRef = C8E42A701D4F2CAF0074C7EA /* UserRulesController.xib */; }; + D8E3630B1E2072980027449B /* ServerProfileTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8E3630A1E2072980027449B /* ServerProfileTests.swift */; }; E0E57CCA7EB34B90F9D340F2 /* Pods_ShadowsocksX_NGTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 388120F062D7EB7DD0D8DDCA /* Pods_ShadowsocksX_NGTests.framework */; }; F0809FF1595BE2966343D3C7 /* libPods-proxy_conf_helper.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E7783AEDB4A3BDDC9FF16AC /* libPods-proxy_conf_helper.a */; }; /* End PBXBuildFile section */ @@ -78,6 +89,13 @@ remoteGlobalIDString = 9B3FFF431D09CD3B0019A709; remoteInfo = proxy_conf_helper; }; + 9B6BF94F1E27B1F20061B9A7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9B6BF94B1E27B1F10061B9A7 /* LaunchHelper.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 9B6BF93B1E27B1F10061B9A7; + remoteInfo = LaunchHelper; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -90,9 +108,20 @@ ); runOnlyForDeploymentPostprocessing = 1; }; + 9B6BF9511E27B2250061B9A7 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = Contents/Library/LoginItems; + dstSubfolderSpec = 1; + files = ( + 9B6BF9521E27B23F0061B9A7 /* LaunchHelper.app in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 08FCA0FE1E24BE1A0070984F /* example-gui-config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "example-gui-config.json"; sourceTree = ""; }; 19083CFCED87354F006967FF /* Pods_ShadowsocksX_NGUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ShadowsocksX_NGUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 1E7783AEDB4A3BDDC9FF16AC /* libPods-proxy_conf_helper.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-proxy_conf_helper.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 283ED1A8E9B711AC65670031 /* Pods_ShadowsocksX_NG.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ShadowsocksX_NG.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -146,6 +175,15 @@ 9B3FFF4E1D09D9D50019A709 /* ProxyConfHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProxyConfHelper.m; sourceTree = ""; }; 9B3FFF501D09DAEA0019A709 /* proxy_conf_helper_version.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = proxy_conf_helper_version.h; sourceTree = ""; }; 9B3FFF511D09DBA20019A709 /* ShadowsocksX-NG-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ShadowsocksX-NG-Bridging-Header.h"; sourceTree = ""; }; + 9B6BF94B1E27B1F10061B9A7 /* LaunchHelper.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = LaunchHelper.xcodeproj; path = LaunchHelper/LaunchHelper.xcodeproj; sourceTree = ""; }; + 9B6BF9531E27B2570061B9A7 /* ServiceManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ServiceManagement.framework; path = System/Library/Frameworks/ServiceManagement.framework; sourceTree = SDKROOT; }; + 9B9CBCA51E25E1DB00FC61AA /* KcptunProfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KcptunProfile.swift; sourceTree = ""; }; + 9B9CBCA71E26310E00FC61AA /* install_kcptun.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = install_kcptun.sh; sourceTree = ""; }; + 9B9CBCA91E2633CB00FC61AA /* kcptun_client */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = kcptun_client; sourceTree = ""; }; + 9B9CBCAD1E263A6600FC61AA /* libpcre.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libpcre.1.dylib; sourceTree = ""; }; + 9B9CBCB01E2644DC00FC61AA /* start_kcptun.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = start_kcptun.sh; sourceTree = ""; }; + 9B9CBCB11E26450D00FC61AA /* stop_kcptun.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = stop_kcptun.sh; sourceTree = ""; }; + 9B9CBCB21E26452500FC61AA /* reload_conf_kcptun.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = reload_conf_kcptun.sh; sourceTree = ""; }; 9BA04B211D23D5A5005AAD7F /* ProxyConfTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProxyConfTool.h; sourceTree = ""; }; 9BA04B221D23D5A5005AAD7F /* ProxyConfTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProxyConfTool.m; sourceTree = ""; }; 9BA04B241D24044D005AAD7F /* ProxyPreferencesController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProxyPreferencesController.swift; sourceTree = ""; }; @@ -176,6 +214,7 @@ C8E42A6A1D4F270A0074C7EA /* UserRulesController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserRulesController.swift; sourceTree = ""; }; C8E42A6F1D4F2CAF0074C7EA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UserRulesController.xib; sourceTree = ""; }; C8E42A721D4F2CB10074C7EA /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/UserRulesController.strings"; sourceTree = ""; }; + D8E3630A1E2072980027449B /* ServerProfileTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServerProfileTests.swift; sourceTree = ""; }; E9E9FB3855DA55D0710EE7BD /* Pods-ShadowsocksX-NG.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShadowsocksX-NG.release.xcconfig"; path = "Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.release.xcconfig"; sourceTree = ""; }; FE3237E9FB24D9B924A0E630 /* Pods-ShadowsocksX-NG.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShadowsocksX-NG.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -185,6 +224,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 9B6BF9541E27B2570061B9A7 /* ServiceManagement.framework in Frameworks */, 9B3FFF3E1D08D9910019A709 /* SystemConfiguration.framework in Frameworks */, 258E511BA910B0521B24DAB8 /* Pods_ShadowsocksX_NG.framework in Frameworks */, ); @@ -227,6 +267,9 @@ 9B07EFB01D048E900052D9DF /* Support Files */ = { isa = PBXGroup; children = ( + 9B9CBCAD1E263A6600FC61AA /* libpcre.1.dylib */, + 9B9CBCA91E2633CB00FC61AA /* kcptun_client */, + 08FCA0FE1E24BE1A0070984F /* example-gui-config.json */, C6D4298E1DA75988002A5711 /* install_privoxy.sh */, C6D4298F1DA75988002A5711 /* privoxy */, C6D429901DA75988002A5711 /* reload_conf_privoxy.sh */, @@ -244,10 +287,14 @@ 9B07EFAA1D048E880052D9DF /* menu_icon_disabled.png */, 9B07EFAB1D048E880052D9DF /* menu_icon_disabled@2x.png */, 9BEEF0651D04CB8500FC52B3 /* install_ss_local.sh */, + 9B9CBCA71E26310E00FC61AA /* install_kcptun.sh */, 9BEEF0661D04CE8D00FC52B3 /* start_ss_local.sh */, 9BEEF0671D04CE9A00FC52B3 /* stop_ss_local.sh */, 9BEEF0681D04CFE500FC52B3 /* reload_conf_ss_local.sh */, C6D429981DA76FBC002A5711 /* privoxy.config.example */, + 9B9CBCB01E2644DC00FC61AA /* start_kcptun.sh */, + 9B9CBCB11E26450D00FC61AA /* stop_kcptun.sh */, + 9B9CBCB21E26452500FC61AA /* reload_conf_kcptun.sh */, ); name = "Support Files"; sourceTree = ""; @@ -255,6 +302,7 @@ 9B0BFFDC1D0460A70040E62B = { isa = PBXGroup; children = ( + 9B6BF94B1E27B1F10061B9A7 /* LaunchHelper.xcodeproj */, 9B172A601D0ADA5B00B87B9A /* genstrings.py */, 9B0BFFE71D0460A70040E62B /* ShadowsocksX-NG */, 9B0BFFF71D0460A70040E62B /* ShadowsocksX-NGTests */, @@ -290,6 +338,7 @@ 9B0BFFEC1D0460A70040E62B /* MainMenu.xib */, 9B0BFFEF1D0460A70040E62B /* Info.plist */, 9BEEF06D1D04DCE400FC52B3 /* ServerProfile.swift */, + 9B9CBCA51E25E1DB00FC61AA /* KcptunProfile.swift */, 9BEEF06F1D04DDB100FC52B3 /* ServerProfileManager.swift */, 9BEEF0771D04FE8A00FC52B3 /* LaunchAgentUtils.swift */, 9B3FFF0C1D05FEB30019A709 /* Utils.swift */, @@ -309,6 +358,7 @@ 9B0BFFF71D0460A70040E62B /* ShadowsocksX-NGTests */ = { isa = PBXGroup; children = ( + D8E3630A1E2072980027449B /* ServerProfileTests.swift */, 9B0BFFF81D0460A70040E62B /* ShadowsocksX_NGTests.swift */, 9B0BFFFA1D0460A70040E62B /* Info.plist */, ); @@ -343,9 +393,18 @@ path = proxy_conf_helper; sourceTree = ""; }; + 9B6BF94C1E27B1F10061B9A7 /* Products */ = { + isa = PBXGroup; + children = ( + 9B6BF9501E27B1F20061B9A7 /* LaunchHelper.app */, + ); + name = Products; + sourceTree = ""; + }; D3CE66CC039F651F28057DDB /* Frameworks */ = { isa = PBXGroup; children = ( + 9B6BF9531E27B2570061B9A7 /* ServiceManagement.framework */, 9B3FFF3D1D08D9910019A709 /* SystemConfiguration.framework */, 9B3FFF3B1D08D93B0019A709 /* WebKit.framework */, 283ED1A8E9B711AC65670031 /* Pods_ShadowsocksX_NG.framework */, @@ -369,6 +428,7 @@ 9B0BFFE31D0460A70040E62B /* Resources */, 5E160625E3EC80E27DA7EF05 /* [CP] Embed Pods Frameworks */, 3E819BD46B855EDB116A3C70 /* [CP] Copy Pods Resources */, + 9B6BF9511E27B2250061B9A7 /* CopyFiles */, ); buildRules = ( ); @@ -427,7 +487,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0730; - LastUpgradeCheck = 0730; + LastUpgradeCheck = 0810; ORGANIZATIONNAME = qiuyuzhou; TargetAttributes = { 9B0BFFE41D0460A70040E62B = { @@ -456,6 +516,12 @@ mainGroup = 9B0BFFDC1D0460A70040E62B; productRefGroup = 9B0BFFE61D0460A70040E62B /* Products */; projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 9B6BF94C1E27B1F10061B9A7 /* Products */; + ProjectRef = 9B6BF94B1E27B1F10061B9A7 /* LaunchHelper.xcodeproj */; + }, + ); projectRoot = ""; targets = ( 9B0BFFE41D0460A70040E62B /* ShadowsocksX-NG */, @@ -465,11 +531,26 @@ }; /* End PBXProject section */ +/* Begin PBXReferenceProxy section */ + 9B6BF9501E27B1F20061B9A7 /* LaunchHelper.app */ = { + isa = PBXReferenceProxy; + fileType = wrapper.application; + path = LaunchHelper.app; + remoteRef = 9B6BF94F1E27B1F20061B9A7 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + /* Begin PBXResourcesBuildPhase section */ 9B0BFFE31D0460A70040E62B /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9B9CBCB41E26453C00FC61AA /* start_kcptun.sh in Resources */, + 9B9CBCB51E26453C00FC61AA /* stop_kcptun.sh in Resources */, + 9B9CBCAF1E263B1600FC61AA /* libpcre.1.dylib in Resources */, + 9B9CBCA81E26312E00FC61AA /* install_kcptun.sh in Resources */, + 9B9CBCAA1E2633CB00FC61AA /* kcptun_client in Resources */, 9BE8FBBF1D0B211600CAFD01 /* libcrypto.1.0.0.dylib in Resources */, 9B3FFF541D09E2D10019A709 /* proxy_conf_helper in Resources */, C6E28E951DA79705004F8330 /* HTTPPreferencesWindowController.xib in Resources */, @@ -490,8 +571,10 @@ C6D429951DA75988002A5711 /* reload_conf_privoxy.sh in Resources */, 9B0BFFEB1D0460A70040E62B /* Assets.xcassets in Resources */, 9B2491B71D0ACC3E003BBECC /* AdvPreferencesWindowController.xib in Resources */, + 08FCA0FF1E24BE1A0070984F /* example-gui-config.json in Resources */, 9B3FFF271D0898EB0019A709 /* gfwlist.txt in Resources */, C6D429931DA75988002A5711 /* install_privoxy.sh in Resources */, + 9B9CBCB31E26452500FC61AA /* reload_conf_kcptun.sh in Resources */, 9BC70EDC1D2E3E3100EDA4CA /* Localizable.strings in Resources */, 9B0BFFEE1D0460A70040E62B /* MainMenu.xib in Resources */, 9B3FFF4C1D09D8F70019A709 /* install_helper.sh in Resources */, @@ -540,7 +623,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_ROOT}/../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"; showEnvVarsInLog = 0; }; 3545247EFCD033C3FA63EA6C /* [CP] Check Pods Manifest.lock */ = { @@ -555,7 +638,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_ROOT}/../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"; showEnvVarsInLog = 0; }; 3E819BD46B855EDB116A3C70 /* [CP] Copy Pods Resources */ = { @@ -615,7 +698,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_ROOT}/../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"; showEnvVarsInLog = 0; }; D8C2D6AF002916F4095E15E3 /* [CP] Copy Pods Resources */ = { @@ -657,6 +740,7 @@ 9BA04B231D23D5A5005AAD7F /* ProxyConfTool.m in Sources */, 9BEEF0781D04FE8A00FC52B3 /* LaunchAgentUtils.swift in Sources */, C6E28E921DA79380004F8330 /* HTTPPreferencesWindowController.swift in Sources */, + 9B9CBCA61E25E1DB00FC61AA /* KcptunProfile.swift in Sources */, C8E42A6C1D4F270A0074C7EA /* UserRulesController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -666,6 +750,7 @@ buildActionMask = 2147483647; files = ( 9B0BFFF91D0460A70040E62B /* ShadowsocksX_NGTests.swift in Sources */, + D8E3630B1E2072980027449B /* ServerProfileTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -764,6 +849,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -774,8 +860,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "Mac Developer"; @@ -809,6 +897,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -819,8 +908,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "Mac Developer"; @@ -839,6 +930,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; }; name = Release; }; @@ -846,6 +938,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = FE3237E9FB24D9B924A0E630 /* Pods-ShadowsocksX-NG.debug.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; COMBINE_HIDPI_IMAGES = YES; @@ -873,6 +966,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = E9E9FB3855DA55D0710EE7BD /* Pods-ShadowsocksX-NG.release.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; COMBINE_HIDPI_IMAGES = YES; @@ -905,6 +999,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.qiuyuzhou.ShadowsocksX-NGTests"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "ShadowsocksX-NG/ShadowsocksX-NG-Bridging-Header.h"; SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ShadowsocksX-NG.app/Contents/MacOS/ShadowsocksX-NG"; }; @@ -920,6 +1015,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.qiuyuzhou.ShadowsocksX-NGTests"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "ShadowsocksX-NG/ShadowsocksX-NG-Bridging-Header.h"; SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ShadowsocksX-NG.app/Contents/MacOS/ShadowsocksX-NG"; }; @@ -931,6 +1027,7 @@ buildSettings = { CODE_SIGN_IDENTITY = ""; PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; }; name = Debug; }; @@ -940,6 +1037,7 @@ buildSettings = { CODE_SIGN_IDENTITY = ""; PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; }; name = Release; }; diff --git a/ShadowsocksX-NG.xcodeproj/xcshareddata/xcschemes/ShadowsocksX-NG.xcscheme b/ShadowsocksX-NG.xcodeproj/xcshareddata/xcschemes/ShadowsocksX-NG.xcscheme index 19af2fe..9e5d441 100644 --- a/ShadowsocksX-NG.xcodeproj/xcshareddata/xcschemes/ShadowsocksX-NG.xcscheme +++ b/ShadowsocksX-NG.xcodeproj/xcshareddata/xcschemes/ShadowsocksX-NG.xcscheme @@ -1,6 +1,6 @@ @@ -28,7 +28,7 @@ buildForAnalyzing = "YES"> @@ -42,7 +42,7 @@ buildForAnalyzing = "YES"> @@ -56,7 +56,7 @@ buildForAnalyzing = "YES"> @@ -70,7 +70,7 @@ buildForAnalyzing = "YES"> diff --git a/ShadowsocksX-NG.xcodeproj/xcshareddata/xcschemes/ShadowsocksX-NGTests.xcscheme b/ShadowsocksX-NG.xcodeproj/xcshareddata/xcschemes/ShadowsocksX-NGTests.xcscheme index c1499a1..f5d83b6 100644 --- a/ShadowsocksX-NG.xcodeproj/xcshareddata/xcschemes/ShadowsocksX-NGTests.xcscheme +++ b/ShadowsocksX-NG.xcodeproj/xcshareddata/xcschemes/ShadowsocksX-NGTests.xcscheme @@ -1,6 +1,6 @@ Void { + var gMyHotKeyID = EventHotKeyID() + gMyHotKeyID.signature = OSType(fourCharCodeFrom(string: "sxng")) + gMyHotKeyID.id = UInt32(keyCode) + + var eventType = EventTypeSpec() + eventType.eventClass = OSType(kEventClassKeyboard) + eventType.eventKind = OSType(kEventHotKeyPressed) + + // Void pointer to `self`: + let context = Unmanaged.passUnretained(self).toOpaque() + + // Install handler. + InstallEventHandler(GetApplicationEventTarget(), {(nextHanlder, theEvent, userContext) -> OSStatus in + // Extract pointer to `self` from void pointer: + let mySelf = Unmanaged.fromOpaque(userContext!).takeUnretainedValue() + + switch Globals.proxyType { + case .pac: + Globals.proxyType = .global + UserDefaults.standard.setValue("global", forKey: "ShadowsocksRunningMode") + mySelf.isNameTextField.stringValue = "Gobal Mode" + mySelf.updateRunningModeMenu() + mySelf.applyConfig() + case .global: + Globals.proxyType = .pac + UserDefaults.standard.setValue("auto", forKey: "ShadowsocksRunningMode") + mySelf.isNameTextField.stringValue = "Auto Mode" + mySelf.updateRunningModeMenu() + mySelf.applyConfig() + } + + mySelf.fadeInHud() + + return noErr + }, 1, &eventType, context, nil) + + // Register hotkey. + RegisterEventHotKey(UInt32(keyCode), + UInt32(modifierKeys), + gMyHotKeyID, + GetApplicationEventTarget(), + 0, + &hotKeyRef) + } + + func fourCharCodeFrom(string: String) -> FourCharCode { + assert(string.characters.count == 4, "String length must be 4") + var result: FourCharCode = 0 + for char in string.utf16 { + result = (result << 8) + FourCharCode(char) + } + return result + } + + // MARK: - UI Methods @IBAction func toggleRunning(_ sender: NSMenuItem) { let defaults = UserDefaults.standard var isOn = defaults.bool(forKey: "ShadowsocksOn") @@ -257,7 +352,20 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele ScanQRCodeOnScreen() } - @IBAction func toggleLaunghAtLogin(_ sender: NSMenuItem) { + @IBAction func showBunchJsonExampleFile(sender: NSMenuItem) { + ServerProfileManager.showExampleConfigFile() + } + + @IBAction func importBunchJsonFile(sender: NSMenuItem) { + ServerProfileManager.instance.importConfigFile() + //updateServersMenu()//not working + } + + @IBAction func exportAllServerProfile(sender: NSMenuItem) { + ServerProfileManager.instance.exportConfigFile() + } + + @IBAction func toggleLaunghAtLogin(sender: NSMenuItem) { launchAtLoginController.launchAtLogin = !launchAtLoginController.launchAtLogin; updateLaunchAtLoginMenu() } @@ -459,6 +567,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele let showQRItem = showQRCodeMenuItem let scanQRItem = scanQRCodeMenuItem let preferencesItem = serversPreferencesMenuItem + let showBunch = showBunchJsonExampleFileItem + let importBuntch = importBunchJsonFileItem + let exportAllServer = exportAllServerProfileItem var i = 0 for p in mgr.profiles { @@ -485,6 +596,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele } serversMenuItem.submenu?.addItem(showQRItem!) serversMenuItem.submenu?.addItem(scanQRItem!) + serversMenuItem.submenu?.addItem(showBunch!) + serversMenuItem.submenu?.addItem(importBuntch!) + serversMenuItem.submenu?.addItem(exportAllServer!) serversMenuItem.submenu?.addItem(NSMenuItem.separator()) serversMenuItem.submenu?.addItem(preferencesItem!) } @@ -511,3 +625,93 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele } } +extension AppDelegate { + func fadeInHud() -> Void { + if timerToFadeOut != nil { + timerToFadeOut?.invalidate() + timerToFadeOut = nil + } + + fadingOut = false + + hudWindow.orderFrontRegardless() + + CATransaction.begin() + CATransaction.setAnimationDuration(kHudFadeInDuration) + CATransaction.setCompletionBlock { self.didFadeIn() } + panelView.layer?.opacity = 1.0 + CATransaction.commit() + } + + func didFadeIn() -> Void { + timerToFadeOut = Timer.scheduledTimer( + timeInterval: kHudDisplayDuration, + target: self, + selector: #selector(fadeOutHud), + userInfo: nil, + repeats: false) + } + + func fadeOutHud() -> Void { + fadingOut = true + + CATransaction.begin() + CATransaction.setAnimationDuration(kHudFadeOutDuration) + CATransaction.setCompletionBlock { self.didFadeOut() } + panelView.layer?.opacity = 0.0 + CATransaction.commit() + } + + func didFadeOut() -> Void { + if fadingOut { + self.hudWindow.orderOut(nil) + } + fadingOut = false + } + + func setupHud() -> Void { + isNameTextField.stringValue = "Global Mode" + isNameTextField.sizeToFit() + + var labelFrame: CGRect = isNameTextField.frame + var hudWindowFrame: CGRect = hudWindow.frame + hudWindowFrame.size.width = labelFrame.size.width + kHudHorizontalMargin * 2 + hudWindowFrame.size.height = kHudHeight + + let screenRect: NSRect = NSScreen.screens()![0].visibleFrame + hudWindowFrame.origin.x = (screenRect.size.width - hudWindowFrame.size.width) / 2 + hudWindowFrame.origin.y = (screenRect.size.height - hudWindowFrame.size.height) / 2 + hudWindow.setFrame(hudWindowFrame, display: true) + + var viewFrame: NSRect = hudWindowFrame; + viewFrame.origin.x = 0 + viewFrame.origin.y = 0 + panelView.frame = viewFrame + + labelFrame.origin.x = kHudHorizontalMargin + labelFrame.origin.y = (hudWindowFrame.size.height - labelFrame.size.height) / 2 + isNameTextField.frame = labelFrame + } + + func initUIComponent() -> Void { + hudWindow.isOpaque = false + hudWindow.backgroundColor = .clear + hudWindow.level = Int(CGWindowLevelForKey(.utilityWindow)) + 1000 + hudWindow.styleMask = .borderless + hudWindow.hidesOnDeactivate = false + hudWindow.collectionBehavior = .canJoinAllSpaces + + let viewLayer: CALayer = CALayer() + viewLayer.backgroundColor = CGColor.init(red: 0.05, green: 0.05, blue: 0.05, alpha: kHudAlphaValue) + viewLayer.cornerRadius = kHudCornerRadius + panelView.wantsLayer = true + panelView.layer = viewLayer + panelView.layer?.opacity = 0.0 + + setupHud() + } + + override func awakeFromNib() { + initUIComponent() + } +} diff --git a/ShadowsocksX-NG/Base.lproj/MainMenu.xib b/ShadowsocksX-NG/Base.lproj/MainMenu.xib index be83a01..e8f315c 100755 --- a/ShadowsocksX-NG/Base.lproj/MainMenu.xib +++ b/ShadowsocksX-NG/Base.lproj/MainMenu.xib @@ -1,8 +1,9 @@ - + - + + @@ -14,16 +15,21 @@ - + - + + + + + + @@ -110,6 +116,24 @@ + + + + + + + + + + + + + + + + + + @@ -135,7 +159,7 @@ - + @@ -164,7 +188,7 @@ - + @@ -178,6 +202,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ShadowsocksX-NG/Base.lproj/PreferencesWindowController.xib b/ShadowsocksX-NG/Base.lproj/PreferencesWindowController.xib index aa75978..a75aca2 100644 --- a/ShadowsocksX-NG/Base.lproj/PreferencesWindowController.xib +++ b/ShadowsocksX-NG/Base.lproj/PreferencesWindowController.xib @@ -1,15 +1,24 @@ - + - + + - + + + + + + + + + @@ -25,20 +34,20 @@ - - + + - + - + - + - + @@ -70,6 +79,7 @@ + @@ -83,14 +93,14 @@ - - + + - + - + @@ -98,9 +108,9 @@ - + - + @@ -109,9 +119,9 @@ - + - + @@ -126,7 +136,7 @@ - + @@ -134,7 +144,7 @@ - + @@ -142,7 +152,7 @@ - + @@ -153,7 +163,7 @@ - + @@ -161,7 +171,7 @@ - + @@ -169,25 +179,15 @@ - + - - + @@ -195,60 +195,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NSAllRomanInputSourcesLocaleIdentifier + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - - - - + + + + + @@ -284,7 +463,7 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + diff --git a/ShadowsocksX-NG/Info.plist b/ShadowsocksX-NG/Info.plist index 084119c..79f2386 100644 --- a/ShadowsocksX-NG/Info.plist +++ b/ShadowsocksX-NG/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.3.2 + 1.4.0 CFBundleSignature ???? CFBundleURLTypes diff --git a/ShadowsocksX-NG/KcptunProfile.swift b/ShadowsocksX-NG/KcptunProfile.swift new file mode 100644 index 0000000..30ef470 --- /dev/null +++ b/ShadowsocksX-NG/KcptunProfile.swift @@ -0,0 +1,137 @@ +// +// KcptunProfile.swift +// ShadowsocksX-NG +// +// Created by 邱宇舟 on 2017/1/11. +// Copyright © 2017年 qiuyuzhou. All rights reserved. +// + +import Foundation + + +class KcptunProfile: NSObject { + + var mode: String = "fast" + + var key: String = "it's a secrect" + var crypt: String = "aes" + var nocomp: Bool = false + var datashard: uint = 10 + var parityshard: uint = 3 + var mtu: uint = 1350 + + + public func copy(with zone: NSZone? = nil) -> Any { + let copy = KcptunProfile() + copy.mode = self.mode + copy.key = self.key + copy.crypt = self.crypt + copy.nocomp = self.nocomp + copy.datashard = self.datashard + copy.parityshard = self.parityshard + return copy; + } + + func toDictionary() -> [String:AnyObject] { + let conf: [String: AnyObject] = [ + "mode": self.mode as AnyObject, + "key": self.key as AnyObject, + "crypt": self.crypt as AnyObject, + "nocomp": NSNumber(value: self.nocomp), + "datashard": NSNumber(value: self.datashard), + "parityshard": NSNumber(value: self.parityshard), + "mtu": NSNumber(value: self.mtu), + ] + return conf + } + + static func fromDictionary(_ data:[String:Any?]) -> KcptunProfile { + let profile = KcptunProfile() + profile.mode = data["mode"] as! String + profile.key = data["key"] as! String + profile.crypt = data["crypt"] as! String + profile.nocomp = (data["nocomp"] as! NSNumber).boolValue + profile.datashard = uint((data["datashard"] as! NSNumber).uintValue) + profile.parityshard = uint((data["parityshard"] as! NSNumber).uintValue) + if let v = data["mtu"] as? NSNumber { + profile.mtu = uint(v.uintValue) + } + + return profile + } + + func toJsonConfig() -> [String: AnyObject] { + let defaults = UserDefaults.standard + let localHost = defaults.string(forKey: "Kcptun.LocalHost")! as String + let localPort = defaults.integer(forKey: "Kcptun.LocalPort") + + let conf: [String: AnyObject] = [ + "localaddr": "\(localHost):\(localPort)" as AnyObject, + "mode": self.mode as AnyObject, + "key": self.key as AnyObject, + "crypt": self.crypt as AnyObject, + "nocomp": NSNumber(value: self.nocomp), + "datashard": NSNumber(value: self.datashard), + "parityshard": NSNumber(value: self.parityshard), + "mtu": NSNumber(value: self.mtu), + ] + return conf + } + + func urlQueryItems() -> [URLQueryItem] { + return [ + URLQueryItem(name: "mode", value: mode), + URLQueryItem(name: "key", value: key), + URLQueryItem(name: "crypt", value: crypt), + URLQueryItem(name: "datashard", value: "\(datashard)"), + URLQueryItem(name: "parityshard", value: "\(parityshard)"), + URLQueryItem(name: "nocomp", value: nocomp.description), + URLQueryItem(name: "mtu", value: "\(mtu)"), + ] + } + + func loadUrlQueryItems(items: [URLQueryItem]) { + for item in items { + switch item.name { + case "mode": + if let v = item.value { + mode = v + } + case "key": + if let v = item.value { + key = v + } + case "crypt": + if let v = item.value { + crypt = v + } + case "datashard": + if let v = item.value { + if let vv = uint(v) { + datashard = vv + } + } + case "parityshard": + if let v = item.value { + if let vv = uint(v) { + parityshard = vv + } + } + case "nocomp": + if let v = item.value { + if let vv = Bool(v) { + nocomp = vv + } + } + case "mtu": + if let v = item.value { + if let vv = uint(v) { + mtu = vv + } + } + default: + continue + } + } + } +} diff --git a/ShadowsocksX-NG/LaunchAgentUtils.swift b/ShadowsocksX-NG/LaunchAgentUtils.swift index e5357c9..c39dff3 100644 --- a/ShadowsocksX-NG/LaunchAgentUtils.swift +++ b/ShadowsocksX-NG/LaunchAgentUtils.swift @@ -8,12 +8,14 @@ import Foundation -let SS_LOCAL_VERSION = "2.4.6" +let SS_LOCAL_VERSION = "2.5.6" +let KCPTUN_CLIENT_VERSION = "20161222" let PRIVOXY_VERSION = "3.0.26.static" let APP_SUPPORT_DIR = "/Library/Application Support/ShadowsocksX-NG/" let LAUNCH_AGENT_DIR = "/Library/LaunchAgents/" let LAUNCH_AGENT_CONF_SSLOCAL_NAME = "com.qiuyuzhou.shadowsocksX-NG.local.plist" let LAUNCH_AGENT_CONF_PRIVOXY_NAME = "com.qiuyuzhou.shadowsocksX-NG.http.plist" +let LAUNCH_AGENT_CONF_KCPTUN_NAME = "com.qiuyuzhou.shadowsocksX-NG.kcptun.plist" func getFileSHA1Sum(_ filepath: String) -> String { @@ -114,7 +116,8 @@ func InstallSSLocal() { let homeDir = NSHomeDirectory() let appSupportDir = homeDir+APP_SUPPORT_DIR if !fileMgr.fileExists(atPath: appSupportDir + "ss-local-\(SS_LOCAL_VERSION)/ss-local") - || !fileMgr.fileExists(atPath: appSupportDir + "libcrypto.1.0.0.dylib") { + || !fileMgr.fileExists(atPath: appSupportDir + "libcrypto.1.0.0.dylib") + || !fileMgr.fileExists(atPath: appSupportDir + "libpcre.1.dylib") { let bundle = Bundle.main let installerPath = bundle.path(forResource: "install_ss_local.sh", ofType: nil) let task = Process.launchedProcess(launchPath: installerPath!, arguments: [""]) @@ -174,8 +177,10 @@ func SyncSSLocal() { } SyncPac() SyncPrivoxy() + SyncKcptun() } +// -------------------------------------------------------------------------------- // MARK: privoxy func generatePrivoxyLauchAgentPlist() -> Bool { @@ -320,3 +325,144 @@ func SyncPrivoxy() { } } } + +// -------------------------------------------------------------------------------- +// kcptun + +func generateKcptunLauchAgentPlist() -> Bool { + let sslocalPath = NSHomeDirectory() + APP_SUPPORT_DIR + "kcptun_client" + let logFilePath = NSHomeDirectory() + "/Library/Logs/kcptun_client.log" + let launchAgentDirPath = NSHomeDirectory() + LAUNCH_AGENT_DIR + let plistFilepath = launchAgentDirPath + LAUNCH_AGENT_CONF_KCPTUN_NAME + + // Ensure launch agent directory is existed. + let fileMgr = FileManager.default + if !fileMgr.fileExists(atPath: launchAgentDirPath) { + try! fileMgr.createDirectory(atPath: launchAgentDirPath, withIntermediateDirectories: true, attributes: nil) + } + + let oldSha1Sum = getFileSHA1Sum(plistFilepath) + + let arguments = [sslocalPath, "-c", "kcptun-config.json"] + + // For a complete listing of the keys, see the launchd.plist manual page. + let dict: NSMutableDictionary = [ + "Label": "com.qiuyuzhou.shadowsocksX-NG.kcptun", + "WorkingDirectory": NSHomeDirectory() + APP_SUPPORT_DIR, + "KeepAlive": true, + "StandardOutPath": logFilePath, + "StandardErrorPath": logFilePath, + "ProgramArguments": arguments, + "EnvironmentVariables": ["DYLD_LIBRARY_PATH": NSHomeDirectory() + APP_SUPPORT_DIR] + ] + dict.write(toFile: plistFilepath, atomically: true) + let Sha1Sum = getFileSHA1Sum(plistFilepath) + if oldSha1Sum != Sha1Sum { + return true + } else { + return false + } +} + +func InstallKcptunClient() { + let fileMgr = FileManager.default + let homeDir = NSHomeDirectory() + let appSupportDir = homeDir+APP_SUPPORT_DIR + if !fileMgr.fileExists(atPath: appSupportDir + "kcptun_\(KCPTUN_CLIENT_VERSION)/kcptun_client") { + let bundle = Bundle.main + let installerPath = bundle.path(forResource: "install_kcptun", ofType: "sh") + let task = Process.launchedProcess(launchPath: installerPath!, arguments: [""]) + task.waitUntilExit() + if task.terminationStatus == 0 { + NSLog("Install kcptun succeeded.") + } else { + NSLog("Install kcptun failed.") + } + } +} + +func writeKcptunConfFile(_ conf:[String:AnyObject]) -> Bool { + do { + let filepath = NSHomeDirectory() + APP_SUPPORT_DIR + "kcptun-config.json" + let data: Data = try JSONSerialization.data(withJSONObject: conf, options: .prettyPrinted) + + let oldSum = getFileSHA1Sum(filepath) + try data.write(to: URL(fileURLWithPath: filepath), options: .atomic) + let newSum = getFileSHA1Sum(filepath) + + if oldSum == newSum { + return false + } + + return true + } catch { + NSLog("Write kcptun config file failed.") + } + return false +} + +func removeKcptunConfFile() { + do { + let filepath = NSHomeDirectory() + APP_SUPPORT_DIR + "kcptun-config.json" + try FileManager.default.removeItem(atPath: filepath) + } catch { + + } +} + + +func ReloadConfKcptun() { + let bundle = Bundle.main + let installerPath = bundle.path(forResource: "reload_conf_kcptun.sh", ofType: nil) + let task = Process.launchedProcess(launchPath: installerPath!, arguments: [""]) + task.waitUntilExit() + if task.terminationStatus == 0 { + NSLog("Start kcptun succeeded.") + } else { + NSLog("Start kcptun failed.") + } +} + +func StartKcptun() { + let bundle = Bundle.main + let installerPath = bundle.path(forResource: "start_kcptun.sh", ofType: nil) + let task = Process.launchedProcess(launchPath: installerPath!, arguments: [""]) + task.waitUntilExit() + if task.terminationStatus == 0 { + NSLog("Start kcptun succeeded.") + } else { + NSLog("Start kcptun failed.") + } +} + +func StopKcptun() { + let bundle = Bundle.main + let installerPath = bundle.path(forResource: "stop_kcptun.sh", ofType: nil) + let task = Process.launchedProcess(launchPath: installerPath!, arguments: [""]) + task.waitUntilExit() + if task.terminationStatus == 0 { + NSLog("Stop kcptun succeeded.") + } else { + NSLog("Stop kcptun failed.") + } +} + +func SyncKcptun() { + var changed: Bool = false + changed = changed || generateKcptunLauchAgentPlist() + let mgr = ServerProfileManager.instance + if let profile = mgr.getActiveProfile() { + if profile.enabledKcptun { + changed = changed || writeKcptunConfFile(profile.toKcptunJsonConfig()) + + let on = UserDefaults.standard.bool(forKey: "ShadowsocksOn") + if on { + StartKcptun() + ReloadConfKcptun() + return + } + } + } + StopKcptun() + removeKcptunConfFile() +} diff --git a/ShadowsocksX-NG/LaunchAtLoginController.h b/ShadowsocksX-NG/LaunchAtLoginController.h index b52c0d7..144f69e 100755 --- a/ShadowsocksX-NG/LaunchAtLoginController.h +++ b/ShadowsocksX-NG/LaunchAtLoginController.h @@ -27,7 +27,5 @@ @property(assign) BOOL launchAtLogin; -- (BOOL) willLaunchAtLogin: (NSURL*) itemURL; -- (void) setLaunchAtLogin: (BOOL) enabled forURL: (NSURL*) itemURL; @end diff --git a/ShadowsocksX-NG/LaunchAtLoginController.m b/ShadowsocksX-NG/LaunchAtLoginController.m index 0f48434..7ba9f7a 100755 --- a/ShadowsocksX-NG/LaunchAtLoginController.m +++ b/ShadowsocksX-NG/LaunchAtLoginController.m @@ -23,24 +23,20 @@ // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "LaunchAtLoginController.h" +#import -static NSString *const StartAtLoginKey = @"launchAtLogin"; +//static NSString *const StartAtLoginKey = @"launchAtLogin"; + +@interface LaunchAtLoginController () { + BOOL _enabled; +} -@interface LaunchAtLoginController () -@property(assign) LSSharedFileListRef loginItems; @end @implementation LaunchAtLoginController -@synthesize loginItems; #pragma mark Change Observing -void sharedFileListDidChange(LSSharedFileListRef inList, void *context) -{ - LaunchAtLoginController *self = (__bridge id) context; - [self willChangeValueForKey:StartAtLoginKey]; - [self didChangeValueForKey:StartAtLoginKey]; -} #pragma mark Initialization @@ -48,76 +44,29 @@ void sharedFileListDidChange(LSSharedFileListRef inList, void *context) { self = [super init]; if (self) { - loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); - LSSharedFileListAddObserver(loginItems, CFRunLoopGetMain(), - (CFStringRef)NSDefaultRunLoopMode, sharedFileListDidChange, (__bridge void *)(self)); + _enabled = [[NSUserDefaults standardUserDefaults] boolForKey: @"LaunchAtLogin"]; } return self; } - (void) dealloc { - LSSharedFileListRemoveObserver(loginItems, CFRunLoopGetMain(), - (CFStringRef)NSDefaultRunLoopMode, sharedFileListDidChange, (__bridge void *)(self)); - CFRelease(loginItems); -} - -#pragma mark Launch List Control - -- (LSSharedFileListItemRef) findItemWithURL: (NSURL*) wantedURL inFileList: (LSSharedFileListRef) fileList -{ - if (wantedURL == NULL || fileList == NULL) - return NULL; - - NSArray *listSnapshot = ((__bridge NSArray *)(LSSharedFileListCopySnapshot(fileList, NULL))); - for (id itemObject in listSnapshot) { - LSSharedFileListItemRef item = (__bridge LSSharedFileListItemRef) itemObject; - UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes; - CFURLRef currentItemURL = NULL; - currentItemURL = LSSharedFileListItemCopyResolvedURL(item, resolutionFlags, NULL); - if (currentItemURL && CFEqual(currentItemURL, (__bridge CFTypeRef)(wantedURL))) { - CFRelease(currentItemURL); - return item; - } - if (currentItemURL) - CFRelease(currentItemURL); - } - - return NULL; -} - -- (BOOL) willLaunchAtLogin: (NSURL*) itemURL -{ - return !![self findItemWithURL:itemURL inFileList:loginItems]; -} - -- (void) setLaunchAtLogin: (BOOL) enabled forURL: (NSURL*) itemURL -{ - LSSharedFileListItemRef appItem = [self findItemWithURL:itemURL inFileList:loginItems]; - if (enabled && !appItem) { - LSSharedFileListInsertItemURL(loginItems, kLSSharedFileListItemBeforeFirst, - NULL, NULL, (__bridge CFURLRef)itemURL, NULL, NULL); - } else if (!enabled && appItem) - LSSharedFileListItemRemove(loginItems, appItem); -} - -#pragma mark Basic Interface - -- (NSURL*) appURL -{ - return [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]; } - (void) setLaunchAtLogin: (BOOL) enabled { - [self willChangeValueForKey:StartAtLoginKey]; - [self setLaunchAtLogin:enabled forURL:[self appURL]]; - [self didChangeValueForKey:StartAtLoginKey]; + if (SMLoginItemSetEnabled( + (__bridge CFStringRef)@"com.qiuyuzhou.ShadowsocksX-NG.LaunchHelper" + , enabled)) { + _enabled = enabled; + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + [defaults setBool: enabled forKey: @"LaunchAtLogin"]; + } } - (BOOL) launchAtLogin { - return [self willLaunchAtLogin:[self appURL]]; + return _enabled; } @end diff --git a/ShadowsocksX-NG/PreferencesWindowController.swift b/ShadowsocksX-NG/PreferencesWindowController.swift index b24939c..62ad829 100644 --- a/ShadowsocksX-NG/PreferencesWindowController.swift +++ b/ShadowsocksX-NG/PreferencesWindowController.swift @@ -14,6 +14,7 @@ class PreferencesWindowController: NSWindowController @IBOutlet weak var profilesTableView: NSTableView! @IBOutlet weak var profileBox: NSBox! + @IBOutlet weak var kcptunProfileBox: NSBox! @IBOutlet weak var hostTextField: NSTextField! @IBOutlet weak var portTextField: NSTextField! @@ -24,7 +25,14 @@ class PreferencesWindowController: NSWindowController @IBOutlet weak var otaCheckBoxBtn: NSButton! - @IBOutlet weak var copyURLBtn: NSButton! + @IBOutlet weak var kcptunCheckBoxBtn: NSButton! + @IBOutlet weak var kcptunCryptComboBox: NSComboBox! + @IBOutlet weak var kcptunKeyTextField: NSTextField! + @IBOutlet weak var kcptunModeComboBox: NSComboBox! + @IBOutlet weak var kcptunNocompCheckBoxBtn: NSButton! + @IBOutlet weak var kcptunDatashardTextField: NSTextField! + @IBOutlet weak var kcptunParityshardTextField: NSTextField! + @IBOutlet weak var kcptunMTUTextField: NSTextField! @IBOutlet weak var removeButton: NSButton! let tableViewDragType: String = "ss.server.profile.data" @@ -48,14 +56,44 @@ class PreferencesWindowController: NSWindowController "aes-256-cfb", "des-cfb", "bf-cfb", + "camellia-128-cfb", + "camellia-192-cfb", + "camellia-256-cfb", + "idea-cfb", "cast5-cfb", + "rc2-cfb", "rc4-md5", + "seed-cfb", "chacha20", + "chacha20-ietf", "salsa20", "rc4", "table", ]) + kcptunCryptComboBox.addItems(withObjectValues: [ + "none", + "aes", + "aes-128", + "aes-192", + "salsa20", + "blowfish", + "twofish", + "cast5", + "3des", + "tea", + "xtea", + "xor", + ]) + + kcptunModeComboBox.addItems(withObjectValues: [ + "default", + "normal", + "fast", + "fast2", + "fast3", + ]) + profilesTableView.reloadData() updateProfileBoxVisible() } @@ -114,6 +152,20 @@ class PreferencesWindowController: NSWindowController window?.performClose(self) } + @IBAction func duplicate(_ sender: Any) { + let profile = profileMgr.profiles[profilesTableView.clickedRow] + let duplicateProfile = profile.copy() as! ServerProfile + duplicateProfile.uuid = UUID().uuidString + profileMgr.profiles.insert(duplicateProfile, at: profilesTableView.clickedRow+1) + profilesTableView.beginUpdates() + let index = IndexSet(integer: profileMgr.profiles.count-1) + profilesTableView.insertRows(at: index, withAnimation: .effectFade) + self.profilesTableView.scrollRowToVisible(profilesTableView.clickedRow+1) + self.profilesTableView.selectRowIndexes(index, byExtendingSelection: false) + profilesTableView.endUpdates() + updateProfileBoxVisible() + } + @IBAction func copyCurrentProfileURL2Pasteboard(_ sender: NSButton) { let index = profilesTableView.selectedRow if index >= 0 { @@ -168,6 +220,34 @@ class PreferencesWindowController: NSWindowController otaCheckBoxBtn.bind("value", to: editingProfile, withKeyPath: "ota" , options: [NSContinuouslyUpdatesValueBindingOption: true]) + + // -------------------------------------------------- + // Kcptun + kcptunCheckBoxBtn.bind("value", to: editingProfile, withKeyPath: "enabledKcptun" + , options: [NSContinuouslyUpdatesValueBindingOption: true]) + + kcptunProfileBox.bind("Hidden", to: editingProfile, withKeyPath: "enabledKcptun" + , options: [NSContinuouslyUpdatesValueBindingOption: false, + NSValueTransformerNameBindingOption: NSValueTransformerName.negateBooleanTransformerName]) + + kcptunNocompCheckBoxBtn.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.nocomp", options: nil) + + kcptunModeComboBox.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.mode", options: nil) + + kcptunCryptComboBox.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.crypt", options: nil) + + kcptunKeyTextField.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.key" + , options: [NSContinuouslyUpdatesValueBindingOption: true]) + + kcptunDatashardTextField.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.datashard" + , options: [NSContinuouslyUpdatesValueBindingOption: true]) + + kcptunParityshardTextField.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.parityshard" + , options: [NSContinuouslyUpdatesValueBindingOption: true]) + + kcptunMTUTextField.bind("value", to: editingProfile, withKeyPath: "kcptunProfile.mtu" + , options: [NSContinuouslyUpdatesValueBindingOption: true]) + } else { editingProfile = nil hostTextField.unbind("value") @@ -179,6 +259,8 @@ class PreferencesWindowController: NSWindowController remarkTextField.unbind("value") otaCheckBoxBtn.unbind("value") + + kcptunCheckBoxBtn.unbind("value") } } diff --git a/ShadowsocksX-NG/ProxyConfHelper.m b/ShadowsocksX-NG/ProxyConfHelper.m index 96c7ada..3665f11 100644 --- a/ShadowsocksX-NG/ProxyConfHelper.m +++ b/ShadowsocksX-NG/ProxyConfHelper.m @@ -211,45 +211,34 @@ FSEventStreamRef fsEventStream; } } -void onPACChange( - ConstFSEventStreamRef streamRef, - void *clientCallBackInfo, - size_t numEvents, - void *eventPaths, - const FSEventStreamEventFlags eventFlags[], - const FSEventStreamEventId eventIds[]) -{ - NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; - if ([defaults boolForKey:@"ShadowsocksOn"]) { - if ([[defaults stringForKey:@"ShadowsocksRunningMode"] isEqualToString:@"auto"]) { - [ProxyConfHelper disableProxy]; - [ProxyConfHelper enablePACProxy]; - } - } -} - + (void)startMonitorPAC { NSString* PACFilePath = [self getPACFilePath]; - - if (fsEventStream) { - return; - } - CFStringRef mypath = (__bridge CFStringRef)(PACFilePath); - CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&mypath, 1, NULL); - void *callbackInfo = NULL; // could put stream-specific data here. - CFAbsoluteTime latency = 3.0; /* Latency in seconds */ - - /* Create the stream, passing in a callback */ - fsEventStream = FSEventStreamCreate(NULL, - &onPACChange, - callbackInfo, - pathsToWatch, - kFSEventStreamEventIdSinceNow, /* Or a previous event ID */ - latency, - kFSEventStreamCreateFlagNone /* Flags explained in reference */ - ); - FSEventStreamScheduleWithRunLoop(fsEventStream, [[NSRunLoop mainRunLoop] getCFRunLoop], (__bridge CFStringRef)NSDefaultRunLoopMode); - FSEventStreamStart(fsEventStream); + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + int fileId = open([PACFilePath UTF8String], O_EVTONLY); + __block dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fileId, + DISPATCH_VNODE_DELETE | DISPATCH_VNODE_WRITE | DISPATCH_VNODE_EXTEND | DISPATCH_VNODE_ATTRIB | DISPATCH_VNODE_LINK | DISPATCH_VNODE_RENAME | DISPATCH_VNODE_REVOKE, + queue); + dispatch_source_set_event_handler(source, ^ + { + unsigned long flags = dispatch_source_get_data(source); + if(flags & DISPATCH_VNODE_DELETE) + { + dispatch_source_cancel(source); + } else { + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + if ([defaults boolForKey:@"ShadowsocksOn"]) { + if ([[defaults stringForKey:@"ShadowsocksRunningMode"] isEqualToString:@"auto"]) { + [ProxyConfHelper disableProxy]; + [ProxyConfHelper enablePACProxy]; + } + } + } + }); + dispatch_source_set_cancel_handler(source, ^(void) + { + close(fileId); + }); + dispatch_resume(source); } @end diff --git a/ShadowsocksX-NG/SWBQRCodeWindowController.h b/ShadowsocksX-NG/SWBQRCodeWindowController.h index 5850870..661cadc 100644 --- a/ShadowsocksX-NG/SWBQRCodeWindowController.h +++ b/ShadowsocksX-NG/SWBQRCodeWindowController.h @@ -14,4 +14,6 @@ @property (nonatomic, copy) NSString *qrCode; @property (nonatomic, weak) NSImageView *imageView; +- (IBAction) copyQRCode: (id) sender; + @end diff --git a/ShadowsocksX-NG/SWBQRCodeWindowController.m b/ShadowsocksX-NG/SWBQRCodeWindowController.m index 8c6a642..a7e97e9 100644 --- a/ShadowsocksX-NG/SWBQRCodeWindowController.m +++ b/ShadowsocksX-NG/SWBQRCodeWindowController.m @@ -71,4 +71,11 @@ return scaledImage; } +- (IBAction) copyQRCode: (id) sender{ + NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; + [pasteboard clearContents]; + NSArray *copiedObjects = [NSArray arrayWithObject: self.imageView.image]; + [pasteboard writeObjects:copiedObjects]; +} + @end diff --git a/ShadowsocksX-NG/SWBQRCodeWindowController.xib b/ShadowsocksX-NG/SWBQRCodeWindowController.xib index 740efba..5133e88 100644 --- a/ShadowsocksX-NG/SWBQRCodeWindowController.xib +++ b/ShadowsocksX-NG/SWBQRCodeWindowController.xib @@ -1,8 +1,9 @@ - + - + + @@ -16,7 +17,7 @@ - + @@ -25,9 +26,22 @@ + + + + + + + + + + + + + diff --git a/ShadowsocksX-NG/ServerProfile.swift b/ShadowsocksX-NG/ServerProfile.swift index c63085d..752583c 100644 --- a/ShadowsocksX-NG/ServerProfile.swift +++ b/ShadowsocksX-NG/ServerProfile.swift @@ -9,10 +9,10 @@ import Cocoa - -class ServerProfile: NSObject { - var uuid: String +class ServerProfile: NSObject, NSCopying { + var uuid: String + var serverHost: String = "" var serverPort: uint16 = 8379 var method:String = "aes-128-cfb" @@ -20,15 +20,91 @@ class ServerProfile: NSObject { var remark:String = "" var ota: Bool = false // onetime authentication + var enabledKcptun: Bool = false + var kcptunProfile = KcptunProfile() + override init() { uuid = UUID().uuidString } - + init(uuid: String) { self.uuid = uuid } + + convenience init?(url: URL?) { + self.init() + + func padBase64(string: String) -> String { + var length = string.characters.count + if length % 4 == 0 { + return string + } else { + length = 4 - length % 4 + length + return string.padding(toLength: length, withPad: "=", startingAt: 0) + } + } + + func decodeUrl(url: URL?) -> String? { + guard let urlStr = url?.absoluteString else { + return nil + } + let index = urlStr.index(urlStr.startIndex, offsetBy: 5) + let encodedStr = urlStr.substring(from: index) + guard let data = Data(base64Encoded: padBase64(string: encodedStr)) else { + return url?.absoluteString + } + guard let decoded = String(data: data, encoding: String.Encoding.utf8) else { + return nil + } + return "ss://\(decoded)" + } + + guard let decodedUrl = decodeUrl(url: url) else { + return nil + } + guard var parsedUrl = URLComponents(string: decodedUrl) else { + return nil + } + guard let host = parsedUrl.host, let port = parsedUrl.port, + let method = parsedUrl.user, let password = parsedUrl.password else { + return nil + } + + self.serverHost = host + self.serverPort = UInt16(port) + self.method = method + self.password = password + + remark = parsedUrl.queryItems? + .filter({ $0.name == "Remark" }).first?.value ?? "" + if let otaStr = parsedUrl.queryItems? + .filter({ $0.name == "OTA" }).first?.value { + ota = NSString(string: otaStr).boolValue + } + if let enabledKcptunStr = parsedUrl.queryItems? + .filter({ $0.name == "Kcptun" }).first?.value { + enabledKcptun = NSString(string: enabledKcptunStr).boolValue + } + + if enabledKcptun { + if let items = parsedUrl.queryItems { + self.kcptunProfile.loadUrlQueryItems(items: items) + } + } + } - static func fromDictionary(_ data:[String:AnyObject]) -> ServerProfile { + public func copy(with zone: NSZone? = nil) -> Any { + let copy = ServerProfile() + copy.serverHost = self.serverHost + copy.serverPort = self.serverPort + copy.method = self.method + copy.password = self.password + copy.remark = self.remark + copy.ota = self.ota + return copy; + } + + static func fromDictionary(_ data:[String:Any?]) -> ServerProfile { let cp = { (profile: ServerProfile) in profile.serverHost = data["ServerHost"] as! String @@ -41,8 +117,14 @@ class ServerProfile: NSObject { if let ota = data["OTA"] { profile.ota = ota as! Bool } + if let enabledKcptun = data["EnabledKcptun"] { + profile.enabledKcptun = enabledKcptun as! Bool + } + if let kcptunData = data["KcptunProfile"] { + profile.kcptunProfile = KcptunProfile.fromDictionary(kcptunData as! [String:Any?]) + } } - + if let id = data["Id"] as? String { let profile = ServerProfile(uuid: id) cp(profile) @@ -53,7 +135,7 @@ class ServerProfile: NSObject { return profile } } - + func toDictionary() -> [String:AnyObject] { var d = [String:AnyObject]() d["Id"] = uuid as AnyObject? @@ -63,13 +145,13 @@ class ServerProfile: NSObject { d["Password"] = password as AnyObject? d["Remark"] = remark as AnyObject? d["OTA"] = ota as AnyObject? + d["EnabledKcptun"] = NSNumber(value: enabledKcptun) + d["KcptunProfile"] = kcptunProfile.toDictionary() as AnyObject return d } - + func toJsonConfig() -> [String: AnyObject] { - var conf: [String: AnyObject] = ["server": serverHost as AnyObject, - "server_port": NSNumber(value: serverPort as UInt16), - "password": password as AnyObject, + var conf: [String: AnyObject] = ["password": password as AnyObject, "method": method as AnyObject,] let defaults = UserDefaults.standard @@ -78,15 +160,32 @@ class ServerProfile: NSObject { conf["timeout"] = NSNumber(value: UInt32(defaults.integer(forKey: "LocalSocks5.Timeout")) as UInt32) conf["auth"] = NSNumber(value: ota as Bool) + if enabledKcptun { + let localHost = defaults.string(forKey: "Kcptun.LocalHost") + let localPort = uint16(defaults.integer(forKey: "Kcptun.LocalPort")) + + conf["server"] = localHost as AnyObject + conf["server_port"] = NSNumber(value: localPort as UInt16) + } else { + conf["server"] = serverHost as AnyObject + conf["server_port"] = NSNumber(value: serverPort as UInt16) + } + return conf } + func toKcptunJsonConfig() -> [String: AnyObject] { + var conf = kcptunProfile.toJsonConfig() + conf["remoteaddr"] = "\(serverHost):\(serverPort)" as AnyObject + return conf + } + func isValid() -> Bool { func validateIpAddress(_ ipToValidate: String) -> Bool { - + var sin = sockaddr_in() var sin6 = sockaddr_in6() - + if ipToValidate.withCString({ cstring in inet_pton(AF_INET6, cstring, &sin6.sin6_addr) }) == 1 { // IPv6 peer. return true @@ -95,35 +194,54 @@ class ServerProfile: NSObject { // IPv4 peer. return true } - + return false; } - + func validateDomainName(_ value: String) -> Bool { let validHostnameRegex = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$" - + if (value.range(of: validHostnameRegex, options: .regularExpression) != nil) { return true } else { return false } } - + if !(validateIpAddress(serverHost) || validateDomainName(serverHost)){ return false } - + if password.isEmpty { return false } - + return true } - + func URL() -> Foundation.URL? { - let parts = "\(method):\(password)@\(serverHost):\(serverPort)" - let base64String = parts.data(using: String.Encoding.utf8)? - .base64EncodedString(options: NSData.Base64EncodingOptions()) + var url = URLComponents() + + url.host = serverHost + url.user = method + url.password = password + url.port = Int(serverPort) + + url.queryItems = [URLQueryItem(name: "Remark", value: remark), + URLQueryItem(name: "OTA", value: ota.description)] + if enabledKcptun { + url.queryItems?.append(contentsOf: [ + URLQueryItem(name: "Kcptun", value: enabledKcptun.description), + ]) + url.queryItems?.append(contentsOf: kcptunProfile.urlQueryItems()) + } + + let parts = url.string?.replacingOccurrences( + of: "//", with: "", + options: String.CompareOptions.anchored, range: nil) + + let base64String = parts?.data(using: String.Encoding.utf8)? + .base64EncodedString(options: Data.Base64EncodingOptions()) if var s = base64String { s = s.trimmingCharacters(in: CharacterSet(charactersIn: "=")) return Foundation.URL(string: "ss://\(s)") diff --git a/ShadowsocksX-NG/ServerProfileManager.swift b/ShadowsocksX-NG/ServerProfileManager.swift index 61b62c7..92df92c 100644 --- a/ShadowsocksX-NG/ServerProfileManager.swift +++ b/ShadowsocksX-NG/ServerProfileManager.swift @@ -2,7 +2,7 @@ // ServerProfileManager.swift // ShadowsocksX-NG // -// Created by 邱宇舟 on 16/6/6. +// Created by 邱宇舟 on 16/6/6. Modified by 秦宇航 16/9/12 // Copyright © 2016年 qiuyuzhou. All rights reserved. // @@ -21,7 +21,7 @@ class ServerProfileManager: NSObject { let defaults = UserDefaults.standard if let _profiles = defaults.array(forKey: "ServerProfiles") { for _profile in _profiles { - let profile = ServerProfile.fromDictionary(_profile as! [String : AnyObject]) + let profile = ServerProfile.fromDictionary(_profile as! [String: Any]) profiles.append(profile) } } @@ -51,7 +51,7 @@ class ServerProfileManager: NSObject { if activeProfileId != nil { defaults.set(activeProfileId, forKey: "ActiveServerProfileId") - writeSSLocalConfFile((getActiveProfile()?.toJsonConfig())!) + _ = writeSSLocalConfFile((getActiveProfile()?.toJsonConfig())!) } else { defaults.removeObject(forKey: "ActiveServerProfileId") removeSSLocalConfFile() @@ -70,4 +70,114 @@ class ServerProfileManager: NSObject { return nil } } + + func importConfigFile() { + let openPanel = NSOpenPanel() + openPanel.title = "Choose Config Json File".localized + openPanel.allowsMultipleSelection = false + openPanel.canChooseDirectories = false + openPanel.canCreateDirectories = false + openPanel.canChooseFiles = true + openPanel.becomeKey() + openPanel.begin { (result) -> Void in + if (result == NSFileHandlingPanelOKButton && (openPanel.url) != nil) { + let fileManager = FileManager.default + let filePath:String = (openPanel.url?.path)! + if (fileManager.fileExists(atPath: filePath) && filePath.hasSuffix("json")) { + let data = fileManager.contents(atPath: filePath) + let readString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)! + let readStringData = readString.data(using: String.Encoding.utf8.rawValue) + + let jsonArr1 = try! JSONSerialization.jsonObject(with: readStringData!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary + + for item in jsonArr1.object(forKey: "configs") as! [[String: AnyObject]]{ + let profile = ServerProfile() + profile.serverHost = item["server"] as! String + profile.serverPort = UInt16((item["server_port"]?.integerValue)!) + profile.method = item["method"] as! String + profile.password = item["password"] as! String + profile.remark = item["remarks"] as! String + self.profiles.append(profile) + self.save() + } + NotificationCenter.default.post(name: NSNotification.Name(rawValue: NOTIFY_SERVER_PROFILES_CHANGED), object: nil) + let configsCount = (jsonArr1.object(forKey: "configs") as! [[String: AnyObject]]).count + let notification = NSUserNotification() + notification.title = "Import Server Profile succeed!".localized + notification.informativeText = "Successful import \(configsCount) items".localized + NSUserNotificationCenter.default + .deliver(notification) + }else{ + let notification = NSUserNotification() + notification.title = "Import Server Profile failed!".localized + notification.informativeText = "Invalid config file!".localized + NSUserNotificationCenter.default + .deliver(notification) + return + } + } + } + } + + func exportConfigFile() { + //读取example文件,删掉configs里面的配置,再用NSDictionary填充到configs里面 + let fileManager = FileManager.default + + let filePath:String = Bundle.main.path(forResource: "example-gui-config", ofType: "json")! + let data = fileManager.contents(atPath: filePath) + let readString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)! + let readStringData = readString.data(using: String.Encoding.utf8.rawValue) + let jsonArr1 = try! JSONSerialization.jsonObject(with: readStringData!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary + + let configsArray:NSMutableArray = [] //not using var? + + for profile in profiles{ + let configProfile:NSMutableDictionary = [:] //not using var? + //standard ss profile + configProfile.setValue(true, forKey: "enable") + configProfile.setValue(profile.serverHost, forKey: "server") + configProfile.setValue(NSNumber(value:profile.serverPort), forKey: "server_port")//not work + configProfile.setValue(profile.password, forKey: "password") + configProfile.setValue(profile.method, forKey: "method") + configProfile.setValue(profile.remark, forKey: "remarks") + configProfile.setValue(profile.remark.data(using: String.Encoding.utf8)?.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0)), forKey: "remarks_base64") + configsArray.add(configProfile) + } + jsonArr1.setValue(configsArray, forKey: "configs") + let jsonData = try! JSONSerialization.data(withJSONObject: jsonArr1, options: JSONSerialization.WritingOptions.prettyPrinted) + let jsonString = NSString(data: jsonData, encoding: String.Encoding.utf8.rawValue)! as String + let savePanel = NSSavePanel() + savePanel.title = "Export Config Json File".localized + savePanel.canCreateDirectories = true + savePanel.allowedFileTypes = ["json"] + savePanel.nameFieldStringValue = "export.json" + savePanel.becomeKey() + savePanel.begin { (result) -> Void in + if (result == NSFileHandlingPanelOKButton && (savePanel.url) != nil) { + //write jsonArr1 back to file + try! jsonString.write(toFile: (savePanel.url?.path)!, atomically: true, encoding: String.Encoding.utf8) + NSWorkspace.shared().selectFile((savePanel.url?.path)!, inFileViewerRootedAtPath: (savePanel.directoryURL?.path)!) + let notification = NSUserNotification() + notification.title = "Export Server Profile succeed!".localized + notification.informativeText = "Successful Export \(self.profiles.count) items".localized + NSUserNotificationCenter.default + .deliver(notification) + } + } + } + + class func showExampleConfigFile() { + //copy file to ~/Downloads folder + let filePath:String = Bundle.main.path(forResource: "example-gui-config", ofType: "json")! + let fileMgr = FileManager.default + let dataPath = NSHomeDirectory() + "/Downloads" + let destPath = dataPath + "/example-gui-config.json" + //检测文件是否已经存在,如果存在直接用sharedWorkspace显示 + if fileMgr.fileExists(atPath: destPath) { + NSWorkspace.shared().selectFile(destPath, inFileViewerRootedAtPath: dataPath) + }else{ + try! fileMgr.copyItem(atPath: filePath, toPath: destPath) + NSWorkspace.shared().selectFile(destPath, inFileViewerRootedAtPath: dataPath) + } + } } diff --git a/ShadowsocksX-NG/Utils.h b/ShadowsocksX-NG/Utils.h index ea24afd..9e9110f 100644 --- a/ShadowsocksX-NG/Utils.h +++ b/ShadowsocksX-NG/Utils.h @@ -11,6 +11,4 @@ void ScanQRCodeOnScreen(); -NSDictionary* ParseSSURL(NSURL* url); - #endif /* QRCodeUtils_h */ diff --git a/ShadowsocksX-NG/Utils.m b/ShadowsocksX-NG/Utils.m index d6f3402..4d34e31 100644 --- a/ShadowsocksX-NG/Utils.m +++ b/ShadowsocksX-NG/Utils.m @@ -71,63 +71,3 @@ void ScanQRCodeOnScreen() { } ]; } - -// 解析SS URL,如果成功则返回一个与ServerProfile类兼容的dict -NSDictionary* ParseSSURL(NSURL* url) { - if (!url.host) { - return nil; - } - - NSString *urlString = [url absoluteString]; - int i = 0; - NSString *errorReason = nil; - while(i < 2) { - if (i == 1) { - NSString* host = url.host; - if ([host length]%4!=0) { - int n = 4 - [host length]%4; - if (1==n) { - host = [host stringByAppendingString:@"="]; - } else if (2==n) { - host = [host stringByAppendingString:@"=="]; - } - } - NSData *data = [[NSData alloc] initWithBase64EncodedString:host options:0]; - NSString *decodedString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - urlString = decodedString; - } - i++; - urlString = [urlString stringByReplacingOccurrencesOfString:@"ss://" withString:@"" options:NSAnchoredSearch range:NSMakeRange(0, urlString.length)]; - NSRange firstColonRange = [urlString rangeOfString:@":"]; - NSRange lastColonRange = [urlString rangeOfString:@":" options:NSBackwardsSearch]; - NSRange lastAtRange = [urlString rangeOfString:@"@" options:NSBackwardsSearch]; - if (firstColonRange.length == 0) { - errorReason = @"colon not found"; - continue; - } - if (firstColonRange.location == lastColonRange.location) { - errorReason = @"only one colon"; - continue; - } - if (lastAtRange.length == 0) { - errorReason = @"at not found"; - continue; - } - if (!((firstColonRange.location < lastAtRange.location) && (lastAtRange.location < lastColonRange.location))) { - errorReason = @"wrong position"; - continue; - } - NSString *method = [urlString substringWithRange:NSMakeRange(0, firstColonRange.location)]; - NSString *password = [urlString substringWithRange:NSMakeRange(firstColonRange.location + 1, lastAtRange.location - firstColonRange.location - 1)]; - NSString *IP = [urlString substringWithRange:NSMakeRange(lastAtRange.location + 1, lastColonRange.location - lastAtRange.location - 1)]; - NSString *port = [urlString substringWithRange:NSMakeRange(lastColonRange.location + 1, urlString.length - lastColonRange.location - 1)]; - - - return @{@"ServerHost": IP, - @"ServerPort": @([port integerValue]), - @"Method": method, - @"Password": password, - }; - } - return nil; -} diff --git a/ShadowsocksX-NG/Utils.swift b/ShadowsocksX-NG/Utils.swift index 74c0f54..280504c 100644 --- a/ShadowsocksX-NG/Utils.swift +++ b/ShadowsocksX-NG/Utils.swift @@ -8,14 +8,12 @@ import Foundation - extension String { var localized: String { return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "") } } - extension Data { func sha1() -> String { let data = self @@ -25,3 +23,12 @@ extension Data { return hexBytes.joined(separator: "") } } + +enum ProxyType { + case pac + case global +} + +struct Globals { + static var proxyType = ProxyType.pac +} diff --git a/ShadowsocksX-NG/example-gui-config.json b/ShadowsocksX-NG/example-gui-config.json new file mode 100644 index 0000000..937e1e3 --- /dev/null +++ b/ShadowsocksX-NG/example-gui-config.json @@ -0,0 +1,44 @@ +{ + "index": 0, + "random": false, + "global": false, + "enabled": true, + "shareOverLan": false, + "isDefault": false, + "localPort": 1080, + "pacUrl": null, + "useOnlinePac": false, + "reconnectTimes": 3, + "randomAlgorithm": 0, + "TTL": 0, + "proxyEnable": false, + "proxyType": 0, + "proxyHost": null, + "proxyPort": 0, + "proxyAuthUser": null, + "proxyAuthPass": null, + "authUser": null, + "authPass": null, + "autoban": false, + "configs": [{ + "remarks": "example", + "server": "abc.xyz", + "server_port": 1234, + "method": "rc4-md5", + "remarks_base64": "ZXhhbXBsZQ==", + "password": "passwd", + "tcp_over_udp": false, + "udp_over_tcp": false, + "enable": true + },{ + "remarks": "example2", + "server": "xyz.xyz", + "server_port": 1234, + "method": "rc4-md5", + "remarks_base64": "ZXhhbXBsZTI=", + "password": "passwd", + "tcp_over_udp": false, + "udp_over_tcp": false, + "enable": true + }] +} \ No newline at end of file diff --git a/ShadowsocksX-NG/install_helper.sh b/ShadowsocksX-NG/install_helper.sh old mode 100644 new mode 100755 diff --git a/ShadowsocksX-NG/install_kcptun.sh b/ShadowsocksX-NG/install_kcptun.sh new file mode 100755 index 0000000..efd72f5 --- /dev/null +++ b/ShadowsocksX-NG/install_kcptun.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +# install_kcptun.sh +# ShadowsocksX-NG +# +# Created by 邱宇舟 on 2017/1/11. +# Copyright © 2017年 qiuyuzhou. All rights reserved. + +cd `dirname "${BASH_SOURCE[0]}"` +mkdir -p "$HOME/Library/Application Support/ShadowsocksX-NG/kcptun_20161222" +cp -f kcptun_client "$HOME/Library/Application Support/ShadowsocksX-NG/kcptun_20161222/" +rm -f "$HOME/Library/Application Support/ShadowsocksX-NG/kcptun_client" +ln -s "$HOME/Library/Application Support/ShadowsocksX-NG/kcptun_20161222/kcptun_client" "$HOME/Library/Application Support/ShadowsocksX-NG/kcptun_client" + +echo "install kcptun done" diff --git a/ShadowsocksX-NG/install_ss_local.sh b/ShadowsocksX-NG/install_ss_local.sh index dc9cbaa..35ba0dd 100755 --- a/ShadowsocksX-NG/install_ss_local.sh +++ b/ShadowsocksX-NG/install_ss_local.sh @@ -8,11 +8,14 @@ cd `dirname "${BASH_SOURCE[0]}"` -mkdir -p "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local-2.4.6" -cp -f ss-local "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local-2.4.6/" +mkdir -p "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local-2.5.6" +cp -f ss-local "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local-2.5.6/" rm -f "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local" -ln -s "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local-2.4.6/ss-local" "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local" +ln -s "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local-2.5.6/ss-local" "$HOME/Library/Application Support/ShadowsocksX-NG/ss-local" cp -f libcrypto.1.0.0.dylib "$HOME/Library/Application Support/ShadowsocksX-NG/" +cp -f libpcre.1.dylib "$HOME/Library/Application Support/ShadowsocksX-NG/" +rm -f "$HOME/Library/Application Support/ShadowsocksX-NG/libpcre.dylib" +ln -s "$HOME/Library/Application Support/ShadowsocksX-NG/libpcre.1.dylib" "$HOME/Library/Application Support/ShadowsocksX-NG/libpcre.dylib" -echo done \ No newline at end of file +echo done diff --git a/ShadowsocksX-NG/kcptun_client b/ShadowsocksX-NG/kcptun_client new file mode 100755 index 0000000..af13c85 Binary files /dev/null and b/ShadowsocksX-NG/kcptun_client differ diff --git a/ShadowsocksX-NG/libpcre.1.dylib b/ShadowsocksX-NG/libpcre.1.dylib new file mode 100644 index 0000000..eaba371 Binary files /dev/null and b/ShadowsocksX-NG/libpcre.1.dylib differ diff --git a/ShadowsocksX-NG/reload_conf_kcptun.sh b/ShadowsocksX-NG/reload_conf_kcptun.sh new file mode 100755 index 0000000..183d135 --- /dev/null +++ b/ShadowsocksX-NG/reload_conf_kcptun.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +# reload_conf_kcptun.sh +# ShadowsocksX-NG +# +# Created by 邱宇舟 on 2017/1/11. +# Copyright © 2017年 qiuyuzhou. All rights reserved. + +launchctl unload "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.kcptun.plist" +launchctl load "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.kcptun.plist" diff --git a/ShadowsocksX-NG/ss-local b/ShadowsocksX-NG/ss-local index c254766..080b436 100755 Binary files a/ShadowsocksX-NG/ss-local and b/ShadowsocksX-NG/ss-local differ diff --git a/ShadowsocksX-NG/start_kcptun.sh b/ShadowsocksX-NG/start_kcptun.sh new file mode 100755 index 0000000..580d40e --- /dev/null +++ b/ShadowsocksX-NG/start_kcptun.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +# start_kcptun.sh +# ShadowsocksX-NG +# +# Created by 邱宇舟 on 2017/1/11. +# Copyright © 2017年 qiuyuzhou. All rights reserved. + +launchctl load "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.kcptun.plist" diff --git a/ShadowsocksX-NG/stop_kcptun.sh b/ShadowsocksX-NG/stop_kcptun.sh new file mode 100755 index 0000000..b192aea --- /dev/null +++ b/ShadowsocksX-NG/stop_kcptun.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +# stop_kcptun.sh +# ShadowsocksX-NG +# +# Created by 邱宇舟 on 2017/1/11. +# Copyright © 2017年 qiuyuzhou. All rights reserved. + +launchctl unload "$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.kcptun.plist" diff --git a/ShadowsocksX-NG/zh-Hans.lproj/Localizable.strings b/ShadowsocksX-NG/zh-Hans.lproj/Localizable.strings index c439ec3..1839eb1 100755 --- a/ShadowsocksX-NG/zh-Hans.lproj/Localizable.strings +++ b/ShadowsocksX-NG/zh-Hans.lproj/Localizable.strings @@ -44,9 +44,9 @@ "Turn Shadowsocks On" = "打开 Shadowsocks"; -"Proxy - Auto By PAC" = "代理 - PAC自动"; +"Proxy - Auto By PAC" = "代理 - PAC自动(⌃⌘P)"; -"Proxy - Global" = "代理 - 全局"; +"Proxy - Global" = "代理 - 全局(⌃⌘P)"; "Proxy - Manual" = "代理 - 手动"; diff --git a/ShadowsocksX-NG/zh-Hans.lproj/MainMenu.strings b/ShadowsocksX-NG/zh-Hans.lproj/MainMenu.strings index 99145f2..655994d 100644 --- a/ShadowsocksX-NG/zh-Hans.lproj/MainMenu.strings +++ b/ShadowsocksX-NG/zh-Hans.lproj/MainMenu.strings @@ -80,3 +80,11 @@ /* Class = "NSMenuItem"; title = "HTTP Proxy Preference ..."; ObjectID = "uEp-Gz-cu0"; */ "uEp-Gz-cu0.title" = "HTTP代理设置..."; +/* Class = "NSMenuItem"; title = "Show Bunch Json Example File..."; ObjectID = "pdy-JE-50Q"; */ +"pdy-JE-50Q.title" = "显示示例服务器配置文件..."; + +/* Class = "NSMenuItem"; title = "Import Bunch Json File..."; ObjectID = "T9g-gy-gvv"; */ +"T9g-gy-gvv.title" = "导入服务器配置文件..."; + +/* Class = "NSMenuItem"; title = "Export All Server To Json..."; ObjectID = "6k0-gn-DQv"; */ +"6k0-gn-DQv.title" = "导出全部服务器配置..."; diff --git a/ShadowsocksX-NG/zh-Hans.lproj/PreferencesWindowController.strings b/ShadowsocksX-NG/zh-Hans.lproj/PreferencesWindowController.strings index afd97be..5e15b09 100644 --- a/ShadowsocksX-NG/zh-Hans.lproj/PreferencesWindowController.strings +++ b/ShadowsocksX-NG/zh-Hans.lproj/PreferencesWindowController.strings @@ -34,3 +34,6 @@ /* Class = "NSButtonCell"; title = "OK"; ObjectID = "zPE-oD-PwK"; */ "zPE-oD-PwK.title" = "确定"; + +/* Class = "NSMenuItem"; title = "Duplicate"; ObjectID = "bl9-lq-u9V"; */ +"bl9-lq-u9V.title" = "复制"; diff --git a/ShadowsocksX-NGTests/ServerProfileTests.swift b/ShadowsocksX-NGTests/ServerProfileTests.swift new file mode 100644 index 0000000..d942895 --- /dev/null +++ b/ShadowsocksX-NGTests/ServerProfileTests.swift @@ -0,0 +1,153 @@ +// +// ServerProfileTests.swift +// ShadowsocksX-NG +// +// Created by Rainux Luo on 07/01/2017. +// Copyright © 2017 qiuyuzhou. All rights reserved. +// + +import XCTest +@testable import ShadowsocksX_NG + +class ServerProfileTests: XCTestCase { + + var profile: ServerProfile! + + override func setUp() { + super.setUp() + + profile = ServerProfile.fromDictionary(["ServerHost": "example.com", + "ServerPort": 8388, + "Method": "aes-256-cfb", + "Password": "password", + "Remark": "Protoss Prism", + "OTA": true]) + XCTAssertNotNil(profile) + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testInitWithSelfGeneratedURL() { + let newProfile = ServerProfile.init(url: profile.URL()) + + XCTAssertEqual(newProfile?.serverHost, profile.serverHost) + XCTAssertEqual(newProfile?.serverPort, profile.serverPort) + XCTAssertEqual(newProfile?.method, profile.method) + XCTAssertEqual(newProfile?.password, profile.password) + XCTAssertEqual(newProfile?.remark, profile.remark) + XCTAssertEqual(newProfile?.ota, profile.ota) + } + + func testInitWithPlainURL() { + let url = URL(string: "ss://aes-256-cfb:password@example.com:8388") + + let profile = ServerProfile(url: url) + + XCTAssertNotNil(profile) + + XCTAssertEqual(profile?.serverHost, "example.com") + XCTAssertEqual(profile?.serverPort, 8388) + XCTAssertEqual(profile?.method, "aes-256-cfb") + XCTAssertEqual(profile?.password, "password") + XCTAssertEqual(profile?.remark, "") + XCTAssertEqual(profile?.ota, false) + } + + func testInitWithPlainURLandQuery() { + let url = URL(string: "ss://aes-256-cfb:password@example.com:8388?Remark=Prism&OTA=true") + + let profile = ServerProfile(url: url) + + XCTAssertNotNil(profile) + + XCTAssertEqual(profile?.serverHost, "example.com") + XCTAssertEqual(profile?.serverPort, 8388) + XCTAssertEqual(profile?.method, "aes-256-cfb") + XCTAssertEqual(profile?.password, "password") + XCTAssertEqual(profile?.remark, "Prism") + XCTAssertEqual(profile?.ota, true) + } + + func testInitWithPlainURLandAnotherQuery() { + let url = URL(string: "ss://aes-256-cfb:password@example.com:8388?Remark=Prism&OTA=0") + + let profile = ServerProfile(url: url) + + XCTAssertNotNil(profile) + + XCTAssertEqual(profile?.serverHost, "example.com") + XCTAssertEqual(profile?.serverPort, 8388) + XCTAssertEqual(profile?.method, "aes-256-cfb") + XCTAssertEqual(profile?.password, "password") + XCTAssertEqual(profile?.remark, "Prism") + XCTAssertEqual(profile?.ota, false) + } + + func testInitWithBase64EncodedURL() { + // "ss://aes-256-cfb:password@example.com:8388" + let url = URL(string: "ss://YWVzLTI1Ni1jZmI6cGFzc3dvcmRAZXhhbXBsZS5jb206ODM4OA") + + let profile = ServerProfile(url: url) + + XCTAssertNotNil(profile) + + XCTAssertEqual(profile?.serverHost, "example.com") + XCTAssertEqual(profile?.serverPort, 8388) + XCTAssertEqual(profile?.method, "aes-256-cfb") + XCTAssertEqual(profile?.password, "password") + XCTAssertEqual(profile?.remark, "") + XCTAssertEqual(profile?.ota, false) + } + + func testInitWithBase64EncodedURLandQuery() { + // "ss://aes-256-cfb:password@example.com:8388?Remark=Prism&OTA=true" + let url = URL(string: "ss://YWVzLTI1Ni1jZmI6cGFzc3dvcmRAZXhhbXBsZS5jb206ODM4OD9SZW1hcms9UHJpc20mT1RBPXRydWU") + + let profile = ServerProfile(url: url) + + XCTAssertNotNil(profile) + + XCTAssertEqual(profile?.serverHost, "example.com") + XCTAssertEqual(profile?.serverPort, 8388) + XCTAssertEqual(profile?.method, "aes-256-cfb") + XCTAssertEqual(profile?.password, "password") + XCTAssertEqual(profile?.remark, "Prism") + XCTAssertEqual(profile?.ota, true) + } + + func testInitWithEmptyURL() { + let url = URL(string: "ss://") + + let profile = ServerProfile(url: url) + + XCTAssertNil(profile) + } + + func testInitWithInvalidURL() { + let url = URL(string: "ss://invalid url") + + let profile = ServerProfile(url: url) + + XCTAssertNil(profile) + } + + func testInitWithBase64EncodedInvalidURL() { + // "ss://invalid url" + let url = URL(string: "ss://aW52YWxpZCB1cmw") + + let profile = ServerProfile(url: url) + + XCTAssertNil(profile) + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/ShadowsocksX-NGTests/ShadowsocksX_NGTests.swift b/ShadowsocksX-NGTests/ShadowsocksX_NGTests.swift index 4bab66f..58c8fa6 100644 --- a/ShadowsocksX-NGTests/ShadowsocksX_NGTests.swift +++ b/ShadowsocksX-NGTests/ShadowsocksX_NGTests.swift @@ -32,5 +32,5 @@ class ShadowsocksX_NGTests: XCTestCase { // Put the code you want to measure the time of here. } } - + }