├── .gitignore ├── .travis.yml ├── Gen ├── Gen-Bridging-Header.h ├── Gen.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── Gen │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── ViewController.swift │ └── gen.swift ├── objc.h └── objc.m ├── LICENSE ├── Obfuscation-Objective-C File.xctemplate ├── NSObjectObjective-C │ ├── ___FILEBASENAME___.coh │ ├── ___FILEBASENAME___.h │ └── ___FILEBASENAME___.m ├── NSObjectSwift │ └── ___FILEBASENAME___.swift ├── TemplateIcon.png ├── TemplateIcon@2x.png ├── TemplateInfo.plist ├── UICollectionReusableViewObjective-C │ ├── ___FILEBASENAME___.coh │ ├── ___FILEBASENAME___.h │ └── ___FILEBASENAME___.m ├── UICollectionReusableViewSwift │ └── ___FILEBASENAME___.swift ├── UICollectionReusableViewXIBObjective-C │ ├── ___FILEBASENAME___.coh │ ├── ___FILEBASENAME___.h │ ├── ___FILEBASENAME___.m │ └── ___FILEBASENAME___.xib ├── UICollectionReusableViewXIBSwift │ ├── ___FILEBASENAME___.swift │ └── ___FILEBASENAME___.xib ├── UICollectionViewCellObjective-C │ ├── ___FILEBASENAME___.coh │ ├── ___FILEBASENAME___.h │ └── ___FILEBASENAME___.m ├── UICollectionViewCellSwift │ └── ___FILEBASENAME___.swift ├── UICollectionViewCellXIBObjective-C │ ├── ___FILEBASENAME___.coh │ ├── ___FILEBASENAME___.h │ ├── ___FILEBASENAME___.m │ └── ___FILEBASENAME___.xib ├── UICollectionViewCellXIBSwift │ ├── ___FILEBASENAME___.swift │ └── ___FILEBASENAME___.xib ├── UICollectionViewControllerObjective-C │ ├── ___FILEBASENAME___.coh │ ├── ___FILEBASENAME___.h │ └── ___FILEBASENAME___.m ├── UICollectionViewControllerSwift │ └── ___FILEBASENAME___.swift ├── UICollectionViewControllerXIBObjective-C │ ├── ___FILEBASENAME___.coh │ ├── ___FILEBASENAME___.h │ ├── ___FILEBASENAME___.m │ └── ___FILEBASENAME___.xib ├── UICollectionViewControllerXIBSwift │ ├── ___FILEBASENAME___.swift │ └── ___FILEBASENAME___.xib ├── UITableViewCellObjective-C │ ├── ___FILEBASENAME___.coh │ ├── ___FILEBASENAME___.h │ └── ___FILEBASENAME___.m ├── UITableViewCellSwift │ └── ___FILEBASENAME___.swift ├── UITableViewCellXIBObjective-C │ ├── ___FILEBASENAME___.coh │ ├── ___FILEBASENAME___.h │ ├── ___FILEBASENAME___.m │ └── ___FILEBASENAME___.xib ├── UITableViewCellXIBSwift │ ├── ___FILEBASENAME___.swift │ └── ___FILEBASENAME___.xib ├── UITableViewControllerObjective-C │ ├── ___FILEBASENAME___.coh │ ├── ___FILEBASENAME___.h │ └── ___FILEBASENAME___.m ├── UITableViewControllerSwift │ └── ___FILEBASENAME___.swift ├── UITableViewControllerXIBObjective-C │ ├── ___FILEBASENAME___.coh │ ├── ___FILEBASENAME___.h │ ├── ___FILEBASENAME___.m │ └── ___FILEBASENAME___.xib ├── UITableViewControllerXIBSwift │ ├── ___FILEBASENAME___.swift │ └── ___FILEBASENAME___.xib ├── UIViewControllerObjective-C │ ├── ___FILEBASENAME___.coh │ ├── ___FILEBASENAME___.h │ └── ___FILEBASENAME___.m ├── UIViewControllerSwift │ └── ___FILEBASENAME___.swift ├── UIViewControllerXIBObjective-C │ ├── ___FILEBASENAME___.coh │ ├── ___FILEBASENAME___.h │ ├── ___FILEBASENAME___.m │ └── ___FILEBASENAME___.xib ├── UIViewControllerXIBSwift │ ├── ___FILEBASENAME___.swift │ └── ___FILEBASENAME___.xib ├── UIViewObjective-C │ ├── ___FILEBASENAME___.coh │ ├── ___FILEBASENAME___.h │ └── ___FILEBASENAME___.m └── UIViewSwift │ └── ___FILEBASENAME___.swift ├── Products └── iOS │ └── obfuse-code ├── README.md ├── TemplateFiles ├── CO-Features.h ├── COTemplateFile.coh ├── COTemplateFile.h ├── COTemplateFile.m ├── JSONModel │ ├── JSONModel.coh │ ├── JSONModel.h │ ├── JSONModel.m │ ├── JSONModelClassProperty.coh │ ├── JSONModelClassProperty.h │ ├── JSONModelClassProperty.m │ ├── JSONModelError.coh │ ├── JSONModelError.h │ └── JSONModelError.m └── JSONModelTransformations │ ├── JSONKeyMapper.coh │ ├── JSONKeyMapper.h │ ├── JSONKeyMapper.m │ ├── JSONValueTransformer.coh │ ├── JSONValueTransformer.h │ └── JSONValueTransformer.m ├── md.res └── database-structure.png └── obfuse-code ├── obfuse-code.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata └── obfuse-code ├── Arguments.swift ├── Clazz.swift ├── FileAnalysis.swift ├── FileOutStream.swift ├── ObfuscationDatabase.swift ├── ObfuscationManager.swift ├── Objective-C ├── BuildSql │ ├── LICENSE │ └── README.md ├── FMDB │ ├── LICENSE.txt │ ├── README.markdown │ └── src │ │ └── fmdb │ │ ├── FMDB.h │ │ ├── FMDatabase.h │ │ ├── FMDatabase.m │ │ ├── FMDatabaseAdditions.h │ │ ├── FMDatabaseAdditions.m │ │ ├── FMDatabasePool.h │ │ ├── FMDatabasePool.m │ │ ├── FMDatabaseQueue.h │ │ ├── FMDatabaseQueue.m │ │ ├── FMResultSet.h │ │ └── FMResultSet.m ├── MetaData │ ├── CacheImage.h │ ├── CacheImage.mm │ ├── GenMetaData.cpp │ └── structs.h ├── NSString+COMD5.h └── NSString+COMD5.m ├── flag.swift ├── main.swift ├── obfuse-code-Bridging-Header.h └── printc.swift /.gitignore: -------------------------------------------------------------------------------- 1 | # ---> Objective-C 2 | # Xcode 3 | # 4 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 5 | 6 | ## Build generated 7 | build/ 8 | DerivedData 9 | 10 | ## Various settings 11 | *.pbxuser 12 | !default.pbxuser 13 | *.mode1v3 14 | !default.mode1v3 15 | *.mode2v3 16 | !default.mode2v3 17 | *.perspectivev3 18 | !default.perspectivev3 19 | xcuserdata 20 | 21 | ## Other 22 | *.xccheckout 23 | *.moved-aside 24 | *.xcuserstate 25 | *.xcscmblueprint 26 | 27 | ## Obj-C/Swift specific 28 | *.hmap 29 | *.ipa 30 | 31 | # CocoaPods 32 | # 33 | # We recommend against adding the Pods directory to your .gitignore. However 34 | # you should judge for yourself, the pros and cons are mentioned at: 35 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 36 | # 37 | #Pods/ 38 | 39 | # Carthage 40 | # 41 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 42 | # Carthage/Checkouts 43 | 44 | Carthage/Build 45 | 46 | # ---> C++ 47 | # Compiled Object files 48 | *.slo 49 | *.lo 50 | *.o 51 | *.obj 52 | 53 | # Precompiled Headers 54 | *.gch 55 | *.pch 56 | 57 | # Compiled Dynamic libraries 58 | *.so 59 | *.dylib 60 | *.dll 61 | 62 | # Fortran module files 63 | *.mod 64 | 65 | # Compiled Static libraries 66 | *.lai 67 | *.la 68 | *.a 69 | *.lib 70 | 71 | # Executables 72 | *.exe 73 | *.out 74 | *.app 75 | 76 | # Pods 77 | CodeObfuscation/Pods/ 78 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # No adding Test project yet. 2 | language: Swift 3 | xcode_project: obfuse-code/obfuse-code.xcodeproj 4 | xcode_scheme: obfuse-code 5 | os: osx -------------------------------------------------------------------------------- /Gen/Gen-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | #import "objc.h" 5 | -------------------------------------------------------------------------------- /Gen/Gen.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Gen/Gen/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Gen 4 | // 5 | // Created by hejunqiu on 2017/8/28. 6 | // Copyright © 2017年 hejunqiu. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | DispatchQueue.main.async { 20 | let gen = Gen.init() 21 | gen.gencode() 22 | } 23 | return true 24 | } 25 | 26 | func applicationWillResignActive(_ application: UIApplication) { 27 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 28 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 29 | } 30 | 31 | func applicationDidEnterBackground(_ application: UIApplication) { 32 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 33 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 34 | } 35 | 36 | func applicationWillEnterForeground(_ application: UIApplication) { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | func applicationDidBecomeActive(_ application: UIApplication) { 41 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 42 | } 43 | 44 | func applicationWillTerminate(_ application: UIApplication) { 45 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 46 | } 47 | 48 | 49 | } 50 | 51 | -------------------------------------------------------------------------------- /Gen/Gen/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /Gen/Gen/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 | 27 | 28 | -------------------------------------------------------------------------------- /Gen/Gen/Base.lproj/Main.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 | 27 | -------------------------------------------------------------------------------- /Gen/Gen/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Gen/Gen/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Gen 4 | // 5 | // Created by hejunqiu on 2017/8/28. 6 | // Copyright © 2017年 hejunqiu. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | } 17 | 18 | override func didReceiveMemoryWarning() { 19 | super.didReceiveMemoryWarning() 20 | // Dispose of any resources that can be recreated. 21 | } 22 | 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /Gen/Gen/gen.swift: -------------------------------------------------------------------------------- 1 | // 2 | // gen.swift 3 | // Gen 4 | // 5 | // Created by hejunqiu on 2017/8/28. 6 | // Copyright © 2017年 hejunqiu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Gen { 12 | fileprivate var cache = EnumerateObjectiveClass() 13 | fileprivate var fileBuffer = NSMutableString.init() 14 | 15 | func gencode() { 16 | guard validation() else { 17 | print("Invalid!") 18 | return 19 | } 20 | gen() 21 | do { 22 | try fileBuffer.write(toFile: (NSTemporaryDirectory() as NSString).appendingPathComponent("GenMetaData.cpp"), atomically: true, encoding: String.Encoding.utf8.rawValue) 23 | print("Generate successfully! File at \(NSTemporaryDirectory())GenMetaData.cpp") 24 | exit(0) 25 | } catch { 26 | print(error) 27 | exit(-1) 28 | } 29 | } 30 | } 31 | 32 | fileprivate extension Gen { 33 | func validation() -> Bool { 34 | let path = (NSTemporaryDirectory() as NSString).appendingPathComponent("output.data") 35 | guard NSKeyedArchiver.archiveRootObject(cache, toFile: path) else { 36 | print("Archiver Failed...") 37 | return false 38 | } 39 | if let data = NSData.init(contentsOfFile: path) { 40 | if let check = NSKeyedUnarchiver.unarchiveObject(with: data as Data) { 41 | return NSDictionary.init(dictionary: cache).isEqual(to: check as! [AnyHashable : Any]) 42 | } 43 | } 44 | return false 45 | } 46 | 47 | func writeln(_ content: String) { 48 | fileBuffer.append("\(content)\n") 49 | } 50 | 51 | func write_prepare() { 52 | writeln("///// For iOS SDK \(ProcessInfo.processInfo.operatingSystemVersionString)\n") 53 | writeln("#ifndef structs_h\n#define structs_h\n") 54 | 55 | writeln("struct __method__ {\n" + 56 | " const char *name;\n" + 57 | "};\n") 58 | 59 | writeln("struct __method__list {\n" + 60 | " unsigned int reserved;\n" + 61 | " unsigned int count;\n" + 62 | " struct __method__ methods[0];\n" + 63 | "};\n") 64 | 65 | writeln("struct __class__ {\n" + 66 | " struct __class__ *superclass;\n" + 67 | " const char *name;\n" + 68 | " const struct __method__list *method_list;\n" + 69 | "};\n") 70 | 71 | writeln("#ifndef CO_EXPORT") 72 | writeln("#define CO_EXPORT extern \"C\"") 73 | writeln("#endif") 74 | } 75 | 76 | func _write(clazzName: String, methodcount: Int, methoddesc: String) { 77 | writeln("") 78 | writeln("/// Meta data for \(clazzName)") 79 | writeln("") 80 | writeln("static struct /*__method__list_t*/ {") 81 | writeln(" unsigned int entsize;") 82 | writeln(" unsigned int method_count;") 83 | writeln(" struct __method__ method_list[\(methodcount == 0 ? 1 : methodcount)];") 84 | writeln("} _CO_METHODNAMES_\(clazzName)_$ __attribute__ ((used, section (\"__DATA,__co_const\"))) = {") 85 | writeln(" sizeof(__method__),") 86 | writeln(" \(methodcount),") 87 | writeln(" {\(methoddesc)}\n};") 88 | 89 | var super_class_t: String? = nil 90 | if let superClass = class_getSuperclass(NSClassFromString(clazzName)) { 91 | super_class_t = "_CO_CLASS_$_\(NSString.init(utf8String: class_getName(superClass)) ?? "")" 92 | writeln("\nCO_EXPORT struct __class__ \(super_class_t!);") 93 | } 94 | writeln("CO_EXPORT struct __class__ _CO_CLASS_$_\(clazzName) __attribute__ ((used, section (\"__DATA,__co_data\"))) = {") 95 | if super_class_t != nil { 96 | writeln(" &\(super_class_t!),") 97 | } else { 98 | writeln(" 0,") 99 | } 100 | writeln(" \"\(clazzName)\",") 101 | writeln(" (const struct __method__list *)&_CO_METHODNAMES_\(clazzName)_$\n};") 102 | } 103 | 104 | func write_tail() { 105 | writeln("\nCO_EXPORT struct __class__ *L_CO_LABEL_CLASS_$[\(cache.count)] __attribute__((used, section (\"__DATA, __co_classlist\"))) = {") 106 | for (key, _) in cache { 107 | writeln(" &_CO_CLASS_$_\(key),") 108 | } 109 | fileBuffer.deleteCharacters(in: NSMakeRange(fileBuffer.length - 2, 1)) 110 | 111 | writeln("};") 112 | 113 | writeln("\nCO_EXPORT struct /*__image_info*/ {\n" + 114 | " const char *version;\n" + 115 | " unsigned long size;\n" + 116 | "} _CO_CLASS_IMAGE_INFO_$ __attribute__ ((used, section (\"__DATA,__co_const\"))) = {\n" + 117 | " \"\(ProcessInfo.processInfo.operatingSystemVersionString)\",\n" + 118 | " \(cache.count)\n" + 119 | "};"); 120 | 121 | writeln("\n#endif"); 122 | } 123 | 124 | func gen() { 125 | write_prepare() 126 | for (key, obj) in cache { 127 | var methods = [String]() 128 | for m in obj { 129 | methods.append(m.method) 130 | } 131 | _write(clazzName: key, methodcount: obj.count, methoddesc: "{\"\(methods.joined(separator: "\"},{\""))\"}") 132 | } 133 | write_tail() 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /Gen/objc.h: -------------------------------------------------------------------------------- 1 | // 2 | // objc.h 3 | // Gen 4 | // 5 | // Created by hejunqiu on 2017/8/28. 6 | // Copyright © 2017年 hejunqiu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class Function; 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | NSDictionary *>* EnumerateObjectiveClass(); 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Gen/objc.m: -------------------------------------------------------------------------------- 1 | // 2 | // objc.m 3 | // Gen 4 | // 5 | // Created by hejunqiu on 2017/8/28. 6 | // Copyright © 2017年 hejunqiu. All rights reserved. 7 | // 8 | 9 | #import "objc.h" 10 | #include 11 | #import "Gen-Swift.h" 12 | 13 | NSDictionary *>* EnumerateObjectiveClass() 14 | { 15 | int num = objc_getClassList(NULL, 0); 16 | Class clazzs[num]; 17 | num = objc_getClassList(clazzs, num); 18 | NSMutableDictionary *> *cache = [NSMutableDictionary dictionaryWithCapacity:num]; 19 | 20 | Class *p = &clazzs[0]; 21 | Class *end = clazzs + num; 22 | do { 23 | NSString *classname = @(class_getName(*p)); 24 | if ([classname containsString:@"."]) { 25 | continue; 26 | } 27 | NSMutableArray *comethods = [NSMutableArray array]; 28 | unsigned int count = 0; 29 | Method *method = class_copyMethodList(*p, &count); 30 | for (unsigned int i=0; i 2 | 3 | 4 | 5 | Kind 6 | Xcode.IDEFoundation.TextSubstitutionFileTemplateKind 7 | Description 8 | A Cocoa Touch class. 9 | Summary 10 | A Cocoa Touch class 11 | SortOrder 12 | 1 13 | DefaultCompletionName 14 | MyClass 15 | Platforms 16 | 17 | com.apple.platform.iphoneos 18 | 19 | Options 20 | 21 | 22 | Identifier 23 | productName 24 | Required 25 | 26 | Name 27 | Class: 28 | Description 29 | The name of the class to create 30 | Type 31 | text 32 | NotPersisted 33 | 34 | 35 | 36 | Identifier 37 | cocoaTouchSubclass 38 | Required 39 | YES 40 | Name 41 | Subclass of: 42 | Description 43 | What class to subclass in the new file 44 | Type 45 | class 46 | Default 47 | NSObject 48 | FallbackHeader 49 | #import <UIKit/UIKit.h> 50 | Values 51 | 52 | NSObject 53 | UIView 54 | UIViewController 55 | UITableViewController 56 | UITableViewCell 57 | UICollectionViewController 58 | UICollectionViewCell 59 | UICollectionReusableView 60 | 61 | Suffixes 62 | 63 | UIViewController 64 | ViewController 65 | UITableViewController 66 | TableViewController 67 | UITableViewCell 68 | TableViewCell 69 | UICollectionViewController 70 | CollectionViewController 71 | UICollectionViewCell 72 | CollectionViewCell 73 | UICollectionReusableView 74 | CollectionReusableView 75 | 76 | 77 | 78 | Identifier 79 | XIB 80 | Name 81 | Also create XIB file 82 | Description 83 | Whether to create a XIB file with the same name 84 | Type 85 | checkbox 86 | RequiredOptions 87 | 88 | cocoaTouchSubclass 89 | 90 | UIViewController 91 | UITableViewController 92 | UITableViewCell 93 | UICollectionViewController 94 | UICollectionViewCell 95 | UICollectionReusableView 96 | 97 | 98 | Default 99 | false 100 | NotPersisted 101 | 102 | 103 | 104 | Identifier 105 | languageChoice 106 | Required 107 | 108 | Name 109 | Language: 110 | Description 111 | The implementation language 112 | Type 113 | popup 114 | Default 115 | Objective-C 116 | Values 117 | 118 | Swift 119 | Objective-C 120 | 121 | MainTemplateFiles 122 | 123 | Swift 124 | ___FILEBASENAME___.swift 125 | Objective-C 126 | ___FILEBASENAME___.m 127 | 128 | AllowedTypes 129 | 130 | Swift 131 | 132 | public.swift-source 133 | 134 | Objective-C 135 | 136 | public.objective-c-source 137 | public.objective-c-plus-plus-source 138 | 139 | 140 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionReusableViewObjective-C/___FILEBASENAME___.coh: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef ___FILEBASENAMEASIDENTIFIER____coh 13 | #define ___FILEBASENAMEASIDENTIFIER____coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #ifndef CO_CONFUSION_PROTOCOL 32 | #define CO_CONFUSION_PROTOCOL 33 | #endif // !CO_CONFUSION_PROTOCOL 34 | 35 | #if __has_include("CO-Features.h") 36 | # include "CO-Features.h" 37 | #endif // __has_include 38 | 39 | #endif /* ___FILEBASENAMEASIDENTIFIER____coh */ 40 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionReusableViewObjective-C/___FILEBASENAME___.h: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | ___IMPORTHEADER_cocoaTouchSubclass___ 10 | #import "___FILEBASENAMEASIDENTIFIER___.coh" 11 | 12 | @interface ___FILEBASENAMEASIDENTIFIER___ : ___VARIABLE_cocoaTouchSubclass___ 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionReusableViewObjective-C/___FILEBASENAME___.m: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #import "___FILEBASENAME___.h" 10 | 11 | @implementation ___FILEBASENAMEASIDENTIFIER___ 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionReusableViewSwift/___FILEBASENAME___.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | import UIKit 10 | 11 | class ___FILEBASENAMEASIDENTIFIER___: ___VARIABLE_cocoaTouchSubclass___ { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionReusableViewXIBObjective-C/___FILEBASENAME___.coh: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef ___FILEBASENAMEASIDENTIFIER____coh 13 | #define ___FILEBASENAMEASIDENTIFIER____coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #ifndef CO_CONFUSION_PROTOCOL 32 | #define CO_CONFUSION_PROTOCOL 33 | #endif // !CO_CONFUSION_PROTOCOL 34 | 35 | #if __has_include("CO-Features.h") 36 | # include "CO-Features.h" 37 | #endif // __has_include 38 | 39 | #endif /* ___FILEBASENAMEASIDENTIFIER____coh */ 40 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionReusableViewXIBObjective-C/___FILEBASENAME___.h: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | ___IMPORTHEADER_cocoaTouchSubclass___ 10 | #import "___FILEBASENAMEASIDENTIFIER___.coh" 11 | 12 | @interface ___FILEBASENAMEASIDENTIFIER___ : ___VARIABLE_cocoaTouchSubclass___ 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionReusableViewXIBObjective-C/___FILEBASENAME___.m: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #import "___FILEBASENAME___.h" 10 | 11 | @implementation ___FILEBASENAMEASIDENTIFIER___ 12 | 13 | - (void)awakeFromNib { 14 | [super awakeFromNib]; 15 | // Initialization code 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionReusableViewXIBObjective-C/___FILEBASENAME___.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionReusableViewXIBSwift/___FILEBASENAME___.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | import UIKit 10 | 11 | class ___FILEBASENAMEASIDENTIFIER___: ___VARIABLE_cocoaTouchSubclass___ { 12 | 13 | override func awakeFromNib() { 14 | super.awakeFromNib() 15 | // Initialization code 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionReusableViewXIBSwift/___FILEBASENAME___.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewCellObjective-C/___FILEBASENAME___.coh: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef ___FILEBASENAMEASIDENTIFIER____coh 13 | #define ___FILEBASENAMEASIDENTIFIER____coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #ifndef CO_CONFUSION_PROTOCOL 32 | #define CO_CONFUSION_PROTOCOL 33 | #endif // !CO_CONFUSION_PROTOCOL 34 | 35 | #if __has_include("CO-Features.h") 36 | # include "CO-Features.h" 37 | #endif // __has_include 38 | 39 | #endif /* ___FILEBASENAMEASIDENTIFIER____coh */ 40 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewCellObjective-C/___FILEBASENAME___.h: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | ___IMPORTHEADER_cocoaTouchSubclass___ 10 | #import "___FILEBASENAMEASIDENTIFIER___.coh" 11 | 12 | @interface ___FILEBASENAMEASIDENTIFIER___ : ___VARIABLE_cocoaTouchSubclass___ 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewCellObjective-C/___FILEBASENAME___.m: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #import "___FILEBASENAME___.h" 10 | 11 | @implementation ___FILEBASENAMEASIDENTIFIER___ 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewCellSwift/___FILEBASENAME___.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | import UIKit 10 | 11 | class ___FILEBASENAMEASIDENTIFIER___: ___VARIABLE_cocoaTouchSubclass___ { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewCellXIBObjective-C/___FILEBASENAME___.coh: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef ___FILEBASENAMEASIDENTIFIER____coh 13 | #define ___FILEBASENAMEASIDENTIFIER____coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #ifndef CO_CONFUSION_PROTOCOL 32 | #define CO_CONFUSION_PROTOCOL 33 | #endif // !CO_CONFUSION_PROTOCOL 34 | 35 | #if __has_include("CO-Features.h") 36 | # include "CO-Features.h" 37 | #endif // __has_include 38 | 39 | #endif /* ___FILEBASENAMEASIDENTIFIER____coh */ 40 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewCellXIBObjective-C/___FILEBASENAME___.h: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | ___IMPORTHEADER_cocoaTouchSubclass___ 10 | #import "___FILEBASENAMEASIDENTIFIER___.coh" 11 | 12 | @interface ___FILEBASENAMEASIDENTIFIER___ : ___VARIABLE_cocoaTouchSubclass___ 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewCellXIBObjective-C/___FILEBASENAME___.m: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #import "___FILEBASENAME___.h" 10 | 11 | @implementation ___FILEBASENAMEASIDENTIFIER___ 12 | 13 | - (void)awakeFromNib { 14 | [super awakeFromNib]; 15 | // Initialization code 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewCellXIBObjective-C/___FILEBASENAME___.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewCellXIBSwift/___FILEBASENAME___.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | import UIKit 10 | 11 | class ___FILEBASENAMEASIDENTIFIER___: ___VARIABLE_cocoaTouchSubclass___ { 12 | 13 | override func awakeFromNib() { 14 | super.awakeFromNib() 15 | // Initialization code 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewCellXIBSwift/___FILEBASENAME___.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewControllerObjective-C/___FILEBASENAME___.coh: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef ___FILEBASENAMEASIDENTIFIER____coh 13 | #define ___FILEBASENAMEASIDENTIFIER____coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #ifndef CO_CONFUSION_PROTOCOL 32 | #define CO_CONFUSION_PROTOCOL 33 | #endif // !CO_CONFUSION_PROTOCOL 34 | 35 | #if __has_include("CO-Features.h") 36 | # include "CO-Features.h" 37 | #endif // __has_include 38 | 39 | #endif /* ___FILEBASENAMEASIDENTIFIER____coh */ 40 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewControllerObjective-C/___FILEBASENAME___.h: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | ___IMPORTHEADER_cocoaTouchSubclass___ 10 | #import "___FILEBASENAMEASIDENTIFIER___.coh" 11 | 12 | @interface ___FILEBASENAMEASIDENTIFIER___ : ___VARIABLE_cocoaTouchSubclass___ 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewControllerObjective-C/___FILEBASENAME___.m: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #import "___FILEBASENAME___.h" 10 | 11 | @interface ___FILEBASENAMEASIDENTIFIER___ () 12 | 13 | @end 14 | 15 | @implementation ___FILEBASENAMEASIDENTIFIER___ 16 | 17 | static NSString * const reuseIdentifier = @"Cell"; 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | 22 | // Uncomment the following line to preserve selection between presentations 23 | // self.clearsSelectionOnViewWillAppear = NO; 24 | 25 | // Register cell classes 26 | [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier]; 27 | 28 | // Do any additional setup after loading the view. 29 | } 30 | 31 | - (void)didReceiveMemoryWarning { 32 | [super didReceiveMemoryWarning]; 33 | // Dispose of any resources that can be recreated. 34 | } 35 | 36 | /* 37 | #pragma mark - Navigation 38 | 39 | // In a storyboard-based application, you will often want to do a little preparation before navigation 40 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 41 | // Get the new view controller using [segue destinationViewController]. 42 | // Pass the selected object to the new view controller. 43 | } 44 | */ 45 | 46 | #pragma mark 47 | 48 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { 49 | #warning Incomplete implementation, return the number of sections 50 | return 0; 51 | } 52 | 53 | 54 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 55 | #warning Incomplete implementation, return the number of items 56 | return 0; 57 | } 58 | 59 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 60 | UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath]; 61 | 62 | // Configure the cell 63 | 64 | return cell; 65 | } 66 | 67 | #pragma mark 68 | 69 | /* 70 | // Uncomment this method to specify if the specified item should be highlighted during tracking 71 | - (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath { 72 | return YES; 73 | } 74 | */ 75 | 76 | /* 77 | // Uncomment this method to specify if the specified item should be selected 78 | - (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath { 79 | return YES; 80 | } 81 | */ 82 | 83 | /* 84 | // Uncomment these methods to specify if an action menu should be displayed for the specified item, and react to actions performed on the item 85 | - (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath { 86 | return NO; 87 | } 88 | 89 | - (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { 90 | return NO; 91 | } 92 | 93 | - (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { 94 | 95 | } 96 | */ 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewControllerSwift/___FILEBASENAME___.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | import UIKit 10 | 11 | private let reuseIdentifier = "Cell" 12 | 13 | class ___FILEBASENAMEASIDENTIFIER___: ___VARIABLE_cocoaTouchSubclass___ { 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | 18 | // Uncomment the following line to preserve selection between presentations 19 | // self.clearsSelectionOnViewWillAppear = false 20 | 21 | // Register cell classes 22 | self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier) 23 | 24 | // Do any additional setup after loading the view. 25 | } 26 | 27 | override func didReceiveMemoryWarning() { 28 | super.didReceiveMemoryWarning() 29 | // Dispose of any resources that can be recreated. 30 | } 31 | 32 | /* 33 | // MARK: - Navigation 34 | 35 | // In a storyboard-based application, you will often want to do a little preparation before navigation 36 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 37 | // Get the new view controller using [segue destinationViewController]. 38 | // Pass the selected object to the new view controller. 39 | } 40 | */ 41 | 42 | // MARK: UICollectionViewDataSource 43 | 44 | override func numberOfSections(in collectionView: UICollectionView) -> Int { 45 | // #warning Incomplete implementation, return the number of sections 46 | return 0 47 | } 48 | 49 | 50 | override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 51 | // #warning Incomplete implementation, return the number of items 52 | return 0 53 | } 54 | 55 | override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 56 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) 57 | 58 | // Configure the cell 59 | 60 | return cell 61 | } 62 | 63 | // MARK: UICollectionViewDelegate 64 | 65 | /* 66 | // Uncomment this method to specify if the specified item should be highlighted during tracking 67 | override func collectionView(_ collectionView: UICollectionView, shouldHighlightItemAt indexPath: IndexPath) -> Bool { 68 | return true 69 | } 70 | */ 71 | 72 | /* 73 | // Uncomment this method to specify if the specified item should be selected 74 | override func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { 75 | return true 76 | } 77 | */ 78 | 79 | /* 80 | // Uncomment these methods to specify if an action menu should be displayed for the specified item, and react to actions performed on the item 81 | override func collectionView(_ collectionView: UICollectionView, shouldShowMenuForItemAt indexPath: IndexPath) -> Bool { 82 | return false 83 | } 84 | 85 | override func collectionView(_ collectionView: UICollectionView, canPerformAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) -> Bool { 86 | return false 87 | } 88 | 89 | override func collectionView(_ collectionView: UICollectionView, performAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) { 90 | 91 | } 92 | */ 93 | 94 | } 95 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewControllerXIBObjective-C/___FILEBASENAME___.coh: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef ___FILEBASENAMEASIDENTIFIER____coh 13 | #define ___FILEBASENAMEASIDENTIFIER____coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #ifndef CO_CONFUSION_PROTOCOL 32 | #define CO_CONFUSION_PROTOCOL 33 | #endif // !CO_CONFUSION_PROTOCOL 34 | 35 | #if __has_include("CO-Features.h") 36 | # include "CO-Features.h" 37 | #endif // __has_include 38 | 39 | #endif /* ___FILEBASENAMEASIDENTIFIER____coh */ 40 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewControllerXIBObjective-C/___FILEBASENAME___.h: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | ___IMPORTHEADER_cocoaTouchSubclass___ 10 | #import "___FILEBASENAMEASIDENTIFIER___.coh" 11 | 12 | @interface ___FILEBASENAMEASIDENTIFIER___ : ___VARIABLE_cocoaTouchSubclass___ 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewControllerXIBObjective-C/___FILEBASENAME___.m: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #import "___FILEBASENAME___.h" 10 | 11 | @interface ___FILEBASENAMEASIDENTIFIER___ () 12 | 13 | @end 14 | 15 | @implementation ___FILEBASENAMEASIDENTIFIER___ 16 | 17 | static NSString * const reuseIdentifier = @"Cell"; 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | 22 | // Uncomment the following line to preserve selection between presentations 23 | // self.clearsSelectionOnViewWillAppear = NO; 24 | 25 | // Register cell classes 26 | [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier]; 27 | 28 | // Do any additional setup after loading the view. 29 | } 30 | 31 | - (void)didReceiveMemoryWarning { 32 | [super didReceiveMemoryWarning]; 33 | // Dispose of any resources that can be recreated. 34 | } 35 | 36 | /* 37 | #pragma mark - Navigation 38 | 39 | // In a storyboard-based application, you will often want to do a little preparation before navigation 40 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 41 | // Get the new view controller using [segue destinationViewController]. 42 | // Pass the selected object to the new view controller. 43 | } 44 | */ 45 | 46 | #pragma mark 47 | 48 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { 49 | #warning Incomplete implementation, return the number of sections 50 | return 0; 51 | } 52 | 53 | 54 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 55 | #warning Incomplete implementation, return the number of items 56 | return 0; 57 | } 58 | 59 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 60 | UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath]; 61 | 62 | // Configure the cell 63 | 64 | return cell; 65 | } 66 | 67 | #pragma mark 68 | 69 | /* 70 | // Uncomment this method to specify if the specified item should be highlighted during tracking 71 | - (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath { 72 | return YES; 73 | } 74 | */ 75 | 76 | /* 77 | // Uncomment this method to specify if the specified item should be selected 78 | - (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath { 79 | return YES; 80 | } 81 | */ 82 | 83 | /* 84 | // Uncomment these methods to specify if an action menu should be displayed for the specified item, and react to actions performed on the item 85 | - (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath { 86 | return NO; 87 | } 88 | 89 | - (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { 90 | return NO; 91 | } 92 | 93 | - (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { 94 | 95 | } 96 | */ 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewControllerXIBObjective-C/___FILEBASENAME___.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 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewControllerXIBSwift/___FILEBASENAME___.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | import UIKit 10 | 11 | private let reuseIdentifier = "Cell" 12 | 13 | class ___FILEBASENAMEASIDENTIFIER___: ___VARIABLE_cocoaTouchSubclass___ { 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | 18 | // Uncomment the following line to preserve selection between presentations 19 | // self.clearsSelectionOnViewWillAppear = false 20 | 21 | // Register cell classes 22 | self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier) 23 | 24 | // Do any additional setup after loading the view. 25 | } 26 | 27 | override func didReceiveMemoryWarning() { 28 | super.didReceiveMemoryWarning() 29 | // Dispose of any resources that can be recreated. 30 | } 31 | 32 | /* 33 | // MARK: - Navigation 34 | 35 | // In a storyboard-based application, you will often want to do a little preparation before navigation 36 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 37 | // Get the new view controller using [segue destinationViewController]. 38 | // Pass the selected object to the new view controller. 39 | } 40 | */ 41 | 42 | // MARK: UICollectionViewDataSource 43 | 44 | override func numberOfSections(in collectionView: UICollectionView) -> Int { 45 | // #warning Incomplete implementation, return the number of sections 46 | return 0 47 | } 48 | 49 | 50 | override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 51 | // #warning Incomplete implementation, return the number of items 52 | return 0 53 | } 54 | 55 | override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 56 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) 57 | 58 | // Configure the cell 59 | 60 | return cell 61 | } 62 | 63 | // MARK: UICollectionViewDelegate 64 | 65 | /* 66 | // Uncomment this method to specify if the specified item should be highlighted during tracking 67 | override func collectionView(_ collectionView: UICollectionView, shouldHighlightItemAt indexPath: IndexPath) -> Bool { 68 | return true 69 | } 70 | */ 71 | 72 | /* 73 | // Uncomment this method to specify if the specified item should be selected 74 | override func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { 75 | return true 76 | } 77 | */ 78 | 79 | /* 80 | // Uncomment these methods to specify if an action menu should be displayed for the specified item, and react to actions performed on the item 81 | override func collectionView(_ collectionView: UICollectionView, shouldShowMenuForItemAt indexPath: IndexPath) -> Bool { 82 | return false 83 | } 84 | 85 | override func collectionView(_ collectionView: UICollectionView, canPerformAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) -> Bool { 86 | return false 87 | } 88 | 89 | override func collectionView(_ collectionView: UICollectionView, performAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) { 90 | 91 | } 92 | */ 93 | 94 | } 95 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UICollectionViewControllerXIBSwift/___FILEBASENAME___.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 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewCellObjective-C/___FILEBASENAME___.coh: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef ___FILEBASENAMEASIDENTIFIER____coh 13 | #define ___FILEBASENAMEASIDENTIFIER____coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #ifndef CO_CONFUSION_PROTOCOL 32 | #define CO_CONFUSION_PROTOCOL 33 | #endif // !CO_CONFUSION_PROTOCOL 34 | 35 | #if __has_include("CO-Features.h") 36 | # include "CO-Features.h" 37 | #endif // __has_include 38 | 39 | #endif /* ___FILEBASENAMEASIDENTIFIER____coh */ 40 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewCellObjective-C/___FILEBASENAME___.h: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | ___IMPORTHEADER_cocoaTouchSubclass___ 10 | #import "___FILEBASENAMEASIDENTIFIER___.coh" 11 | 12 | @interface ___FILEBASENAMEASIDENTIFIER___ : ___VARIABLE_cocoaTouchSubclass___ 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewCellObjective-C/___FILEBASENAME___.m: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #import "___FILEBASENAME___.h" 10 | 11 | @implementation ___FILEBASENAMEASIDENTIFIER___ 12 | 13 | - (void)awakeFromNib { 14 | [super awakeFromNib]; 15 | // Initialization code 16 | } 17 | 18 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 19 | [super setSelected:selected animated:animated]; 20 | 21 | // Configure the view for the selected state 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewCellSwift/___FILEBASENAME___.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | import UIKit 10 | 11 | class ___FILEBASENAMEASIDENTIFIER___: ___VARIABLE_cocoaTouchSubclass___ { 12 | 13 | override func awakeFromNib() { 14 | super.awakeFromNib() 15 | // Initialization code 16 | } 17 | 18 | override func setSelected(_ selected: Bool, animated: Bool) { 19 | super.setSelected(selected, animated: animated) 20 | 21 | // Configure the view for the selected state 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewCellXIBObjective-C/___FILEBASENAME___.coh: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef ___FILEBASENAMEASIDENTIFIER____coh 13 | #define ___FILEBASENAMEASIDENTIFIER____coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #ifndef CO_CONFUSION_PROTOCOL 32 | #define CO_CONFUSION_PROTOCOL 33 | #endif // !CO_CONFUSION_PROTOCOL 34 | 35 | #if __has_include("CO-Features.h") 36 | # include "CO-Features.h" 37 | #endif // __has_include 38 | 39 | #endif /* ___FILEBASENAMEASIDENTIFIER____coh */ 40 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewCellXIBObjective-C/___FILEBASENAME___.h: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | ___IMPORTHEADER_cocoaTouchSubclass___ 10 | #import "___FILEBASENAMEASIDENTIFIER___.coh" 11 | 12 | @interface ___FILEBASENAMEASIDENTIFIER___ : ___VARIABLE_cocoaTouchSubclass___ 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewCellXIBObjective-C/___FILEBASENAME___.m: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #import "___FILEBASENAME___.h" 10 | 11 | @implementation ___FILEBASENAMEASIDENTIFIER___ 12 | 13 | - (void)awakeFromNib { 14 | [super awakeFromNib]; 15 | // Initialization code 16 | } 17 | 18 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 19 | [super setSelected:selected animated:animated]; 20 | 21 | // Configure the view for the selected state 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewCellXIBObjective-C/___FILEBASENAME___.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewCellXIBSwift/___FILEBASENAME___.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | import UIKit 10 | 11 | class ___FILEBASENAMEASIDENTIFIER___: ___VARIABLE_cocoaTouchSubclass___ { 12 | 13 | override func awakeFromNib() { 14 | super.awakeFromNib() 15 | // Initialization code 16 | } 17 | 18 | override func setSelected(_ selected: Bool, animated: Bool) { 19 | super.setSelected(selected, animated: animated) 20 | 21 | // Configure the view for the selected state 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewCellXIBSwift/___FILEBASENAME___.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewControllerObjective-C/___FILEBASENAME___.coh: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef ___FILEBASENAMEASIDENTIFIER____coh 13 | #define ___FILEBASENAMEASIDENTIFIER____coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #ifndef CO_CONFUSION_PROTOCOL 32 | #define CO_CONFUSION_PROTOCOL 33 | #endif // !CO_CONFUSION_PROTOCOL 34 | 35 | #if __has_include("CO-Features.h") 36 | # include "CO-Features.h" 37 | #endif // __has_include 38 | 39 | #endif /* ___FILEBASENAMEASIDENTIFIER____coh */ 40 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewControllerObjective-C/___FILEBASENAME___.h: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | ___IMPORTHEADER_cocoaTouchSubclass___ 10 | #import "___FILEBASENAMEASIDENTIFIER___.coh" 11 | 12 | @interface ___FILEBASENAMEASIDENTIFIER___ : ___VARIABLE_cocoaTouchSubclass___ 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewControllerObjective-C/___FILEBASENAME___.m: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #import "___FILEBASENAME___.h" 10 | 11 | @interface ___FILEBASENAMEASIDENTIFIER___ () 12 | 13 | @end 14 | 15 | @implementation ___FILEBASENAMEASIDENTIFIER___ 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | 20 | // Uncomment the following line to preserve selection between presentations. 21 | // self.clearsSelectionOnViewWillAppear = NO; 22 | 23 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 24 | // self.navigationItem.rightBarButtonItem = self.editButtonItem; 25 | } 26 | 27 | - (void)didReceiveMemoryWarning { 28 | [super didReceiveMemoryWarning]; 29 | // Dispose of any resources that can be recreated. 30 | } 31 | 32 | #pragma mark - Table view data source 33 | 34 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 35 | #warning Incomplete implementation, return the number of sections 36 | return 0; 37 | } 38 | 39 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 40 | #warning Incomplete implementation, return the number of rows 41 | return 0; 42 | } 43 | 44 | /* 45 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 46 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:<#@"reuseIdentifier"#> forIndexPath:indexPath]; 47 | 48 | // Configure the cell... 49 | 50 | return cell; 51 | } 52 | */ 53 | 54 | /* 55 | // Override to support conditional editing of the table view. 56 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { 57 | // Return NO if you do not want the specified item to be editable. 58 | return YES; 59 | } 60 | */ 61 | 62 | /* 63 | // Override to support editing the table view. 64 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 65 | if (editingStyle == UITableViewCellEditingStyleDelete) { 66 | // Delete the row from the data source 67 | [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 68 | } else if (editingStyle == UITableViewCellEditingStyleInsert) { 69 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 70 | } 71 | } 72 | */ 73 | 74 | /* 75 | // Override to support rearranging the table view. 76 | - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { 77 | } 78 | */ 79 | 80 | /* 81 | // Override to support conditional rearranging of the table view. 82 | - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { 83 | // Return NO if you do not want the item to be re-orderable. 84 | return YES; 85 | } 86 | */ 87 | 88 | /* 89 | #pragma mark - Navigation 90 | 91 | // In a storyboard-based application, you will often want to do a little preparation before navigation 92 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 93 | // Get the new view controller using [segue destinationViewController]. 94 | // Pass the selected object to the new view controller. 95 | } 96 | */ 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewControllerSwift/___FILEBASENAME___.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | import UIKit 10 | 11 | class ___FILEBASENAMEASIDENTIFIER___: ___VARIABLE_cocoaTouchSubclass___ { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Uncomment the following line to preserve selection between presentations 17 | // self.clearsSelectionOnViewWillAppear = false 18 | 19 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 20 | // self.navigationItem.rightBarButtonItem = self.editButtonItem() 21 | } 22 | 23 | override func didReceiveMemoryWarning() { 24 | super.didReceiveMemoryWarning() 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | // MARK: - Table view data source 29 | 30 | override func numberOfSections(in tableView: UITableView) -> Int { 31 | // #warning Incomplete implementation, return the number of sections 32 | return 0 33 | } 34 | 35 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 36 | // #warning Incomplete implementation, return the number of rows 37 | return 0 38 | } 39 | 40 | /* 41 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 42 | let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) 43 | 44 | // Configure the cell... 45 | 46 | return cell 47 | } 48 | */ 49 | 50 | /* 51 | // Override to support conditional editing of the table view. 52 | override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 53 | // Return false if you do not want the specified item to be editable. 54 | return true 55 | } 56 | */ 57 | 58 | /* 59 | // Override to support editing the table view. 60 | override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 61 | if editingStyle == .delete { 62 | // Delete the row from the data source 63 | tableView.deleteRows(at: [indexPath], with: .fade) 64 | } else if editingStyle == .insert { 65 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 66 | } 67 | } 68 | */ 69 | 70 | /* 71 | // Override to support rearranging the table view. 72 | override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) { 73 | 74 | } 75 | */ 76 | 77 | /* 78 | // Override to support conditional rearranging of the table view. 79 | override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { 80 | // Return false if you do not want the item to be re-orderable. 81 | return true 82 | } 83 | */ 84 | 85 | /* 86 | // MARK: - Navigation 87 | 88 | // In a storyboard-based application, you will often want to do a little preparation before navigation 89 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 90 | // Get the new view controller using segue.destinationViewController. 91 | // Pass the selected object to the new view controller. 92 | } 93 | */ 94 | 95 | } 96 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewControllerXIBObjective-C/___FILEBASENAME___.coh: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef ___FILEBASENAMEASIDENTIFIER____coh 13 | #define ___FILEBASENAMEASIDENTIFIER____coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #ifndef CO_CONFUSION_PROTOCOL 32 | #define CO_CONFUSION_PROTOCOL 33 | #endif // !CO_CONFUSION_PROTOCOL 34 | 35 | #if __has_include("CO-Features.h") 36 | # include "CO-Features.h" 37 | #endif // __has_include 38 | 39 | #endif /* ___FILEBASENAMEASIDENTIFIER____coh */ 40 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewControllerXIBObjective-C/___FILEBASENAME___.h: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | ___IMPORTHEADER_cocoaTouchSubclass___ 10 | #import "___FILEBASENAMEASIDENTIFIER___.coh" 11 | 12 | @interface ___FILEBASENAMEASIDENTIFIER___ : ___VARIABLE_cocoaTouchSubclass___ 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewControllerXIBObjective-C/___FILEBASENAME___.m: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #import "___FILEBASENAME___.h" 10 | 11 | @interface ___FILEBASENAMEASIDENTIFIER___ () 12 | 13 | @end 14 | 15 | @implementation ___FILEBASENAMEASIDENTIFIER___ 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | 20 | // Uncomment the following line to preserve selection between presentations. 21 | // self.clearsSelectionOnViewWillAppear = NO; 22 | 23 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 24 | // self.navigationItem.rightBarButtonItem = self.editButtonItem; 25 | } 26 | 27 | - (void)didReceiveMemoryWarning { 28 | [super didReceiveMemoryWarning]; 29 | // Dispose of any resources that can be recreated. 30 | } 31 | 32 | #pragma mark - Table view data source 33 | 34 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 35 | #warning Incomplete implementation, return the number of sections 36 | return 0; 37 | } 38 | 39 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 40 | #warning Incomplete implementation, return the number of rows 41 | return 0; 42 | } 43 | 44 | /* 45 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 46 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:<#@"reuseIdentifier"#> forIndexPath:indexPath]; 47 | 48 | // Configure the cell... 49 | 50 | return cell; 51 | } 52 | */ 53 | 54 | /* 55 | // Override to support conditional editing of the table view. 56 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { 57 | // Return NO if you do not want the specified item to be editable. 58 | return YES; 59 | } 60 | */ 61 | 62 | /* 63 | // Override to support editing the table view. 64 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 65 | if (editingStyle == UITableViewCellEditingStyleDelete) { 66 | // Delete the row from the data source 67 | [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 68 | } else if (editingStyle == UITableViewCellEditingStyleInsert) { 69 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 70 | } 71 | } 72 | */ 73 | 74 | /* 75 | // Override to support rearranging the table view. 76 | - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { 77 | } 78 | */ 79 | 80 | /* 81 | // Override to support conditional rearranging of the table view. 82 | - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { 83 | // Return NO if you do not want the item to be re-orderable. 84 | return YES; 85 | } 86 | */ 87 | 88 | /* 89 | #pragma mark - Table view delegate 90 | 91 | // In a xib-based application, navigation from a table can be handled in -tableView:didSelectRowAtIndexPath: 92 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 93 | // Navigation logic may go here, for example: 94 | // Create the next view controller. 95 | <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:<#@"Nib name"#> bundle:nil]; 96 | 97 | // Pass the selected object to the new view controller. 98 | 99 | // Push the view controller. 100 | [self.navigationController pushViewController:detailViewController animated:YES]; 101 | } 102 | */ 103 | 104 | /* 105 | #pragma mark - Navigation 106 | 107 | // In a storyboard-based application, you will often want to do a little preparation before navigation 108 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 109 | // Get the new view controller using [segue destinationViewController]. 110 | // Pass the selected object to the new view controller. 111 | } 112 | */ 113 | 114 | @end 115 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewControllerXIBObjective-C/___FILEBASENAME___.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 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewControllerXIBSwift/___FILEBASENAME___.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | import UIKit 10 | 11 | class ___FILEBASENAMEASIDENTIFIER___: ___VARIABLE_cocoaTouchSubclass___ { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Uncomment the following line to preserve selection between presentations 17 | // self.clearsSelectionOnViewWillAppear = false 18 | 19 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 20 | // self.navigationItem.rightBarButtonItem = self.editButtonItem() 21 | } 22 | 23 | override func didReceiveMemoryWarning() { 24 | super.didReceiveMemoryWarning() 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | // MARK: - Table view data source 29 | 30 | override func numberOfSections(in tableView: UITableView) -> Int { 31 | // #warning Incomplete implementation, return the number of sections 32 | return 0 33 | } 34 | 35 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 36 | // #warning Incomplete implementation, return the number of rows 37 | return 0 38 | } 39 | 40 | /* 41 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 42 | let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) 43 | 44 | // Configure the cell... 45 | 46 | return cell 47 | } 48 | */ 49 | 50 | /* 51 | // Override to support conditional editing of the table view. 52 | override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 53 | // Return false if you do not want the specified item to be editable. 54 | return true 55 | } 56 | */ 57 | 58 | /* 59 | // Override to support editing the table view. 60 | override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 61 | if editingStyle == .delete { 62 | // Delete the row from the data source 63 | tableView.deleteRows(at: [indexPath], with: .fade) 64 | } else if editingStyle == .insert { 65 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 66 | } 67 | } 68 | */ 69 | 70 | /* 71 | // Override to support rearranging the table view. 72 | override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) { 73 | 74 | } 75 | */ 76 | 77 | /* 78 | // Override to support conditional rearranging of the table view. 79 | override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { 80 | // Return false if you do not want the item to be re-orderable. 81 | return true 82 | } 83 | */ 84 | 85 | /* 86 | // MARK: - Navigation 87 | 88 | // In a storyboard-based application, you will often want to do a little preparation before navigation 89 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 90 | // Get the new view controller using segue.destinationViewController. 91 | // Pass the selected object to the new view controller. 92 | } 93 | */ 94 | 95 | } 96 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UITableViewControllerXIBSwift/___FILEBASENAME___.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 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UIViewControllerObjective-C/___FILEBASENAME___.coh: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef ___FILEBASENAMEASIDENTIFIER____coh 13 | #define ___FILEBASENAMEASIDENTIFIER____coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #ifndef CO_CONFUSION_PROTOCOL 32 | #define CO_CONFUSION_PROTOCOL 33 | #endif // !CO_CONFUSION_PROTOCOL 34 | 35 | #if __has_include("CO-Features.h") 36 | # include "CO-Features.h" 37 | #endif // __has_include 38 | 39 | #endif /* ___FILEBASENAMEASIDENTIFIER____coh */ 40 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UIViewControllerObjective-C/___FILEBASENAME___.h: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | ___IMPORTHEADER_cocoaTouchSubclass___ 10 | #import "___FILEBASENAMEASIDENTIFIER___.coh" 11 | 12 | @interface ___FILEBASENAMEASIDENTIFIER___ : ___VARIABLE_cocoaTouchSubclass___ 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UIViewControllerObjective-C/___FILEBASENAME___.m: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #import "___FILEBASENAME___.h" 10 | 11 | @interface ___FILEBASENAMEASIDENTIFIER___ () 12 | 13 | @end 14 | 15 | @implementation ___FILEBASENAMEASIDENTIFIER___ 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | } 21 | 22 | - (void)didReceiveMemoryWarning { 23 | [super didReceiveMemoryWarning]; 24 | // Dispose of any resources that can be recreated. 25 | } 26 | 27 | /* 28 | #pragma mark - Navigation 29 | 30 | // In a storyboard-based application, you will often want to do a little preparation before navigation 31 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 32 | // Get the new view controller using [segue destinationViewController]. 33 | // Pass the selected object to the new view controller. 34 | } 35 | */ 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UIViewControllerSwift/___FILEBASENAME___.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | import UIKit 10 | 11 | class ___FILEBASENAMEASIDENTIFIER___: ___VARIABLE_cocoaTouchSubclass___ { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Do any additional setup after loading the view. 17 | } 18 | 19 | override func didReceiveMemoryWarning() { 20 | super.didReceiveMemoryWarning() 21 | // Dispose of any resources that can be recreated. 22 | } 23 | 24 | 25 | /* 26 | // MARK: - Navigation 27 | 28 | // In a storyboard-based application, you will often want to do a little preparation before navigation 29 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 30 | // Get the new view controller using segue.destinationViewController. 31 | // Pass the selected object to the new view controller. 32 | } 33 | */ 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UIViewControllerXIBObjective-C/___FILEBASENAME___.coh: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef ___FILEBASENAMEASIDENTIFIER____coh 13 | #define ___FILEBASENAMEASIDENTIFIER____coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #ifndef CO_CONFUSION_PROTOCOL 32 | #define CO_CONFUSION_PROTOCOL 33 | #endif // !CO_CONFUSION_PROTOCOL 34 | 35 | #if __has_include("CO-Features.h") 36 | # include "CO-Features.h" 37 | #endif // __has_include 38 | 39 | #endif /* ___FILEBASENAMEASIDENTIFIER____coh */ 40 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UIViewControllerXIBObjective-C/___FILEBASENAME___.h: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | ___IMPORTHEADER_cocoaTouchSubclass___ 10 | #import "___FILEBASENAMEASIDENTIFIER___.coh" 11 | 12 | @interface ___FILEBASENAMEASIDENTIFIER___ : ___VARIABLE_cocoaTouchSubclass___ 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UIViewControllerXIBObjective-C/___FILEBASENAME___.m: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #import "___FILEBASENAME___.h" 10 | 11 | @interface ___FILEBASENAMEASIDENTIFIER___ () 12 | 13 | @end 14 | 15 | @implementation ___FILEBASENAMEASIDENTIFIER___ 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view from its nib. 20 | } 21 | 22 | - (void)didReceiveMemoryWarning { 23 | [super didReceiveMemoryWarning]; 24 | // Dispose of any resources that can be recreated. 25 | } 26 | 27 | /* 28 | #pragma mark - Navigation 29 | 30 | // In a storyboard-based application, you will often want to do a little preparation before navigation 31 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 32 | // Get the new view controller using [segue destinationViewController]. 33 | // Pass the selected object to the new view controller. 34 | } 35 | */ 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UIViewControllerXIBObjective-C/___FILEBASENAME___.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UIViewControllerXIBSwift/___FILEBASENAME___.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | import UIKit 10 | 11 | class ___FILEBASENAMEASIDENTIFIER___: ___VARIABLE_cocoaTouchSubclass___ { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Do any additional setup after loading the view. 17 | } 18 | 19 | override func didReceiveMemoryWarning() { 20 | super.didReceiveMemoryWarning() 21 | // Dispose of any resources that can be recreated. 22 | } 23 | 24 | 25 | /* 26 | // MARK: - Navigation 27 | 28 | // In a storyboard-based application, you will often want to do a little preparation before navigation 29 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 30 | // Get the new view controller using segue.destinationViewController. 31 | // Pass the selected object to the new view controller. 32 | } 33 | */ 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UIViewControllerXIBSwift/___FILEBASENAME___.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UIViewObjective-C/___FILEBASENAME___.coh: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef ___FILEBASENAMEASIDENTIFIER____coh 13 | #define ___FILEBASENAMEASIDENTIFIER____coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #ifndef CO_CONFUSION_PROTOCOL 32 | #define CO_CONFUSION_PROTOCOL 33 | #endif // !CO_CONFUSION_PROTOCOL 34 | 35 | #if __has_include("CO-Features.h") 36 | # include "CO-Features.h" 37 | #endif // __has_include 38 | 39 | #endif /* ___FILEBASENAMEASIDENTIFIER____coh */ 40 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UIViewObjective-C/___FILEBASENAME___.h: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | ___IMPORTHEADER_cocoaTouchSubclass___ 10 | #import "___FILEBASENAMEASIDENTIFIER___.coh" 11 | 12 | @interface ___FILEBASENAMEASIDENTIFIER___ : ___VARIABLE_cocoaTouchSubclass___ 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UIViewObjective-C/___FILEBASENAME___.m: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #import "___FILEBASENAME___.h" 10 | 11 | @implementation ___FILEBASENAMEASIDENTIFIER___ 12 | 13 | /* 14 | // Only override drawRect: if you perform custom drawing. 15 | // An empty implementation adversely affects performance during animation. 16 | - (void)drawRect:(CGRect)rect { 17 | // Drawing code 18 | } 19 | */ 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Obfuscation-Objective-C File.xctemplate/UIViewSwift/___FILEBASENAME___.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | import UIKit 10 | 11 | class ___FILEBASENAMEASIDENTIFIER___: ___VARIABLE_cocoaTouchSubclass___ { 12 | 13 | /* 14 | // Only override draw() if you perform custom drawing. 15 | // An empty implementation adversely affects performance during animation. 16 | override func draw(_ rect: CGRect) { 17 | // Drawing code 18 | } 19 | */ 20 | 21 | } 22 | -------------------------------------------------------------------------------- /Products/iOS/obfuse-code: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CUITCHE/code-obfuscation/3cf075422e4e3748424ff6f90606f7f7f7ab2f2d/Products/iOS/obfuse-code -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # code-obfuscation 2 | 3 | [![Build Status](https://travis-ci.org/CUITCHE/code-obfuscation.svg?branch=master)](https://travis-ci.org/CUITCHE/code-obfuscation) 4 | 5 | A code obfuscation tool for iOS. 6 | 7 | Because I turned to Swift, the code-obfuscation won't be updated any more. And I am coding [Swift Obfuscator](https://github.com/CUITCHE/swiftObfuscator) that based on [Swift Syntax and Structured Editing Library](https://github.com/apple/swift/tree/master/lib/Syntax). 8 | 9 | # Pre-setting 10 | 11 | - Copy the directory [Obfuscation-Objective-C File.xctemplate](Obfuscation-Objective-C%20File.xctemplate) to `/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/File Templates/Source`, like below order: 12 | 13 | ```sh 14 | sudo cp -r Obfuscation-Objective-C\ File.xctemplate/ /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/File\ Templates/Source 15 | ``` 16 | 17 | Now, you can create obfuscation files in your projects. You might try to create them in your project, and then you will get 3 files. 18 | 19 | - Copy the file [CO-Features.h](CodeObfuscation/CodeObfuscation/TemplateFiles/CO-Features.h) to your project if you need the blow macro **Features**. 20 | 21 | # How to Use 22 | 23 | Execute the order `./CodeObfuscation-release` or `./CodeObfuscation-debug` at your root path of your project. 24 | 25 | > Also set the shell script at you Xcode project to exectue it. Also see **Features**. 26 | 27 | You could copy the program [obfuse-code](Products/iOS/obfuse-code) for iOS platform. 28 | 29 | # Obfuscation Syntax 30 | 31 | - Add macro **`CO_CONFUSION_CLASS`** after keyword **`@interface`** and before classname. It tags the class is added to obfuscation task. e.g. 32 | 33 | ```objective-c 34 | @interface CO_CONFUSION_CLASS COTemplateFile : NSObject 35 | @end 36 | ``` 37 | 38 | - Also modify the category by **`CO_CONFUSION_CATEGORY`**. And the macro **`CO_CONFUSION_CATEGORY`** must be before category-name at bracket e.g. 39 | 40 | ```objective-c 41 | @interface NSString (CO_CONFUSION_CATEGORY abcde) 42 | @end 43 | ``` 44 | 45 | - Add macro **`CO_CONFUSION_PROPERTY`** before a property-name declared. It tags the property is added to obfuscation task. e.g. 46 | 47 | ```objective-c 48 | @interface CO_CONFUSION_CLASS COTemplateFile : NSObject 49 | 50 | @property (nonatomic, strong) NSString * CO_CONFUSION_PROPERTY prop1; 51 | @property CGFloat CO_CONFUSION_PROPERTY prop2; 52 | 53 | @end 54 | ``` 55 | 56 | - Add macro **`CO_CONFUSION_METHOD`** before a method head of declare or implementation. It tags the method is added to obfuscation task. e.g. 57 | 58 | ```objective-c 59 | // .h 60 | @interface CO_CONFUSION_CLASS COTemplateFile : NSObject 61 | 62 | CO_CONFUSION_METHOD 63 | - (void)makeFoo:(NSString *)foo1 arg2:(NSInteger)arg2; 64 | 65 | CO_CONFUSION_METHOD 66 | - (instancetype)initWithArg1:(CGFloat)arg, ...; 67 | 68 | @end 69 | 70 | // .m or .mm 71 | @implementation COTemplateFile 72 | 73 | CO_CONFUSION_METHOD 74 | - (void)_private:(NSString *)arg1 method:(float)arg2 scanned:(BOOL)scanned 75 | { 76 | ; 77 | } 78 | 79 | @end 80 | ``` 81 | 82 | - Add macro **`CO_CONFUSION_PROTOCOL`** before a method head of declare or implementation. It tags the method is added to obfuscation task. e.g. 83 | 84 | ```objective-c 85 | @protocol CO_CONFUSION_PROTOCOL COProtocol 86 | 87 | @property (nonatomic, strong) id CO_CONFUSION_PROPERTY aVar; 88 | 89 | CO_CONFUSION_METHOD 90 | - (BOOL)doSome:(NSString *)task withYou:(id)you another:(id)someWho; 91 | 92 | @end 93 | ``` 94 | 95 | Property and method are same to `CO_CONFUSION_PROPERTY` and ` CO_CONFUSION_METHOD`. 96 | 97 | # Features 98 | 99 | - Support commands. (You can alse obtain these from command: -h or -help) 100 | 101 | **-id** string 102 | 103 | ​ The directory of info.plist. Default is current executed path. (default ".") 104 | 105 | **-offset** int 106 | 107 | ​ The offset of obfuscation. Default is 0. 108 | 109 | **-db** string 110 | 111 | ​ The directory of obfuscation database. Default is current executed path. (default ".") 112 | 113 | **-root** string 114 | 115 | ​ The directory of project file or what you want to start. Default is current executed path. (default ".") 116 | 117 | **-super** 118 | 119 | ​ Check the user-class' names which have been entranced obfuscation whether their super classes exist or not. If exists, will info a warning. For strict option, will check all of classes of iOS Kits. 120 | 121 | **-strict** 122 | 123 | ​ See -super. 124 | 125 | **-st** 126 | 127 | ​ Strengthen the obfuscation. Default is true. (default true) 128 | 129 | **-version** 130 | 131 | ​ Get the program supported iOS SDK version. 132 | 133 | **-q** string 134 | 135 | ​ Query the method whether exist or not. 136 | 137 | - Output `origin-name: obfuscation` map into database. Its structure like: 138 | 139 | ![database-structure](md.res/database-structure.png) 140 | 141 | Use the SQL to search real name: 142 | 143 | ```sql lite 144 | SELECT real 145 | FROM JSONModel_coh 146 | WHERE fake = 'AAAAA_$_S97Gcom_placeholder_com_s_p' 147 | AND type = 'method' 148 | -- Output: toJSONStringWithKeys 149 | ``` 150 | 151 | - Use the macro **`CO_NAME`** to obtain the class name on runtime if the class name has been obfused. The 'CO_NAME' always return correct name even If the class name has not been obfused. 152 | 153 | - Use the macro **`CO_PROPERTY_SET`** or **`CO_PROPERTY_SET_TYPE`** to help your write setter of property which is added to obfuscation task. e.g. 154 | 155 | ```objective-c 156 | // Assume there is a NSString property named fullpath at Foo class. 157 | CO_PROPERTY_SET(fullpath, Fullpath, Foo) 158 | { 159 | // Use macro _ or CO_VAR_NAME get the synthesis variable. 160 | if (![_(fullpath) isEqualToString:fullpath]) { 161 | _(fullpath) = fulpath; 162 | // TODO other things... 163 | } 164 | } 165 | 166 | // If you want not to use class name 167 | CO_PROPERTY_SET_TYPE(fullpath, Fullpath, NSString*) 168 | { 169 | // Some codes... 170 | } 171 | ``` 172 | 173 | - Use **`CO_PROPERTY_GET`** to synthesis getter method. 174 | 175 | - Use **`CO_VAR_NAME`** to obtain synthsis variable. It looks like a little long, you can use **`_`** to do if available. 176 | 177 | 178 | 179 | # Notice 180 | 181 | - `CO_CONFUSION_CLASS` and `CO_CONFUSION_CATEGORY` is a prerequisite for `CO_CONFUSION_PROPERTY` and `CO_CONFUSION_METHOD`. 182 | - **COULD NOT** use the code-obfuscation if your code contains runtime code. Unless you can control it. 183 | - **[IMPORTANT]** The obfuscator works with macro. So if a target label was obfuscated with the same name of another API and your code used it. That would cause a compile error under release model. For example, `class Foo` has a property named `length` and been obfuscated, if you invoke it and then use `NSString`'s length property in a code block with `Foo.length`. The property `length` word of `NSString` will be replaced with `Foo`'s obfuscation in release model. 184 | 185 | # License 186 | 187 | The MIT License. 188 | -------------------------------------------------------------------------------- /TemplateFiles/CO-Features.h: -------------------------------------------------------------------------------- 1 | // 2 | // CO-Features.h 3 | // CodeObfuscation 4 | // 5 | // Created by hejunqiu on 2017/7/5. 6 | // Copyright © 2017年 CHE. All rights reserved. 7 | // 8 | 9 | #ifndef CO_FEATURES_H 10 | #define CO_FEATURES_H 11 | 12 | // For make an obfuscation c-string. 13 | // Use @CO_NAME to make a NSString, such as NSClassFromNSString(@CO_NAME(CUSTOME_CLASS)), the 'CUSTOME_CLASS' might have been obfused. 14 | #ifndef CO_NAME 15 | # define ____name____(name) #name 16 | # define CO_NAME(name) ____name____(name) 17 | #endif // !CO_NAME 18 | 19 | #ifndef CO_PROPERTY_SET 20 | # define __CO_SET_TYPE__(property, Property, type) - (void)set##Property:(type)property 21 | # define __CO_SET__(property, Property, clazz) __CO_SET_TYPE__(property, Property, __typeof__(((clazz *)0).property)) 22 | # if defined(DEBUG) 23 | // For arguments: 1th is your wirtten, 2nd is a text whose first letter is captial, 3rd is a type 24 | # define CO_PROPERTY_SET(property, Property, clazz) __CO_SET__(property, Property, clazz) 25 | # define CO_PROPERTY_SET_TYPE(property, Property, type) __CO_SET_TYPE__(property, Property, type) 26 | # else 27 | // Under Release, property starts with a capital letter. 28 | # define CO_PROPERTY_SET(property, Property, clazz) __CO_SET__(property, property, clazz) 29 | # define CO_PROPERTY_SET_TYPE(property, Property, type) __CO_SET_TYPE__(property, property, type) 30 | # endif // defined(DEBUG) 31 | #endif // !CO_PROPERTY_SET 32 | 33 | #ifndef CO_PROPERTY_GET 34 | # define __CO_GET_TYPE__(property, type) - (type)property 35 | # define __CO_GET__(property, clazz) __CO_GET_TYPE__(property, __typeof__(((clazz *)0).property)) 36 | # define CO_PROPERTY_GET(property, clazz) __CO_GET__(property, clazz) 37 | # define CO_PROPERTY_GET_TYPE(property, type) __CO_GET_TYPE__(property, type) 38 | #endif // !CO_PROPERTY_GET 39 | 40 | #ifndef CO_VAR_NAME 41 | # define __CO_P_NAME__(property) _##property 42 | # define CO_VAR_NAME(property) __CO_P_NAME__(property) 43 | 44 | // convenience macro if macro `_` is not exist. 45 | # ifndef _ 46 | # define _(property) CO_VAR_NAME(property) 47 | # endif // !_ 48 | #endif // !CO_VAR_NAME 49 | 50 | #endif /* CO_FEATURES_H */ 51 | -------------------------------------------------------------------------------- /TemplateFiles/COTemplateFile.coh: -------------------------------------------------------------------------------- 1 | // 2 | // COTemplateFile.coh 3 | // CodeObfuscation 4 | // 5 | // Created by hejunqiu on 2017/5/25. 6 | // Copyright © 2017年 CHE. All rights reserved. 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [COTemplateFile.h] = f7898c440344dec4dde86e9dfc520ce6 11 | // [COTemplateFile.m] = b629878ebb9dc55a1dfd452ae770ebf9 12 | // [self] = e3b0e2e74260f82b848ff36e9e06b5f5 13 | 14 | #ifndef COTEMPLATEFILE_COH 15 | #define COTEMPLATEFILE_COH 16 | 17 | #ifndef CO_CONFUSION_PROTOCOL 18 | #define CO_CONFUSION_PROTOCOL 19 | #endif // !CO_CONFUSION_PROTOCOL 20 | 21 | #ifndef CO_CONFUSION_CLASS 22 | #define CO_CONFUSION_CLASS 23 | #endif // !CO_CONFUSION_CLASS 24 | 25 | #ifndef CO_CONFUSION_CATEGORY 26 | #define CO_CONFUSION_CATEGORY 27 | #endif // !CO_CONFUSION_CATEGORY 28 | 29 | #ifndef CO_CONFUSION_PROPERTY 30 | #define CO_CONFUSION_PROPERTY 31 | #endif // !CO_CONFUSION_PROPERTY 32 | 33 | #ifndef CO_CONFUSION_METHOD 34 | #define CO_CONFUSION_METHOD 35 | #endif // !CO_CONFUSION_METHOD 36 | 37 | #if __has_include("CO-Features.h") 38 | # include "CO-Features.h" 39 | #endif // __has_include 40 | 41 | #if !defined(DEBUG) 42 | #ifndef oxxxxo 43 | #define oxxxxo a2416470583z 44 | #endif 45 | 46 | #ifndef _pri 47 | #define _pri c2416470585z 48 | #endif 49 | 50 | #ifndef prop3 51 | #define prop3 b2416470584c 52 | #endif 53 | 54 | #ifndef arg2 55 | #define arg2 d2416470586q 56 | #endif 57 | 58 | #ifndef abcde 59 | #define abcde e2416470587W 60 | #endif 61 | 62 | #ifndef _pri 63 | #define _pri c2416470585z 64 | #endif 65 | 66 | #ifndef test 67 | #define test f2416470588y 68 | #endif 69 | 70 | #ifndef arg2 71 | #define arg2 d2416470586q 72 | #endif 73 | 74 | #ifndef method 75 | #define method p2416470598M 76 | #endif 77 | 78 | #ifndef scanned 79 | #define scanned q2416470599P 80 | #endif 81 | 82 | #ifndef makeFoo 83 | #define makeFoo l2416470594e 84 | #endif 85 | 86 | #ifndef prop1 87 | #define prop1 j2416470592e 88 | #endif 89 | 90 | #ifndef COTemplateFile 91 | #define COTemplateFile i2416470591v 92 | #endif 93 | 94 | #ifndef initWithArg1 95 | #define initWithArg1 n2416470596B 96 | #endif 97 | 98 | #ifndef arg2 99 | #define arg2 d2416470586q 100 | #endif 101 | 102 | #ifndef _private 103 | #define _private o2416470597a 104 | #endif 105 | 106 | #ifndef prop2 107 | #define prop2 k2416470593j 108 | #endif 109 | 110 | #endif 111 | 112 | #endif /* COTEMPLATEFILE_COH */ 113 | -------------------------------------------------------------------------------- /TemplateFiles/COTemplateFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // COTemplateFile.h 3 | // CodeObfuscation 4 | // 5 | // Created by hejunqiu on 2017/5/25. 6 | // Copyright © 2017年 CHE. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "COTemplateFile.coh" 11 | 12 | @protocol CO_CONFUSION_PROTOCOL COProtocol 13 | 14 | @property (nonatomic, strong) id CO_CONFUSION_PROPERTY aVar; 15 | 16 | CO_CONFUSION_METHOD 17 | - (BOOL)doSome:(NSString *)task withYou:(id)you another:(id)someWho; 18 | 19 | @end 20 | 21 | @interface CO_CONFUSION_CLASS COTemplateFile : NSObject 22 | 23 | @property (nonatomic, strong) NSString * CO_CONFUSION_PROPERTY prop1; 24 | @property CGFloat CO_CONFUSION_PROPERTY prop2; 25 | 26 | CO_CONFUSION_METHOD 27 | - (void)makeFoo:(NSString *)foo1 arg2:(NSInteger)arg2; 28 | 29 | CO_CONFUSION_METHOD 30 | - (instancetype)initWithArg1:(CGFloat)arg, ...; 31 | 32 | @end 33 | 34 | @interface COTemplateFile (CO_CONFUSION_CATEGORY oxxxxo) 35 | 36 | @property (nonatomic) CGFloat CO_CONFUSION_PROPERTY prop3; 37 | 38 | @end 39 | 40 | @interface NSString (CO_CONFUSION_CATEGORY abcde) 41 | 42 | CO_CONFUSION_METHOD 43 | - (void)test:(CGFloat)arg; 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /TemplateFiles/COTemplateFile.m: -------------------------------------------------------------------------------- 1 | // 2 | // COTemplateFile.m 3 | // CodeObfuscation 4 | // 5 | // Created by hejunqiu on 2017/5/25. 6 | // Copyright © 2017年 CHE. All rights reserved. 7 | // 8 | 9 | #import "COTemplateFile.h" 10 | 11 | @interface COTemplateFile () 12 | 13 | @end 14 | 15 | @implementation COTemplateFile 16 | 17 | - (instancetype)init 18 | { 19 | if (self = [super init]) { 20 | NSLog(@"constructor..."); 21 | } 22 | return self; 23 | } 24 | 25 | - (void)makeFoo:(NSString *)foo1 arg2:(NSInteger)arg2 26 | { 27 | ; 28 | } 29 | 30 | - (instancetype)initWithArg1:(CGFloat)arg, ... 31 | { 32 | return nil; 33 | } 34 | 35 | CO_CONFUSION_METHOD 36 | - (void)_private:(NSString *)arg1 method:(float)arg2 scanned:(BOOL)scanned 37 | { 38 | ; 39 | } 40 | 41 | - (void)_private:(NSString *)arg1 untagged:(NSUInteger)arg2 doNotBeScanned:(NSArray *)arg3 42 | { 43 | ; 44 | } 45 | 46 | #pragma mark - property 47 | CO_PROPERTY_SET(prop1, Prop1, COTemplateFile) 48 | { 49 | _(prop1) = prop1; 50 | } 51 | @end 52 | 53 | @implementation COTemplateFile (oxxxxo) 54 | 55 | CO_CONFUSION_METHOD 56 | - (void)_pri:(NSString *)arg1 arg2:(NSString *)arg2 57 | { 58 | ; 59 | } 60 | 61 | @end 62 | 63 | @implementation NSString (abcde) 64 | 65 | CO_CONFUSION_METHOD 66 | - (void)_pri:(NSString *)arg1 arg2:(NSString *)arg2 67 | { 68 | ; 69 | } 70 | 71 | - (void)test:(CGFloat)arg 72 | { 73 | ; 74 | } 75 | 76 | @end 77 | -------------------------------------------------------------------------------- /TemplateFiles/JSONModel/JSONModel.coh: -------------------------------------------------------------------------------- 1 | // 2 | // COClass.coh 3 | // CodeObfuscation 4 | // 5 | // Created by hejunqiu on 2017/7/2. 6 | // Copyright © 2017年 CHE. All rights reserved. 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef COClass_coh 13 | #define COClass_coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #endif /* COClass_coh */ 32 | -------------------------------------------------------------------------------- /TemplateFiles/JSONModel/JSONModelClassProperty.coh: -------------------------------------------------------------------------------- 1 | // 2 | // COClass.coh 3 | // CodeObfuscation 4 | // 5 | // Created by hejunqiu on 2017/7/2. 6 | // Copyright © 2017年 CHE. All rights reserved. 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef COClass_coh 13 | #define COClass_coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #endif /* COClass_coh */ 32 | -------------------------------------------------------------------------------- /TemplateFiles/JSONModel/JSONModelClassProperty.h: -------------------------------------------------------------------------------- 1 | // 2 | // JSONModelClassProperty.h 3 | // JSONModel 4 | // 5 | 6 | #import 7 | #import "JSONModelClassProperty.coh" 8 | 9 | /** 10 | * **You do not need to instantiate this class yourself.** This class is used internally by JSONModel 11 | * to inspect the declared properties of your model class. 12 | * 13 | * Class to contain the information, representing a class property 14 | * It features the property's name, type, whether it's a required property, 15 | * and (optionally) the class protocol 16 | */ 17 | @interface CO_CONFUSION_CLASS JSONModelClassProperty : NSObject 18 | 19 | // deprecated 20 | @property (assign, nonatomic) BOOL CO_CONFUSION_PROPERTY isIndex DEPRECATED_ATTRIBUTE; 21 | 22 | /** The name of the declared property (not the ivar name) */ 23 | @property (copy, nonatomic) NSString *CO_CONFUSION_PROPERTY name; 24 | 25 | /** A property class type */ 26 | @property (assign, nonatomic) Class CO_CONFUSION_PROPERTY type; 27 | 28 | /** Struct name if a struct */ 29 | @property (strong, nonatomic) NSString *CO_CONFUSION_PROPERTY structName; 30 | 31 | /** The name of the protocol the property conforms to (or nil) */ 32 | @property (copy, nonatomic) NSString *CO_CONFUSION_PROPERTY protocol; 33 | 34 | /** If YES, it can be missing in the input data, and the input would be still valid */ 35 | @property (assign, nonatomic) BOOL CO_CONFUSION_PROPERTY isOptional; 36 | 37 | /** If YES - don't call any transformers on this property's value */ 38 | @property (assign, nonatomic) BOOL CO_CONFUSION_PROPERTY isStandardJSONType; 39 | 40 | /** If YES - create a mutable object for the value of the property */ 41 | @property (assign, nonatomic) BOOL CO_CONFUSION_PROPERTY isMutable; 42 | 43 | /** a custom getter for this property, found in the owning model */ 44 | @property (assign, nonatomic) SEL CO_CONFUSION_PROPERTY customGetter; 45 | 46 | /** custom setters for this property, found in the owning model */ 47 | @property (strong, nonatomic) NSMutableDictionary *CO_CONFUSION_PROPERTY customSetters; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /TemplateFiles/JSONModel/JSONModelClassProperty.m: -------------------------------------------------------------------------------- 1 | // 2 | // JSONModelClassProperty.m 3 | // JSONModel 4 | // 5 | 6 | #import "JSONModelClassProperty.h" 7 | 8 | @implementation JSONModelClassProperty 9 | 10 | -(NSString*)description 11 | { 12 | //build the properties string for the current class property 13 | NSMutableArray* properties = [NSMutableArray arrayWithCapacity:8]; 14 | 15 | #pragma GCC diagnostic push 16 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 17 | if (self.isIndex) [properties addObject:@"Index"]; 18 | #pragma GCC diagnostic pop 19 | 20 | if (self.isOptional) [properties addObject:@"Optional"]; 21 | if (self.isMutable) [properties addObject:@"Mutable"]; 22 | if (self.isStandardJSONType) [properties addObject:@"Standard JSON type"]; 23 | if (self.customGetter) [properties addObject:[NSString stringWithFormat: @"Getter = %@", NSStringFromSelector(self.customGetter)]]; 24 | 25 | if (self.customSetters) 26 | { 27 | NSMutableArray *setters = [NSMutableArray array]; 28 | 29 | for (id obj in self.customSetters.allValues) 30 | { 31 | SEL selector; 32 | [obj getValue:&selector]; 33 | [setters addObject:NSStringFromSelector(selector)]; 34 | } 35 | 36 | [properties addObject:[NSString stringWithFormat: @"Setters = [%@]", [setters componentsJoinedByString:@", "]]]; 37 | } 38 | 39 | NSString* propertiesString = @""; 40 | if (properties.count>0) { 41 | propertiesString = [NSString stringWithFormat:@"(%@)", [properties componentsJoinedByString:@", "]]; 42 | } 43 | 44 | //return the name, type and additional properties 45 | return [NSString stringWithFormat:@"@property %@%@ %@ %@", 46 | self.type?[NSString stringWithFormat:@"%@*",self.type]:(self.structName?self.structName:@"primitive"), 47 | self.protocol?[NSString stringWithFormat:@"<%@>", self.protocol]:@"", 48 | self.name, 49 | propertiesString 50 | ]; 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /TemplateFiles/JSONModel/JSONModelError.coh: -------------------------------------------------------------------------------- 1 | // 2 | // COClass.coh 3 | // CodeObfuscation 4 | // 5 | // Created by hejunqiu on 2017/7/2. 6 | // Copyright © 2017年 CHE. All rights reserved. 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef COClass_coh 13 | #define COClass_coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #endif /* COClass_coh */ 32 | -------------------------------------------------------------------------------- /TemplateFiles/JSONModel/JSONModelError.h: -------------------------------------------------------------------------------- 1 | // 2 | // JSONModelError.h 3 | // JSONModel 4 | // 5 | 6 | #import 7 | #import "JSONModelError.coh" 8 | 9 | ///////////////////////////////////////////////////////////////////////////////////////////// 10 | typedef NS_ENUM(int, kJSONModelErrorTypes) 11 | { 12 | kJSONModelErrorInvalidData = 1, 13 | kJSONModelErrorBadResponse = 2, 14 | kJSONModelErrorBadJSON = 3, 15 | kJSONModelErrorModelIsInvalid = 4, 16 | kJSONModelErrorNilInput = 5 17 | }; 18 | 19 | ///////////////////////////////////////////////////////////////////////////////////////////// 20 | /** The domain name used for the JSONModelError instances */ 21 | extern NSString *const JSONModelErrorDomain; 22 | 23 | /** 24 | * If the model JSON input misses keys that are required, check the 25 | * userInfo dictionary of the JSONModelError instance you get back - 26 | * under the kJSONModelMissingKeys key you will find a list of the 27 | * names of the missing keys. 28 | */ 29 | extern NSString *const kJSONModelMissingKeys; 30 | 31 | /** 32 | * If JSON input has a different type than expected by the model, check the 33 | * userInfo dictionary of the JSONModelError instance you get back - 34 | * under the kJSONModelTypeMismatch key you will find a description 35 | * of the mismatched types. 36 | */ 37 | extern NSString *const kJSONModelTypeMismatch; 38 | 39 | /** 40 | * If an error occurs in a nested model, check the userInfo dictionary of 41 | * the JSONModelError instance you get back - under the kJSONModelKeyPath 42 | * key you will find key-path at which the error occurred. 43 | */ 44 | extern NSString *const kJSONModelKeyPath; 45 | 46 | ///////////////////////////////////////////////////////////////////////////////////////////// 47 | /** 48 | * Custom NSError subclass with shortcut methods for creating 49 | * the common JSONModel errors 50 | */ 51 | @interface CO_CONFUSION_CLASS JSONModelError : NSError 52 | 53 | @property (strong, nonatomic) NSHTTPURLResponse *CO_CONFUSION_PROPERTY httpResponse; 54 | 55 | @property (strong, nonatomic) NSData *CO_CONFUSION_PROPERTY responseData; 56 | 57 | /** 58 | * Creates a JSONModelError instance with code kJSONModelErrorInvalidData = 1 59 | */ 60 | CO_CONFUSION_METHOD+ (id)errorInvalidDataWithMessage:(NSString *)message; 61 | 62 | /** 63 | * Creates a JSONModelError instance with code kJSONModelErrorInvalidData = 1 64 | * @param keys a set of field names that were required, but not found in the input 65 | */ 66 | CO_CONFUSION_METHOD+ (id)errorInvalidDataWithMissingKeys:(NSSet *)keys; 67 | 68 | /** 69 | * Creates a JSONModelError instance with code kJSONModelErrorInvalidData = 1 70 | * @param mismatchDescription description of the type mismatch that was encountered. 71 | */ 72 | CO_CONFUSION_METHOD+ (id)errorInvalidDataWithTypeMismatch:(NSString *)mismatchDescription; 73 | 74 | /** 75 | * Creates a JSONModelError instance with code kJSONModelErrorBadResponse = 2 76 | */ 77 | CO_CONFUSION_METHOD+ (id)errorBadResponse; 78 | 79 | /** 80 | * Creates a JSONModelError instance with code kJSONModelErrorBadJSON = 3 81 | */ 82 | CO_CONFUSION_METHOD+ (id)errorBadJSON; 83 | 84 | /** 85 | * Creates a JSONModelError instance with code kJSONModelErrorModelIsInvalid = 4 86 | */ 87 | CO_CONFUSION_METHOD+ (id)errorModelIsInvalid; 88 | 89 | /** 90 | * Creates a JSONModelError instance with code kJSONModelErrorNilInput = 5 91 | */ 92 | CO_CONFUSION_METHOD+ (id)errorInputIsNil; 93 | 94 | /** 95 | * Creates a new JSONModelError with the same values plus information about the key-path of the error. 96 | * Properties in the new error object are the same as those from the receiver, 97 | * except that a new key kJSONModelKeyPath is added to the userInfo dictionary. 98 | * This key contains the component string parameter. If the key is already present 99 | * then the new error object has the component string prepended to the existing value. 100 | */ 101 | CO_CONFUSION_METHOD- (instancetype)errorByPrependingKeyPathComponent:(NSString *)component; 102 | 103 | ///////////////////////////////////////////////////////////////////////////////////////////// 104 | @end 105 | -------------------------------------------------------------------------------- /TemplateFiles/JSONModel/JSONModelError.m: -------------------------------------------------------------------------------- 1 | // 2 | // JSONModelError.m 3 | // JSONModel 4 | // 5 | 6 | #import "JSONModelError.h" 7 | 8 | NSString* const JSONModelErrorDomain = @"JSONModelErrorDomain"; 9 | NSString* const kJSONModelMissingKeys = @"kJSONModelMissingKeys"; 10 | NSString* const kJSONModelTypeMismatch = @"kJSONModelTypeMismatch"; 11 | NSString* const kJSONModelKeyPath = @"kJSONModelKeyPath"; 12 | 13 | @implementation JSONModelError 14 | 15 | +(id)errorInvalidDataWithMessage:(NSString*)message 16 | { 17 | message = [NSString stringWithFormat:@"Invalid JSON data: %@", message]; 18 | return [JSONModelError errorWithDomain:JSONModelErrorDomain 19 | code:kJSONModelErrorInvalidData 20 | userInfo:@{NSLocalizedDescriptionKey:message}]; 21 | } 22 | 23 | +(id)errorInvalidDataWithMissingKeys:(NSSet *)keys 24 | { 25 | return [JSONModelError errorWithDomain:JSONModelErrorDomain 26 | code:kJSONModelErrorInvalidData 27 | userInfo:@{NSLocalizedDescriptionKey:@"Invalid JSON data. Required JSON keys are missing from the input. Check the error user information.",kJSONModelMissingKeys:[keys allObjects]}]; 28 | } 29 | 30 | +(id)errorInvalidDataWithTypeMismatch:(NSString*)mismatchDescription 31 | { 32 | return [JSONModelError errorWithDomain:JSONModelErrorDomain 33 | code:kJSONModelErrorInvalidData 34 | userInfo:@{NSLocalizedDescriptionKey:@"Invalid JSON data. The JSON type mismatches the expected type. Check the error user information.",kJSONModelTypeMismatch:mismatchDescription}]; 35 | } 36 | 37 | +(id)errorBadResponse 38 | { 39 | return [JSONModelError errorWithDomain:JSONModelErrorDomain 40 | code:kJSONModelErrorBadResponse 41 | userInfo:@{NSLocalizedDescriptionKey:@"Bad network response. Probably the JSON URL is unreachable."}]; 42 | } 43 | 44 | +(id)errorBadJSON 45 | { 46 | return [JSONModelError errorWithDomain:JSONModelErrorDomain 47 | code:kJSONModelErrorBadJSON 48 | userInfo:@{NSLocalizedDescriptionKey:@"Malformed JSON. Check the JSONModel data input."}]; 49 | } 50 | 51 | +(id)errorModelIsInvalid 52 | { 53 | return [JSONModelError errorWithDomain:JSONModelErrorDomain 54 | code:kJSONModelErrorModelIsInvalid 55 | userInfo:@{NSLocalizedDescriptionKey:@"Model does not validate. The custom validation for the input data failed."}]; 56 | } 57 | 58 | +(id)errorInputIsNil 59 | { 60 | return [JSONModelError errorWithDomain:JSONModelErrorDomain 61 | code:kJSONModelErrorNilInput 62 | userInfo:@{NSLocalizedDescriptionKey:@"Initializing model with nil input object."}]; 63 | } 64 | 65 | - (instancetype)errorByPrependingKeyPathComponent:(NSString*)component 66 | { 67 | // Create a mutable copy of the user info so that we can add to it and update it 68 | NSMutableDictionary* userInfo = [self.userInfo mutableCopy]; 69 | 70 | // Create or update the key-path 71 | NSString* existingPath = userInfo[kJSONModelKeyPath]; 72 | NSString* separator = [existingPath hasPrefix:@"["] ? @"" : @"."; 73 | NSString* updatedPath = (existingPath == nil) ? component : [component stringByAppendingFormat:@"%@%@", separator, existingPath]; 74 | userInfo[kJSONModelKeyPath] = updatedPath; 75 | 76 | // Create the new error 77 | return [JSONModelError errorWithDomain:self.domain 78 | code:self.code 79 | userInfo:[NSDictionary dictionaryWithDictionary:userInfo]]; 80 | } 81 | 82 | @end 83 | -------------------------------------------------------------------------------- /TemplateFiles/JSONModelTransformations/JSONKeyMapper.coh: -------------------------------------------------------------------------------- 1 | // 2 | // COClass.coh 3 | // CodeObfuscation 4 | // 5 | // Created by hejunqiu on 2017/7/2. 6 | // Copyright © 2017年 CHE. All rights reserved. 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef COClass_coh 13 | #define COClass_coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #endif /* COClass_coh */ 32 | -------------------------------------------------------------------------------- /TemplateFiles/JSONModelTransformations/JSONKeyMapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // JSONKeyMapper.h 3 | // JSONModel 4 | // 5 | 6 | #import 7 | #import "JSONKeyMapper.coh" 8 | 9 | typedef NSString *(^JSONModelKeyMapBlock)(NSString *keyName); 10 | 11 | /** 12 | * **You won't need to create or store instances of this class yourself.** If you want your model 13 | * to have different property names than the JSON feed keys, look below on how to 14 | * make your model use a key mapper. 15 | * 16 | * For example if you consume JSON from twitter 17 | * you get back underscore_case style key names. For example: 18 | * 19 | *
"profile_sidebar_border_color": "0094C2",
20 |  * "profile_background_tile": false,
21 | * 22 | * To comply with Obj-C accepted camelCase property naming for your classes, 23 | * you need to provide mapping between JSON keys and ObjC property names. 24 | * 25 | * In your model overwrite the + (JSONKeyMapper *)keyMapper method and provide a JSONKeyMapper 26 | * instance to convert the key names for your model. 27 | * 28 | * If you need custom mapping it's as easy as: 29 | *
30 |  * + (JSONKeyMapper *)keyMapper {
31 |  *   return [[JSONKeyMapper alloc] initWithDictionary:@{@"crazy_JSON_name":@"myCamelCaseName"}];
32 |  * }
33 |  * 
34 | * In case you want to handle underscore_case, **use the predefined key mapper**, like so: 35 | *
36 |  * + (JSONKeyMapper *)keyMapper {
37 |  *   return [JSONKeyMapper mapperFromUnderscoreCaseToCamelCase];
38 |  * }
39 |  * 
40 | */ 41 | @interface JSONKeyMapper : NSObject 42 | 43 | // deprecated 44 | @property (readonly, nonatomic) JSONModelKeyMapBlock JSONToModelKeyBlock DEPRECATED_ATTRIBUTE; 45 | - (NSString *)convertValue:(NSString *)value isImportingToModel:(BOOL)importing DEPRECATED_MSG_ATTRIBUTE("use convertValue:"); 46 | - (instancetype)initWithDictionary:(NSDictionary *)map DEPRECATED_MSG_ATTRIBUTE("use initWithModelToJSONDictionary:"); 47 | - (instancetype)initWithJSONToModelBlock:(JSONModelKeyMapBlock)toModel modelToJSONBlock:(JSONModelKeyMapBlock)toJSON DEPRECATED_MSG_ATTRIBUTE("use initWithModelToJSONBlock:"); 48 | + (instancetype)mapper:(JSONKeyMapper *)baseKeyMapper withExceptions:(NSDictionary *)exceptions DEPRECATED_MSG_ATTRIBUTE("use baseMapper:withModelToJSONExceptions:"); 49 | + (instancetype)mapperFromUnderscoreCaseToCamelCase DEPRECATED_MSG_ATTRIBUTE("use mapperForSnakeCase:"); 50 | + (instancetype)mapperFromUpperCaseToLowerCase DEPRECATED_ATTRIBUTE; 51 | 52 | /** @name Name converters */ 53 | /** Block, which takes in a property name and converts it to the corresponding JSON key name */ 54 | @property (readonly, nonatomic) JSONModelKeyMapBlock modelToJSONKeyBlock; 55 | 56 | /** Combined converter method 57 | * @param value the source name 58 | * @return JSONKeyMapper instance 59 | */ 60 | - (NSString *)convertValue:(NSString *)value; 61 | 62 | /** @name Creating a key mapper */ 63 | 64 | /** 65 | * Creates a JSONKeyMapper instance, based on the block you provide this initializer. 66 | * The parameter takes in a JSONModelKeyMapBlock block: 67 | *
NSString *(^JSONModelKeyMapBlock)(NSString *keyName)
68 | * The block takes in a string and returns the transformed (if at all) string. 69 | * @param toJSON transforms your model property name to a JSON key 70 | */ 71 | - (instancetype)initWithModelToJSONBlock:(JSONModelKeyMapBlock)toJSON; 72 | 73 | /** 74 | * Creates a JSONKeyMapper instance, based on the mapping you provide. 75 | * Use your JSONModel property names as keys, and the JSON key names as values. 76 | * @param toJSON map dictionary, in the format:
@{@"myCamelCaseName":@"crazy_JSON_name"}
77 | * @return JSONKeyMapper instance 78 | */ 79 | - (instancetype)initWithModelToJSONDictionary:(NSDictionary *)toJSON; 80 | 81 | /** 82 | * Given a camelCase model property, this mapper finds JSON keys using the snake_case equivalent. 83 | */ 84 | + (instancetype)mapperForSnakeCase; 85 | 86 | /** 87 | * Given a camelCase model property, this mapper finds JSON keys using the TitleCase equivalent. 88 | */ 89 | + (instancetype)mapperForTitleCase; 90 | 91 | /** 92 | * Creates a JSONKeyMapper based on a built-in JSONKeyMapper, with specific exceptions. 93 | * Use your JSONModel property names as keys, and the JSON key names as values. 94 | */ 95 | + (instancetype)baseMapper:(JSONKeyMapper *)baseKeyMapper withModelToJSONExceptions:(NSDictionary *)toJSON; 96 | 97 | @end 98 | -------------------------------------------------------------------------------- /TemplateFiles/JSONModelTransformations/JSONKeyMapper.m: -------------------------------------------------------------------------------- 1 | // 2 | // JSONKeyMapper.m 3 | // JSONModel 4 | // 5 | 6 | #import "JSONKeyMapper.h" 7 | 8 | @implementation JSONKeyMapper 9 | 10 | - (instancetype)initWithJSONToModelBlock:(JSONModelKeyMapBlock)toModel modelToJSONBlock:(JSONModelKeyMapBlock)toJSON 11 | { 12 | return [self initWithModelToJSONBlock:toJSON]; 13 | } 14 | 15 | - (instancetype)initWithModelToJSONBlock:(JSONModelKeyMapBlock)toJSON 16 | { 17 | if (!(self = [self init])) 18 | return nil; 19 | 20 | _modelToJSONKeyBlock = toJSON; 21 | 22 | return self; 23 | } 24 | 25 | - (instancetype)initWithDictionary:(NSDictionary *)map 26 | { 27 | NSDictionary *toJSON = [JSONKeyMapper swapKeysAndValuesInDictionary:map]; 28 | 29 | return [self initWithModelToJSONDictionary:toJSON]; 30 | } 31 | 32 | - (instancetype)initWithModelToJSONDictionary:(NSDictionary *)toJSON 33 | { 34 | if (!(self = [super init])) 35 | return nil; 36 | 37 | _modelToJSONKeyBlock = ^NSString *(NSString *keyName) 38 | { 39 | return [toJSON valueForKeyPath:keyName] ?: keyName; 40 | }; 41 | 42 | return self; 43 | } 44 | 45 | - (JSONModelKeyMapBlock)JSONToModelKeyBlock 46 | { 47 | return nil; 48 | } 49 | 50 | + (NSDictionary *)swapKeysAndValuesInDictionary:(NSDictionary *)dictionary 51 | { 52 | NSArray *keys = dictionary.allKeys; 53 | NSArray *values = [dictionary objectsForKeys:keys notFoundMarker:[NSNull null]]; 54 | 55 | return [NSDictionary dictionaryWithObjects:keys forKeys:values]; 56 | } 57 | 58 | - (NSString *)convertValue:(NSString *)value isImportingToModel:(BOOL)importing 59 | { 60 | return [self convertValue:value]; 61 | } 62 | 63 | - (NSString *)convertValue:(NSString *)value 64 | { 65 | return _modelToJSONKeyBlock(value); 66 | } 67 | 68 | + (instancetype)mapperFromUnderscoreCaseToCamelCase 69 | { 70 | return [self mapperForSnakeCase]; 71 | } 72 | 73 | + (instancetype)mapperForSnakeCase 74 | { 75 | return [[self alloc] initWithModelToJSONBlock:^NSString *(NSString *keyName) 76 | { 77 | NSMutableString *result = [NSMutableString stringWithString:keyName]; 78 | NSRange range; 79 | 80 | // handle upper case chars 81 | range = [result rangeOfCharacterFromSet:[NSCharacterSet uppercaseLetterCharacterSet]]; 82 | while (range.location != NSNotFound) 83 | { 84 | NSString *lower = [result substringWithRange:range].lowercaseString; 85 | [result replaceCharactersInRange:range withString:[NSString stringWithFormat:@"_%@", lower]]; 86 | range = [result rangeOfCharacterFromSet:[NSCharacterSet uppercaseLetterCharacterSet]]; 87 | } 88 | 89 | // handle numbers 90 | range = [result rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]]; 91 | while (range.location != NSNotFound) 92 | { 93 | NSRange end = [result rangeOfString:@"\\D" options:NSRegularExpressionSearch range:NSMakeRange(range.location, result.length - range.location)]; 94 | 95 | // spans to the end of the key name 96 | if (end.location == NSNotFound) 97 | end = NSMakeRange(result.length, 1); 98 | 99 | NSRange replaceRange = NSMakeRange(range.location, end.location - range.location); 100 | NSString *digits = [result substringWithRange:replaceRange]; 101 | [result replaceCharactersInRange:replaceRange withString:[NSString stringWithFormat:@"_%@", digits]]; 102 | range = [result rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet] options:0 range:NSMakeRange(end.location + 1, result.length - end.location - 1)]; 103 | } 104 | 105 | return result; 106 | }]; 107 | } 108 | 109 | + (instancetype)mapperForTitleCase 110 | { 111 | return [[self alloc] initWithModelToJSONBlock:^NSString *(NSString *keyName) 112 | { 113 | return [keyName stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[keyName substringToIndex:1].uppercaseString]; 114 | }]; 115 | } 116 | 117 | + (instancetype)mapperFromUpperCaseToLowerCase 118 | { 119 | return [[self alloc] initWithModelToJSONBlock:^NSString *(NSString *keyName) 120 | { 121 | return keyName.uppercaseString; 122 | }]; 123 | } 124 | 125 | + (instancetype)mapper:(JSONKeyMapper *)baseKeyMapper withExceptions:(NSDictionary *)exceptions 126 | { 127 | NSDictionary *toJSON = [JSONKeyMapper swapKeysAndValuesInDictionary:exceptions]; 128 | 129 | return [self baseMapper:baseKeyMapper withModelToJSONExceptions:toJSON]; 130 | } 131 | 132 | + (instancetype)baseMapper:(JSONKeyMapper *)baseKeyMapper withModelToJSONExceptions:(NSDictionary *)toJSON 133 | { 134 | return [[self alloc] initWithModelToJSONBlock:^NSString *(NSString *keyName) 135 | { 136 | if (!keyName) 137 | return nil; 138 | 139 | if (toJSON[keyName]) 140 | return toJSON[keyName]; 141 | 142 | return baseKeyMapper.modelToJSONKeyBlock(keyName); 143 | }]; 144 | } 145 | 146 | @end 147 | -------------------------------------------------------------------------------- /TemplateFiles/JSONModelTransformations/JSONValueTransformer.coh: -------------------------------------------------------------------------------- 1 | // 2 | // COClass.coh 3 | // CodeObfuscation 4 | // 5 | // Created by hejunqiu on 2017/7/2. 6 | // Copyright © 2017年 CHE. All rights reserved. 7 | // 8 | 9 | // DO NOT TRY TO MODIFY THIS FILE! 10 | // [self] = self 11 | 12 | #ifndef COClass_coh 13 | #define COClass_coh 14 | 15 | #ifndef CO_CONFUSION_CLASS 16 | #define CO_CONFUSION_CLASS 17 | #endif 18 | 19 | #ifndef CO_CONFUSION_CATEGORY 20 | #define CO_CONFUSION_CATEGORY 21 | #endif 22 | 23 | #ifndef CO_CONFUSION_PROPERTY 24 | #define CO_CONFUSION_PROPERTY 25 | #endif 26 | 27 | #ifndef CO_CONFUSION_METHOD 28 | #define CO_CONFUSION_METHOD 29 | #endif 30 | 31 | #endif /* COClass_coh */ 32 | -------------------------------------------------------------------------------- /TemplateFiles/JSONModelTransformations/JSONValueTransformer.h: -------------------------------------------------------------------------------- 1 | // 2 | // JSONValueTransformer.h 3 | // JSONModel 4 | // 5 | 6 | #import 7 | #import "JSONValueTransformer.coh" 8 | 9 | ///////////////////////////////////////////////////////////////////////////////////////////// 10 | 11 | #pragma mark - extern definitions 12 | /** 13 | * Boolean function to check for null values. Handy when you need to both check 14 | * for nil and [NSNUll null] 15 | */ 16 | extern BOOL isNull(id value); 17 | 18 | ///////////////////////////////////////////////////////////////////////////////////////////// 19 | 20 | #pragma mark - JSONValueTransformer interface 21 | /** 22 | * **You don't need to call methods of this class manually.** 23 | * 24 | * Class providing methods to transform values from one class to another. 25 | * You are given a number of built-in transformers, but you are encouraged to 26 | * extend this class with your own categories to add further value transformers. 27 | * Just few examples of what can you add to JSONValueTransformer: hex colors in JSON to UIColor, 28 | * hex numbers in JSON to NSNumber model properties, base64 encoded strings in JSON to UIImage properties, and more. 29 | * 30 | * The class is invoked by JSONModel while transforming incoming 31 | * JSON types into your target class property classes, and vice versa. 32 | * One static copy is create and store in the JSONModel class scope. 33 | */ 34 | @interface JSONValueTransformer : NSObject 35 | 36 | @property (strong, nonatomic, readonly) NSDictionary *primitivesNames; 37 | 38 | /** @name Resolving cluster class names */ 39 | /** 40 | * This method returns the umbrella class for any standard class cluster members. 41 | * For example returns NSString when given as input NSString, NSMutableString, __CFString and __CFConstantString 42 | * The method currently looksup a pre-defined list. 43 | * @param sourceClass the class to get the umbrella class for 44 | * @return Class 45 | */ 46 | + (Class)classByResolvingClusterClasses:(Class)sourceClass; 47 | 48 | #pragma mark - NSMutableString <-> NSString 49 | /** @name Transforming to Mutable copies */ 50 | /** 51 | * Transforms a string value to a mutable string value 52 | * @param string incoming string 53 | * @return mutable string 54 | */ 55 | - (NSMutableString *)NSMutableStringFromNSString:(NSString *)string; 56 | 57 | #pragma mark - NSMutableArray <-> NSArray 58 | /** 59 | * Transforms an array to a mutable array 60 | * @param array incoming array 61 | * @return mutable array 62 | */ 63 | - (NSMutableArray *)NSMutableArrayFromNSArray:(NSArray *)array; 64 | 65 | #pragma mark - NSMutableDictionary <-> NSDictionary 66 | /** 67 | * Transforms a dictionary to a mutable dictionary 68 | * @param dict incoming dictionary 69 | * @return mutable dictionary 70 | */ 71 | - (NSMutableDictionary *)NSMutableDictionaryFromNSDictionary:(NSDictionary *)dict; 72 | 73 | #pragma mark - NSSet <-> NSArray 74 | /** @name Transforming Sets */ 75 | /** 76 | * Transforms an array to a set 77 | * @param array incoming array 78 | * @return set with the array's elements 79 | */ 80 | - (NSSet *)NSSetFromNSArray:(NSArray *)array; 81 | 82 | /** 83 | * Transforms an array to a mutable set 84 | * @param array incoming array 85 | * @return mutable set with the array's elements 86 | */ 87 | - (NSMutableSet *)NSMutableSetFromNSArray:(NSArray *)array; 88 | 89 | /** 90 | * Transforms a set to an array 91 | * @param set incoming set 92 | * @return an array with the set's elements 93 | */ 94 | - (NSArray *)JSONObjectFromNSSet:(NSSet *)set; 95 | 96 | /** 97 | * Transforms a mutable set to an array 98 | * @param set incoming mutable set 99 | * @return an array with the set's elements 100 | */ 101 | - (NSArray *)JSONObjectFromNSMutableSet:(NSMutableSet *)set; 102 | 103 | #pragma mark - BOOL <-> number/string 104 | /** @name Transforming JSON types */ 105 | /** 106 | * Transforms a number object to a bool number object 107 | * @param number the number to convert 108 | * @return the resulting number 109 | */ 110 | - (NSNumber *)BOOLFromNSNumber:(NSNumber *)number; 111 | 112 | /** 113 | * Transforms a number object to a bool number object 114 | * @param string the string value to convert, "0" converts to NO, everything else to YES 115 | * @return the resulting number 116 | */ 117 | - (NSNumber *)BOOLFromNSString:(NSString *)string; 118 | 119 | /** 120 | * Transforms a BOOL value to a bool number object 121 | * @param number an NSNumber value coming from the model 122 | * @return the result number 123 | */ 124 | - (NSNumber *)JSONObjectFromBOOL:(NSNumber *)number; 125 | 126 | #pragma mark - string <-> number 127 | /** 128 | * Transforms a string object to a number object 129 | * @param string the string to convert 130 | * @return the resulting number 131 | */ 132 | - (NSNumber *)NSNumberFromNSString:(NSString *)string; 133 | 134 | /** 135 | * Transforms a number object to a string object 136 | * @param number the number to convert 137 | * @return the resulting string 138 | */ 139 | - (NSString *)NSStringFromNSNumber:(NSNumber *)number; 140 | 141 | /** 142 | * Transforms a string object to a nsdecimalnumber object 143 | * @param string the string to convert 144 | * @return the resulting number 145 | */ 146 | - (NSDecimalNumber *)NSDecimalNumberFromNSString:(NSString *)string; 147 | 148 | /** 149 | * Transforms a nsdecimalnumber object to a string object 150 | * @param number the number to convert 151 | * @return the resulting string 152 | */ 153 | - (NSString *)NSStringFromNSDecimalNumber:(NSDecimalNumber *)number; 154 | 155 | 156 | #pragma mark - string <-> url 157 | /** @name Transforming URLs */ 158 | /** 159 | * Transforms a string object to an NSURL object 160 | * @param string the string to convert 161 | * @return the resulting url object 162 | */ 163 | - (NSURL *)NSURLFromNSString:(NSString *)string; 164 | 165 | /** 166 | * Transforms an NSURL object to a string 167 | * @param url the url object to convert 168 | * @return the resulting string 169 | */ 170 | - (NSString *)JSONObjectFromNSURL:(NSURL *)url; 171 | 172 | #pragma mark - string <-> time zone 173 | 174 | /** @name Transforming NSTimeZone */ 175 | /** 176 | * Transforms a string object to an NSTimeZone object 177 | * @param string the string to convert 178 | * @return the resulting NSTimeZone object 179 | */ 180 | - (NSTimeZone *)NSTimeZoneFromNSString:(NSString *)string; 181 | 182 | /** 183 | * Transforms an NSTimeZone object to a string 184 | * @param timeZone the time zone object to convert 185 | * @return the resulting string 186 | */ 187 | - (NSString *)JSONObjectFromNSTimeZone:(NSTimeZone *)timeZone; 188 | 189 | #pragma mark - string <-> date 190 | /** @name Transforming Dates */ 191 | /** 192 | * The following two methods are not public. This way if there is a category on converting 193 | * dates it'll override them. If there isn't a category the default methods found in the .m 194 | * file will be invoked. If these are public a warning is produced at the point of overriding 195 | * them in a category, so they have to stay hidden here. 196 | */ 197 | 198 | //- (NSDate *)NSDateFromNSString:(NSString *)string; 199 | //- (NSString *)JSONObjectFromNSDate:(NSDate *)date; 200 | 201 | #pragma mark - number <-> date 202 | 203 | /** 204 | * Transforms a number to an NSDate object 205 | * @param number the number to convert 206 | * @return the resulting date 207 | */ 208 | - (NSDate *)NSDateFromNSNumber:(NSNumber *)number; 209 | 210 | @end 211 | -------------------------------------------------------------------------------- /TemplateFiles/JSONModelTransformations/JSONValueTransformer.m: -------------------------------------------------------------------------------- 1 | // 2 | // JSONValueTransformer.m 3 | // JSONModel 4 | // 5 | 6 | #import "JSONValueTransformer.h" 7 | 8 | #pragma mark - functions 9 | extern BOOL isNull(id value) 10 | { 11 | if (!value) return YES; 12 | if ([value isKindOfClass:[NSNull class]]) return YES; 13 | 14 | return NO; 15 | } 16 | 17 | @implementation JSONValueTransformer 18 | 19 | -(id)init 20 | { 21 | self = [super init]; 22 | if (self) { 23 | _primitivesNames = @{@"f":@"float", @"i":@"int", @"d":@"double", @"l":@"long", @"B":@"BOOL", @"s":@"short", 24 | @"I":@"unsigned int", @"L":@"usigned long", @"q":@"long long", @"Q":@"unsigned long long", @"S":@"unsigned short", @"c":@"char", @"C":@"unsigned char", 25 | //and some famous aliases of primitive types 26 | // BOOL is now "B" on iOS __LP64 builds 27 | @"I":@"NSInteger", @"Q":@"NSUInteger", @"B":@"BOOL", 28 | 29 | @"@?":@"Block"}; 30 | } 31 | return self; 32 | } 33 | 34 | +(Class)classByResolvingClusterClasses:(Class)sourceClass 35 | { 36 | //check for all variations of strings 37 | if ([sourceClass isSubclassOfClass:[NSString class]]) { 38 | return [NSString class]; 39 | } 40 | 41 | //check for all variations of numbers 42 | if ([sourceClass isSubclassOfClass:[NSNumber class]]) { 43 | return [NSNumber class]; 44 | } 45 | 46 | //check for all variations of dictionaries 47 | if ([sourceClass isSubclassOfClass:[NSArray class]]) { 48 | return [NSArray class]; 49 | } 50 | 51 | //check for all variations of arrays 52 | if ([sourceClass isSubclassOfClass:[NSDictionary class]]) { 53 | return [NSDictionary class]; 54 | } 55 | 56 | //check for all variations of dates 57 | if ([sourceClass isSubclassOfClass:[NSDate class]]) { 58 | return [NSDate class]; 59 | } 60 | 61 | //no cluster parent class found 62 | return sourceClass; 63 | } 64 | 65 | #pragma mark - NSMutableString <-> NSString 66 | -(NSMutableString*)NSMutableStringFromNSString:(NSString*)string 67 | { 68 | return [NSMutableString stringWithString:string]; 69 | } 70 | 71 | #pragma mark - NSMutableArray <-> NSArray 72 | -(NSMutableArray*)NSMutableArrayFromNSArray:(NSArray*)array 73 | { 74 | return [NSMutableArray arrayWithArray:array]; 75 | } 76 | 77 | #pragma mark - NSMutableDictionary <-> NSDictionary 78 | -(NSMutableDictionary*)NSMutableDictionaryFromNSDictionary:(NSDictionary*)dict 79 | { 80 | return [NSMutableDictionary dictionaryWithDictionary:dict]; 81 | } 82 | 83 | #pragma mark - NSSet <-> NSArray 84 | -(NSSet*)NSSetFromNSArray:(NSArray*)array 85 | { 86 | return [NSSet setWithArray:array]; 87 | } 88 | 89 | -(NSMutableSet*)NSMutableSetFromNSArray:(NSArray*)array 90 | { 91 | return [NSMutableSet setWithArray:array]; 92 | } 93 | 94 | -(id)JSONObjectFromNSSet:(NSSet*)set 95 | { 96 | return [set allObjects]; 97 | } 98 | 99 | -(id)JSONObjectFromNSMutableSet:(NSMutableSet*)set 100 | { 101 | return [set allObjects]; 102 | } 103 | 104 | // 105 | // 0 converts to NO, everything else converts to YES 106 | // 107 | 108 | #pragma mark - BOOL <-> number/string 109 | -(NSNumber*)BOOLFromNSNumber:(NSNumber*)number 110 | { 111 | if (isNull(number)) return [NSNumber numberWithBool:NO]; 112 | return [NSNumber numberWithBool: number.intValue==0?NO:YES]; 113 | } 114 | 115 | -(NSNumber*)BOOLFromNSString:(NSString*)string 116 | { 117 | if (string != nil && 118 | ([string caseInsensitiveCompare:@"true"] == NSOrderedSame || 119 | [string caseInsensitiveCompare:@"yes"] == NSOrderedSame)) { 120 | return [NSNumber numberWithBool:YES]; 121 | } 122 | return [NSNumber numberWithBool: ([string intValue]==0)?NO:YES]; 123 | } 124 | 125 | -(NSNumber*)JSONObjectFromBOOL:(NSNumber*)number 126 | { 127 | return [NSNumber numberWithBool: number.intValue==0?NO:YES]; 128 | } 129 | 130 | #pragma mark - string/number <-> float 131 | -(float)floatFromObject:(id)obj 132 | { 133 | return [obj floatValue]; 134 | } 135 | 136 | -(float)floatFromNSString:(NSString*)string 137 | { 138 | return [self floatFromObject:string]; 139 | } 140 | 141 | -(float)floatFromNSNumber:(NSNumber*)number 142 | { 143 | return [self floatFromObject:number]; 144 | } 145 | 146 | -(NSNumber*)NSNumberFromfloat:(float)f 147 | { 148 | return [NSNumber numberWithFloat:f]; 149 | } 150 | 151 | #pragma mark - string <-> number 152 | -(NSNumber*)NSNumberFromNSString:(NSString*)string 153 | { 154 | return [NSNumber numberWithDouble:[string doubleValue]]; 155 | } 156 | 157 | -(NSString*)NSStringFromNSNumber:(NSNumber*)number 158 | { 159 | return [number stringValue]; 160 | } 161 | 162 | -(NSDecimalNumber*)NSDecimalNumberFromNSString:(NSString*)string 163 | { 164 | return [NSDecimalNumber decimalNumberWithString:string]; 165 | } 166 | 167 | -(NSString*)NSStringFromNSDecimalNumber:(NSDecimalNumber*)number 168 | { 169 | return [number stringValue]; 170 | } 171 | 172 | #pragma mark - string <-> url 173 | -(NSURL*)NSURLFromNSString:(NSString*)string 174 | { 175 | // do not change this behavior - there are other ways of overriding it 176 | // see: https://github.com/jsonmodel/jsonmodel/pull/119 177 | return [NSURL URLWithString:string]; 178 | } 179 | 180 | -(NSString*)JSONObjectFromNSURL:(NSURL*)url 181 | { 182 | return [url absoluteString]; 183 | } 184 | 185 | #pragma mark - string <-> date 186 | -(NSDateFormatter*)importDateFormatter 187 | { 188 | static dispatch_once_t onceInput; 189 | static NSDateFormatter* inputDateFormatter; 190 | dispatch_once(&onceInput, ^{ 191 | inputDateFormatter = [[NSDateFormatter alloc] init]; 192 | [inputDateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]]; 193 | [inputDateFormatter setDateFormat:@"yyyy-MM-dd'T'HHmmssZZZ"]; 194 | }); 195 | return inputDateFormatter; 196 | } 197 | 198 | -(NSDate*)__NSDateFromNSString:(NSString*)string 199 | { 200 | string = [string stringByReplacingOccurrencesOfString:@":" withString:@""]; // this is such an ugly code, is this the only way? 201 | return [self.importDateFormatter dateFromString: string]; 202 | } 203 | 204 | -(NSString*)__JSONObjectFromNSDate:(NSDate*)date 205 | { 206 | static dispatch_once_t onceOutput; 207 | static NSDateFormatter *outputDateFormatter; 208 | dispatch_once(&onceOutput, ^{ 209 | outputDateFormatter = [[NSDateFormatter alloc] init]; 210 | [outputDateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]]; 211 | [outputDateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZ"]; 212 | }); 213 | return [outputDateFormatter stringFromDate:date]; 214 | } 215 | 216 | #pragma mark - number <-> date 217 | - (NSDate*)NSDateFromNSNumber:(NSNumber*)number 218 | { 219 | return [NSDate dateWithTimeIntervalSince1970:number.doubleValue]; 220 | } 221 | 222 | #pragma mark - string <-> NSTimeZone 223 | 224 | - (NSTimeZone *)NSTimeZoneFromNSString:(NSString *)string { 225 | return [NSTimeZone timeZoneWithName:string]; 226 | } 227 | 228 | - (id)JSONObjectFromNSTimeZone:(NSTimeZone *)timeZone { 229 | return [timeZone name]; 230 | } 231 | 232 | #pragma mark - hidden transform for empty dictionaries 233 | //https://github.com/jsonmodel/jsonmodel/issues/163 234 | -(NSDictionary*)__NSDictionaryFromNSArray:(NSArray*)array 235 | { 236 | if (array.count==0) return @{}; 237 | return (id)array; 238 | } 239 | 240 | -(NSMutableDictionary*)__NSMutableDictionaryFromNSArray:(NSArray*)array 241 | { 242 | if (array.count==0) return [[self __NSDictionaryFromNSArray:array] mutableCopy]; 243 | return (id)array; 244 | } 245 | 246 | @end 247 | -------------------------------------------------------------------------------- /md.res/database-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CUITCHE/code-obfuscation/3cf075422e4e3748424ff6f90606f7f7f7ab2f2d/md.res/database-structure.png -------------------------------------------------------------------------------- /obfuse-code/obfuse-code.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /obfuse-code/obfuse-code/Arguments.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Arguments.swift 3 | // CodeObfuscation 4 | // 5 | // Created by hejunqiu on 2017/7/12. 6 | // Copyright © 2017年 CHE. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | fileprivate struct __Arguments { 12 | let id = flag.String(name: "id", defValue: ".", usage: "The directory of info.plist. Default is current executed path.") 13 | let offset = flag.Integer(name: "offset", defValue: 0, usage: "The offset of obfuscation. Default is 0.") 14 | let db = flag.String(name: "db", defValue: ".", usage: "The directory of obfuscation database. Default is current executed path.") 15 | let root = flag.String(name: "root", defValue: ".", usage: "The directory of project file or what you want to start. Default is current executed path.") 16 | let `super` = flag.Bool(name: "super", defValue: false, usage: "Check the user-class' names which have been entranced obfuscation whether their super classes exist or not. If exists, will info a warning. For strict option, will check all of classes of iOS Kits.") 17 | let strict = flag.Bool(name: "strict", defValue: false, usage: "See -super.") 18 | let st = flag.Bool(name: "st", defValue: true, usage: "Strengthen the obfuscation. Default is true.") 19 | let version = flag.Bool(name: "version", defValue: false, usage: "Get the program supported iOS SDK version.") 20 | let query = flag.String(name: "q", defValue: "", usage: "Query the method whether exist or not.") 21 | } 22 | 23 | public struct Arguments { 24 | fileprivate let __arguments = __Arguments.init() 25 | public var infoPlistFilepath: NSString { return __arguments.id.pointee } 26 | public var obfuscationOffset: sint64 { return __arguments.offset.pointee } 27 | public var dbFilepath: NSString { return __arguments.db.pointee } 28 | public var rootpath : NSString { return __arguments.root.pointee } 29 | 30 | public var supercheck: Bool { return __arguments.`super`.pointee } 31 | public var strict: Bool { return __arguments.strict.pointee } 32 | public var st: Bool { return __arguments.st.pointee } 33 | 34 | public var executedPath: String { return flag.executedPath } 35 | 36 | public private(set) var identifier: String = "" 37 | 38 | public private(set) var appVersion: String = "" 39 | 40 | public init() { 41 | if flag.parsed() == false { 42 | flag.parse() 43 | } 44 | identifier = { 45 | if let infoBundle = Bundle.init(path: __arguments.id.pointee as String), let path = infoBundle.path(forResource: "info", ofType: "plist"), let dict = NSDictionary.init(contentsOfFile: path) { 46 | if let id = dict[kCFBundleIdentifierKey as Any] as? String { 47 | return id.replacingOccurrences(of: ".", with: "_").replacingOccurrences(of: "-", with: "_") 48 | } 49 | } 50 | return "com_placeholder_co" 51 | }() 52 | 53 | appVersion = { 54 | if let infoBundle = Bundle.init(path: __arguments.id.pointee as String), let path = infoBundle.path(forResource: "info", ofType: "plist"), let dict = NSDictionary.init(contentsOfFile: path) { 55 | if let ver = dict[kCFBundleVersionKey as Any] as? String { 56 | return ver.replacingOccurrences(of: ".", with: "_").replacingOccurrences(of: "-", with: "_") 57 | } 58 | } 59 | return "m_s_p" 60 | }() 61 | 62 | if __arguments.version.pointee { 63 | Arguments.printVersion() 64 | } 65 | if __arguments.query.pointee != "" { 66 | Arguments.query(with: __arguments.query.pointee as String) 67 | } 68 | } 69 | 70 | public static let arguments = Arguments.init() 71 | } 72 | 73 | fileprivate extension Arguments { 74 | static func printVersion() { 75 | printc.println(text: CacheImage.versionString) 76 | exit(0) 77 | } 78 | 79 | static func query(with statement: String) { 80 | let cache = CacheImage.init() 81 | var similarClass = [String]() 82 | var similarMethods = Set.init() 83 | 84 | printc.console.IORedirector = stdout 85 | printc.println(text: "🍺 searching...", marks: .yellow) 86 | var arrayMutex = pthread_mutex_t.init() 87 | var setMutext = pthread_mutex_t.init() 88 | pthread_mutex_init(&arrayMutex, nil) 89 | pthread_mutex_init(&setMutext, nil) 90 | cache.enumerateCache { (classname, methods, progress) -> Bool in 91 | if classname.contains(statement) { 92 | pthread_mutex_lock(&arrayMutex) 93 | similarClass.append(classname.replacingOccurrences(of: statement, with: printc.write(statement, .bold, .red).takeAssembleBuffer())) 94 | pthread_mutex_unlock(&arrayMutex) 95 | } 96 | for m in methods { 97 | if m.method.contains(statement) { 98 | pthread_mutex_lock(&setMutext) 99 | similarMethods.insert(m.method.replacingOccurrences(of: statement, with: printc.write(statement, .bold, .red).takeAssembleBuffer())) 100 | pthread_mutex_unlock(&setMutext) 101 | } 102 | } 103 | printc.console.drawProgressBar(with: progress, drawInMultiThread: true) 104 | if progress == 100 { 105 | printc.console.isHideCursor = false 106 | printc.println(text: "") 107 | if similarClass.count > 0 { 108 | similarClass.sort(by: <) 109 | printc.println(text: "Found similar class: ", marks: .bold) 110 | printc.println(text: "\(similarClass.joined(separator: "\n"))\n") 111 | } else { 112 | printc().write("Class: No such ").write("'\(statement)' ", .bold).writeln(" Found.") 113 | } 114 | if similarMethods.count > 0 { 115 | printc.println(text: "Found similar method: ", marks: .bold) 116 | var methods = similarMethods.sorted(by: <) 117 | if let idx = methods.index(where: { return $0 == statement }) { 118 | methods.remove(at: idx) 119 | printc.println(text: statement, marks: .underline) 120 | } 121 | printc.println(text: "\(methods.joined(separator: "\n"))\n") 122 | } else { 123 | printc().write("Method: No such ").write("'\(statement)' ", .bold).writeln(" Found.") 124 | } 125 | pthread_mutex_destroy(&arrayMutex) 126 | pthread_mutex_destroy(&setMutext) 127 | exit(0) 128 | } 129 | return false 130 | } 131 | RunLoop.main.run() 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /obfuse-code/obfuse-code/FileOutStream.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FileOutStream.swift 3 | // CodeObfuscation 4 | // 5 | // Created by hejunqiu on 2017/8/15. 6 | // Copyright © 2017年 CHE. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | fileprivate extension String { 12 | static func encrypt_md5(content: String) -> String { 13 | return ("\(content)\(content.characters.count)" as NSString).md5 14 | } 15 | 16 | static func md5_for_self(content: String) -> String? { 17 | let text = content as NSString 18 | var range = text.range(of: "[self] = ") 19 | if range.location == NSNotFound { 20 | return nil 21 | } 22 | range.location = NSMaxRange(range) 23 | range.length = 32 24 | let `self` = text.replacingCharacters(in: range, with: "") 25 | return (`self` as NSString).md5 26 | } 27 | 28 | static let obfusedmd5 = "fileold" // [String: String] 29 | static let obfusemd5 = "files" // String 30 | static let selfmd5 = "self" // String 31 | } 32 | 33 | struct FileOutStream { 34 | var needGenerateObfuscationCode: Bool { return gen != nil } 35 | 36 | fileprivate var headerFilename = "" 37 | fileprivate var selfLocation = 0 38 | 39 | fileprivate let filepath: String 40 | fileprivate let originalFileContent: String 41 | fileprivate var attributed = [String: Any]() 42 | fileprivate var gen: String? = nil 43 | 44 | fileprivate static let fmtter: DateFormatter = { 45 | let fmtter = DateFormatter.init() 46 | fmtter.dateFormat = "yyyy/MM/dd" 47 | return fmtter 48 | }() 49 | 50 | init?(filepath: String) { 51 | do { 52 | let content = try String.init(contentsOfFile: filepath) 53 | originalFileContent = content 54 | self.filepath = filepath 55 | } catch { 56 | print(error) 57 | return nil 58 | } 59 | } 60 | 61 | mutating func read() { 62 | if attributed.count > 0 { 63 | return 64 | } 65 | var cohFileSearchEndIndex = 0 66 | var scanner = Scanner.init(string: originalFileContent) 67 | if scanner.scanUpTo("[self] =", into: nil) { 68 | cohFileSearchEndIndex = scanner.scanLocation 69 | scanner.scanString("[self] =", into: nil) 70 | var selfmd5: NSString? = nil 71 | scanner.scanUpToCharacters(from: .whitespaces, into: &selfmd5) 72 | if let selfmd5 = selfmd5 { 73 | let curCOHMd5 = String.md5_for_self(content: originalFileContent) 74 | self.attributed[.selfmd5] = curCOHMd5 ?? "" 75 | // coh文件校验 76 | if selfmd5.isEqual(to: curCOHMd5 ?? "") == false { 77 | gen = "" 78 | } 79 | } else { 80 | gen = "" 81 | } 82 | } 83 | // 扫描关联文件的md5值 84 | scanner = Scanner.init(string: originalFileContent.substring(to: originalFileContent.index(originalFileContent.startIndex, offsetBy: cohFileSearchEndIndex))) 85 | var oldmd5 = [String: String]() 86 | while scanner.scanUpTo("[", into: nil) { 87 | scanner.scanString("[", into: nil); 88 | var filename: NSString? = nil 89 | scanner.scanUpTo("]", into: &filename) 90 | 91 | scanner.scanUpTo("= ", into: nil) 92 | scanner.scanString("= ", into: nil) 93 | 94 | var md5: NSString? = nil 95 | scanner.scanUpToCharacters(from: .whitespacesAndNewlines, into: &md5) 96 | if let filename = filename, let md5 = md5 { 97 | if filename.isEqual(to: .selfmd5) { 98 | oldmd5[filename as String] = md5 as String 99 | } 100 | } 101 | } 102 | self.attributed[.obfusedmd5] = oldmd5 103 | } 104 | 105 | mutating func worth(parsing file: String, filename: String) -> Bool { 106 | let md5 = String.encrypt_md5(content: file) 107 | var md5s = self.attributed[.obfusemd5] as? [String: String] 108 | if md5s == nil { 109 | md5s = [String: String]() 110 | } 111 | md5s![filename] = md5 112 | self.attributed[.obfusemd5] = md5s! 113 | if md5 == (self.attributed[.obfusemd5] as! [String: String])[filename] { 114 | // FIXME: 由于当前设计缺陷,暂且决策每次都需要重新生成混淆数据 115 | return true 116 | } 117 | if gen == nil { 118 | gen = "" 119 | } 120 | return true 121 | } 122 | 123 | mutating func begin() { 124 | assert(gen != nil, "Logic error, you need not to generate code") 125 | assert(originalFileContent.characters.count != 0, "No original data") 126 | 127 | // 写头部注释 128 | let headerfilename = (self.filepath as NSString).lastPathComponent 129 | gen!.append("//\n// \(headerfilename)\n") 130 | gen!.append("// Code-Obfuscation Auto Generator\n\n") 131 | gen!.append("// Created by \((Arguments.arguments.executedPath as NSString).lastPathComponent) on \(FileOutStream.fmtter.string(from: Date.init())).\n") 132 | gen!.append("// Copyright © 2102 year \((Arguments.arguments.executedPath as NSString).lastPathComponent). All rights reserved.\n\n") 133 | 134 | gen!.append("// DO NOT TRY TO MODIFY THIS FILE!\n") 135 | let md5s = self.attributed[.obfusemd5] 136 | if let md5s = md5s { 137 | for (key, value) in md5s as! [String: String] { 138 | gen!.append("// [\(key)] = \(value)\n") 139 | } 140 | } 141 | gen!.append("// [self] = ") 142 | self.selfLocation = gen!.characters.count 143 | self.headerFilename = headerfilename.replacingOccurrences(of: ".coh", with: "_coh").uppercased() 144 | 145 | // 写头文件header 宏 146 | gen!.append("#ifndef \(self.headerFilename)\n") 147 | gen!.append("#define \(self.headerFilename)\n\n") 148 | 149 | // 生成COF的必用宏 150 | _write(macro: "CO_CONFUSION_CLASS") 151 | _write(macro: "CO_CONFUSION_CATEGORY") 152 | _write(macro: "CO_CONFUSION_PROPERTY") 153 | _write(macro: "CO_CONFUSION_METHOD") 154 | _write(macro: "CO_CONFUSION_PROTOCOL") 155 | 156 | // 尝试包含features头文件 157 | gen!.append("#if __has_include(\"CO-Features.h\")\n") 158 | gen!.append("# include \"CO-Features.h\"\n") 159 | gen!.append("#endif // __has_include\n\n") 160 | 161 | // debug下才生效 162 | gen!.append("#if !defined(DEBUG)\n") 163 | } 164 | 165 | mutating func write(obfuscation code: [String: String]) { 166 | assert(gen != nil, "Logic error, you need not to generate code") 167 | for (key, value) in code { 168 | _write(fake: value, realText: key) 169 | } 170 | } 171 | 172 | mutating func end() { 173 | assert(gen != nil, "Logic error, you need not to generate code") 174 | gen!.append("#endif\n\n") 175 | gen!.append("#endif /* \(self.headerFilename) */") 176 | 177 | let md5 = String.encrypt_md5(content: gen!) 178 | let text = NSMutableString.init(string: gen!) 179 | text.insert("\(md5)\n\n", at: selfLocation) 180 | var oldAttribute = try! FileManager.default.attributesOfItem(atPath: filepath) 181 | oldAttribute[.immutable] = false 182 | try! FileManager.default.setAttributes(oldAttribute, ofItemAtPath: filepath) 183 | do { 184 | try text.write(toFile: filepath, atomically: true, encoding: String.Encoding.utf8.rawValue) 185 | } catch { 186 | print(error) 187 | } 188 | oldAttribute[.immutable] = true 189 | try! FileManager.default.setAttributes(oldAttribute, ofItemAtPath: filepath) 190 | } 191 | } 192 | 193 | fileprivate extension FileOutStream { 194 | mutating func _write(fake text: String, realText: String) { 195 | gen!.append("#ifndef \(realText)\n") 196 | gen!.append("#define \(realText) \(text)\n") 197 | gen!.append("#endif\n\n") 198 | } 199 | 200 | mutating func _write(macro: String) { 201 | gen!.append("#ifndef \(macro)\n") 202 | gen!.append("# define \(macro)\n") 203 | gen!.append("#endif // !\(macro)\n\n") 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /obfuse-code/obfuse-code/ObfuscationDatabase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ObfuscationDatabase.swift 3 | // obfuse-code 4 | // 5 | // Created by hejunqiu on 2017/8/28. 6 | // Copyright © 2017年 hejunqiu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public protocol AbstractDatabaseCreation { 12 | var creationSql: Array { get } 13 | } 14 | 15 | open class AbstractDatabase: AbstractDatabaseCreation { 16 | public var creationSql: Array { return [] } 17 | 18 | public let db: FMDatabase 19 | public let databsePath: String 20 | 21 | init?(filepath: String) { 22 | guard type(of: self) != AbstractDatabase.self else { 23 | return nil 24 | } 25 | let fm = FileManager.default 26 | if fm.fileExists(atPath: filepath) == false { 27 | do { 28 | try fm.createDirectory(atPath: (filepath as NSString).deletingLastPathComponent, withIntermediateDirectories: true, attributes: nil) 29 | } catch { 30 | print(error) 31 | return nil 32 | } 33 | guard fm.createFile(atPath: filepath, contents: nil, attributes: nil) else { 34 | printc.println(text: "Create db file failed!", marks: .red) 35 | return nil 36 | } 37 | } 38 | databsePath = filepath 39 | db = FMDatabase.init(path: filepath) 40 | guard db.open() else { 41 | printc.println(text: db.lastErrorMessage(), marks: .red) 42 | return nil 43 | } 44 | for sql in self.creationSql { 45 | guard db.executeStatements(sql) else { 46 | printc.println(text: "Create sql failed.", marks: .red) 47 | return nil 48 | } 49 | } 50 | printc.println(text: "Create db at \(filepath)") 51 | } 52 | } 53 | 54 | class ObfuscationDatabase: AbstractDatabase { 55 | enum ObfuscationType { 56 | case `class`, category, property, method, `protocol` 57 | } 58 | let bundleIdentifier: String 59 | let appVersion: String 60 | 61 | init?(filepath: String, bundleIdentifier: String, appVersion: String) { 62 | self.bundleIdentifier = bundleIdentifier 63 | self.appVersion = appVersion 64 | super.init(filepath: (((filepath as NSString).appendingPathComponent(bundleIdentifier) as NSString).appendingPathComponent(appVersion) as NSString).appendingPathComponent("\(Date()).db")) 65 | } 66 | } 67 | 68 | extension ObfuscationDatabase { 69 | func insert(filename: String, real: String, fake: String, type: ObfuscationType, location: String = "") { 70 | if self._createTable(with: filename) { 71 | self._insert(to: filename, with: (real, fake, location), type: "\(type)") 72 | } 73 | } 74 | 75 | fileprivate func _createTable(with tableName: String) -> Bool { 76 | let sql = "CREATE TABLE IF NOT EXISTS \(tableName)(real Text NOT NULL,fake Varchar(4096) NOT NULL,location Text NOT NULL,type Text NOT NULL);" 77 | guard db.executeStatements(sql) else { 78 | printc.println(text: db.lastErrorMessage(), marks: .yellow) 79 | return false 80 | } 81 | return true 82 | } 83 | 84 | @discardableResult 85 | fileprivate func _insert(to table: String, with obfuscation: (real: String, fake: String, location: String), type: String) -> Bool { 86 | let sql = "INSERT INTO \(table)(real, fake, location, type) VALUES(?,?,?,?);" 87 | guard db.executeUpdate(sql, withArgumentsIn: [obfuscation.real, obfuscation.fake, obfuscation.location, type]) else { 88 | printc.println(text: db.lastErrorMessage(), marks: .yellow) 89 | return false 90 | } 91 | return true 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /obfuse-code/obfuse-code/Objective-C/BuildSql/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | Copyright (c) 2017 hejunqiu 3 | 4 | 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 the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 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. 9 | -------------------------------------------------------------------------------- /obfuse-code/obfuse-code/Objective-C/BuildSql/README.md: -------------------------------------------------------------------------------- 1 | # buildSQL 2 | 基于C++和Objective-C的buildSQL,可以用代码语言来build一条SQL语句。 3 | # 简介 4 | 某天,我写了很多SQL语句,实在受不了了,就有了buildSQL。在有代码提示的情况下,写起来会更爽,阅读这样的SQL语句也更清晰明了。 5 | # 如何使用 6 | 将`BuildSql.h`和`BuildSql.mm`包含进你的工程,并在包含`BuildSql.h`的文件的后缀名改为`mm`即可。 7 | 具体用法: 8 | ```Objective-C 9 | // 不用把BuildSql对象建立在堆上,栈变量的点语法有助于阅读。 10 | BuildSql sqlBuilder; // 另外一个构造函数是BuildSql(@"@"),传入的参数起到placeholder作用 11 | // select 12 | sqlBuilder.select(@"field0", @"field1", @"field2").from(@"table").where(@"id").equalTo(@(1)).And(@"type").lessThan(@(9)).end(); 13 | // sames to 'SELECT field0, field1, field2 FROM table WHERE id=1 AND type<9;' 14 | 15 | // insert into 16 | sqlBuilder.insertInto(@"table").field(@"field0", @"field1", @"field2", @"field3").values(); 17 | // sames to 'INSERT INTO table(field0, field1, field2, field3) VALUES(?,?,?,?);' 18 | 19 | // update 20 | sqlBuilder.update(@"table").fieldPh(@"field0", @"field1", @"field2", @"field3").where(@"name").equalTo(@"buildSql").end(); 21 | // sames to 'UPDATE table SET field0=?, field1=?, field2=?, field3=? WHERE name='buildSql';' 22 | 23 | // delete 24 | sqlBuilder.Delete(@"table").where(@"id").greaterThan(@1001).Or(@"id").lessThanOrEqualtTo(@2001); 25 | // sames to 'DELETE FROM table WHERE id>1001 OR id<=2001' 26 | 27 | // order by 28 | sqlBuilder.select(@"field0", @"field1", @"field2").from(@"table").where(@"id").equalTo(@(1)).And(@"type").lessThan(@(9)).orderBy(@"field0").end(); 29 | // sames to 'SELECT field0, field1, field2 FROM table WHERE id=1 AND type<9 ORDER BY field0;' 30 | 31 | // create table 32 | sqlBuilder.create(@"table"). 33 | column(@"id", SqlTypeInteger).primaryKey(). 34 | column(@"name", SqlTypeVarchar, bs_max(200)).nonull(). 35 | column(@"number", SqlTypeDecimal, bs_precision(20, 8)).nonull().end(); // 这儿的end()调用是必须的 36 | // sames to 'CREATE TABLE IF NOT EXISTS table(id Integer PRIMARY KEY,name Varchar(200) NOT NULL,number Decimal(20,8) NOT NULL);' 37 | ``` 38 | 更多的用法,请参考我编写的[测试用例](/buildSQLTest/buildSQLTest.mm)。 39 | 40 | BuildSql可以被多次使用,只需要在使用前调用`reset()`就可以恢复到初始状态。 41 | # 使用要求 42 | * Only support [C]. 由于使用了Objective-C的`NSString`,所以暂时只支持[C],以后会考虑改成纯C++的构建。 43 | * 你需要知道必要的SQL语法,请参考[SQL 教程](http://www.w3school.com.cn/sql/) 44 | 45 | # 注意 46 | * buildSql基本上不会去检查语法错误! 47 | * buildSql只会简单提示一些可能会影响到sql build时的小错误。 48 | 49 | # 未实现 50 | * 「drop」、「alter」 51 | * 有的组合代码需要合并优化 52 | 53 | # 其它 54 | 欢迎各位对此感兴趣的社区同仁共同维护buildSQL。欢迎大家提bug issue。 55 | -------------------------------------------------------------------------------- /obfuse-code/obfuse-code/Objective-C/FMDB/LICENSE.txt: -------------------------------------------------------------------------------- 1 | If you are using FMDB in your project, I'd love to hear about it. Let Gus know 2 | by sending an email to gus@flyingmeat.com. 3 | 4 | And if you happen to come across either Gus Mueller or Rob Ryan in a bar, you 5 | might consider purchasing a drink of their choosing if FMDB has been useful to 6 | you. 7 | 8 | Finally, and shortly, this is the MIT License. 9 | 10 | Copyright (c) 2008-2014 Flying Meat Inc. 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in 20 | all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | THE SOFTWARE. -------------------------------------------------------------------------------- /obfuse-code/obfuse-code/Objective-C/FMDB/src/fmdb/FMDB.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | FOUNDATION_EXPORT double FMDBVersionNumber; 4 | FOUNDATION_EXPORT const unsigned char FMDBVersionString[]; 5 | 6 | #import "FMDatabase.h" 7 | #import "FMResultSet.h" 8 | #import "FMDatabaseAdditions.h" 9 | #import "FMDatabaseQueue.h" 10 | #import "FMDatabasePool.h" 11 | -------------------------------------------------------------------------------- /obfuse-code/obfuse-code/Objective-C/FMDB/src/fmdb/FMDatabaseAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabaseAdditions.h 3 | // fmdb 4 | // 5 | // Created by August Mueller on 10/30/05. 6 | // Copyright 2005 Flying Meat Inc.. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FMDatabase.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | /** Category of additions for `` class. 15 | 16 | ### See also 17 | 18 | - `` 19 | */ 20 | 21 | @interface FMDatabase (FMDatabaseAdditions) 22 | 23 | ///---------------------------------------- 24 | /// @name Return results of SQL to variable 25 | ///---------------------------------------- 26 | 27 | /** Return `int` value for query 28 | 29 | @param query The SQL query to be performed. 30 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 31 | 32 | @return `int` value. 33 | 34 | @note This is not available from Swift. 35 | */ 36 | 37 | - (int)intForQuery:(NSString*)query, ...; 38 | 39 | /** Return `long` value for query 40 | 41 | @param query The SQL query to be performed. 42 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 43 | 44 | @return `long` value. 45 | 46 | @note This is not available from Swift. 47 | */ 48 | 49 | - (long)longForQuery:(NSString*)query, ...; 50 | 51 | /** Return `BOOL` value for query 52 | 53 | @param query The SQL query to be performed. 54 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 55 | 56 | @return `BOOL` value. 57 | 58 | @note This is not available from Swift. 59 | */ 60 | 61 | - (BOOL)boolForQuery:(NSString*)query, ...; 62 | 63 | /** Return `double` value for query 64 | 65 | @param query The SQL query to be performed. 66 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 67 | 68 | @return `double` value. 69 | 70 | @note This is not available from Swift. 71 | */ 72 | 73 | - (double)doubleForQuery:(NSString*)query, ...; 74 | 75 | /** Return `NSString` value for query 76 | 77 | @param query The SQL query to be performed. 78 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 79 | 80 | @return `NSString` value. 81 | 82 | @note This is not available from Swift. 83 | */ 84 | 85 | - (NSString * _Nullable)stringForQuery:(NSString*)query, ...; 86 | 87 | /** Return `NSData` value for query 88 | 89 | @param query The SQL query to be performed. 90 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 91 | 92 | @return `NSData` value. 93 | 94 | @note This is not available from Swift. 95 | */ 96 | 97 | - (NSData * _Nullable)dataForQuery:(NSString*)query, ...; 98 | 99 | /** Return `NSDate` value for query 100 | 101 | @param query The SQL query to be performed. 102 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 103 | 104 | @return `NSDate` value. 105 | 106 | @note This is not available from Swift. 107 | */ 108 | 109 | - (NSDate * _Nullable)dateForQuery:(NSString*)query, ...; 110 | 111 | 112 | // Notice that there's no dataNoCopyForQuery:. 113 | // That would be a bad idea, because we close out the result set, and then what 114 | // happens to the data that we just didn't copy? Who knows, not I. 115 | 116 | 117 | ///-------------------------------- 118 | /// @name Schema related operations 119 | ///-------------------------------- 120 | 121 | /** Does table exist in database? 122 | 123 | @param tableName The name of the table being looked for. 124 | 125 | @return `YES` if table found; `NO` if not found. 126 | */ 127 | 128 | - (BOOL)tableExists:(NSString*)tableName; 129 | 130 | /** The schema of the database. 131 | 132 | This will be the schema for the entire database. For each entity, each row of the result set will include the following fields: 133 | 134 | - `type` - The type of entity (e.g. table, index, view, or trigger) 135 | - `name` - The name of the object 136 | - `tbl_name` - The name of the table to which the object references 137 | - `rootpage` - The page number of the root b-tree page for tables and indices 138 | - `sql` - The SQL that created the entity 139 | 140 | @return `FMResultSet` of schema; `nil` on error. 141 | 142 | @see [SQLite File Format](http://www.sqlite.org/fileformat.html) 143 | */ 144 | 145 | - (FMResultSet *)getSchema; 146 | 147 | /** The schema of the database. 148 | 149 | This will be the schema for a particular table as report by SQLite `PRAGMA`, for example: 150 | 151 | PRAGMA table_info('employees') 152 | 153 | This will report: 154 | 155 | - `cid` - The column ID number 156 | - `name` - The name of the column 157 | - `type` - The data type specified for the column 158 | - `notnull` - whether the field is defined as NOT NULL (i.e. values required) 159 | - `dflt_value` - The default value for the column 160 | - `pk` - Whether the field is part of the primary key of the table 161 | 162 | @param tableName The name of the table for whom the schema will be returned. 163 | 164 | @return `FMResultSet` of schema; `nil` on error. 165 | 166 | @see [table_info](http://www.sqlite.org/pragma.html#pragma_table_info) 167 | */ 168 | 169 | - (FMResultSet*)getTableSchema:(NSString*)tableName; 170 | 171 | /** Test to see if particular column exists for particular table in database 172 | 173 | @param columnName The name of the column. 174 | 175 | @param tableName The name of the table. 176 | 177 | @return `YES` if column exists in table in question; `NO` otherwise. 178 | */ 179 | 180 | - (BOOL)columnExists:(NSString*)columnName inTableWithName:(NSString*)tableName; 181 | 182 | /** Test to see if particular column exists for particular table in database 183 | 184 | @param columnName The name of the column. 185 | 186 | @param tableName The name of the table. 187 | 188 | @return `YES` if column exists in table in question; `NO` otherwise. 189 | 190 | @see columnExists:inTableWithName: 191 | 192 | @warning Deprecated - use `` instead. 193 | */ 194 | 195 | - (BOOL)columnExists:(NSString*)tableName columnName:(NSString*)columnName __deprecated_msg("Use columnExists:inTableWithName: instead"); 196 | 197 | 198 | /** Validate SQL statement 199 | 200 | This validates SQL statement by performing `sqlite3_prepare_v2`, but not returning the results, but instead immediately calling `sqlite3_finalize`. 201 | 202 | @param sql The SQL statement being validated. 203 | 204 | @param error This is a pointer to a `NSError` object that will receive the autoreleased `NSError` object if there was any error. If this is `nil`, no `NSError` result will be returned. 205 | 206 | @return `YES` if validation succeeded without incident; `NO` otherwise. 207 | 208 | */ 209 | 210 | - (BOOL)validateSQL:(NSString*)sql error:(NSError * _Nullable *)error; 211 | 212 | 213 | ///----------------------------------- 214 | /// @name Application identifier tasks 215 | ///----------------------------------- 216 | 217 | /** Retrieve application ID 218 | 219 | @return The `uint32_t` numeric value of the application ID. 220 | 221 | @see setApplicationID: 222 | */ 223 | 224 | @property (nonatomic) uint32_t applicationID; 225 | 226 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE 227 | 228 | /** Retrieve application ID string 229 | 230 | @see setApplicationIDString: 231 | */ 232 | 233 | @property (nonatomic, retain) NSString *applicationIDString; 234 | 235 | #endif 236 | 237 | ///----------------------------------- 238 | /// @name user version identifier tasks 239 | ///----------------------------------- 240 | 241 | /** Retrieve user version 242 | 243 | @see setUserVersion: 244 | */ 245 | 246 | @property (nonatomic) uint32_t userVersion; 247 | 248 | @end 249 | 250 | NS_ASSUME_NONNULL_END 251 | -------------------------------------------------------------------------------- /obfuse-code/obfuse-code/Objective-C/FMDB/src/fmdb/FMDatabaseAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabaseAdditions.m 3 | // fmdb 4 | // 5 | // Created by August Mueller on 10/30/05. 6 | // Copyright 2005 Flying Meat Inc.. All rights reserved. 7 | // 8 | 9 | #import "FMDatabase.h" 10 | #import "FMDatabaseAdditions.h" 11 | #import "TargetConditionals.h" 12 | 13 | #if FMDB_SQLITE_STANDALONE 14 | #import 15 | #else 16 | #import 17 | #endif 18 | 19 | @interface FMDatabase (PrivateStuff) 20 | - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray * _Nullable)arrayArgs orDictionary:(NSDictionary * _Nullable)dictionaryArgs orVAList:(va_list)args; 21 | @end 22 | 23 | @implementation FMDatabase (FMDatabaseAdditions) 24 | 25 | #define RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(type, sel) \ 26 | va_list args; \ 27 | va_start(args, query); \ 28 | FMResultSet *resultSet = [self executeQuery:query withArgumentsInArray:0x00 orDictionary:0x00 orVAList:args]; \ 29 | va_end(args); \ 30 | if (![resultSet next]) { return (type)0; } \ 31 | type ret = [resultSet sel:0]; \ 32 | [resultSet close]; \ 33 | [resultSet setParentDB:nil]; \ 34 | return ret; 35 | 36 | 37 | - (NSString *)stringForQuery:(NSString*)query, ... { 38 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSString *, stringForColumnIndex); 39 | } 40 | 41 | - (int)intForQuery:(NSString*)query, ... { 42 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(int, intForColumnIndex); 43 | } 44 | 45 | - (long)longForQuery:(NSString*)query, ... { 46 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(long, longForColumnIndex); 47 | } 48 | 49 | - (BOOL)boolForQuery:(NSString*)query, ... { 50 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(BOOL, boolForColumnIndex); 51 | } 52 | 53 | - (double)doubleForQuery:(NSString*)query, ... { 54 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(double, doubleForColumnIndex); 55 | } 56 | 57 | - (NSData*)dataForQuery:(NSString*)query, ... { 58 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSData *, dataForColumnIndex); 59 | } 60 | 61 | - (NSDate*)dateForQuery:(NSString*)query, ... { 62 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSDate *, dateForColumnIndex); 63 | } 64 | 65 | 66 | - (BOOL)tableExists:(NSString*)tableName { 67 | 68 | tableName = [tableName lowercaseString]; 69 | 70 | FMResultSet *rs = [self executeQuery:@"select [sql] from sqlite_master where [type] = 'table' and lower(name) = ?", tableName]; 71 | 72 | //if at least one next exists, table exists 73 | BOOL returnBool = [rs next]; 74 | 75 | //close and free object 76 | [rs close]; 77 | 78 | return returnBool; 79 | } 80 | 81 | /* 82 | get table with list of tables: result colums: type[STRING], name[STRING],tbl_name[STRING],rootpage[INTEGER],sql[STRING] 83 | check if table exist in database (patch from OZLB) 84 | */ 85 | - (FMResultSet*)getSchema { 86 | 87 | //result colums: type[STRING], name[STRING],tbl_name[STRING],rootpage[INTEGER],sql[STRING] 88 | FMResultSet *rs = [self executeQuery:@"SELECT type, name, tbl_name, rootpage, sql FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) WHERE type != 'meta' AND name NOT LIKE 'sqlite_%' ORDER BY tbl_name, type DESC, name"]; 89 | 90 | return rs; 91 | } 92 | 93 | /* 94 | get table schema: result colums: cid[INTEGER], name,type [STRING], notnull[INTEGER], dflt_value[],pk[INTEGER] 95 | */ 96 | - (FMResultSet*)getTableSchema:(NSString*)tableName { 97 | 98 | //result colums: cid[INTEGER], name,type [STRING], notnull[INTEGER], dflt_value[],pk[INTEGER] 99 | FMResultSet *rs = [self executeQuery:[NSString stringWithFormat: @"pragma table_info('%@')", tableName]]; 100 | 101 | return rs; 102 | } 103 | 104 | - (BOOL)columnExists:(NSString*)columnName inTableWithName:(NSString*)tableName { 105 | 106 | BOOL returnBool = NO; 107 | 108 | tableName = [tableName lowercaseString]; 109 | columnName = [columnName lowercaseString]; 110 | 111 | FMResultSet *rs = [self getTableSchema:tableName]; 112 | 113 | //check if column is present in table schema 114 | while ([rs next]) { 115 | if ([[[rs stringForColumn:@"name"] lowercaseString] isEqualToString:columnName]) { 116 | returnBool = YES; 117 | break; 118 | } 119 | } 120 | 121 | //If this is not done FMDatabase instance stays out of pool 122 | [rs close]; 123 | 124 | return returnBool; 125 | } 126 | 127 | 128 | 129 | - (uint32_t)applicationID { 130 | #if SQLITE_VERSION_NUMBER >= 3007017 131 | uint32_t r = 0; 132 | 133 | FMResultSet *rs = [self executeQuery:@"pragma application_id"]; 134 | 135 | if ([rs next]) { 136 | r = (uint32_t)[rs longLongIntForColumnIndex:0]; 137 | } 138 | 139 | [rs close]; 140 | 141 | return r; 142 | #else 143 | NSString *errorMessage = NSLocalizedString(@"Application ID functions require SQLite 3.7.17", nil); 144 | if (self.logsErrors) NSLog(@"%@", errorMessage); 145 | return 0; 146 | #endif 147 | } 148 | 149 | - (void)setApplicationID:(uint32_t)appID { 150 | #if SQLITE_VERSION_NUMBER >= 3007017 151 | NSString *query = [NSString stringWithFormat:@"pragma application_id=%d", appID]; 152 | FMResultSet *rs = [self executeQuery:query]; 153 | [rs next]; 154 | [rs close]; 155 | #else 156 | NSString *errorMessage = NSLocalizedString(@"Application ID functions require SQLite 3.7.17", nil); 157 | if (self.logsErrors) NSLog(@"%@", errorMessage); 158 | #endif 159 | } 160 | 161 | 162 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE 163 | 164 | - (NSString*)applicationIDString { 165 | #if SQLITE_VERSION_NUMBER >= 3007017 166 | NSString *s = NSFileTypeForHFSTypeCode([self applicationID]); 167 | 168 | assert([s length] == 6); 169 | 170 | s = [s substringWithRange:NSMakeRange(1, 4)]; 171 | 172 | 173 | return s; 174 | #else 175 | NSString *errorMessage = NSLocalizedString(@"Application ID functions require SQLite 3.7.17", nil); 176 | if (self.logsErrors) NSLog(@"%@", errorMessage); 177 | return nil; 178 | #endif 179 | } 180 | 181 | - (void)setApplicationIDString:(NSString*)s { 182 | #if SQLITE_VERSION_NUMBER >= 3007017 183 | if ([s length] != 4) { 184 | NSLog(@"setApplicationIDString: string passed is not exactly 4 chars long. (was %ld)", [s length]); 185 | } 186 | 187 | [self setApplicationID:NSHFSTypeCodeFromFileType([NSString stringWithFormat:@"'%@'", s])]; 188 | #else 189 | NSString *errorMessage = NSLocalizedString(@"Application ID functions require SQLite 3.7.17", nil); 190 | if (self.logsErrors) NSLog(@"%@", errorMessage); 191 | #endif 192 | } 193 | 194 | #endif 195 | 196 | - (uint32_t)userVersion { 197 | uint32_t r = 0; 198 | 199 | FMResultSet *rs = [self executeQuery:@"pragma user_version"]; 200 | 201 | if ([rs next]) { 202 | r = (uint32_t)[rs longLongIntForColumnIndex:0]; 203 | } 204 | 205 | [rs close]; 206 | return r; 207 | } 208 | 209 | - (void)setUserVersion:(uint32_t)version { 210 | NSString *query = [NSString stringWithFormat:@"pragma user_version = %d", version]; 211 | FMResultSet *rs = [self executeQuery:query]; 212 | [rs next]; 213 | [rs close]; 214 | } 215 | 216 | #pragma clang diagnostic push 217 | #pragma clang diagnostic ignored "-Wdeprecated-implementations" 218 | 219 | - (BOOL)columnExists:(NSString*)tableName columnName:(NSString*)columnName __attribute__ ((deprecated)) { 220 | return [self columnExists:columnName inTableWithName:tableName]; 221 | } 222 | 223 | #pragma clang diagnostic pop 224 | 225 | - (BOOL)validateSQL:(NSString*)sql error:(NSError**)error { 226 | sqlite3_stmt *pStmt = NULL; 227 | BOOL validationSucceeded = YES; 228 | 229 | int rc = sqlite3_prepare_v2([self sqliteHandle], [sql UTF8String], -1, &pStmt, 0); 230 | if (rc != SQLITE_OK) { 231 | validationSucceeded = NO; 232 | if (error) { 233 | *error = [NSError errorWithDomain:NSCocoaErrorDomain 234 | code:[self lastErrorCode] 235 | userInfo:[NSDictionary dictionaryWithObject:[self lastErrorMessage] 236 | forKey:NSLocalizedDescriptionKey]]; 237 | } 238 | } 239 | 240 | sqlite3_finalize(pStmt); 241 | 242 | return validationSucceeded; 243 | } 244 | 245 | @end 246 | -------------------------------------------------------------------------------- /obfuse-code/obfuse-code/Objective-C/FMDB/src/fmdb/FMDatabasePool.h: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabasePool.h 3 | // fmdb 4 | // 5 | // Created by August Mueller on 6/22/11. 6 | // Copyright 2011 Flying Meat Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class FMDatabase; 14 | 15 | /** Pool of `` objects. 16 | 17 | ### See also 18 | 19 | - `` 20 | - `` 21 | 22 | @warning Before using `FMDatabasePool`, please consider using `` instead. 23 | 24 | If you really really really know what you're doing and `FMDatabasePool` is what 25 | you really really need (ie, you're using a read only database), OK you can use 26 | it. But just be careful not to deadlock! 27 | 28 | For an example on deadlocking, search for: 29 | `ONLY_USE_THE_POOL_IF_YOU_ARE_DOING_READS_OTHERWISE_YOULL_DEADLOCK_USE_FMDATABASEQUEUE_INSTEAD` 30 | in the main.m file. 31 | */ 32 | 33 | @interface FMDatabasePool : NSObject 34 | 35 | /** Database path */ 36 | 37 | @property (atomic, copy, nullable) NSString *path; 38 | 39 | /** Delegate object */ 40 | 41 | @property (atomic, assign, nullable) id delegate; 42 | 43 | /** Maximum number of databases to create */ 44 | 45 | @property (atomic, assign) NSUInteger maximumNumberOfDatabasesToCreate; 46 | 47 | /** Open flags */ 48 | 49 | @property (atomic, readonly) int openFlags; 50 | 51 | /** Custom virtual file system name */ 52 | 53 | @property (atomic, copy, nullable) NSString *vfsName; 54 | 55 | 56 | ///--------------------- 57 | /// @name Initialization 58 | ///--------------------- 59 | 60 | /** Create pool using path. 61 | 62 | @param aPath The file path of the database. 63 | 64 | @return The `FMDatabasePool` object. `nil` on error. 65 | */ 66 | 67 | + (instancetype)databasePoolWithPath:(NSString * _Nullable)aPath; 68 | 69 | /** Create pool using file URL. 70 | 71 | @param url The file `NSURL` of the database. 72 | 73 | @return The `FMDatabasePool` object. `nil` on error. 74 | */ 75 | 76 | + (instancetype)databasePoolWithURL:(NSURL * _Nullable)url; 77 | 78 | /** Create pool using path and specified flags 79 | 80 | @param aPath The file path of the database. 81 | @param openFlags Flags passed to the openWithFlags method of the database. 82 | 83 | @return The `FMDatabasePool` object. `nil` on error. 84 | */ 85 | 86 | + (instancetype)databasePoolWithPath:(NSString * _Nullable)aPath flags:(int)openFlags; 87 | 88 | /** Create pool using file URL and specified flags 89 | 90 | @param url The file `NSURL` of the database. 91 | @param openFlags Flags passed to the openWithFlags method of the database. 92 | 93 | @return The `FMDatabasePool` object. `nil` on error. 94 | */ 95 | 96 | + (instancetype)databasePoolWithURL:(NSURL * _Nullable)url flags:(int)openFlags; 97 | 98 | /** Create pool using path. 99 | 100 | @param aPath The file path of the database. 101 | 102 | @return The `FMDatabasePool` object. `nil` on error. 103 | */ 104 | 105 | - (instancetype)initWithPath:(NSString * _Nullable)aPath; 106 | 107 | /** Create pool using file URL. 108 | 109 | @param url The file `NSURL of the database. 110 | 111 | @return The `FMDatabasePool` object. `nil` on error. 112 | */ 113 | 114 | - (instancetype)initWithURL:(NSURL * _Nullable)url; 115 | 116 | /** Create pool using path and specified flags. 117 | 118 | @param aPath The file path of the database. 119 | @param openFlags Flags passed to the openWithFlags method of the database 120 | 121 | @return The `FMDatabasePool` object. `nil` on error. 122 | */ 123 | 124 | - (instancetype)initWithPath:(NSString * _Nullable)aPath flags:(int)openFlags; 125 | 126 | /** Create pool using file URL and specified flags. 127 | 128 | @param url The file `NSURL` of the database. 129 | @param openFlags Flags passed to the openWithFlags method of the database 130 | 131 | @return The `FMDatabasePool` object. `nil` on error. 132 | */ 133 | 134 | - (instancetype)initWithURL:(NSURL * _Nullable)url flags:(int)openFlags; 135 | 136 | /** Create pool using path and specified flags. 137 | 138 | @param aPath The file path of the database. 139 | @param openFlags Flags passed to the openWithFlags method of the database 140 | @param vfsName The name of a custom virtual file system 141 | 142 | @return The `FMDatabasePool` object. `nil` on error. 143 | */ 144 | 145 | - (instancetype)initWithPath:(NSString * _Nullable)aPath flags:(int)openFlags vfs:(NSString * _Nullable)vfsName; 146 | 147 | /** Create pool using file URL and specified flags. 148 | 149 | @param url The file `NSURL` of the database. 150 | @param openFlags Flags passed to the openWithFlags method of the database 151 | @param vfsName The name of a custom virtual file system 152 | 153 | @return The `FMDatabasePool` object. `nil` on error. 154 | */ 155 | 156 | - (instancetype)initWithURL:(NSURL * _Nullable)url flags:(int)openFlags vfs:(NSString * _Nullable)vfsName; 157 | 158 | /** Returns the Class of 'FMDatabase' subclass, that will be used to instantiate database object. 159 | 160 | Subclasses can override this method to return specified Class of 'FMDatabase' subclass. 161 | 162 | @return The Class of 'FMDatabase' subclass, that will be used to instantiate database object. 163 | */ 164 | 165 | + (Class)databaseClass; 166 | 167 | ///------------------------------------------------ 168 | /// @name Keeping track of checked in/out databases 169 | ///------------------------------------------------ 170 | 171 | /** Number of checked-in databases in pool 172 | */ 173 | 174 | @property (nonatomic, readonly) NSUInteger countOfCheckedInDatabases; 175 | 176 | /** Number of checked-out databases in pool 177 | */ 178 | 179 | @property (nonatomic, readonly) NSUInteger countOfCheckedOutDatabases; 180 | 181 | /** Total number of databases in pool 182 | */ 183 | 184 | @property (nonatomic, readonly) NSUInteger countOfOpenDatabases; 185 | 186 | /** Release all databases in pool */ 187 | 188 | - (void)releaseAllDatabases; 189 | 190 | ///------------------------------------------ 191 | /// @name Perform database operations in pool 192 | ///------------------------------------------ 193 | 194 | /** Synchronously perform database operations in pool. 195 | 196 | @param block The code to be run on the `FMDatabasePool` pool. 197 | */ 198 | 199 | - (void)inDatabase:(__attribute__((noescape)) void (^)(FMDatabase *db))block; 200 | 201 | /** Synchronously perform database operations in pool using transaction. 202 | 203 | @param block The code to be run on the `FMDatabasePool` pool. 204 | */ 205 | 206 | - (void)inTransaction:(__attribute__((noescape)) void (^)(FMDatabase *db, BOOL *rollback))block; 207 | 208 | /** Synchronously perform database operations in pool using deferred transaction. 209 | 210 | @param block The code to be run on the `FMDatabasePool` pool. 211 | */ 212 | 213 | - (void)inDeferredTransaction:(__attribute__((noescape)) void (^)(FMDatabase *db, BOOL *rollback))block; 214 | 215 | /** Synchronously perform database operations in pool using save point. 216 | 217 | @param block The code to be run on the `FMDatabasePool` pool. 218 | 219 | @return `NSError` object if error; `nil` if successful. 220 | 221 | @warning You can not nest these, since calling it will pull another database out of the pool and you'll get a deadlock. If you need to nest, use `<[FMDatabase startSavePointWithName:error:]>` instead. 222 | */ 223 | 224 | - (NSError * _Nullable)inSavePoint:(__attribute__((noescape)) void (^)(FMDatabase *db, BOOL *rollback))block; 225 | 226 | @end 227 | 228 | 229 | /** FMDatabasePool delegate category 230 | 231 | This is a category that defines the protocol for the FMDatabasePool delegate 232 | */ 233 | 234 | @interface NSObject (FMDatabasePoolDelegate) 235 | 236 | /** Asks the delegate whether database should be added to the pool. 237 | 238 | @param pool The `FMDatabasePool` object. 239 | @param database The `FMDatabase` object. 240 | 241 | @return `YES` if it should add database to pool; `NO` if not. 242 | 243 | */ 244 | 245 | - (BOOL)databasePool:(FMDatabasePool*)pool shouldAddDatabaseToPool:(FMDatabase*)database; 246 | 247 | /** Tells the delegate that database was added to the pool. 248 | 249 | @param pool The `FMDatabasePool` object. 250 | @param database The `FMDatabase` object. 251 | 252 | */ 253 | 254 | - (void)databasePool:(FMDatabasePool*)pool didAddDatabase:(FMDatabase*)database; 255 | 256 | @end 257 | 258 | NS_ASSUME_NONNULL_END 259 | -------------------------------------------------------------------------------- /obfuse-code/obfuse-code/Objective-C/MetaData/CacheImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // COCacheImage.h 3 | // CodeObfuscation 4 | // 5 | // Created by hejunqiu on 2017/6/18. 6 | // Copyright © 2017年 CHE. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class Function; 14 | 15 | @interface CacheImage : NSObject 16 | 17 | - (BOOL)searchFunction:(Function *)method withSuperName:(NSString *)supername; 18 | - (nullable NSString *)getSuperNameWithClassname:(NSString *)classname; 19 | 20 | @property (nonatomic, strong, readonly) NSString *imageVersion; 21 | @property (nonatomic, strong, readonly, class) NSString *versionString; 22 | 23 | - (void)enumerateCacheWithBlock:(BOOL(^)(NSString *clazz, NSArray *method, NSInteger progress))block; 24 | 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /obfuse-code/obfuse-code/Objective-C/MetaData/CacheImage.mm: -------------------------------------------------------------------------------- 1 | // 2 | // COCacheImage.m 3 | // CodeObfuscation 4 | // 5 | // Created by hejunqiu on 2017/6/18. 6 | // Copyright © 2017年 CHE. All rights reserved. 7 | // 8 | 9 | #import "CacheImage.h" 10 | #import "structs.h" 11 | #import "obfuse_code-Swift.h" 12 | #include 13 | 14 | using namespace std; 15 | 16 | FOUNDATION_EXTERN struct __class__ **L_CO_LABEL_CLASS_$; 17 | FOUNDATION_EXTERN struct __image_info _CO_CLASS_IMAGE_INFO_$; 18 | 19 | struct __image_info { 20 | const char *version; 21 | unsigned long size; 22 | }; 23 | 24 | NS_INLINE NSUInteger image_size() 25 | { 26 | return _CO_CLASS_IMAGE_INFO_$.size; 27 | } 28 | 29 | NS_INLINE const char * image_ver() 30 | { 31 | return _CO_CLASS_IMAGE_INFO_$.version; 32 | } 33 | 34 | @interface COCPointer : NSObject 35 | @property (nonatomic) struct __class__ *val; 36 | @end 37 | 38 | @implementation COCPointer 39 | 40 | + (instancetype)pointer:(struct __class__ *)val 41 | { 42 | COCPointer *obj = [COCPointer new]; 43 | obj.val = val; 44 | return obj; 45 | } 46 | 47 | @end 48 | 49 | @interface CacheImage () 50 | 51 | @property (nonatomic, strong) NSMutableDictionary *> *cache; 52 | @property (nonatomic, strong) NSMutableDictionary *image_hash; 53 | 54 | @end 55 | 56 | @implementation CacheImage 57 | 58 | - (instancetype)init 59 | { 60 | if (self = [super init]) { 61 | _cache = [NSMutableDictionary dictionary]; 62 | _image_hash = [NSMutableDictionary dictionary]; 63 | [self _read_image]; 64 | } 65 | return self; 66 | } 67 | 68 | - (BOOL)searchFunction:(Function *)method withSuperName:(NSString *)supername 69 | { 70 | NSArray *methods = _cache[supername]; 71 | struct __class__ *clazz = NULL; 72 | if (!methods) { 73 | methods = [self __cacheWithClassName:supername clazz:&clazz]; 74 | if (!methods) { 75 | fprintf(stderr, "\033[41;37m[Error]: %s is not exists in cache image. Check your SDK Version(%s).\033[0m", supername.UTF8String, image_ver()); 76 | exit(-1); 77 | } 78 | } 79 | for (Function *m in methods) { 80 | if ([method isEqual:m]) { 81 | return YES; 82 | } 83 | } 84 | if (!clazz) { 85 | return NO; 86 | } 87 | return [self searchFunction:method withSuperName:@(clazz->name)]; 88 | } 89 | 90 | - (nullable NSString *)getSuperNameWithClassname:(NSString *)classname 91 | { 92 | COCPointer *obj = _image_hash[classname]; 93 | return obj.val->superclass->name ? @(obj.val->superclass->name) : nil; 94 | } 95 | 96 | - (nullable NSArray *)__cacheWithClassName:(NSString *)classname clazz:(struct __class__ **)clazz 97 | { 98 | COCPointer *obj = _image_hash[classname]; 99 | if (!obj) { 100 | return nil; 101 | } 102 | 103 | auto p = obj.val; 104 | NSMutableArray *methods = [NSMutableArray array]; 105 | struct __method__ *p_method = (struct __method__ *)p->method_list->methods; 106 | for (unsigned int i=0; imethod_list->count; ++i) { 107 | NSString *selector = @(p_method[i].name); 108 | Function *m = [[Function alloc] initWithName:selector location:NSMakeRange(0, 0)]; 109 | [methods addObject:m]; 110 | NSArray *sels = [selector componentsSeparatedByString:@":"]; 111 | for (NSString *sel in sels) { 112 | if (sel.length) { 113 | [m addWithSelector:[[SelectorPart alloc] initWithName:sel location:NSMakeRange(0, 0)]]; 114 | } 115 | } 116 | } 117 | if (clazz) { 118 | *clazz = p; 119 | [_cache setObject:methods forKey:classname]; 120 | } 121 | return methods; 122 | } 123 | 124 | - (NSString *)imageVersion 125 | { 126 | return @(image_ver()); 127 | } 128 | 129 | - (void)_read_image 130 | { 131 | struct __class__ *p = L_CO_LABEL_CLASS_$[0]; 132 | struct __class__ *end = p + image_size(); 133 | do { 134 | _image_hash[@(p->name)] = [COCPointer pointer:p]; 135 | } while (++p < end); 136 | } 137 | 138 | + (NSString *)versionString 139 | { 140 | return @(image_ver()); 141 | } 142 | 143 | - (void)enumerateCacheWithBlock:(BOOL(^)(NSString *clazz, NSArray *method, NSInteger progress))block 144 | { 145 | static atomic_long idx; 146 | idx = 0; 147 | double total = self.image_hash.count; 148 | NSUInteger count = self.image_hash.count / 4; 149 | NSArray *objects = self.image_hash.allValues; 150 | NSArray *_1 = [objects subarrayWithRange:NSMakeRange(0, count)]; 151 | NSArray *_2 = [objects subarrayWithRange:NSMakeRange(count, count)]; 152 | NSArray *_3 = [objects subarrayWithRange:NSMakeRange(2 * count, count)]; 153 | NSArray *_4 = [objects subarrayWithRange:NSMakeRange(3 * count, self.image_hash.count - 3 * count)]; 154 | 155 | NSArray *pool = @[_1, _2, _3, _4]; 156 | 157 | void(^threadBlock)(NSUInteger index) = ^(NSUInteger index){ 158 | for (COCPointer *obj in pool[index]) { 159 | NSArray *methods = [self __cacheWithClassName:@(obj.val->name) clazz:nil]; 160 | if (methods != nil) { 161 | if (block(@(obj.val->name), methods, (++idx / total) * 100)) { 162 | break; 163 | } 164 | } 165 | } 166 | }; 167 | 168 | [NSThread detachNewThreadWithBlock:^{ threadBlock(0); }]; 169 | [NSThread detachNewThreadWithBlock:^{ threadBlock(1); }]; 170 | [NSThread detachNewThreadWithBlock:^{ threadBlock(2); }]; 171 | [NSThread detachNewThreadWithBlock:^{ threadBlock(3); }]; 172 | } 173 | @end 174 | -------------------------------------------------------------------------------- /obfuse-code/obfuse-code/Objective-C/MetaData/structs.h: -------------------------------------------------------------------------------- 1 | // 2 | // structs.h 3 | // CodeObfuscation 4 | // 5 | // Created by hejunqiu on 2017/6/18. 6 | // Copyright © 2017年 CHE. All rights reserved. 7 | // 8 | 9 | #ifndef structs_h 10 | #define structs_h 11 | 12 | struct __method__ 13 | { 14 | const char *name; 15 | }; 16 | 17 | struct __method__list 18 | { 19 | unsigned int reserved; 20 | unsigned int count; 21 | struct __method__ methods[0]; 22 | }; 23 | 24 | struct __class__ 25 | { 26 | struct __class__ *superclass; 27 | const char *name; 28 | const struct __method__list *method_list; 29 | }; 30 | 31 | #endif /* structs_h */ 32 | -------------------------------------------------------------------------------- /obfuse-code/obfuse-code/Objective-C/NSString+COMD5.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+COMD5.h 3 | // CodeObfuscation 4 | // 5 | // Created by hejunqiu on 2017/5/31. 6 | // Copyright © 2017年 CHE. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface NSString (COMD5) 14 | 15 | @property (nonatomic, strong, readonly) NSString *md5; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /obfuse-code/obfuse-code/Objective-C/NSString+COMD5.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+COMD5.m 3 | // CodeObfuscation 4 | // 5 | // Created by hejunqiu on 2017/5/31. 6 | // Copyright © 2017年 CHE. All rights reserved. 7 | // 8 | 9 | #import "NSString+COMD5.h" 10 | #import 11 | 12 | @implementation NSString (COMD5) 13 | 14 | - (NSString *)md5 15 | { 16 | const char *cStr = [self UTF8String]; 17 | unsigned char result[16]; 18 | CC_MD5(cStr, (CC_LONG)strlen(cStr), result); 19 | return [NSString stringWithFormat: 20 | @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 21 | result[0], result[1], result[2], result[3], 22 | result[4], result[5], result[6], result[7], 23 | result[8], result[9], result[10], result[11], 24 | result[12], result[13], result[14], result[15] 25 | ]; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /obfuse-code/obfuse-code/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // main.swift 3 | // CodeObfuscation 4 | // 5 | // Created by hejunqiu on 2017/8/15. 6 | // Copyright © 2017年 CHE. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | var manager = ObfuscationManager.init() 12 | do { 13 | try manager.go(with: Arguments.arguments.rootpath as String) 14 | } catch { 15 | print(error) 16 | } 17 | -------------------------------------------------------------------------------- /obfuse-code/obfuse-code/obfuse-code-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | 2 | #import "NSString+COMD5.h" 3 | #import "CacheImage.h" 4 | #import "FMDB.h" 5 | --------------------------------------------------------------------------------