├── .gitignore ├── SGNetworkTest.xcodeproj ├── project.pbxproj └── xcshareddata │ └── xcschemes │ └── SGNetworkTest.xcscheme └── SGNetworkTest ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets ├── AccentColor.colorset │ └── Contents.json ├── AppIcon.appiconset │ ├── Artboard@1x.png │ └── Contents.json └── Contents.json ├── Base.lproj └── LaunchScreen.storyboard ├── Info.plist ├── MainTableViewController.h ├── MainTableViewController.m ├── PrefixHeader.pch ├── ResizeCell.h ├── ResizeCell.m ├── ResizeCell.xib ├── SFMono-Medium.otf ├── SFMono-Regular.otf ├── SFMono-Semibold.otf ├── SGNetworkTest.entitlements ├── TestObject.h ├── TestObject.m ├── TestRunningViewController.h ├── TestRunningViewController.m ├── TestRunningViewController.xib └── main.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | *.xcworkspace 13 | !default.xcworkspace 14 | xcuserdata 15 | profile 16 | *.moved-aside 17 | DerivedData 18 | .idea/ -------------------------------------------------------------------------------- /SGNetworkTest.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 55; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 46112BFB2785728400D0EFD7 /* TestObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 46112BFA2785728400D0EFD7 /* TestObject.m */; }; 11 | 46112C032785792300D0EFD7 /* SFMono-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 46112C002785792300D0EFD7 /* SFMono-Medium.otf */; }; 12 | 46112C042785792300D0EFD7 /* SFMono-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 46112C012785792300D0EFD7 /* SFMono-Regular.otf */; }; 13 | 46112C052785792300D0EFD7 /* SFMono-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 46112C022785792300D0EFD7 /* SFMono-Semibold.otf */; }; 14 | 46427BA6274DD891000653B1 /* TestRunningViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 46427BA4274DD891000653B1 /* TestRunningViewController.m */; }; 15 | 46427BA7274DD891000653B1 /* TestRunningViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 46427BA5274DD891000653B1 /* TestRunningViewController.xib */; }; 16 | 46C53500273BE6C400415729 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 46C534FF273BE6C400415729 /* AppDelegate.m */; }; 17 | 46C5350B273BE6C600415729 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 46C5350A273BE6C600415729 /* Assets.xcassets */; }; 18 | 46C5350E273BE6C600415729 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 46C5350C273BE6C600415729 /* LaunchScreen.storyboard */; }; 19 | 46C53511273BE6C600415729 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 46C53510273BE6C600415729 /* main.m */; }; 20 | 46C535F1273BE92100415729 /* MainTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 46C535F0273BE92100415729 /* MainTableViewController.m */; }; 21 | 46C535FB273BFCB800415729 /* ResizeCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 46C535F9273BFCB800415729 /* ResizeCell.m */; }; 22 | 46C535FC273BFCB800415729 /* ResizeCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 46C535FA273BFCB800415729 /* ResizeCell.xib */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 46112BF92785728400D0EFD7 /* TestObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestObject.h; sourceTree = ""; }; 27 | 46112BFA2785728400D0EFD7 /* TestObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestObject.m; sourceTree = ""; }; 28 | 46112C002785792300D0EFD7 /* SFMono-Medium.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SFMono-Medium.otf"; sourceTree = ""; }; 29 | 46112C012785792300D0EFD7 /* SFMono-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SFMono-Regular.otf"; sourceTree = ""; }; 30 | 46112C022785792300D0EFD7 /* SFMono-Semibold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SFMono-Semibold.otf"; sourceTree = ""; }; 31 | 46427BA3274DD891000653B1 /* TestRunningViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestRunningViewController.h; sourceTree = ""; }; 32 | 46427BA4274DD891000653B1 /* TestRunningViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestRunningViewController.m; sourceTree = ""; }; 33 | 46427BA5274DD891000653B1 /* TestRunningViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TestRunningViewController.xib; sourceTree = ""; }; 34 | 46C534FB273BE6C400415729 /* SGNetworkTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SGNetworkTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; 35 | 46C534FE273BE6C400415729 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 36 | 46C534FF273BE6C400415729 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 37 | 46C5350A273BE6C600415729 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 38 | 46C5350D273BE6C600415729 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 39 | 46C5350F273BE6C600415729 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 40 | 46C53510273BE6C600415729 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 41 | 46C535ED273BE73F00415729 /* PrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrefixHeader.pch; sourceTree = ""; }; 42 | 46C535EF273BE92100415729 /* MainTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MainTableViewController.h; sourceTree = ""; }; 43 | 46C535F0273BE92100415729 /* MainTableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MainTableViewController.m; sourceTree = ""; }; 44 | 46C535F8273BFCB800415729 /* ResizeCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResizeCell.h; sourceTree = ""; }; 45 | 46C535F9273BFCB800415729 /* ResizeCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ResizeCell.m; sourceTree = ""; }; 46 | 46C535FA273BFCB800415729 /* ResizeCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ResizeCell.xib; sourceTree = ""; }; 47 | 46D9F29627857136007F2BF5 /* SGNetworkTest.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SGNetworkTest.entitlements; sourceTree = ""; }; 48 | /* End PBXFileReference section */ 49 | 50 | /* Begin PBXFrameworksBuildPhase section */ 51 | 46C534F8273BE6C400415729 /* Frameworks */ = { 52 | isa = PBXFrameworksBuildPhase; 53 | buildActionMask = 2147483647; 54 | files = ( 55 | ); 56 | runOnlyForDeploymentPostprocessing = 0; 57 | }; 58 | /* End PBXFrameworksBuildPhase section */ 59 | 60 | /* Begin PBXGroup section */ 61 | 46C534F2273BE6C400415729 = { 62 | isa = PBXGroup; 63 | children = ( 64 | 46C534FD273BE6C400415729 /* SGNetworkTest */, 65 | 46C534FC273BE6C400415729 /* Products */, 66 | ); 67 | sourceTree = ""; 68 | }; 69 | 46C534FC273BE6C400415729 /* Products */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | 46C534FB273BE6C400415729 /* SGNetworkTest.app */, 73 | ); 74 | name = Products; 75 | sourceTree = ""; 76 | }; 77 | 46C534FD273BE6C400415729 /* SGNetworkTest */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | 46112C002785792300D0EFD7 /* SFMono-Medium.otf */, 81 | 46112C012785792300D0EFD7 /* SFMono-Regular.otf */, 82 | 46112C022785792300D0EFD7 /* SFMono-Semibold.otf */, 83 | 46D9F29627857136007F2BF5 /* SGNetworkTest.entitlements */, 84 | 46C535F8273BFCB800415729 /* ResizeCell.h */, 85 | 46C535F9273BFCB800415729 /* ResizeCell.m */, 86 | 46C535FA273BFCB800415729 /* ResizeCell.xib */, 87 | 46C535ED273BE73F00415729 /* PrefixHeader.pch */, 88 | 46C534FE273BE6C400415729 /* AppDelegate.h */, 89 | 46C534FF273BE6C400415729 /* AppDelegate.m */, 90 | 46C5350A273BE6C600415729 /* Assets.xcassets */, 91 | 46C5350C273BE6C600415729 /* LaunchScreen.storyboard */, 92 | 46C5350F273BE6C600415729 /* Info.plist */, 93 | 46C53510273BE6C600415729 /* main.m */, 94 | 46C535EF273BE92100415729 /* MainTableViewController.h */, 95 | 46C535F0273BE92100415729 /* MainTableViewController.m */, 96 | 46427BA3274DD891000653B1 /* TestRunningViewController.h */, 97 | 46427BA4274DD891000653B1 /* TestRunningViewController.m */, 98 | 46427BA5274DD891000653B1 /* TestRunningViewController.xib */, 99 | 46112BF92785728400D0EFD7 /* TestObject.h */, 100 | 46112BFA2785728400D0EFD7 /* TestObject.m */, 101 | ); 102 | path = SGNetworkTest; 103 | sourceTree = ""; 104 | }; 105 | /* End PBXGroup section */ 106 | 107 | /* Begin PBXNativeTarget section */ 108 | 46C534FA273BE6C400415729 /* SGNetworkTest */ = { 109 | isa = PBXNativeTarget; 110 | buildConfigurationList = 46C53514273BE6C600415729 /* Build configuration list for PBXNativeTarget "SGNetworkTest" */; 111 | buildPhases = ( 112 | 46C534F7273BE6C400415729 /* Sources */, 113 | 46C534F8273BE6C400415729 /* Frameworks */, 114 | 46C534F9273BE6C400415729 /* Resources */, 115 | ); 116 | buildRules = ( 117 | ); 118 | dependencies = ( 119 | ); 120 | name = SGNetworkTest; 121 | productName = SGAdmin; 122 | productReference = 46C534FB273BE6C400415729 /* SGNetworkTest.app */; 123 | productType = "com.apple.product-type.application"; 124 | }; 125 | /* End PBXNativeTarget section */ 126 | 127 | /* Begin PBXProject section */ 128 | 46C534F3273BE6C400415729 /* Project object */ = { 129 | isa = PBXProject; 130 | attributes = { 131 | BuildIndependentTargetsInParallel = 1; 132 | LastUpgradeCheck = 1310; 133 | TargetAttributes = { 134 | 46C534FA273BE6C400415729 = { 135 | CreatedOnToolsVersion = 13.1; 136 | }; 137 | }; 138 | }; 139 | buildConfigurationList = 46C534F6273BE6C400415729 /* Build configuration list for PBXProject "SGNetworkTest" */; 140 | compatibilityVersion = "Xcode 13.0"; 141 | developmentRegion = en; 142 | hasScannedForEncodings = 0; 143 | knownRegions = ( 144 | en, 145 | Base, 146 | ); 147 | mainGroup = 46C534F2273BE6C400415729; 148 | productRefGroup = 46C534FC273BE6C400415729 /* Products */; 149 | projectDirPath = ""; 150 | projectRoot = ""; 151 | targets = ( 152 | 46C534FA273BE6C400415729 /* SGNetworkTest */, 153 | ); 154 | }; 155 | /* End PBXProject section */ 156 | 157 | /* Begin PBXResourcesBuildPhase section */ 158 | 46C534F9273BE6C400415729 /* Resources */ = { 159 | isa = PBXResourcesBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | 46112C042785792300D0EFD7 /* SFMono-Regular.otf in Resources */, 163 | 46C5350E273BE6C600415729 /* LaunchScreen.storyboard in Resources */, 164 | 46C535FC273BFCB800415729 /* ResizeCell.xib in Resources */, 165 | 46C5350B273BE6C600415729 /* Assets.xcassets in Resources */, 166 | 46112C032785792300D0EFD7 /* SFMono-Medium.otf in Resources */, 167 | 46112C052785792300D0EFD7 /* SFMono-Semibold.otf in Resources */, 168 | 46427BA7274DD891000653B1 /* TestRunningViewController.xib in Resources */, 169 | ); 170 | runOnlyForDeploymentPostprocessing = 0; 171 | }; 172 | /* End PBXResourcesBuildPhase section */ 173 | 174 | /* Begin PBXSourcesBuildPhase section */ 175 | 46C534F7273BE6C400415729 /* Sources */ = { 176 | isa = PBXSourcesBuildPhase; 177 | buildActionMask = 2147483647; 178 | files = ( 179 | 46C535F1273BE92100415729 /* MainTableViewController.m in Sources */, 180 | 46C535FB273BFCB800415729 /* ResizeCell.m in Sources */, 181 | 46112BFB2785728400D0EFD7 /* TestObject.m in Sources */, 182 | 46C53500273BE6C400415729 /* AppDelegate.m in Sources */, 183 | 46C53511273BE6C600415729 /* main.m in Sources */, 184 | 46427BA6274DD891000653B1 /* TestRunningViewController.m in Sources */, 185 | ); 186 | runOnlyForDeploymentPostprocessing = 0; 187 | }; 188 | /* End PBXSourcesBuildPhase section */ 189 | 190 | /* Begin PBXVariantGroup section */ 191 | 46C5350C273BE6C600415729 /* LaunchScreen.storyboard */ = { 192 | isa = PBXVariantGroup; 193 | children = ( 194 | 46C5350D273BE6C600415729 /* Base */, 195 | ); 196 | name = LaunchScreen.storyboard; 197 | sourceTree = ""; 198 | }; 199 | /* End PBXVariantGroup section */ 200 | 201 | /* Begin XCBuildConfiguration section */ 202 | 46C53512273BE6C600415729 /* Debug */ = { 203 | isa = XCBuildConfiguration; 204 | buildSettings = { 205 | ALWAYS_SEARCH_USER_PATHS = NO; 206 | CLANG_ANALYZER_NONNULL = YES; 207 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 208 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 209 | CLANG_CXX_LIBRARY = "libc++"; 210 | CLANG_ENABLE_MODULES = YES; 211 | CLANG_ENABLE_OBJC_ARC = YES; 212 | CLANG_ENABLE_OBJC_WEAK = YES; 213 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 214 | CLANG_WARN_BOOL_CONVERSION = YES; 215 | CLANG_WARN_COMMA = YES; 216 | CLANG_WARN_CONSTANT_CONVERSION = YES; 217 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 218 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 219 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 220 | CLANG_WARN_EMPTY_BODY = YES; 221 | CLANG_WARN_ENUM_CONVERSION = YES; 222 | CLANG_WARN_INFINITE_RECURSION = YES; 223 | CLANG_WARN_INT_CONVERSION = YES; 224 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 225 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 226 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 227 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 228 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 229 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 230 | CLANG_WARN_STRICT_PROTOTYPES = YES; 231 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 232 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 233 | CLANG_WARN_UNREACHABLE_CODE = YES; 234 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 235 | COPY_PHASE_STRIP = NO; 236 | DEBUG_INFORMATION_FORMAT = dwarf; 237 | ENABLE_STRICT_OBJC_MSGSEND = YES; 238 | ENABLE_TESTABILITY = YES; 239 | GCC_C_LANGUAGE_STANDARD = gnu11; 240 | GCC_DYNAMIC_NO_PIC = NO; 241 | GCC_NO_COMMON_BLOCKS = YES; 242 | GCC_OPTIMIZATION_LEVEL = 0; 243 | GCC_PREPROCESSOR_DEFINITIONS = ( 244 | "DEBUG=1", 245 | "$(inherited)", 246 | ); 247 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 248 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 249 | GCC_WARN_UNDECLARED_SELECTOR = YES; 250 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 251 | GCC_WARN_UNUSED_FUNCTION = YES; 252 | GCC_WARN_UNUSED_VARIABLE = YES; 253 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 254 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 255 | MTL_FAST_MATH = YES; 256 | ONLY_ACTIVE_ARCH = YES; 257 | SDKROOT = iphoneos; 258 | }; 259 | name = Debug; 260 | }; 261 | 46C53513273BE6C600415729 /* Release */ = { 262 | isa = XCBuildConfiguration; 263 | buildSettings = { 264 | ALWAYS_SEARCH_USER_PATHS = NO; 265 | CLANG_ANALYZER_NONNULL = YES; 266 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 267 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 268 | CLANG_CXX_LIBRARY = "libc++"; 269 | CLANG_ENABLE_MODULES = YES; 270 | CLANG_ENABLE_OBJC_ARC = YES; 271 | CLANG_ENABLE_OBJC_WEAK = YES; 272 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 273 | CLANG_WARN_BOOL_CONVERSION = YES; 274 | CLANG_WARN_COMMA = YES; 275 | CLANG_WARN_CONSTANT_CONVERSION = YES; 276 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 277 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 278 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 279 | CLANG_WARN_EMPTY_BODY = YES; 280 | CLANG_WARN_ENUM_CONVERSION = YES; 281 | CLANG_WARN_INFINITE_RECURSION = YES; 282 | CLANG_WARN_INT_CONVERSION = YES; 283 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 284 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 285 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 286 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 287 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 288 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 289 | CLANG_WARN_STRICT_PROTOTYPES = YES; 290 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 291 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 292 | CLANG_WARN_UNREACHABLE_CODE = YES; 293 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 294 | COPY_PHASE_STRIP = NO; 295 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 296 | ENABLE_NS_ASSERTIONS = NO; 297 | ENABLE_STRICT_OBJC_MSGSEND = YES; 298 | GCC_C_LANGUAGE_STANDARD = gnu11; 299 | GCC_NO_COMMON_BLOCKS = YES; 300 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 301 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 302 | GCC_WARN_UNDECLARED_SELECTOR = YES; 303 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 304 | GCC_WARN_UNUSED_FUNCTION = YES; 305 | GCC_WARN_UNUSED_VARIABLE = YES; 306 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 307 | MTL_ENABLE_DEBUG_INFO = NO; 308 | MTL_FAST_MATH = YES; 309 | SDKROOT = iphoneos; 310 | VALIDATE_PRODUCT = YES; 311 | }; 312 | name = Release; 313 | }; 314 | 46C53515273BE6C600415729 /* Debug */ = { 315 | isa = XCBuildConfiguration; 316 | buildSettings = { 317 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 318 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 319 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = NO; 320 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO; 321 | CODE_SIGN_ENTITLEMENTS = SGNetworkTest/SGNetworkTest.entitlements; 322 | CODE_SIGN_IDENTITY = "Apple Development"; 323 | CODE_SIGN_STYLE = Automatic; 324 | CURRENT_PROJECT_VERSION = 7; 325 | DEVELOPMENT_TEAM = YCKFLA6N72; 326 | "ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = YES; 327 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 328 | GCC_PREFIX_HEADER = SGNetworkTest/PrefixHeader.pch; 329 | GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; 330 | GENERATE_INFOPLIST_FILE = YES; 331 | INFOPLIST_FILE = SGNetworkTest/Info.plist; 332 | INFOPLIST_KEY_CFBundleDisplayName = SGNetworkTest; 333 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 334 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; 335 | INFOPLIST_KEY_UIRequiredDeviceCapabilities = armv7; 336 | INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; 337 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 338 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 339 | LD_RUNPATH_SEARCH_PATHS = ( 340 | "$(inherited)", 341 | "@executable_path/Frameworks", 342 | ); 343 | MARKETING_VERSION = 1.0; 344 | PRODUCT_BUNDLE_IDENTIFIER = com.nssurge.SGNetworkTest; 345 | PRODUCT_NAME = "$(TARGET_NAME)"; 346 | PROVISIONING_PROFILE_SPECIFIER = ""; 347 | SUPPORTS_MACCATALYST = YES; 348 | SWIFT_EMIT_LOC_STRINGS = YES; 349 | TARGETED_DEVICE_FAMILY = "1,2"; 350 | }; 351 | name = Debug; 352 | }; 353 | 46C53516273BE6C600415729 /* Release */ = { 354 | isa = XCBuildConfiguration; 355 | buildSettings = { 356 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 357 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 358 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = NO; 359 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO; 360 | CODE_SIGN_ENTITLEMENTS = SGNetworkTest/SGNetworkTest.entitlements; 361 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; 362 | "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Mac Developer"; 363 | CODE_SIGN_STYLE = Manual; 364 | CURRENT_PROJECT_VERSION = 7; 365 | DEVELOPMENT_TEAM = ""; 366 | "DEVELOPMENT_TEAM[sdk=iphoneos*]" = YCKFLA6N72; 367 | "DEVELOPMENT_TEAM[sdk=macosx*]" = YCKFLA6N72; 368 | "ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = YES; 369 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 370 | GCC_PREFIX_HEADER = SGNetworkTest/PrefixHeader.pch; 371 | GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; 372 | GENERATE_INFOPLIST_FILE = YES; 373 | INFOPLIST_FILE = SGNetworkTest/Info.plist; 374 | INFOPLIST_KEY_CFBundleDisplayName = SGNetworkTest; 375 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 376 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; 377 | INFOPLIST_KEY_UIRequiredDeviceCapabilities = armv7; 378 | INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; 379 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 380 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 381 | LD_RUNPATH_SEARCH_PATHS = ( 382 | "$(inherited)", 383 | "@executable_path/Frameworks", 384 | ); 385 | MARKETING_VERSION = 1.0; 386 | PRODUCT_BUNDLE_IDENTIFIER = com.nssurge.SGNetworkTest; 387 | PRODUCT_NAME = "$(TARGET_NAME)"; 388 | PROVISIONING_PROFILE_SPECIFIER = ""; 389 | "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "SGNetworkTest App Store"; 390 | "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; 391 | SUPPORTS_MACCATALYST = YES; 392 | SWIFT_EMIT_LOC_STRINGS = YES; 393 | TARGETED_DEVICE_FAMILY = "1,2"; 394 | }; 395 | name = Release; 396 | }; 397 | /* End XCBuildConfiguration section */ 398 | 399 | /* Begin XCConfigurationList section */ 400 | 46C534F6273BE6C400415729 /* Build configuration list for PBXProject "SGNetworkTest" */ = { 401 | isa = XCConfigurationList; 402 | buildConfigurations = ( 403 | 46C53512273BE6C600415729 /* Debug */, 404 | 46C53513273BE6C600415729 /* Release */, 405 | ); 406 | defaultConfigurationIsVisible = 0; 407 | defaultConfigurationName = Release; 408 | }; 409 | 46C53514273BE6C600415729 /* Build configuration list for PBXNativeTarget "SGNetworkTest" */ = { 410 | isa = XCConfigurationList; 411 | buildConfigurations = ( 412 | 46C53515273BE6C600415729 /* Debug */, 413 | 46C53516273BE6C600415729 /* Release */, 414 | ); 415 | defaultConfigurationIsVisible = 0; 416 | defaultConfigurationName = Release; 417 | }; 418 | /* End XCConfigurationList section */ 419 | }; 420 | rootObject = 46C534F3273BE6C400415729 /* Project object */; 421 | } 422 | -------------------------------------------------------------------------------- /SGNetworkTest.xcodeproj/xcshareddata/xcschemes/SGNetworkTest.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /SGNetworkTest/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // KDIOSAppTemplate 4 | // 5 | // Created by Blankwonder on 2021/11/10. 6 | // 7 | 8 | #import 9 | 10 | @interface AppDelegate : UIResponder 11 | 12 | @property (nonatomic) UIWindow *window; 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /SGNetworkTest/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // KDIOSAppTemplate 4 | // 5 | // Created by Blankwonder on 2021/11/10. 6 | // 7 | 8 | #import "AppDelegate.h" 9 | #import "MainTableViewController.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | #if TARGET_OS_MACCATALYST 20 | for (UIScene *scene in UIApplication.sharedApplication.connectedScenes) { 21 | if ([scene isKindOfClass:UIWindowScene.class]) { 22 | UIWindowScene *windowSecen = (id)scene; 23 | windowSecen.titlebar.titleVisibility = UITitlebarTitleVisibilityHidden; 24 | } 25 | } 26 | #endif 27 | 28 | [[NSURLSession.sharedSession dataTaskWithURL:[NSURL URLWithString:@"https://www.apple.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 29 | }] resume]; 30 | 31 | MainTableViewController *vc = [[MainTableViewController alloc] init]; 32 | 33 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 34 | self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:vc]; 35 | [self.window makeKeyAndVisible]; 36 | 37 | return YES; 38 | } 39 | 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /SGNetworkTest/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SGNetworkTest/Assets.xcassets/AppIcon.appiconset/Artboard@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blankwonder/SGNetworkTest/810454804f7a6277440a385cec4bee2a1e91cb83/SGNetworkTest/Assets.xcassets/AppIcon.appiconset/Artboard@1x.png -------------------------------------------------------------------------------- /SGNetworkTest/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Artboard@1x.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SGNetworkTest/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SGNetworkTest/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /SGNetworkTest/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CADisableMinimumFrameDurationOnPhone 6 | 7 | CFBundleIcons 8 | 9 | CFBundlePrimaryIcon 10 | 11 | CFBundleIconFiles 12 | 13 | AppIcon 14 | 15 | 16 | 17 | CFBundleIcons~ipad 18 | 19 | CFBundlePrimaryIcon 20 | 21 | CFBundleIconFiles 22 | 23 | AppIcon 24 | 25 | 26 | 27 | CFBundleSignature 28 | ???? 29 | ITSAppUsesNonExemptEncryption 30 | 31 | NSAppTransportSecurity 32 | 33 | NSAllowsArbitraryLoads 34 | 35 | 36 | UIAppFonts 37 | 38 | SFMono-Medium.otf 39 | SFMono-Semibold.otf 40 | SFMono-Regular.otf 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /SGNetworkTest/MainTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MainTableViewController.h 3 | // Surge-Admin 4 | // 5 | // Created by Blankwonder on 2021/11/10. 6 | // 7 | 8 | #import 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface KDActionCell : UITableViewCell 13 | 14 | @property (nonatomic, copy) void (^action)(KDActionCell *cell, NSIndexPath *indexPath); 15 | @property (nonatomic, copy) void (^deleteAction)(KDActionCell *cell, NSIndexPath *indexPath); 16 | @property (nonatomic, copy) UIContextMenuActionProvider menuActionProvider; 17 | 18 | @end 19 | 20 | @interface MainTableViewController : UIViewController 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /SGNetworkTest/MainTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MainTableViewController.m 3 | // Surge-Admin 4 | // 5 | // Created by Blankwonder on 2021/11/10. 6 | // 7 | 8 | #import "MainTableViewController.h" 9 | #import "TestRunningViewController.h" 10 | #import "TestObject.h" 11 | 12 | @interface MainTableViewController () 13 | 14 | @end 15 | 16 | @implementation MainTableViewController { 17 | NSArray *_cells; 18 | UITableView *_tableView; 19 | } 20 | 21 | 22 | - (void)loadView { 23 | UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 375, 1000) style:UITableViewStyleInsetGrouped]; 24 | tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAutomatic; 25 | tableView.delegate = self; 26 | tableView.dataSource = self; 27 | _tableView = tableView; 28 | self.view = tableView; 29 | } 30 | 31 | - (void)viewDidLoad { 32 | [super viewDidLoad]; 33 | 34 | [NSNotificationCenter.defaultCenter addObserver:_tableView selector:@selector(reloadData) name:UIApplicationWillEnterForegroundNotification object:nil]; 35 | 36 | self.title = @"SGNetworkTest"; 37 | 38 | KDActionCell *httpDelayTest = [[KDActionCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil]; 39 | [httpDelayTest setAction:^(KDActionCell *cell, NSIndexPath *indexPath) { 40 | HTTPDelayTestObject *obj = [[HTTPDelayTestObject alloc] init]; 41 | obj.testURLs = @[@"http://www.baidu.com", 42 | @"http://www.qq.com", 43 | @"http://www.sina.com.cn", 44 | @"http://www.taobao.com", 45 | @"http://www.weibo.com"]; 46 | TestRunningViewController *vc = [[TestRunningViewController alloc] initWithTestObj:obj]; 47 | vc.title = cell.textLabel.text; 48 | 49 | [self.navigationController pushViewController:vc animated:YES]; 50 | }]; 51 | httpDelayTest.textLabel.text = @"HTTP Delay Test (China)"; 52 | httpDelayTest.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 53 | 54 | KDActionCell *httpsDelayTest = [[KDActionCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil]; 55 | [httpsDelayTest setAction:^(KDActionCell *cell, NSIndexPath *indexPath) { 56 | HTTPDelayTestObject *obj = [[HTTPDelayTestObject alloc] init]; 57 | obj.testURLs = @[@"https://www.baidu.com", 58 | @"https://www.qq.com", 59 | @"https://www.sina.com.cn", 60 | @"https://www.taobao.com", 61 | @"https://www.weibo.com"]; 62 | TestRunningViewController *vc = [[TestRunningViewController alloc] initWithTestObj:obj]; 63 | vc.title = cell.textLabel.text; 64 | 65 | [self.navigationController pushViewController:vc animated:YES]; 66 | }]; 67 | httpsDelayTest.textLabel.text = @"HTTPS Delay Test (China)"; 68 | httpsDelayTest.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 69 | 70 | 71 | KDActionCell *httpDelayTestGlobal = [[KDActionCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil]; 72 | [httpDelayTestGlobal setAction:^(KDActionCell *cell, NSIndexPath *indexPath) { 73 | HTTPDelayTestObject *obj = [[HTTPDelayTestObject alloc] init]; 74 | obj.testURLs = @[@"http://www.cloudflare.com", 75 | @"http://www.facebook.com", 76 | @"https://www.gstatic.com/generate_204", 77 | @"http://www.live.com", 78 | @"http://www.apple.com"]; 79 | TestRunningViewController *vc = [[TestRunningViewController alloc] initWithTestObj:obj]; 80 | vc.title = cell.textLabel.text; 81 | 82 | [self.navigationController pushViewController:vc animated:YES]; 83 | }]; 84 | httpDelayTestGlobal.textLabel.text = @"HTTP Delay Test (Global)"; 85 | httpDelayTestGlobal.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 86 | 87 | KDActionCell *httpsDelayTestGlobal = [[KDActionCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil]; 88 | [httpsDelayTestGlobal setAction:^(KDActionCell *cell, NSIndexPath *indexPath) { 89 | HTTPDelayTestObject *obj = [[HTTPDelayTestObject alloc] init]; 90 | obj.testURLs = @[@"https://www.cloudflare.com", 91 | @"https://www.facebook.com", 92 | @"https://www.gstatic.com/generate_204", 93 | @"https://www.live.com", 94 | @"https://www.apple.com"]; 95 | TestRunningViewController *vc = [[TestRunningViewController alloc] initWithTestObj:obj]; 96 | vc.title = cell.textLabel.text; 97 | 98 | [self.navigationController pushViewController:vc animated:YES]; 99 | }]; 100 | httpsDelayTestGlobal.textLabel.text = @"HTTPS Delay Test (Global)"; 101 | httpsDelayTestGlobal.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 102 | 103 | 104 | KDActionCell *httpsConnectivityTestGlobal = [[KDActionCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil]; 105 | [httpsConnectivityTestGlobal setAction:^(KDActionCell *cell, NSIndexPath *indexPath) { 106 | HTTPConnectivyTestObject *obj = [[HTTPConnectivyTestObject alloc] init]; 107 | obj.testURLs = @[@"https://www.cloudflare.com"]; 108 | TestRunningViewController *vc = [[TestRunningViewController alloc] initWithTestObj:obj]; 109 | vc.title = cell.textLabel.text; 110 | 111 | [self.navigationController pushViewController:vc animated:YES]; 112 | }]; 113 | httpsConnectivityTestGlobal.textLabel.text = @"Connectivity Test (https://www.cloudflare.com)"; 114 | httpsConnectivityTestGlobal.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 115 | 116 | KDActionCell *baiduConnectivityTestGlobal = [[KDActionCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil]; 117 | [baiduConnectivityTestGlobal setAction:^(KDActionCell *cell, NSIndexPath *indexPath) { 118 | HTTPConnectivyTestObject *obj = [[HTTPConnectivyTestObject alloc] init]; 119 | obj.testURLs = @[@"http://www.baidu.com"]; 120 | TestRunningViewController *vc = [[TestRunningViewController alloc] initWithTestObj:obj]; 121 | vc.title = cell.textLabel.text; 122 | 123 | [self.navigationController pushViewController:vc animated:YES]; 124 | }]; 125 | baiduConnectivityTestGlobal.textLabel.text = @"Connectivity Test (http://www.baidu.com)"; 126 | baiduConnectivityTestGlobal.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 127 | 128 | #if DEBUG 129 | KDActionCell *lanConnectivityTestGlobal = [[KDActionCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil]; 130 | [lanConnectivityTestGlobal setAction:^(KDActionCell *cell, NSIndexPath *indexPath) { 131 | HTTPConnectivyTestObject *obj = [[HTTPConnectivyTestObject alloc] init]; 132 | obj.testURLs = @[@"http://c.bridge.yach.me"]; 133 | TestRunningViewController *vc = [[TestRunningViewController alloc] initWithTestObj:obj]; 134 | vc.title = cell.textLabel.text; 135 | 136 | [self.navigationController pushViewController:vc animated:YES]; 137 | }]; 138 | lanConnectivityTestGlobal.textLabel.text = @"Connectivity Test (http://c.bridge.yach.me)"; 139 | lanConnectivityTestGlobal.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 140 | 141 | _cells = @[@[httpDelayTest, httpsDelayTest, httpDelayTestGlobal, httpsDelayTestGlobal], @[baiduConnectivityTestGlobal, httpsConnectivityTestGlobal, lanConnectivityTestGlobal]]; 142 | 143 | #else 144 | _cells = @[@[httpDelayTest, httpsDelayTest, httpDelayTestGlobal, httpsDelayTestGlobal], @[baiduConnectivityTestGlobal, httpsConnectivityTestGlobal]]; 145 | #endif 146 | 147 | 148 | } 149 | 150 | 151 | - (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath { 152 | KDActionCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 153 | return [cell isKindOfClass:[KDActionCell class]] && cell.action; 154 | } 155 | 156 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 157 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 158 | 159 | KDActionCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 160 | if ([cell isKindOfClass:[KDActionCell class]]) { 161 | if (cell.action) { 162 | cell.action(cell, indexPath); 163 | } 164 | return; 165 | } 166 | } 167 | 168 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 169 | return [_cells[section] count]; 170 | } 171 | 172 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 173 | return _cells.count; 174 | } 175 | 176 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 177 | return _cells[indexPath.section][indexPath.row]; 178 | } 179 | 180 | - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { 181 | if (section != 1) return nil; 182 | CFDictionaryRef dicRef = CFNetworkCopySystemProxySettings(); 183 | const CFStringRef proxyCFstr = (const CFStringRef)CFDictionaryGetValue(dicRef, (const void*)kCFNetworkProxiesHTTPProxy); 184 | 185 | if (proxyCFstr) { 186 | return [NSString stringWithFormat:@"Proxy %@", proxyCFstr]; 187 | } else { 188 | return nil; 189 | } 190 | } 191 | 192 | @end 193 | 194 | 195 | @implementation KDActionCell 196 | 197 | @end 198 | -------------------------------------------------------------------------------- /SGNetworkTest/PrefixHeader.pch: -------------------------------------------------------------------------------- 1 | // 2 | // PrefixHeader.pch 3 | // KDIOSAppTemplate 4 | // 5 | // Created by Blankwonder on 2021/11/10. 6 | // 7 | 8 | #ifndef PrefixHeader_pch 9 | #define PrefixHeader_pch 10 | 11 | #include 12 | 13 | #endif /* PrefixHeader_pch */ 14 | -------------------------------------------------------------------------------- /SGNetworkTest/ResizeCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // ResizeCell.h 3 | // Surge-iOS 4 | // 5 | // Created by Blankwonder on 1/11/16. 6 | // Copyright © 2016 Yach. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ResizeCell : UITableViewCell 12 | 13 | + (ResizeCell *)cell; 14 | 15 | @property (nonatomic) IBOutlet UILabel *label; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /SGNetworkTest/ResizeCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // ResizeCell.m 3 | // Surge-iOS 4 | // 5 | // Created by Blankwonder on 1/11/16. 6 | // Copyright © 2016 Yach. All rights reserved. 7 | // 8 | 9 | #import "ResizeCell.h" 10 | 11 | @implementation ResizeCell 12 | 13 | + (ResizeCell *)cell { 14 | return [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([ResizeCell class]) owner:nil options:nil].firstObject; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /SGNetworkTest/ResizeCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /SGNetworkTest/SFMono-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blankwonder/SGNetworkTest/810454804f7a6277440a385cec4bee2a1e91cb83/SGNetworkTest/SFMono-Medium.otf -------------------------------------------------------------------------------- /SGNetworkTest/SFMono-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blankwonder/SGNetworkTest/810454804f7a6277440a385cec4bee2a1e91cb83/SGNetworkTest/SFMono-Regular.otf -------------------------------------------------------------------------------- /SGNetworkTest/SFMono-Semibold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blankwonder/SGNetworkTest/810454804f7a6277440a385cec4bee2a1e91cb83/SGNetworkTest/SFMono-Semibold.otf -------------------------------------------------------------------------------- /SGNetworkTest/SGNetworkTest.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SGNetworkTest/TestObject.h: -------------------------------------------------------------------------------- 1 | // 2 | // TestObject.h 3 | // SGNetworkTest 4 | // 5 | // Created by Blankwonder on 1/5/22. 6 | // 7 | 8 | #import 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @class TestObject; 13 | @protocol TestObjectOutput 14 | 15 | - (void)testObject:(TestObject *)obj hasNewOutput:(NSString *)line; 16 | 17 | @end 18 | 19 | @interface TestObject : NSObject 20 | 21 | - (void)start; 22 | 23 | @property (nonatomic, weak) id output; 24 | @property (nonatomic) int totalRound; 25 | @property (nonatomic) NSArray *testURLs; 26 | 27 | @end 28 | 29 | @interface HTTPDelayTestObject : TestObject 30 | @end 31 | 32 | @interface HTTPConnectivyTestObject : TestObject 33 | @end 34 | 35 | 36 | 37 | NS_ASSUME_NONNULL_END 38 | -------------------------------------------------------------------------------- /SGNetworkTest/TestObject.m: -------------------------------------------------------------------------------- 1 | // 2 | // TestObject.m 3 | // SGNetworkTest 4 | // 5 | // Created by Blankwonder on 1/5/22. 6 | // 7 | 8 | #import "TestObject.h" 9 | 10 | @implementation TestObject { 11 | @protected 12 | int _currentRound; 13 | } 14 | 15 | - (void)jobStart { 16 | } 17 | 18 | - (void)jobEnd { 19 | [self.output testObject:self hasNewOutput:[NSString stringWithFormat:@"Round #%d completed", _currentRound - 1]]; 20 | [self.output testObject:self hasNewOutput:@"\n"]; 21 | [self performSelector:@selector(start) withObject:nil afterDelay:0.5]; 22 | } 23 | 24 | - (void)allCompleted { 25 | 26 | } 27 | 28 | - (void)start { 29 | if (_currentRound < self.totalRound + 1) { 30 | _currentRound++; 31 | [self jobStart]; 32 | } else { 33 | [self allCompleted]; 34 | } 35 | } 36 | 37 | @end 38 | 39 | @interface HTTPDelayTestObject () 40 | 41 | @end 42 | 43 | @implementation HTTPDelayTestObject { 44 | NSURLSession *_session; 45 | 46 | NSMutableArray *_results, *_roundResults; 47 | } 48 | 49 | - (instancetype)init { 50 | self = [super init]; 51 | 52 | _roundResults = [NSMutableArray array]; 53 | self.totalRound = 10; 54 | 55 | return self; 56 | } 57 | 58 | - (void)jobStart { 59 | _session = [NSURLSession sessionWithConfiguration:NSURLSessionConfiguration.ephemeralSessionConfiguration delegate:self delegateQueue:NSOperationQueue.mainQueue]; 60 | 61 | _results = [NSMutableArray array]; 62 | 63 | if (_currentRound == 1) { 64 | [self.output testObject:self hasNewOutput:@"Warming up round, the result won't count."]; 65 | } 66 | 67 | for (NSString *url in self.testURLs) { 68 | [self.output testObject:self hasNewOutput:[NSString stringWithFormat:@"Start testing: %@", url]]; 69 | 70 | CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 71 | 72 | NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; 73 | req.HTTPMethod = @"HEAD"; 74 | req.timeoutInterval = 5; 75 | 76 | [[_session dataTaskWithRequest:req completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 77 | if (!error && ((NSHTTPURLResponse *)response).statusCode >= 400) { 78 | error = [NSError errorWithDomain:@"SGNetworkTest" code:1 userInfo:@{NSLocalizedDescriptionKey:[NSString stringWithFormat:@"Invalid status code: %d", ((NSHTTPURLResponse *)response).statusCode]}]; 79 | } 80 | 81 | if (error || !response) { 82 | [self.output testObject:self hasNewOutput:[NSString stringWithFormat:@"Test failed: %@ %@", url, error]]; 83 | [_results addObject:@(-1)]; 84 | 85 | return; 86 | } 87 | 88 | double res = (CFAbsoluteTimeGetCurrent() - t) * 1000.0; 89 | [_results addObject:@(res)]; 90 | 91 | [self.output testObject:self hasNewOutput:[NSString stringWithFormat:@"Test completed in %.0fms: %@", res, url]]; 92 | 93 | if (_results.count == self.testURLs.count) { 94 | int sum = 0; 95 | 96 | for (NSNumber *n in _results) { 97 | sum += n.intValue; 98 | if (n.intValue == -1) { 99 | [self jobEnd]; 100 | return; 101 | } 102 | } 103 | 104 | double avg = sum / (double)_results.count; 105 | [_roundResults addObject:@(avg)]; 106 | [_session invalidateAndCancel]; 107 | _session = nil; 108 | 109 | [self.output testObject:self hasNewOutput:[NSString stringWithFormat:@"All test completed, average: %.0fms", avg]]; 110 | [self jobEnd]; 111 | } 112 | }] resume]; 113 | } 114 | } 115 | 116 | - (void)URLSession:(NSURLSession *)session 117 | task:(NSURLSessionTask *)task 118 | willPerformHTTPRedirection:(NSHTTPURLResponse *)response 119 | newRequest:(NSURLRequest *)request 120 | completionHandler:(void (^)(NSURLRequest *))completionHandler { 121 | completionHandler(nil); // Disable 301/302 redirect 122 | } 123 | 124 | - (void)allCompleted { 125 | [_roundResults removeObjectAtIndex:0]; 126 | 127 | NSInteger top = _roundResults.count / 2; 128 | 129 | [_roundResults sortUsingSelector:@selector(compare:)]; 130 | [_roundResults removeObjectsInRange:NSMakeRange(top, _roundResults.count - top)]; 131 | 132 | [self.output testObject:self hasNewOutput:[NSString stringWithFormat:@"All round completed, average of the top %ld rounds: %.0fms", _roundResults.count, [[_roundResults valueForKeyPath:@"@avg.self"] doubleValue]]]; 133 | } 134 | 135 | @end 136 | 137 | 138 | @interface HTTPConnectivyTestObject () 139 | 140 | @end 141 | 142 | 143 | @implementation HTTPConnectivyTestObject { 144 | NSURLSession *_session; 145 | 146 | NSMutableArray *_results, *_roundResults; 147 | } 148 | 149 | - (instancetype)init { 150 | self = [super init]; 151 | 152 | _roundResults = [NSMutableArray array]; 153 | self.totalRound = 0; 154 | 155 | return self; 156 | } 157 | 158 | - (void)jobStart { 159 | _session = [NSURLSession sessionWithConfiguration:NSURLSessionConfiguration.ephemeralSessionConfiguration delegate:self delegateQueue:NSOperationQueue.mainQueue]; 160 | 161 | _results = [NSMutableArray array]; 162 | 163 | for (NSString *url in self.testURLs) { 164 | [self.output testObject:self hasNewOutput:[NSString stringWithFormat:@"Start testing: %@", url]]; 165 | 166 | CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 167 | 168 | NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; 169 | req.HTTPMethod = @"HEAD"; 170 | req.timeoutInterval = 5; 171 | 172 | [[_session dataTaskWithRequest:req completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 173 | 174 | if (error || !response) { 175 | [self.output testObject:self hasNewOutput:[NSString stringWithFormat:@"Test failed: %@ %@", url, error]]; 176 | [_results addObject:@(-1)]; 177 | 178 | return; 179 | } 180 | 181 | double res = (CFAbsoluteTimeGetCurrent() - t) * 1000.0; 182 | [_results addObject:@(res)]; 183 | 184 | [self.output testObject:self hasNewOutput:[NSString stringWithFormat:@"Test completed in %.0fms: %@", res, url]]; 185 | 186 | if (_results.count == self.testURLs.count) { 187 | int sum = 0; 188 | 189 | for (NSNumber *n in _results) { 190 | sum += n.intValue; 191 | if (n.intValue == -1) { 192 | [self jobEnd]; 193 | return; 194 | } 195 | } 196 | 197 | double avg = sum / (double)_results.count; 198 | [_roundResults addObject:@(avg)]; 199 | [_session invalidateAndCancel]; 200 | _session = nil; 201 | 202 | [self.output testObject:self hasNewOutput:[NSString stringWithFormat:@"All test completed, average: %.0fms", avg]]; 203 | [self jobEnd]; 204 | } 205 | }] resume]; 206 | } 207 | } 208 | 209 | - (void)URLSession:(NSURLSession *)session 210 | task:(NSURLSessionTask *)task 211 | willPerformHTTPRedirection:(NSHTTPURLResponse *)response 212 | newRequest:(NSURLRequest *)request 213 | completionHandler:(void (^)(NSURLRequest *))completionHandler { 214 | completionHandler(nil); // Disable 301/302 redirect 215 | } 216 | 217 | - (void)allCompleted { 218 | } 219 | 220 | 221 | @end 222 | -------------------------------------------------------------------------------- /SGNetworkTest/TestRunningViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TextViewController.h 3 | // SGAdmin 4 | // 5 | // Created by Blankwonder on 2021/11/24. 6 | // 7 | 8 | #import 9 | #import "TestObject.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface TestRunningViewController : UIViewController { 14 | IBOutlet UITextView *_textView; 15 | } 16 | 17 | - (instancetype)initWithTestObj:(TestObject *)obj; 18 | 19 | @property (nonatomic, readonly) TestObject *testObject; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /SGNetworkTest/TestRunningViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TextViewController.m 3 | // SGAdmin 4 | // 5 | // Created by Blankwonder on 2021/11/24. 6 | // 7 | 8 | #import "TestRunningViewController.h" 9 | 10 | @interface TestRunningViewController () { 11 | } 12 | 13 | @end 14 | 15 | @implementation TestRunningViewController 16 | 17 | - (instancetype)initWithTestObj:(TestObject *)obj { 18 | self = [super init]; 19 | 20 | _testObject = obj; 21 | obj.output = self; 22 | 23 | return self; 24 | } 25 | 26 | 27 | - (void)viewDidLoad { 28 | [super viewDidLoad]; 29 | 30 | } 31 | 32 | - (void)viewDidAppear:(BOOL)animated { 33 | [super viewDidAppear:animated]; 34 | 35 | [_testObject start]; 36 | } 37 | 38 | - (void)testObject:(TestObject *)obj hasNewOutput:(NSString *)line { 39 | [_textView.textStorage appendAttributedString:[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@\n", line] attributes:@{ 40 | NSForegroundColorAttributeName: UIColor.labelColor, 41 | #if TARGET_OS_MACCATALYST 42 | NSFontAttributeName: [UIFont fontWithName:@"SFMono-Regular" size:22] 43 | #else 44 | NSFontAttributeName: [UIFont fontWithName:@"SFMono-Regular" size:15] 45 | #endif 46 | }]]; 47 | 48 | [self performSelector:@selector(scrollToBottom) withObject:nil afterDelay:0.1]; 49 | } 50 | 51 | - (void)scrollToBottom { 52 | [_textView scrollRectToVisible:CGRectMake(0, _textView.contentSize.height - 1, 320, 1) animated:YES]; 53 | } 54 | 55 | 56 | /* 57 | #pragma mark - Navigation 58 | 59 | // In a storyboard-based application, you will often want to do a little preparation before navigation 60 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 61 | // Get the new view controller using [segue destinationViewController]. 62 | // Pass the selected object to the new view controller. 63 | } 64 | */ 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /SGNetworkTest/TestRunningViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /SGNetworkTest/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // KDIOSAppTemplate 4 | // 5 | // Created by Blankwonder on 2021/11/10. 6 | // 7 | 8 | #import 9 | #import "AppDelegate.h" 10 | 11 | int main(int argc, char * argv[]) { 12 | NSString * appDelegateClassName; 13 | @autoreleasepool { 14 | // Setup code that might create autoreleased objects goes here. 15 | appDelegateClassName = NSStringFromClass([AppDelegate class]); 16 | } 17 | return UIApplicationMain(argc, argv, nil, appDelegateClassName); 18 | } 19 | --------------------------------------------------------------------------------