├── .gitignore ├── LICENSE ├── README.md ├── ZXPUnicode ├── ZXPUnicode.h └── ZXPUnicode.m └── demo ├── demo.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata └── demo └── main.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | #Pods/ 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ZXPUnicode 2 | 在Xcode的控制台里支持array and dictionary 的中文输出,Xcode默认是不支持的.导入分类即可在控制台自动支持中文输出 3 | -------------------------------------------------------------------------------- /ZXPUnicode/ZXPUnicode.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZXPUnicode.h 3 | // 4 | // blog : http://blog.csdn.net/biggercoffee 5 | // github : https://github.com/biggercoffee/ZXPUnicode 6 | // 7 | // Created by Mango on 2017/3/31. 8 | // Copyright © 2017年 coffee. All rights reserved. 9 | // 10 | 11 | #import 12 | 13 | 14 | -------------------------------------------------------------------------------- /ZXPUnicode/ZXPUnicode.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZXPUnicode.m 3 | // 4 | // blog : http://blog.csdn.net/biggercoffee 5 | // github : https://github.com/biggercoffee/ZXPUnicode 6 | // 7 | // Created by Mango on 2017/3/31. 8 | // Copyright © 2017年 coffee. All rights reserved. 9 | // 10 | 11 | #import "ZXPUnicode.h" 12 | #import 13 | 14 | static inline void zxp_swizzleSelector(Class class, SEL originalSelector, SEL swizzledSelector) { 15 | Method originalMethod = class_getInstanceMethod(class, originalSelector); 16 | Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); 17 | if (class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))) { 18 | class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); 19 | } else { 20 | method_exchangeImplementations(originalMethod, swizzledMethod); 21 | } 22 | } 23 | 24 | @implementation NSString (ZXPUnicode) 25 | 26 | - (NSString *)stringByReplaceUnicode { 27 | NSMutableString *convertedString = [self mutableCopy]; 28 | [convertedString replaceOccurrencesOfString:@"\\U" 29 | withString:@"\\u" 30 | options:0 31 | range:NSMakeRange(0, convertedString.length)]; 32 | 33 | CFStringRef transform = CFSTR("Any-Hex/Java"); 34 | CFStringTransform((__bridge CFMutableStringRef)convertedString, NULL, transform, YES); 35 | return convertedString; 36 | } 37 | 38 | @end 39 | 40 | @implementation NSArray (ZXPUnicode) 41 | 42 | + (void)load { 43 | static dispatch_once_t onceToken; 44 | dispatch_once(&onceToken, ^{ 45 | Class class = [self class]; 46 | zxp_swizzleSelector(class, @selector(description), @selector(zxp_description)); 47 | zxp_swizzleSelector(class, @selector(descriptionWithLocale:), @selector(zxp_descriptionWithLocale:)); 48 | zxp_swizzleSelector(class, @selector(descriptionWithLocale:indent:), @selector(zxp_descriptionWithLocale:indent:)); 49 | }); 50 | } 51 | 52 | /** 53 | * 我觉得 54 | * 可以把以下的方法放到一个NSObject的category中 55 | * 然后在需要的类中进行swizzle 56 | * 但是又觉得这样太粗暴了。。。。 57 | */ 58 | 59 | - (NSString *)zxp_description { 60 | return [[self zxp_description] stringByReplaceUnicode]; 61 | } 62 | 63 | - (NSString *)zxp_descriptionWithLocale:(nullable id)locale { 64 | return [[self zxp_descriptionWithLocale:locale] stringByReplaceUnicode]; 65 | } 66 | 67 | - (NSString *)zxp_descriptionWithLocale:(nullable id)locale indent:(NSUInteger)level { 68 | return [[self zxp_descriptionWithLocale:locale indent:level] stringByReplaceUnicode]; 69 | } 70 | 71 | @end 72 | 73 | @implementation NSDictionary (ZXPUnicode) 74 | 75 | + (void)load { 76 | static dispatch_once_t onceToken; 77 | dispatch_once(&onceToken, ^{ 78 | Class class = [self class]; 79 | zxp_swizzleSelector(class, @selector(description), @selector(zxp_description)); 80 | zxp_swizzleSelector(class, @selector(descriptionWithLocale:), @selector(zxp_descriptionWithLocale:)); 81 | zxp_swizzleSelector(class, @selector(descriptionWithLocale:indent:), @selector(zxp_descriptionWithLocale:indent:)); 82 | }); 83 | } 84 | 85 | - (NSString *)zxp_description { 86 | return [[self zxp_description] stringByReplaceUnicode]; 87 | } 88 | 89 | - (NSString *)zxp_descriptionWithLocale:(nullable id)locale { 90 | return [[self zxp_descriptionWithLocale:locale] stringByReplaceUnicode]; 91 | } 92 | 93 | - (NSString *)zxp_descriptionWithLocale:(nullable id)locale indent:(NSUInteger)level { 94 | return [[self zxp_descriptionWithLocale:locale indent:level] stringByReplaceUnicode]; 95 | } 96 | 97 | @end 98 | 99 | @implementation NSSet (ZXPUnicode) 100 | 101 | + (void)load { 102 | static dispatch_once_t onceToken; 103 | dispatch_once(&onceToken, ^{ 104 | Class class = [self class]; 105 | zxp_swizzleSelector(class, @selector(description), @selector(zxp_description)); 106 | zxp_swizzleSelector(class, @selector(descriptionWithLocale:), @selector(zxp_descriptionWithLocale:)); 107 | zxp_swizzleSelector(class, @selector(descriptionWithLocale:indent:), @selector(zxp_descriptionWithLocale:indent:)); 108 | }); 109 | } 110 | 111 | - (NSString *)zxp_description { 112 | return [[self zxp_description] stringByReplaceUnicode]; 113 | } 114 | 115 | - (NSString *)zxp_descriptionWithLocale:(nullable id)locale { 116 | return [[self zxp_descriptionWithLocale:locale] stringByReplaceUnicode]; 117 | } 118 | 119 | - (NSString *)zxp_descriptionWithLocale:(nullable id)locale indent:(NSUInteger)level { 120 | return [[self zxp_descriptionWithLocale:locale indent:level] stringByReplaceUnicode]; 121 | } 122 | 123 | @end 124 | 125 | -------------------------------------------------------------------------------- /demo/demo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1D61351F1C031B0D00CAE85F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D61351E1C031B0D00CAE85F /* main.m */; }; 11 | DBFC175A1E8E5FE900A3DFF1 /* ZXPUnicode.m in Sources */ = {isa = PBXBuildFile; fileRef = DBFC17591E8E5FE900A3DFF1 /* ZXPUnicode.m */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXCopyFilesBuildPhase section */ 15 | 1D6135191C031B0D00CAE85F /* CopyFiles */ = { 16 | isa = PBXCopyFilesBuildPhase; 17 | buildActionMask = 2147483647; 18 | dstPath = /usr/share/man/man1/; 19 | dstSubfolderSpec = 0; 20 | files = ( 21 | ); 22 | runOnlyForDeploymentPostprocessing = 1; 23 | }; 24 | /* End PBXCopyFilesBuildPhase section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | 1D61351B1C031B0D00CAE85F /* demo */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = demo; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | 1D61351E1C031B0D00CAE85F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 29 | DBFC17581E8E5FE900A3DFF1 /* ZXPUnicode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPUnicode.h; sourceTree = ""; }; 30 | DBFC17591E8E5FE900A3DFF1 /* ZXPUnicode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPUnicode.m; sourceTree = ""; }; 31 | /* End PBXFileReference section */ 32 | 33 | /* Begin PBXFrameworksBuildPhase section */ 34 | 1D6135181C031B0D00CAE85F /* Frameworks */ = { 35 | isa = PBXFrameworksBuildPhase; 36 | buildActionMask = 2147483647; 37 | files = ( 38 | ); 39 | runOnlyForDeploymentPostprocessing = 0; 40 | }; 41 | /* End PBXFrameworksBuildPhase section */ 42 | 43 | /* Begin PBXGroup section */ 44 | 1D6135121C031B0D00CAE85F = { 45 | isa = PBXGroup; 46 | children = ( 47 | 1D61351D1C031B0D00CAE85F /* demo */, 48 | 1D61351C1C031B0D00CAE85F /* Products */, 49 | ); 50 | sourceTree = ""; 51 | }; 52 | 1D61351C1C031B0D00CAE85F /* Products */ = { 53 | isa = PBXGroup; 54 | children = ( 55 | 1D61351B1C031B0D00CAE85F /* demo */, 56 | ); 57 | name = Products; 58 | sourceTree = ""; 59 | }; 60 | 1D61351D1C031B0D00CAE85F /* demo */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | 1D61352F1C031BF200CAE85F /* ZXPUnicode */, 64 | 1D61351E1C031B0D00CAE85F /* main.m */, 65 | ); 66 | path = demo; 67 | sourceTree = ""; 68 | }; 69 | 1D61352F1C031BF200CAE85F /* ZXPUnicode */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | DBFC17581E8E5FE900A3DFF1 /* ZXPUnicode.h */, 73 | DBFC17591E8E5FE900A3DFF1 /* ZXPUnicode.m */, 74 | ); 75 | name = ZXPUnicode; 76 | path = ../../ZXPUnicode; 77 | sourceTree = ""; 78 | }; 79 | /* End PBXGroup section */ 80 | 81 | /* Begin PBXNativeTarget section */ 82 | 1D61351A1C031B0D00CAE85F /* demo */ = { 83 | isa = PBXNativeTarget; 84 | buildConfigurationList = 1D6135221C031B0D00CAE85F /* Build configuration list for PBXNativeTarget "demo" */; 85 | buildPhases = ( 86 | 1D6135171C031B0D00CAE85F /* Sources */, 87 | 1D6135181C031B0D00CAE85F /* Frameworks */, 88 | 1D6135191C031B0D00CAE85F /* CopyFiles */, 89 | ); 90 | buildRules = ( 91 | ); 92 | dependencies = ( 93 | ); 94 | name = demo; 95 | productName = demo; 96 | productReference = 1D61351B1C031B0D00CAE85F /* demo */; 97 | productType = "com.apple.product-type.tool"; 98 | }; 99 | /* End PBXNativeTarget section */ 100 | 101 | /* Begin PBXProject section */ 102 | 1D6135131C031B0D00CAE85F /* Project object */ = { 103 | isa = PBXProject; 104 | attributes = { 105 | LastUpgradeCheck = 0710; 106 | ORGANIZATIONNAME = coffee; 107 | TargetAttributes = { 108 | 1D61351A1C031B0D00CAE85F = { 109 | CreatedOnToolsVersion = 7.1.1; 110 | }; 111 | }; 112 | }; 113 | buildConfigurationList = 1D6135161C031B0D00CAE85F /* Build configuration list for PBXProject "demo" */; 114 | compatibilityVersion = "Xcode 3.2"; 115 | developmentRegion = English; 116 | hasScannedForEncodings = 0; 117 | knownRegions = ( 118 | en, 119 | ); 120 | mainGroup = 1D6135121C031B0D00CAE85F; 121 | productRefGroup = 1D61351C1C031B0D00CAE85F /* Products */; 122 | projectDirPath = ""; 123 | projectRoot = ""; 124 | targets = ( 125 | 1D61351A1C031B0D00CAE85F /* demo */, 126 | ); 127 | }; 128 | /* End PBXProject section */ 129 | 130 | /* Begin PBXSourcesBuildPhase section */ 131 | 1D6135171C031B0D00CAE85F /* Sources */ = { 132 | isa = PBXSourcesBuildPhase; 133 | buildActionMask = 2147483647; 134 | files = ( 135 | 1D61351F1C031B0D00CAE85F /* main.m in Sources */, 136 | DBFC175A1E8E5FE900A3DFF1 /* ZXPUnicode.m in Sources */, 137 | ); 138 | runOnlyForDeploymentPostprocessing = 0; 139 | }; 140 | /* End PBXSourcesBuildPhase section */ 141 | 142 | /* Begin XCBuildConfiguration section */ 143 | 1D6135201C031B0D00CAE85F /* Debug */ = { 144 | isa = XCBuildConfiguration; 145 | buildSettings = { 146 | ALWAYS_SEARCH_USER_PATHS = NO; 147 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 148 | CLANG_CXX_LIBRARY = "libc++"; 149 | CLANG_ENABLE_MODULES = YES; 150 | CLANG_ENABLE_OBJC_ARC = YES; 151 | CLANG_WARN_BOOL_CONVERSION = YES; 152 | CLANG_WARN_CONSTANT_CONVERSION = YES; 153 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 154 | CLANG_WARN_EMPTY_BODY = YES; 155 | CLANG_WARN_ENUM_CONVERSION = YES; 156 | CLANG_WARN_INT_CONVERSION = YES; 157 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 158 | CLANG_WARN_UNREACHABLE_CODE = YES; 159 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 160 | CODE_SIGN_IDENTITY = "-"; 161 | COPY_PHASE_STRIP = NO; 162 | DEBUG_INFORMATION_FORMAT = dwarf; 163 | ENABLE_STRICT_OBJC_MSGSEND = YES; 164 | ENABLE_TESTABILITY = YES; 165 | GCC_C_LANGUAGE_STANDARD = gnu99; 166 | GCC_DYNAMIC_NO_PIC = NO; 167 | GCC_NO_COMMON_BLOCKS = YES; 168 | GCC_OPTIMIZATION_LEVEL = 0; 169 | GCC_PREPROCESSOR_DEFINITIONS = ( 170 | "DEBUG=1", 171 | "$(inherited)", 172 | ); 173 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 174 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 175 | GCC_WARN_UNDECLARED_SELECTOR = YES; 176 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 177 | GCC_WARN_UNUSED_FUNCTION = YES; 178 | GCC_WARN_UNUSED_VARIABLE = YES; 179 | MACOSX_DEPLOYMENT_TARGET = 10.11; 180 | MTL_ENABLE_DEBUG_INFO = YES; 181 | ONLY_ACTIVE_ARCH = YES; 182 | SDKROOT = macosx; 183 | }; 184 | name = Debug; 185 | }; 186 | 1D6135211C031B0D00CAE85F /* Release */ = { 187 | isa = XCBuildConfiguration; 188 | buildSettings = { 189 | ALWAYS_SEARCH_USER_PATHS = NO; 190 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 191 | CLANG_CXX_LIBRARY = "libc++"; 192 | CLANG_ENABLE_MODULES = YES; 193 | CLANG_ENABLE_OBJC_ARC = YES; 194 | CLANG_WARN_BOOL_CONVERSION = YES; 195 | CLANG_WARN_CONSTANT_CONVERSION = YES; 196 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 197 | CLANG_WARN_EMPTY_BODY = YES; 198 | CLANG_WARN_ENUM_CONVERSION = YES; 199 | CLANG_WARN_INT_CONVERSION = YES; 200 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 201 | CLANG_WARN_UNREACHABLE_CODE = YES; 202 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 203 | CODE_SIGN_IDENTITY = "-"; 204 | COPY_PHASE_STRIP = NO; 205 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 206 | ENABLE_NS_ASSERTIONS = NO; 207 | ENABLE_STRICT_OBJC_MSGSEND = YES; 208 | GCC_C_LANGUAGE_STANDARD = gnu99; 209 | GCC_NO_COMMON_BLOCKS = YES; 210 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 211 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 212 | GCC_WARN_UNDECLARED_SELECTOR = YES; 213 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 214 | GCC_WARN_UNUSED_FUNCTION = YES; 215 | GCC_WARN_UNUSED_VARIABLE = YES; 216 | MACOSX_DEPLOYMENT_TARGET = 10.11; 217 | MTL_ENABLE_DEBUG_INFO = NO; 218 | SDKROOT = macosx; 219 | }; 220 | name = Release; 221 | }; 222 | 1D6135231C031B0D00CAE85F /* Debug */ = { 223 | isa = XCBuildConfiguration; 224 | buildSettings = { 225 | PRODUCT_NAME = "$(TARGET_NAME)"; 226 | }; 227 | name = Debug; 228 | }; 229 | 1D6135241C031B0D00CAE85F /* Release */ = { 230 | isa = XCBuildConfiguration; 231 | buildSettings = { 232 | PRODUCT_NAME = "$(TARGET_NAME)"; 233 | }; 234 | name = Release; 235 | }; 236 | /* End XCBuildConfiguration section */ 237 | 238 | /* Begin XCConfigurationList section */ 239 | 1D6135161C031B0D00CAE85F /* Build configuration list for PBXProject "demo" */ = { 240 | isa = XCConfigurationList; 241 | buildConfigurations = ( 242 | 1D6135201C031B0D00CAE85F /* Debug */, 243 | 1D6135211C031B0D00CAE85F /* Release */, 244 | ); 245 | defaultConfigurationIsVisible = 0; 246 | defaultConfigurationName = Release; 247 | }; 248 | 1D6135221C031B0D00CAE85F /* Build configuration list for PBXNativeTarget "demo" */ = { 249 | isa = XCConfigurationList; 250 | buildConfigurations = ( 251 | 1D6135231C031B0D00CAE85F /* Debug */, 252 | 1D6135241C031B0D00CAE85F /* Release */, 253 | ); 254 | defaultConfigurationIsVisible = 0; 255 | defaultConfigurationName = Release; 256 | }; 257 | /* End XCConfigurationList section */ 258 | }; 259 | rootObject = 1D6135131C031B0D00CAE85F /* Project object */; 260 | } 261 | -------------------------------------------------------------------------------- /demo/demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /demo/demo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // demo 4 | // 5 | // blog : http://blog.csdn.net/biggercoffee 6 | // github : https://github.com/biggercoffee/ZXPUnicode 7 | 8 | // Created by coffee on 15/11/23. 9 | // Copyright © 2015年 coffee. All rights reserved. 10 | // 11 | 12 | #import 13 | 14 | int main(int argc, const char * argv[]) { 15 | @autoreleasepool { 16 | NSMutableString *mutableString = [@"中文可变字符串" mutableCopy]; 17 | 18 | NSDictionary *dictionary = @{@"中文key": @"中文value"}; 19 | NSArray *array = @[@"第一个中文数组的值", @"第二个中文数组的值", mutableString]; 20 | NSSet *set = [[NSSet alloc] initWithArray:array]; 21 | 22 | NSLog(@"dictionary:%@",dictionary); 23 | NSLog(@"array:%@",array); 24 | NSLog(@"set:%@",set); 25 | } 26 | return 0; 27 | } 28 | --------------------------------------------------------------------------------