├── .gitignore ├── AnnotationKit.podspec ├── AnnotationKit ├── Category │ ├── NSDictionary+AnnotationKit.h │ └── NSDictionary+AnnotationKit.m ├── Core │ ├── AKEngine.h │ ├── AKEngine.m │ ├── AnnotationMacro.h │ ├── PHAnnotationHandler.h │ ├── PHAnnotationHandler.m │ └── metamacro.h ├── EventCenter │ ├── LifeCycleAnnnotation.h │ └── LifeCycleAnnnotation.m ├── Router │ ├── AKRouteAnnotation.h │ ├── AKRouteAnnotation.m │ ├── AKRouter.h │ └── AKRouter.m └── install.sh ├── AnnotationKitDemo ├── AnnotationKitDemo.xcodeproj │ └── project.pbxproj ├── AnnotationKitDemo │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── ProfileController.h │ ├── ProfileController.m │ ├── ViewController+Counter.h │ ├── ViewController+Counter.m │ ├── ViewController.h │ ├── ViewController.m │ └── main.m ├── BussinessOneDylib │ ├── BizOneController.h │ ├── BizOneController.m │ └── BussinessOneDylib.podspec ├── BussinessTwoDylib │ ├── BizTwoController.h │ ├── BizTwoController.m │ └── BussinessTwoDylib.podspec └── Podfile ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | */Pods/ 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 | # fastlane 47 | # 48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 49 | # screenshots whenever they are needed. 50 | # For more information about the recommended setup visit: 51 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 52 | 53 | fastlane/report.xml 54 | fastlane/screenshots 55 | 56 | #Code Injection 57 | # 58 | # After new code Injection tools there's a generated folder /iOSInjectionProject 59 | # https://github.com/johnno1962/injectionforxcode 60 | 61 | iOSInjectionProject/ 62 | -------------------------------------------------------------------------------- /AnnotationKit.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "AnnotationKit" 4 | s.version = "1.0.2" 5 | s.summary = "an annotation solution using objective-c" 6 | 7 | s.description = <<-DESC 8 | AnnotationKit provides you a way for meta-programming 9 | DESC 10 | 11 | s.homepage = "https://github.com/luoqisheng/AnnotationKit" 12 | s.license = "MIT" 13 | s.author = { "luoqisheng" => "540025011@qq.com" } 14 | 15 | s.platform = :ios, "8.0" 16 | s.requires_arc = true 17 | s.source = { :git => 'https://github.com/luoqisheng/AnnotationKit.git', :tag => 'v1.0.2' } 18 | 19 | s.subspec 'Core' do |core| 20 | core.source_files = ["AnnotationKit/Core/*.{h,m}" , "AnnotationKit/Category/*.{h,m}"] 21 | core.requires_arc = true 22 | end 23 | 24 | s.subspec 'Router' do |rt| 25 | rt.source_files = 'AnnotationKit/Router/*.{h,m}' 26 | rt.requires_arc = true 27 | rt.dependency 'AnnotationKit/Core' 28 | rt.dependency 'HHRouter' 29 | end 30 | 31 | s.subspec 'EventCenter' do |ec| 32 | ec.source_files = 'AnnotationKit/EventCenter/*.{h,m}' 33 | ec.requires_arc = true 34 | ec.dependency 'AnnotationKit/Core' 35 | end 36 | 37 | 38 | s.xcconfig = { 39 | 'CLANG_CXX_LANGUAGE_STANDARD' => 'compiler-default', 40 | 'CLANG_CXX_LIBRARY' => 'compiler-default', 41 | 'GCC_C_LANGUAGE_STANDARD' => 'compiler-default' 42 | } 43 | 44 | 45 | end 46 | -------------------------------------------------------------------------------- /AnnotationKit/Category/NSDictionary+AnnotationKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+AnnotationKit.h 3 | // AnnotationKit 4 | // 5 | // Created by luoqihsneg on 2016/11/23. 6 | // Copyright © 2016年 com.luoqihsneg. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDictionary (AnnotationKit) 12 | - (id)akSafeObjectForKey:(NSString *)key; 13 | @end 14 | -------------------------------------------------------------------------------- /AnnotationKit/Category/NSDictionary+AnnotationKit.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+AnnotationKit.m 3 | // AnnotationKit 4 | // 5 | // Created by luoqihsneg on 2016/11/23. 6 | // Copyright © 2016年 com.luoqihsneg. All rights reserved. 7 | // 8 | 9 | #import "NSDictionary+AnnotationKit.h" 10 | 11 | @implementation NSDictionary (AnnotaionKit) 12 | - (id)akSafeObjectForKey:(NSString *)key { 13 | id value = [self objectForKey:key]; 14 | if([value isKindOfClass:[NSNull class]]){ 15 | value = nil; 16 | } 17 | return value; 18 | } 19 | @end 20 | -------------------------------------------------------------------------------- /AnnotationKit/Core/AKEngine.h: -------------------------------------------------------------------------------- 1 | // 2 | // AKEngine.h 3 | // AnnotationKit 4 | // 5 | // Created by luoqihsneg on 2016/11/23. 6 | // Copyright © 2016年 com.luoqihsneg. All rights reserved. 7 | // 8 | 9 | #import 10 | #include "AnnotationMacro.h" 11 | #import "PHAnnotationHandler.h" 12 | #import 13 | 14 | #ifndef DefineAnnotation /*use @DefineAnnotation() to declare your custom annotation */ 15 | 16 | #define AnnotationSectName "annotation" 17 | #define DefineAnnotation(handler,section) \ 18 | class AKEngine; char *const NameGen(handler) AnnotationDATA(annotation) = "{\""#handler"\":\""#section"\"}"; 19 | #endif 20 | 21 | @interface AKEngine : NSObject 22 | @property(nonatomic,copy)NSDictionary *launchOptions; 23 | @property(nonatomic,strong)UIApplication *application; 24 | 25 | + (AKEngine *)sharedAKEngine; 26 | - (void)setUp; 27 | @end 28 | -------------------------------------------------------------------------------- /AnnotationKit/Core/AKEngine.m: -------------------------------------------------------------------------------- 1 | // 2 | // AKEngine.m 3 | // AKEngine 4 | // 5 | // Created by luoqihsneg on 2016/11/23. 6 | // Copyright © 2016年 luoqihsneg. All rights reserved. 7 | // 8 | 9 | #import "AKEngine.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #import 15 | #import 16 | #import 17 | #import "NSDictionary+AnnotationKit.h" 18 | #include "AnnotationMacro.h" 19 | #import "PHAnnotationHandler.h" 20 | 21 | #ifndef __LP64__ 22 | 23 | typedef struct mach_header mach_header_t; 24 | typedef struct section section_t; 25 | #define getsectbynamefromheader getsectbynamefromheader 26 | 27 | #else 28 | 29 | typedef struct mach_header_64 mach_header_t; 30 | typedef struct section_64 section_t; 31 | #define getsectbynamefromheader getsectbynamefromheader_64 32 | #endif 33 | 34 | static NSMutableArray *_annotations = nil; 35 | NSArray* annotation_read_content(const char *sectionName,const mach_header_t *header) { 36 | 37 | NSMutableArray *configs = [NSMutableArray array]; 38 | const mach_header_t *mhp = header; 39 | Dl_info info; 40 | if (mhp == NULL) { 41 | dladdr(annotation_read_content, &info); 42 | mhp = (const mach_header_t*)info.dli_fbase; 43 | } 44 | unsigned long size = 0; 45 | uintptr_t *memory = (uintptr_t*)getsectiondata(mhp, SEG_PHET, sectionName, & size); 46 | unsigned long counter = size/sizeof(void*); 47 | for(int idx = 0; idx < counter; ++idx){ 48 | char *string = (char*)memory[idx]; 49 | NSString *str = [NSString stringWithUTF8String:string]; 50 | if(!str)continue; 51 | 52 | NSLog(@"config = %@", str); 53 | if(str) [configs addObject:str]; 54 | } 55 | 56 | return configs; 57 | } 58 | 59 | static void prepare_annotation(const struct mach_header *header, intptr_t slide) 60 | { 61 | for (NSDictionary *map in _annotations) { 62 | if ([map isKindOfClass:[NSDictionary class]] && [map allKeys].count) { 63 | NSString *sectionName = [[map allKeys] firstObject]; 64 | const char *sectionCName = [sectionName UTF8String]; 65 | const section_t *sect = getsectbynamefromheader((const mach_header_t *)header, SEG_PHET, sectionCName); 66 | if (!sect || sect->size <= 0) { 67 | continue; 68 | } 69 | 70 | NSString *handler = [map akSafeObjectForKey:sectionName]; 71 | Class handlerClass = NSClassFromString(handler); 72 | NSArray*configs = annotation_read_content(sectionCName,(const mach_header_t *)header); 73 | if (handlerClass && [handlerClass isSubclassOfClass:[PHAnnotationHandler class]]) { 74 | 75 | __kindof PHAnnotationHandler *annotation = [handlerClass shared]; 76 | [annotation handleAnnotationConfig:configs]; 77 | 78 | } 79 | } 80 | } 81 | } 82 | 83 | @implementation AKEngine 84 | 85 | + (id)sharedAKEngine 86 | { 87 | static AKEngine *engine = nil; 88 | static dispatch_once_t onceToken; 89 | dispatch_once(&onceToken, ^{ 90 | engine = [[AKEngine alloc]init]; 91 | }); 92 | return engine; 93 | } 94 | 95 | - (void)setUp 96 | { 97 | _annotations = [NSMutableArray array]; 98 | mach_header_t *mhp = NULL; 99 | Dl_info info; 100 | if (mhp == NULL) { 101 | dladdr(annotation_read_content, &info); 102 | mhp = (mach_header_t*)info.dli_fbase; 103 | } 104 | 105 | static dispatch_once_t onceToken; 106 | dispatch_once(&onceToken, ^{ 107 | NSArray *annotations = annotation_read_content(AnnotationSectName,mhp); 108 | for (NSString *map in annotations) { 109 | NSData *jsonData = [map dataUsingEncoding:NSUTF8StringEncoding]; 110 | NSError *error = nil; 111 | id json = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; 112 | if (!error) { 113 | if ([json isKindOfClass:[NSDictionary class]] && [json allKeys].count) { 114 | NSString *handler = [[json allKeys] firstObject]; 115 | NSString *sectionName = [json akSafeObjectForKey:handler]; 116 | 117 | if (handler && sectionName) { 118 | [_annotations addObject:@{sectionName:handler}]; 119 | } 120 | } 121 | } 122 | } 123 | 124 | }); 125 | 126 | if (_annotations.count) { 127 | //register callback for image additions 128 | _dyld_register_func_for_add_image(prepare_annotation); 129 | } 130 | } 131 | 132 | @end 133 | 134 | -------------------------------------------------------------------------------- /AnnotationKit/Core/AnnotationMacro.h: -------------------------------------------------------------------------------- 1 | // 2 | // AnnotationMacro.h 3 | // Annotation 4 | // 5 | // Created by luoqihsneg on 2016/11/5. 6 | // Copyright © 2016年 com.luoqihsneg. All rights reserved. 7 | // 8 | 9 | #ifndef AnnotationMacro_h 10 | #define AnnotationMacro_h 11 | #include "metamacro.h" 12 | 13 | #define NameGen(cls) NameGen_(cls, __LINE__, __COUNTER__) 14 | 15 | #define NameGen_(...) metamacro_concat( metamacro_concat_args , metamacro_argcount(__VA_ARGS__))(__VA_ARGS__) 16 | #define metamacro_concat_args1(...) metamacro_at(0,__VA_ARGS__) 17 | #define metamacro_concat_args2(...) metamacro_concat(metamacro_at(0,__VA_ARGS__),metamacro_at(1,__VA_ARGS__)) 18 | #define metamacro_concat_args3(...) metamacro_concat(metamacro_concat_args2(__VA_ARGS__),metamacro_at(2,__VA_ARGS__)) 19 | 20 | #ifndef SEG_PHET 21 | #define SEG_PHET SEG_DATA 22 | #endif 23 | 24 | #ifndef AnnotationDATA 25 | #define AnnotationDATA(sectName) __attribute((used, section("__DATA,"#sectName" "), no_sanitize_address)) 26 | #endif 27 | 28 | #endif /* AnnotationMacro_h */ 29 | -------------------------------------------------------------------------------- /AnnotationKit/Core/PHAnnotationHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // PHAnnotationHandler.h 3 | // Pods 4 | // 5 | // Created by luoqihsneg on 2017/1/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface PHAnnotationHandler : NSObject 12 | 13 | + (instancetype)shared; 14 | 15 | - (instancetype)init NS_UNAVAILABLE; 16 | 17 | //need be override 18 | - (void)handleAnnotationConfig:(NSArray*)configs; 19 | @end 20 | -------------------------------------------------------------------------------- /AnnotationKit/Core/PHAnnotationHandler.m: -------------------------------------------------------------------------------- 1 | // 2 | // PHAnnotationHandler.m 3 | // Pods 4 | // 5 | // Created by luoqihsneg on 2017/1/13. 6 | // 7 | // 8 | 9 | #import "PHAnnotationHandler.h" 10 | 11 | @interface PHAnnotationHandler () 12 | @end 13 | 14 | static NSMutableDictionary * _sharedInstances = nil; 15 | @implementation PHAnnotationHandler 16 | 17 | + (instancetype)shared { 18 | 19 | static dispatch_once_t onceToken; 20 | dispatch_once(&onceToken, ^{ 21 | _sharedInstances = [NSMutableDictionary dictionary]; 22 | }); 23 | 24 | __kindof PHAnnotationHandler *instance = nil; 25 | @synchronized (self) { 26 | NSString *instanceClass = NSStringFromClass(self); 27 | // Looking for existing instance 28 | instance = [_sharedInstances objectForKey:instanceClass]; 29 | if (!instance) { 30 | instance = [[self alloc] init]; 31 | [_sharedInstances setObject:instance forKey:instanceClass]; 32 | } 33 | } 34 | 35 | return instance; 36 | } 37 | 38 | - (void)handleAnnotationConfig:(NSArray*)configs 39 | { 40 | @throw [NSException exceptionWithName:@"PHAnnotation Exception" reason:[NSString stringWithFormat:@"you have should override @selector(handleAnnotationConfig:) in %@",[self class]] userInfo:nil]; 41 | } 42 | @end 43 | -------------------------------------------------------------------------------- /AnnotationKit/Core/metamacro.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Macros for metaprogramming 3 | * ExtendedC 4 | * 5 | * Copyright (C) 2012 Justin Spahr-Summers 6 | * Released under the MIT license 7 | */ 8 | 9 | #ifndef EXTC_METAMACROS_H 10 | #define EXTC_METAMACROS_H 11 | 12 | 13 | /** 14 | * Executes one or more expressions (which may have a void type, such as a call 15 | * to a function that returns no value) and always returns true. 16 | */ 17 | #define metamacro_exprify(...) \ 18 | ((__VA_ARGS__), true) 19 | 20 | /** 21 | * Returns a string representation of VALUE after full macro expansion. 22 | */ 23 | #define metamacro_stringify(VALUE) \ 24 | metamacro_stringify_(VALUE) 25 | 26 | /** 27 | * Returns A and B concatenated after full macro expansion. 28 | */ 29 | #define metamacro_concat(A, B) \ 30 | metamacro_concat_(A, B) 31 | 32 | /** 33 | * Returns the Nth variadic argument (starting from zero). At least 34 | * N + 1 variadic arguments must be given. N must be between zero and twenty, 35 | * inclusive. 36 | */ 37 | #define metamacro_at(N, ...) \ 38 | metamacro_concat(metamacro_at, N)(__VA_ARGS__) 39 | 40 | /** 41 | * Returns the number of arguments (up to twenty) provided to the macro. At 42 | * least one argument must be provided. 43 | * 44 | * Inspired by P99: http://p99.gforge.inria.fr 45 | */ 46 | #define metamacro_argcount(...) \ 47 | metamacro_at(20, __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) 48 | 49 | /** 50 | * Identical to #metamacro_foreach_cxt, except that no CONTEXT argument is 51 | * given. Only the index and current argument will thus be passed to MACRO. 52 | */ 53 | #define metamacro_foreach(MACRO, SEP, ...) \ 54 | metamacro_foreach_cxt(metamacro_foreach_iter, SEP, MACRO, __VA_ARGS__) 55 | 56 | /** 57 | * For each consecutive variadic argument (up to twenty), MACRO is passed the 58 | * zero-based index of the current argument, CONTEXT, and then the argument 59 | * itself. The results of adjoining invocations of MACRO are then separated by 60 | * SEP. 61 | * 62 | * Inspired by P99: http://p99.gforge.inria.fr 63 | */ 64 | #define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \ 65 | metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__) 66 | 67 | /** 68 | * Identical to #metamacro_foreach_cxt. This can be used when the former would 69 | * fail due to recursive macro expansion. 70 | */ 71 | #define metamacro_foreach_cxt_recursive(MACRO, SEP, CONTEXT, ...) \ 72 | metamacro_concat(metamacro_foreach_cxt_recursive, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__) 73 | 74 | /** 75 | * In consecutive order, appends each variadic argument (up to twenty) onto 76 | * BASE. The resulting concatenations are then separated by SEP. 77 | * 78 | * This is primarily useful to manipulate a list of macro invocations into instead 79 | * invoking a different, possibly related macro. 80 | */ 81 | #define metamacro_foreach_concat(BASE, SEP, ...) \ 82 | metamacro_foreach_cxt(metamacro_foreach_concat_iter, SEP, BASE, __VA_ARGS__) 83 | 84 | /** 85 | * Iterates COUNT times, each time invoking MACRO with the current index 86 | * (starting at zero) and CONTEXT. The results of adjoining invocations of MACRO 87 | * are then separated by SEP. 88 | * 89 | * COUNT must be an integer between zero and twenty, inclusive. 90 | */ 91 | #define metamacro_for_cxt(COUNT, MACRO, SEP, CONTEXT) \ 92 | metamacro_concat(metamacro_for_cxt, COUNT)(MACRO, SEP, CONTEXT) 93 | 94 | /** 95 | * Returns the first argument given. At least one argument must be provided. 96 | * 97 | * This is useful when implementing a variadic macro, where you may have only 98 | * one variadic argument, but no way to retrieve it (for example, because \c ... 99 | * always needs to match at least one argument). 100 | * 101 | * @code 102 | #define varmacro(...) \ 103 | metamacro_head(__VA_ARGS__) 104 | * @endcode 105 | */ 106 | #define metamacro_head(...) \ 107 | metamacro_head_(__VA_ARGS__, 0) 108 | 109 | /** 110 | * Returns every argument except the first. At least two arguments must be 111 | * provided. 112 | */ 113 | #define metamacro_tail(...) \ 114 | metamacro_tail_(__VA_ARGS__) 115 | 116 | /** 117 | * Returns the first N (up to twenty) variadic arguments as a new argument list. 118 | * At least N variadic arguments must be provided. 119 | */ 120 | #define metamacro_take(N, ...) \ 121 | metamacro_concat(metamacro_take, N)(__VA_ARGS__) 122 | 123 | /** 124 | * Removes the first N (up to twenty) variadic arguments from the given argument 125 | * list. At least N variadic arguments must be provided. 126 | */ 127 | #define metamacro_drop(N, ...) \ 128 | metamacro_concat(metamacro_drop, N)(__VA_ARGS__) 129 | 130 | /** 131 | * Decrements VAL, which must be a number between zero and twenty, inclusive. 132 | * 133 | * This is primarily useful when dealing with indexes and counts in 134 | * metaprogramming. 135 | */ 136 | #define metamacro_dec(VAL) \ 137 | metamacro_at(VAL, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) 138 | 139 | /** 140 | * Increments VAL, which must be a number between zero and twenty, inclusive. 141 | * 142 | * This is primarily useful when dealing with indexes and counts in 143 | * metaprogramming. 144 | */ 145 | #define metamacro_inc(VAL) \ 146 | metamacro_at(VAL, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) 147 | 148 | /** 149 | * If A is equal to B, the next argument list is expanded; otherwise, the 150 | * argument list after that is expanded. A and B must be numbers between zero 151 | * and twenty, inclusive. Additionally, B must be greater than or equal to A. 152 | * 153 | * @code 154 | // expands to true 155 | metamacro_if_eq(0, 0)(true)(false) 156 | // expands to false 157 | metamacro_if_eq(0, 1)(true)(false) 158 | * @endcode 159 | * 160 | * This is primarily useful when dealing with indexes and counts in 161 | * metaprogramming. 162 | */ 163 | #define metamacro_if_eq(A, B) \ 164 | metamacro_concat(metamacro_if_eq, A)(B) 165 | 166 | /** 167 | * Identical to #metamacro_if_eq. This can be used when the former would fail 168 | * due to recursive macro expansion. 169 | */ 170 | #define metamacro_if_eq_recursive(A, B) \ 171 | metamacro_concat(metamacro_if_eq_recursive, A)(B) 172 | 173 | /** 174 | * Returns 1 if N is an even number, or 0 otherwise. N must be between zero and 175 | * twenty, inclusive. 176 | * 177 | * For the purposes of this test, zero is considered even. 178 | */ 179 | #define metamacro_is_even(N) \ 180 | metamacro_at(N, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1) 181 | 182 | /** 183 | * Returns the logical NOT of B, which must be the number zero or one. 184 | */ 185 | #define metamacro_not(B) \ 186 | metamacro_at(B, 1, 0) 187 | 188 | // IMPLEMENTATION DETAILS FOLLOW! 189 | // Do not write code that depends on anything below this line. 190 | #define metamacro_stringify_(VALUE) # VALUE 191 | #define metamacro_concat_(A, B) A ## B 192 | #define metamacro_foreach_iter(INDEX, MACRO, ARG) MACRO(INDEX, ARG) 193 | #define metamacro_head_(FIRST, ...) FIRST 194 | #define metamacro_tail_(FIRST, ...) __VA_ARGS__ 195 | #define metamacro_consume_(...) 196 | #define metamacro_expand_(...) __VA_ARGS__ 197 | 198 | // implemented from scratch so that metamacro_concat() doesn't end up nesting 199 | #define metamacro_foreach_concat_iter(INDEX, BASE, ARG) metamacro_foreach_concat_iter_(BASE, ARG) 200 | #define metamacro_foreach_concat_iter_(BASE, ARG) BASE ## ARG 201 | 202 | // metamacro_at expansions 203 | #define metamacro_at0(...) metamacro_head(__VA_ARGS__) 204 | #define metamacro_at1(_0, ...) metamacro_head(__VA_ARGS__) 205 | #define metamacro_at2(_0, _1, ...) metamacro_head(__VA_ARGS__) 206 | #define metamacro_at3(_0, _1, _2, ...) metamacro_head(__VA_ARGS__) 207 | #define metamacro_at4(_0, _1, _2, _3, ...) metamacro_head(__VA_ARGS__) 208 | #define metamacro_at5(_0, _1, _2, _3, _4, ...) metamacro_head(__VA_ARGS__) 209 | #define metamacro_at6(_0, _1, _2, _3, _4, _5, ...) metamacro_head(__VA_ARGS__) 210 | #define metamacro_at7(_0, _1, _2, _3, _4, _5, _6, ...) metamacro_head(__VA_ARGS__) 211 | #define metamacro_at8(_0, _1, _2, _3, _4, _5, _6, _7, ...) metamacro_head(__VA_ARGS__) 212 | #define metamacro_at9(_0, _1, _2, _3, _4, _5, _6, _7, _8, ...) metamacro_head(__VA_ARGS__) 213 | #define metamacro_at10(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, ...) metamacro_head(__VA_ARGS__) 214 | #define metamacro_at11(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, ...) metamacro_head(__VA_ARGS__) 215 | #define metamacro_at12(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, ...) metamacro_head(__VA_ARGS__) 216 | #define metamacro_at13(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, ...) metamacro_head(__VA_ARGS__) 217 | #define metamacro_at14(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, ...) metamacro_head(__VA_ARGS__) 218 | #define metamacro_at15(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, ...) metamacro_head(__VA_ARGS__) 219 | #define metamacro_at16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) metamacro_head(__VA_ARGS__) 220 | #define metamacro_at17(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, ...) metamacro_head(__VA_ARGS__) 221 | #define metamacro_at18(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, ...) metamacro_head(__VA_ARGS__) 222 | #define metamacro_at19(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, ...) metamacro_head(__VA_ARGS__) 223 | #define metamacro_at20(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, ...) metamacro_head(__VA_ARGS__) 224 | 225 | // metamacro_foreach_cxt expansions 226 | #define metamacro_foreach_cxt0(MACRO, SEP, CONTEXT) 227 | #define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0) 228 | 229 | #define metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \ 230 | metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) \ 231 | SEP \ 232 | MACRO(1, CONTEXT, _1) 233 | 234 | #define metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \ 235 | metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \ 236 | SEP \ 237 | MACRO(2, CONTEXT, _2) 238 | 239 | #define metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ 240 | metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \ 241 | SEP \ 242 | MACRO(3, CONTEXT, _3) 243 | 244 | #define metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ 245 | metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ 246 | SEP \ 247 | MACRO(4, CONTEXT, _4) 248 | 249 | #define metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ 250 | metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ 251 | SEP \ 252 | MACRO(5, CONTEXT, _5) 253 | 254 | #define metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ 255 | metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ 256 | SEP \ 257 | MACRO(6, CONTEXT, _6) 258 | 259 | #define metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ 260 | metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ 261 | SEP \ 262 | MACRO(7, CONTEXT, _7) 263 | 264 | #define metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ 265 | metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ 266 | SEP \ 267 | MACRO(8, CONTEXT, _8) 268 | 269 | #define metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ 270 | metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ 271 | SEP \ 272 | MACRO(9, CONTEXT, _9) 273 | 274 | #define metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ 275 | metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ 276 | SEP \ 277 | MACRO(10, CONTEXT, _10) 278 | 279 | #define metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ 280 | metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ 281 | SEP \ 282 | MACRO(11, CONTEXT, _11) 283 | 284 | #define metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ 285 | metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ 286 | SEP \ 287 | MACRO(12, CONTEXT, _12) 288 | 289 | #define metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ 290 | metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ 291 | SEP \ 292 | MACRO(13, CONTEXT, _13) 293 | 294 | #define metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ 295 | metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ 296 | SEP \ 297 | MACRO(14, CONTEXT, _14) 298 | 299 | #define metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ 300 | metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ 301 | SEP \ 302 | MACRO(15, CONTEXT, _15) 303 | 304 | #define metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ 305 | metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ 306 | SEP \ 307 | MACRO(16, CONTEXT, _16) 308 | 309 | #define metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ 310 | metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ 311 | SEP \ 312 | MACRO(17, CONTEXT, _17) 313 | 314 | #define metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ 315 | metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ 316 | SEP \ 317 | MACRO(18, CONTEXT, _18) 318 | 319 | #define metamacro_foreach_cxt20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \ 320 | metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ 321 | SEP \ 322 | MACRO(19, CONTEXT, _19) 323 | 324 | // metamacro_foreach_cxt_recursive expansions 325 | #define metamacro_foreach_cxt_recursive0(MACRO, SEP, CONTEXT) 326 | #define metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0) 327 | 328 | #define metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \ 329 | metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) \ 330 | SEP \ 331 | MACRO(1, CONTEXT, _1) 332 | 333 | #define metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \ 334 | metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \ 335 | SEP \ 336 | MACRO(2, CONTEXT, _2) 337 | 338 | #define metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ 339 | metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \ 340 | SEP \ 341 | MACRO(3, CONTEXT, _3) 342 | 343 | #define metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ 344 | metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ 345 | SEP \ 346 | MACRO(4, CONTEXT, _4) 347 | 348 | #define metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ 349 | metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ 350 | SEP \ 351 | MACRO(5, CONTEXT, _5) 352 | 353 | #define metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ 354 | metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ 355 | SEP \ 356 | MACRO(6, CONTEXT, _6) 357 | 358 | #define metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ 359 | metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ 360 | SEP \ 361 | MACRO(7, CONTEXT, _7) 362 | 363 | #define metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ 364 | metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ 365 | SEP \ 366 | MACRO(8, CONTEXT, _8) 367 | 368 | #define metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ 369 | metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ 370 | SEP \ 371 | MACRO(9, CONTEXT, _9) 372 | 373 | #define metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ 374 | metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ 375 | SEP \ 376 | MACRO(10, CONTEXT, _10) 377 | 378 | #define metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ 379 | metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ 380 | SEP \ 381 | MACRO(11, CONTEXT, _11) 382 | 383 | #define metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ 384 | metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ 385 | SEP \ 386 | MACRO(12, CONTEXT, _12) 387 | 388 | #define metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ 389 | metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ 390 | SEP \ 391 | MACRO(13, CONTEXT, _13) 392 | 393 | #define metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ 394 | metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ 395 | SEP \ 396 | MACRO(14, CONTEXT, _14) 397 | 398 | #define metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ 399 | metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ 400 | SEP \ 401 | MACRO(15, CONTEXT, _15) 402 | 403 | #define metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ 404 | metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ 405 | SEP \ 406 | MACRO(16, CONTEXT, _16) 407 | 408 | #define metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ 409 | metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ 410 | SEP \ 411 | MACRO(17, CONTEXT, _17) 412 | 413 | #define metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ 414 | metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ 415 | SEP \ 416 | MACRO(18, CONTEXT, _18) 417 | 418 | #define metamacro_foreach_cxt_recursive20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \ 419 | metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ 420 | SEP \ 421 | MACRO(19, CONTEXT, _19) 422 | 423 | // metamacro_for_cxt expansions 424 | #define metamacro_for_cxt0(MACRO, SEP, CONTEXT) 425 | #define metamacro_for_cxt1(MACRO, SEP, CONTEXT) MACRO(0, CONTEXT) 426 | 427 | #define metamacro_for_cxt2(MACRO, SEP, CONTEXT) \ 428 | metamacro_for_cxt1(MACRO, SEP, CONTEXT) \ 429 | SEP \ 430 | MACRO(1, CONTEXT) 431 | 432 | #define metamacro_for_cxt3(MACRO, SEP, CONTEXT) \ 433 | metamacro_for_cxt2(MACRO, SEP, CONTEXT) \ 434 | SEP \ 435 | MACRO(2, CONTEXT) 436 | 437 | #define metamacro_for_cxt4(MACRO, SEP, CONTEXT) \ 438 | metamacro_for_cxt3(MACRO, SEP, CONTEXT) \ 439 | SEP \ 440 | MACRO(3, CONTEXT) 441 | 442 | #define metamacro_for_cxt5(MACRO, SEP, CONTEXT) \ 443 | metamacro_for_cxt4(MACRO, SEP, CONTEXT) \ 444 | SEP \ 445 | MACRO(4, CONTEXT) 446 | 447 | #define metamacro_for_cxt6(MACRO, SEP, CONTEXT) \ 448 | metamacro_for_cxt5(MACRO, SEP, CONTEXT) \ 449 | SEP \ 450 | MACRO(5, CONTEXT) 451 | 452 | #define metamacro_for_cxt7(MACRO, SEP, CONTEXT) \ 453 | metamacro_for_cxt6(MACRO, SEP, CONTEXT) \ 454 | SEP \ 455 | MACRO(6, CONTEXT) 456 | 457 | #define metamacro_for_cxt8(MACRO, SEP, CONTEXT) \ 458 | metamacro_for_cxt7(MACRO, SEP, CONTEXT) \ 459 | SEP \ 460 | MACRO(7, CONTEXT) 461 | 462 | #define metamacro_for_cxt9(MACRO, SEP, CONTEXT) \ 463 | metamacro_for_cxt8(MACRO, SEP, CONTEXT) \ 464 | SEP \ 465 | MACRO(8, CONTEXT) 466 | 467 | #define metamacro_for_cxt10(MACRO, SEP, CONTEXT) \ 468 | metamacro_for_cxt9(MACRO, SEP, CONTEXT) \ 469 | SEP \ 470 | MACRO(9, CONTEXT) 471 | 472 | #define metamacro_for_cxt11(MACRO, SEP, CONTEXT) \ 473 | metamacro_for_cxt10(MACRO, SEP, CONTEXT) \ 474 | SEP \ 475 | MACRO(10, CONTEXT) 476 | 477 | #define metamacro_for_cxt12(MACRO, SEP, CONTEXT) \ 478 | metamacro_for_cxt11(MACRO, SEP, CONTEXT) \ 479 | SEP \ 480 | MACRO(11, CONTEXT) 481 | 482 | #define metamacro_for_cxt13(MACRO, SEP, CONTEXT) \ 483 | metamacro_for_cxt12(MACRO, SEP, CONTEXT) \ 484 | SEP \ 485 | MACRO(12, CONTEXT) 486 | 487 | #define metamacro_for_cxt14(MACRO, SEP, CONTEXT) \ 488 | metamacro_for_cxt13(MACRO, SEP, CONTEXT) \ 489 | SEP \ 490 | MACRO(13, CONTEXT) 491 | 492 | #define metamacro_for_cxt15(MACRO, SEP, CONTEXT) \ 493 | metamacro_for_cxt14(MACRO, SEP, CONTEXT) \ 494 | SEP \ 495 | MACRO(14, CONTEXT) 496 | 497 | #define metamacro_for_cxt16(MACRO, SEP, CONTEXT) \ 498 | metamacro_for_cxt15(MACRO, SEP, CONTEXT) \ 499 | SEP \ 500 | MACRO(15, CONTEXT) 501 | 502 | #define metamacro_for_cxt17(MACRO, SEP, CONTEXT) \ 503 | metamacro_for_cxt16(MACRO, SEP, CONTEXT) \ 504 | SEP \ 505 | MACRO(16, CONTEXT) 506 | 507 | #define metamacro_for_cxt18(MACRO, SEP, CONTEXT) \ 508 | metamacro_for_cxt17(MACRO, SEP, CONTEXT) \ 509 | SEP \ 510 | MACRO(17, CONTEXT) 511 | 512 | #define metamacro_for_cxt19(MACRO, SEP, CONTEXT) \ 513 | metamacro_for_cxt18(MACRO, SEP, CONTEXT) \ 514 | SEP \ 515 | MACRO(18, CONTEXT) 516 | 517 | #define metamacro_for_cxt20(MACRO, SEP, CONTEXT) \ 518 | metamacro_for_cxt19(MACRO, SEP, CONTEXT) \ 519 | SEP \ 520 | MACRO(19, CONTEXT) 521 | 522 | // metamacro_if_eq expansions 523 | #define metamacro_if_eq0(VALUE) \ 524 | metamacro_concat(metamacro_if_eq0_, VALUE) 525 | 526 | #define metamacro_if_eq0_0(...) __VA_ARGS__ metamacro_consume_ 527 | #define metamacro_if_eq0_1(...) metamacro_expand_ 528 | #define metamacro_if_eq0_2(...) metamacro_expand_ 529 | #define metamacro_if_eq0_3(...) metamacro_expand_ 530 | #define metamacro_if_eq0_4(...) metamacro_expand_ 531 | #define metamacro_if_eq0_5(...) metamacro_expand_ 532 | #define metamacro_if_eq0_6(...) metamacro_expand_ 533 | #define metamacro_if_eq0_7(...) metamacro_expand_ 534 | #define metamacro_if_eq0_8(...) metamacro_expand_ 535 | #define metamacro_if_eq0_9(...) metamacro_expand_ 536 | #define metamacro_if_eq0_10(...) metamacro_expand_ 537 | #define metamacro_if_eq0_11(...) metamacro_expand_ 538 | #define metamacro_if_eq0_12(...) metamacro_expand_ 539 | #define metamacro_if_eq0_13(...) metamacro_expand_ 540 | #define metamacro_if_eq0_14(...) metamacro_expand_ 541 | #define metamacro_if_eq0_15(...) metamacro_expand_ 542 | #define metamacro_if_eq0_16(...) metamacro_expand_ 543 | #define metamacro_if_eq0_17(...) metamacro_expand_ 544 | #define metamacro_if_eq0_18(...) metamacro_expand_ 545 | #define metamacro_if_eq0_19(...) metamacro_expand_ 546 | #define metamacro_if_eq0_20(...) metamacro_expand_ 547 | 548 | #define metamacro_if_eq1(VALUE) metamacro_if_eq0(metamacro_dec(VALUE)) 549 | #define metamacro_if_eq2(VALUE) metamacro_if_eq1(metamacro_dec(VALUE)) 550 | #define metamacro_if_eq3(VALUE) metamacro_if_eq2(metamacro_dec(VALUE)) 551 | #define metamacro_if_eq4(VALUE) metamacro_if_eq3(metamacro_dec(VALUE)) 552 | #define metamacro_if_eq5(VALUE) metamacro_if_eq4(metamacro_dec(VALUE)) 553 | #define metamacro_if_eq6(VALUE) metamacro_if_eq5(metamacro_dec(VALUE)) 554 | #define metamacro_if_eq7(VALUE) metamacro_if_eq6(metamacro_dec(VALUE)) 555 | #define metamacro_if_eq8(VALUE) metamacro_if_eq7(metamacro_dec(VALUE)) 556 | #define metamacro_if_eq9(VALUE) metamacro_if_eq8(metamacro_dec(VALUE)) 557 | #define metamacro_if_eq10(VALUE) metamacro_if_eq9(metamacro_dec(VALUE)) 558 | #define metamacro_if_eq11(VALUE) metamacro_if_eq10(metamacro_dec(VALUE)) 559 | #define metamacro_if_eq12(VALUE) metamacro_if_eq11(metamacro_dec(VALUE)) 560 | #define metamacro_if_eq13(VALUE) metamacro_if_eq12(metamacro_dec(VALUE)) 561 | #define metamacro_if_eq14(VALUE) metamacro_if_eq13(metamacro_dec(VALUE)) 562 | #define metamacro_if_eq15(VALUE) metamacro_if_eq14(metamacro_dec(VALUE)) 563 | #define metamacro_if_eq16(VALUE) metamacro_if_eq15(metamacro_dec(VALUE)) 564 | #define metamacro_if_eq17(VALUE) metamacro_if_eq16(metamacro_dec(VALUE)) 565 | #define metamacro_if_eq18(VALUE) metamacro_if_eq17(metamacro_dec(VALUE)) 566 | #define metamacro_if_eq19(VALUE) metamacro_if_eq18(metamacro_dec(VALUE)) 567 | #define metamacro_if_eq20(VALUE) metamacro_if_eq19(metamacro_dec(VALUE)) 568 | 569 | // metamacro_if_eq_recursive expansions 570 | #define metamacro_if_eq_recursive0(VALUE) \ 571 | metamacro_concat(metamacro_if_eq_recursive0_, VALUE) 572 | 573 | #define metamacro_if_eq_recursive0_0(...) __VA_ARGS__ metamacro_consume_ 574 | #define metamacro_if_eq_recursive0_1(...) metamacro_expand_ 575 | #define metamacro_if_eq_recursive0_2(...) metamacro_expand_ 576 | #define metamacro_if_eq_recursive0_3(...) metamacro_expand_ 577 | #define metamacro_if_eq_recursive0_4(...) metamacro_expand_ 578 | #define metamacro_if_eq_recursive0_5(...) metamacro_expand_ 579 | #define metamacro_if_eq_recursive0_6(...) metamacro_expand_ 580 | #define metamacro_if_eq_recursive0_7(...) metamacro_expand_ 581 | #define metamacro_if_eq_recursive0_8(...) metamacro_expand_ 582 | #define metamacro_if_eq_recursive0_9(...) metamacro_expand_ 583 | #define metamacro_if_eq_recursive0_10(...) metamacro_expand_ 584 | #define metamacro_if_eq_recursive0_11(...) metamacro_expand_ 585 | #define metamacro_if_eq_recursive0_12(...) metamacro_expand_ 586 | #define metamacro_if_eq_recursive0_13(...) metamacro_expand_ 587 | #define metamacro_if_eq_recursive0_14(...) metamacro_expand_ 588 | #define metamacro_if_eq_recursive0_15(...) metamacro_expand_ 589 | #define metamacro_if_eq_recursive0_16(...) metamacro_expand_ 590 | #define metamacro_if_eq_recursive0_17(...) metamacro_expand_ 591 | #define metamacro_if_eq_recursive0_18(...) metamacro_expand_ 592 | #define metamacro_if_eq_recursive0_19(...) metamacro_expand_ 593 | #define metamacro_if_eq_recursive0_20(...) metamacro_expand_ 594 | 595 | #define metamacro_if_eq_recursive1(VALUE) metamacro_if_eq_recursive0(metamacro_dec(VALUE)) 596 | #define metamacro_if_eq_recursive2(VALUE) metamacro_if_eq_recursive1(metamacro_dec(VALUE)) 597 | #define metamacro_if_eq_recursive3(VALUE) metamacro_if_eq_recursive2(metamacro_dec(VALUE)) 598 | #define metamacro_if_eq_recursive4(VALUE) metamacro_if_eq_recursive3(metamacro_dec(VALUE)) 599 | #define metamacro_if_eq_recursive5(VALUE) metamacro_if_eq_recursive4(metamacro_dec(VALUE)) 600 | #define metamacro_if_eq_recursive6(VALUE) metamacro_if_eq_recursive5(metamacro_dec(VALUE)) 601 | #define metamacro_if_eq_recursive7(VALUE) metamacro_if_eq_recursive6(metamacro_dec(VALUE)) 602 | #define metamacro_if_eq_recursive8(VALUE) metamacro_if_eq_recursive7(metamacro_dec(VALUE)) 603 | #define metamacro_if_eq_recursive9(VALUE) metamacro_if_eq_recursive8(metamacro_dec(VALUE)) 604 | #define metamacro_if_eq_recursive10(VALUE) metamacro_if_eq_recursive9(metamacro_dec(VALUE)) 605 | #define metamacro_if_eq_recursive11(VALUE) metamacro_if_eq_recursive10(metamacro_dec(VALUE)) 606 | #define metamacro_if_eq_recursive12(VALUE) metamacro_if_eq_recursive11(metamacro_dec(VALUE)) 607 | #define metamacro_if_eq_recursive13(VALUE) metamacro_if_eq_recursive12(metamacro_dec(VALUE)) 608 | #define metamacro_if_eq_recursive14(VALUE) metamacro_if_eq_recursive13(metamacro_dec(VALUE)) 609 | #define metamacro_if_eq_recursive15(VALUE) metamacro_if_eq_recursive14(metamacro_dec(VALUE)) 610 | #define metamacro_if_eq_recursive16(VALUE) metamacro_if_eq_recursive15(metamacro_dec(VALUE)) 611 | #define metamacro_if_eq_recursive17(VALUE) metamacro_if_eq_recursive16(metamacro_dec(VALUE)) 612 | #define metamacro_if_eq_recursive18(VALUE) metamacro_if_eq_recursive17(metamacro_dec(VALUE)) 613 | #define metamacro_if_eq_recursive19(VALUE) metamacro_if_eq_recursive18(metamacro_dec(VALUE)) 614 | #define metamacro_if_eq_recursive20(VALUE) metamacro_if_eq_recursive19(metamacro_dec(VALUE)) 615 | 616 | // metamacro_take expansions 617 | #define metamacro_take0(...) 618 | #define metamacro_take1(...) metamacro_head(__VA_ARGS__) 619 | #define metamacro_take2(...) metamacro_head(__VA_ARGS__), metamacro_take1(metamacro_tail(__VA_ARGS__)) 620 | #define metamacro_take3(...) metamacro_head(__VA_ARGS__), metamacro_take2(metamacro_tail(__VA_ARGS__)) 621 | #define metamacro_take4(...) metamacro_head(__VA_ARGS__), metamacro_take3(metamacro_tail(__VA_ARGS__)) 622 | #define metamacro_take5(...) metamacro_head(__VA_ARGS__), metamacro_take4(metamacro_tail(__VA_ARGS__)) 623 | #define metamacro_take6(...) metamacro_head(__VA_ARGS__), metamacro_take5(metamacro_tail(__VA_ARGS__)) 624 | #define metamacro_take7(...) metamacro_head(__VA_ARGS__), metamacro_take6(metamacro_tail(__VA_ARGS__)) 625 | #define metamacro_take8(...) metamacro_head(__VA_ARGS__), metamacro_take7(metamacro_tail(__VA_ARGS__)) 626 | #define metamacro_take9(...) metamacro_head(__VA_ARGS__), metamacro_take8(metamacro_tail(__VA_ARGS__)) 627 | #define metamacro_take10(...) metamacro_head(__VA_ARGS__), metamacro_take9(metamacro_tail(__VA_ARGS__)) 628 | #define metamacro_take11(...) metamacro_head(__VA_ARGS__), metamacro_take10(metamacro_tail(__VA_ARGS__)) 629 | #define metamacro_take12(...) metamacro_head(__VA_ARGS__), metamacro_take11(metamacro_tail(__VA_ARGS__)) 630 | #define metamacro_take13(...) metamacro_head(__VA_ARGS__), metamacro_take12(metamacro_tail(__VA_ARGS__)) 631 | #define metamacro_take14(...) metamacro_head(__VA_ARGS__), metamacro_take13(metamacro_tail(__VA_ARGS__)) 632 | #define metamacro_take15(...) metamacro_head(__VA_ARGS__), metamacro_take14(metamacro_tail(__VA_ARGS__)) 633 | #define metamacro_take16(...) metamacro_head(__VA_ARGS__), metamacro_take15(metamacro_tail(__VA_ARGS__)) 634 | #define metamacro_take17(...) metamacro_head(__VA_ARGS__), metamacro_take16(metamacro_tail(__VA_ARGS__)) 635 | #define metamacro_take18(...) metamacro_head(__VA_ARGS__), metamacro_take17(metamacro_tail(__VA_ARGS__)) 636 | #define metamacro_take19(...) metamacro_head(__VA_ARGS__), metamacro_take18(metamacro_tail(__VA_ARGS__)) 637 | #define metamacro_take20(...) metamacro_head(__VA_ARGS__), metamacro_take19(metamacro_tail(__VA_ARGS__)) 638 | 639 | // metamacro_drop expansions 640 | #define metamacro_drop0(...) __VA_ARGS__ 641 | #define metamacro_drop1(...) metamacro_tail(__VA_ARGS__) 642 | #define metamacro_drop2(...) metamacro_drop1(metamacro_tail(__VA_ARGS__)) 643 | #define metamacro_drop3(...) metamacro_drop2(metamacro_tail(__VA_ARGS__)) 644 | #define metamacro_drop4(...) metamacro_drop3(metamacro_tail(__VA_ARGS__)) 645 | #define metamacro_drop5(...) metamacro_drop4(metamacro_tail(__VA_ARGS__)) 646 | #define metamacro_drop6(...) metamacro_drop5(metamacro_tail(__VA_ARGS__)) 647 | #define metamacro_drop7(...) metamacro_drop6(metamacro_tail(__VA_ARGS__)) 648 | #define metamacro_drop8(...) metamacro_drop7(metamacro_tail(__VA_ARGS__)) 649 | #define metamacro_drop9(...) metamacro_drop8(metamacro_tail(__VA_ARGS__)) 650 | #define metamacro_drop10(...) metamacro_drop9(metamacro_tail(__VA_ARGS__)) 651 | #define metamacro_drop11(...) metamacro_drop10(metamacro_tail(__VA_ARGS__)) 652 | #define metamacro_drop12(...) metamacro_drop11(metamacro_tail(__VA_ARGS__)) 653 | #define metamacro_drop13(...) metamacro_drop12(metamacro_tail(__VA_ARGS__)) 654 | #define metamacro_drop14(...) metamacro_drop13(metamacro_tail(__VA_ARGS__)) 655 | #define metamacro_drop15(...) metamacro_drop14(metamacro_tail(__VA_ARGS__)) 656 | #define metamacro_drop16(...) metamacro_drop15(metamacro_tail(__VA_ARGS__)) 657 | #define metamacro_drop17(...) metamacro_drop16(metamacro_tail(__VA_ARGS__)) 658 | #define metamacro_drop18(...) metamacro_drop17(metamacro_tail(__VA_ARGS__)) 659 | #define metamacro_drop19(...) metamacro_drop18(metamacro_tail(__VA_ARGS__)) 660 | #define metamacro_drop20(...) metamacro_drop19(metamacro_tail(__VA_ARGS__)) 661 | 662 | #endif 663 | -------------------------------------------------------------------------------- /AnnotationKit/EventCenter/LifeCycleAnnnotation.h: -------------------------------------------------------------------------------- 1 | // 2 | // LifeCycleAnnnotation.h 3 | // Pods 4 | // 5 | // Created by luoqihsneg on 2016/11/5. 6 | // 7 | // 8 | 9 | #import 10 | #import "AKEngine.h" 11 | 12 | #ifndef When 13 | 14 | #define AppLaunched 15 | #define AppResignActive 16 | #define AppBecameActive 17 | #define AppEnterForeground 18 | #define AppEnterBackground 19 | #define AppWillTerminate 20 | #define AppFirstLaunched 21 | 22 | #define When(event,cls,selector) \ 23 | class AKEngine; char *const NameGen(cls) AnnotationDATA(eventkit) = "{\"cls\":\""#cls"\",\"sel\":\""#selector"\",\"event\":\""#event"\"}"; 24 | #endif 25 | -------------------------------------------------------------------------------- /AnnotationKit/EventCenter/LifeCycleAnnnotation.m: -------------------------------------------------------------------------------- 1 | // 2 | // LifeCycleAnnnotation.m 3 | // Pods 4 | // 5 | // Created by luoqihsneg on 2016/11/5. 6 | // 7 | // 8 | 9 | #import "LifeCycleAnnnotation.h" 10 | #import "NSDictionary+AnnotationKit.h" 11 | 12 | 13 | 14 | //section 是这个注解的配置来源,无需加双引号 15 | //handler 是获取注解配置的地方。 16 | @DefineAnnotation(LifeCycleAnnnotation,eventkit) 17 | @interface LifeCycleAnnnotation : PHAnnotationHandler 18 | 19 | @property (nonatomic,strong)NSMutableArray *AppLaunchedHandler; 20 | @property (nonatomic,strong)NSMutableArray *AppResignActiveHandler; 21 | @property (nonatomic,strong)NSMutableArray *AppBecameActiveHandler; 22 | @property (nonatomic,strong)NSMutableArray *AppToForegroundHandler; 23 | @property (nonatomic,strong)NSMutableArray *AppToBackgroundHandler; 24 | @property (nonatomic,strong)NSMutableArray *AppFirstLaunchedHandler; 25 | 26 | @end 27 | 28 | static NSString *const AppLaunchedEventName = @"AppLaunched"; 29 | static NSString *const AppResignActiveEventName = @"AppResignActive"; 30 | static NSString *const AppBecameActiveEventName = @"AppBecameActive"; 31 | static NSString *const AppToForegroundEventName = @"AppEnterForeground"; 32 | static NSString *const AppToBackgroundEventName = @"AppEnterBackground"; 33 | static NSString *const AppFirstLaunchedEventName = @"AppFirstLaunched"; 34 | 35 | @implementation LifeCycleAnnnotation 36 | - (instancetype)init 37 | { 38 | self = [super init]; 39 | if (self) { 40 | self.AppLaunchedHandler = [NSMutableArray array]; 41 | self.AppResignActiveHandler = [NSMutableArray array]; 42 | self.AppBecameActiveHandler = [NSMutableArray array]; 43 | self.AppToForegroundHandler = [NSMutableArray array]; 44 | self.AppToBackgroundHandler = [NSMutableArray array]; 45 | self.AppFirstLaunchedHandler = [NSMutableArray array]; 46 | 47 | [[NSNotificationCenter defaultCenter]addObserver:self 48 | selector:@selector(onLifeCycleCallBack:) 49 | name:UIApplicationDidFinishLaunchingNotification 50 | object:nil]; 51 | 52 | [[NSNotificationCenter defaultCenter]addObserver:self 53 | selector:@selector(onLifeCycleCallBack:) 54 | name:UIApplicationWillResignActiveNotification 55 | object:nil]; 56 | 57 | [[NSNotificationCenter defaultCenter]addObserver:self 58 | selector:@selector(onLifeCycleCallBack:) 59 | name:UIApplicationDidBecomeActiveNotification 60 | object:nil]; 61 | 62 | [[NSNotificationCenter defaultCenter]addObserver:self 63 | selector:@selector(onLifeCycleCallBack:) 64 | name:UIApplicationWillEnterForegroundNotification 65 | object:nil]; 66 | 67 | [[NSNotificationCenter defaultCenter]addObserver:self 68 | selector:@selector(onLifeCycleCallBack:) 69 | name:UIApplicationDidEnterBackgroundNotification 70 | object:nil]; 71 | 72 | } 73 | return self; 74 | } 75 | 76 | - (void)handleAnnotationConfig:(NSArray *)configs 77 | { 78 | for (NSString *map in configs) { 79 | NSData *jsonData = [map dataUsingEncoding:NSUTF8StringEncoding]; 80 | NSError *error = nil; 81 | id json = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; 82 | if (!error) { 83 | if ([json isKindOfClass:[NSDictionary class]]) { 84 | NSString *clsName = [json akSafeObjectForKey:@"cls"]; 85 | NSString *sel = [json akSafeObjectForKey:@"sel"]; 86 | NSString *event = [json akSafeObjectForKey:@"event"]; 87 | 88 | if ([event isEqualToString:AppLaunchedEventName]) { 89 | [self.AppLaunchedHandler addObject:@{clsName:sel}]; 90 | } 91 | 92 | if ([event isEqualToString:AppResignActiveEventName]) { 93 | [self.AppResignActiveHandler addObject:@{clsName:sel}]; 94 | } 95 | 96 | if ([event isEqualToString:AppBecameActiveEventName]) { 97 | [self.AppBecameActiveHandler addObject:@{clsName:sel}]; 98 | } 99 | 100 | if ([event isEqualToString:AppToForegroundEventName]) { 101 | [self.AppToForegroundHandler addObject:@{clsName:sel}]; 102 | } 103 | 104 | if ([event isEqualToString:AppToBackgroundEventName]) { 105 | [self.AppToBackgroundHandler addObject:@{clsName:sel}]; 106 | } 107 | 108 | if ([event isEqualToString:AppFirstLaunchedEventName]) { 109 | [self.AppFirstLaunchedHandler addObject:@{clsName:sel}]; 110 | } 111 | } 112 | } 113 | } 114 | } 115 | 116 | #pragma mark - notification 117 | - (void)onLifeCycleCallBack:(NSNotification *)note 118 | { 119 | @synchronized (self) { 120 | NSMutableArray *dispatcher = nil; 121 | if ([note.name isEqualToString:UIApplicationDidFinishLaunchingNotification]) { 122 | dispatcher = self.AppLaunchedHandler; 123 | } 124 | 125 | if ([note.name isEqualToString:UIApplicationWillResignActiveNotification]) { 126 | dispatcher = self.AppResignActiveHandler; 127 | } 128 | 129 | if ([note.name isEqualToString:UIApplicationDidBecomeActiveNotification]) { 130 | dispatcher = self.AppBecameActiveHandler; 131 | } 132 | 133 | if ([note.name isEqualToString:UIApplicationWillEnterForegroundNotification]) { 134 | dispatcher = self.AppToForegroundHandler; 135 | } 136 | 137 | if ([note.name isEqualToString:UIApplicationDidEnterBackgroundNotification]) { 138 | dispatcher = self.AppToBackgroundHandler; 139 | } 140 | 141 | for (NSDictionary *map in dispatcher) { 142 | NSString *clsName = [[map allKeys]firstObject]; 143 | NSString *selName = [self extractSelectorNameFrom:[map akSafeObjectForKey:clsName]]; 144 | 145 | if (clsName && selName) { 146 | Class cls = NSClassFromString(clsName); 147 | SEL sel = NSSelectorFromString(selName); 148 | if ([cls respondsToSelector:sel]) { 149 | ((void (*)(id, SEL,NSNotification *))[cls methodForSelector:sel])(cls, sel,note); 150 | } 151 | } 152 | } 153 | } 154 | } 155 | 156 | // str likes `@selector(func:arg:)` 157 | // return `func:arg:` 158 | - (NSString *)extractSelectorNameFrom:(NSString *)str { 159 | if (!str) { 160 | return nil; 161 | } 162 | NSString *selName = [str stringByReplacingOccurrencesOfString:@"@selector(" withString:@""]; 163 | selName = [selName stringByReplacingOccurrencesOfString:@")" withString:@""]; 164 | return selName; 165 | } 166 | @end 167 | -------------------------------------------------------------------------------- /AnnotationKit/Router/AKRouteAnnotation.h: -------------------------------------------------------------------------------- 1 | // 2 | // AKRouteAnnotaion.h 3 | // Pods 4 | // 5 | // Created by luoqihsneg on 2016/11/5. 6 | // 7 | // 8 | 9 | #import 10 | #import "AKEngine.h" 11 | 12 | #ifndef RequestMapping 13 | #define RequestMapping(cls,url) \ 14 | class AKEngine; char *const NameGen(cls) AnnotationDATA(route) = "{\""#cls"\":"#url"}"; 15 | #endif 16 | 17 | #ifndef AKNPC 18 | #define AKNPC(cls,sel,url) \ 19 | class AKEngine; char *const NameGen(cls) AnnotationDATA(npc) = "{\"cls_name\":\""#cls"\",\"sel_name\":\""#sel"\",\"url\":"#url"}"; 20 | #endif 21 | 22 | @interface AKRouteAnnotation : PHAnnotationHandler 23 | @end 24 | 25 | @interface AKNPCAnnotation : PHAnnotationHandler 26 | @end 27 | -------------------------------------------------------------------------------- /AnnotationKit/Router/AKRouteAnnotation.m: -------------------------------------------------------------------------------- 1 | // 2 | // AKRouteAnnotaion.m 3 | // Pods 4 | // 5 | // Created by luoqihsneg on 2016/11/5. 6 | // 7 | // 8 | 9 | #import "AKRouteAnnotation.h" 10 | #import "NSDictionary+AnnotationKit.h" 11 | #import "AKRouter.h" 12 | @interface AKRouteAnnotation () 13 | @property (nonatomic,strong)NSMutableArray *configs; 14 | @end 15 | 16 | @DefineAnnotation(AKRouteAnnotation,route) 17 | @implementation AKRouteAnnotation 18 | - (instancetype)init 19 | { 20 | self = [super init]; 21 | if (self) { 22 | self.configs = [NSMutableArray array]; 23 | } 24 | return self; 25 | } 26 | 27 | - (void)handleAnnotationConfig:(NSArray *)configs { 28 | for (NSString *map in configs) { 29 | NSData *jsonData = [map dataUsingEncoding:NSUTF8StringEncoding]; 30 | NSError *error = nil; 31 | id json = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; 32 | if (!error) { 33 | if ([json isKindOfClass:[NSDictionary class]] && [json allKeys].count == 1) { 34 | NSString *clsName = [[json allKeys] firstObject]; 35 | NSString *url = [json akSafeObjectForKey:clsName]; 36 | if (clsName && url) { 37 | [[AKRouter shared]map:url toControllerClass:NSClassFromString(clsName)]; 38 | [self.configs addObject:@{url:clsName}]; 39 | } 40 | } 41 | } 42 | } 43 | } 44 | @end 45 | 46 | @DefineAnnotation(AKNPCAnnotation,npc) 47 | @implementation AKNPCAnnotation 48 | - (void)handleAnnotationConfig:(NSArray *)configs 49 | { 50 | for (NSString *map in configs) { 51 | NSData *jsonData = [map dataUsingEncoding:NSUTF8StringEncoding]; 52 | NSError *error = nil; 53 | id json = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; 54 | if (!error) { 55 | if ([json isKindOfClass:[NSDictionary class]] && [json allKeys].count == 3) { 56 | NSString *clsName = [json akSafeObjectForKey:@"cls_name"]; 57 | NSString *selName = [json akSafeObjectForKey:@"sel_name"]; 58 | NSString *url = [json akSafeObjectForKey:@"url"]; 59 | 60 | Class cls = NSClassFromString(clsName); 61 | SEL sel = NSSelectorFromString([NSString stringWithFormat:@"%@:",selName]); 62 | 63 | if ([cls respondsToSelector:sel] && url) { 64 | 65 | [[AKRouter shared]map:url toBlock:(id)^(NSDictionary *params) { 66 | id ret = ((id (*)(id, SEL,NSDictionary *))[cls methodForSelector:sel])(cls, sel,params); 67 | return ret; 68 | }]; 69 | } 70 | } 71 | } 72 | } 73 | 74 | } 75 | @end 76 | -------------------------------------------------------------------------------- /AnnotationKit/Router/AKRouter.h: -------------------------------------------------------------------------------- 1 | // 2 | // AKRouter.h 3 | // Pods 4 | // 5 | // Created by luoqihsneg on 2017/3/30. 6 | // 7 | // 8 | 9 | #import 10 | 11 | typedef id (^AKRouterBlock)(NSDictionary *params); 12 | 13 | 14 | @interface AKRouter : NSObject 15 | + (instancetype)shared; 16 | - (UIViewController *)matchController:(NSString *)route; 17 | - (void)routeTo:(NSString *)route; 18 | - (BOOL)canRoute:(NSString *)route; 19 | - (void)map:(NSString *)route toControllerClass:(Class)controllerClass; 20 | - (void)map:(NSString *)route toBlock:(AKRouterBlock)block; 21 | 22 | @end 23 | 24 | ///-------------------------------- 25 | /// @name UIViewController Category 26 | ///-------------------------------- 27 | 28 | @interface UIViewController (AKRouter) 29 | 30 | @property (nonatomic, strong) NSDictionary *params; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /AnnotationKit/Router/AKRouter.m: -------------------------------------------------------------------------------- 1 | // 2 | // AKRouter.m 3 | // Pods 4 | // 5 | // Created by luoqihsneg on 2017/3/30. 6 | // 7 | // 8 | 9 | #import "AKRouter.h" 10 | #import 11 | @implementation AKRouter 12 | 13 | + (instancetype)shared 14 | { 15 | static AKRouter *router = nil; 16 | static dispatch_once_t onceToken; 17 | 18 | dispatch_once(&onceToken, ^{ 19 | router = [[self alloc] init]; 20 | }); 21 | return router; 22 | } 23 | 24 | 25 | - (UIViewController *)matchController:(NSString *)route 26 | { 27 | return [[HHRouter shared]matchController:route]; 28 | } 29 | 30 | - (void)routeTo:(NSString *)route 31 | { 32 | HHRouteType ret= [[HHRouter shared]canRoute:route]; 33 | 34 | switch (ret) { 35 | case HHRouteTypeViewController: 36 | { 37 | UIViewController *vc = [self matchController:route]; 38 | [[self topViewController].navigationController pushViewController:vc animated:YES]; 39 | } 40 | break; 41 | case HHRouteTypeBlock: 42 | { 43 | [[HHRouter shared]callBlock:route]; 44 | 45 | } 46 | break; 47 | default: 48 | break; 49 | } 50 | } 51 | 52 | - (BOOL)canRoute:(NSString *)route 53 | { 54 | HHRouteType ret= [[HHRouter shared]canRoute:route]; 55 | 56 | return (ret != HHRouteTypeNone); 57 | } 58 | 59 | - (void)map:(NSString *)route toControllerClass:(Class)controllerClass 60 | { 61 | [[HHRouter shared]map:route toControllerClass:controllerClass]; 62 | } 63 | 64 | - (void)map:(NSString *)route toBlock:(AKRouterBlock)block 65 | { 66 | [[HHRouter shared]map:route toBlock:block]; 67 | } 68 | 69 | 70 | - (UIViewController *)topViewController{ 71 | return [self topViewController:[UIApplication sharedApplication].keyWindow.rootViewController]; 72 | } 73 | 74 | - (UIViewController *)topViewController:(UIViewController *)rootViewController 75 | { 76 | if ([rootViewController isKindOfClass:[UINavigationController class]]) { 77 | UINavigationController *navigationController = (UINavigationController *)rootViewController; 78 | return [self topViewController:[navigationController.viewControllers lastObject]]; 79 | } 80 | if ([rootViewController isKindOfClass:[UITabBarController class]]) { 81 | UITabBarController *tabController = (UITabBarController *)rootViewController; 82 | return [self topViewController:tabController.selectedViewController]; 83 | } 84 | if (rootViewController.presentedViewController) { 85 | return [self topViewController:rootViewController]; 86 | } 87 | return rootViewController; 88 | } 89 | @end 90 | -------------------------------------------------------------------------------- /AnnotationKit/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mkdir ~/Library/Developer/Xcode/UserData/CodeSnippets/ 3 | cp -R CodeSnippets/ ~/Library/Developer/Xcode/UserData/CodeSnippets/ 4 | -------------------------------------------------------------------------------- /AnnotationKitDemo/AnnotationKitDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2B05EBF021800CB800ADD2C9 /* ViewController+Counter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B05EBEE21800CB800ADD2C9 /* ViewController+Counter.m */; }; 11 | B098B1DA447AC728B690F82D /* Pods_AnnotationKitDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A0138AD7D99EF53C9073A144 /* Pods_AnnotationKitDemo.framework */; }; 12 | F8CB9E931E8CD0CE00431C16 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F8CB9E921E8CD0CE00431C16 /* main.m */; }; 13 | F8CB9E961E8CD0CE00431C16 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F8CB9E951E8CD0CE00431C16 /* AppDelegate.m */; }; 14 | F8CB9E991E8CD0CE00431C16 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F8CB9E981E8CD0CE00431C16 /* ViewController.m */; }; 15 | F8CB9E9C1E8CD0CE00431C16 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F8CB9E9A1E8CD0CE00431C16 /* Main.storyboard */; }; 16 | F8CB9E9E1E8CD0CE00431C16 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F8CB9E9D1E8CD0CE00431C16 /* Assets.xcassets */; }; 17 | F8CB9EA11E8CD0CE00431C16 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F8CB9E9F1E8CD0CE00431C16 /* LaunchScreen.storyboard */; }; 18 | F8CB9EAA1E8CD3EC00431C16 /* ProfileController.m in Sources */ = {isa = PBXBuildFile; fileRef = F8CB9EA91E8CD3EC00431C16 /* ProfileController.m */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXFileReference section */ 22 | 2B05EBEE21800CB800ADD2C9 /* ViewController+Counter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ViewController+Counter.m"; sourceTree = ""; }; 23 | 2B05EBEF21800CB800ADD2C9 /* ViewController+Counter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ViewController+Counter.h"; sourceTree = ""; }; 24 | 2E9C89D8FCC017BA82ED3885 /* Pods-AnnotationKitDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AnnotationKitDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AnnotationKitDemo/Pods-AnnotationKitDemo.debug.xcconfig"; sourceTree = ""; }; 25 | A0138AD7D99EF53C9073A144 /* Pods_AnnotationKitDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AnnotationKitDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 26 | AAECAFBC6F58FE01A32A007A /* Pods-AnnotationKitDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AnnotationKitDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-AnnotationKitDemo/Pods-AnnotationKitDemo.release.xcconfig"; sourceTree = ""; }; 27 | F8CB9E8E1E8CD0CE00431C16 /* AnnotationKitDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AnnotationKitDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | F8CB9E921E8CD0CE00431C16 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 29 | F8CB9E941E8CD0CE00431C16 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 30 | F8CB9E951E8CD0CE00431C16 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 31 | F8CB9E971E8CD0CE00431C16 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 32 | F8CB9E981E8CD0CE00431C16 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 33 | F8CB9E9B1E8CD0CE00431C16 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 34 | F8CB9E9D1E8CD0CE00431C16 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 35 | F8CB9EA01E8CD0CE00431C16 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 36 | F8CB9EA21E8CD0CE00431C16 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 37 | F8CB9EA81E8CD3EC00431C16 /* ProfileController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProfileController.h; sourceTree = ""; }; 38 | F8CB9EA91E8CD3EC00431C16 /* ProfileController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProfileController.m; sourceTree = ""; }; 39 | /* End PBXFileReference section */ 40 | 41 | /* Begin PBXFrameworksBuildPhase section */ 42 | F8CB9E8B1E8CD0CE00431C16 /* Frameworks */ = { 43 | isa = PBXFrameworksBuildPhase; 44 | buildActionMask = 2147483647; 45 | files = ( 46 | B098B1DA447AC728B690F82D /* Pods_AnnotationKitDemo.framework in Frameworks */, 47 | ); 48 | runOnlyForDeploymentPostprocessing = 0; 49 | }; 50 | /* End PBXFrameworksBuildPhase section */ 51 | 52 | /* Begin PBXGroup section */ 53 | 07E6A286F2637AEF7B7B8A2A /* Frameworks */ = { 54 | isa = PBXGroup; 55 | children = ( 56 | A0138AD7D99EF53C9073A144 /* Pods_AnnotationKitDemo.framework */, 57 | ); 58 | name = Frameworks; 59 | sourceTree = ""; 60 | }; 61 | 3DCD6A6BAFF5E6C520D36A70 /* Pods */ = { 62 | isa = PBXGroup; 63 | children = ( 64 | 2E9C89D8FCC017BA82ED3885 /* Pods-AnnotationKitDemo.debug.xcconfig */, 65 | AAECAFBC6F58FE01A32A007A /* Pods-AnnotationKitDemo.release.xcconfig */, 66 | ); 67 | name = Pods; 68 | sourceTree = ""; 69 | }; 70 | F8CB9E851E8CD0CE00431C16 = { 71 | isa = PBXGroup; 72 | children = ( 73 | F8CB9E901E8CD0CE00431C16 /* AnnotationKitDemo */, 74 | F8CB9E8F1E8CD0CE00431C16 /* Products */, 75 | 3DCD6A6BAFF5E6C520D36A70 /* Pods */, 76 | 07E6A286F2637AEF7B7B8A2A /* Frameworks */, 77 | ); 78 | sourceTree = ""; 79 | }; 80 | F8CB9E8F1E8CD0CE00431C16 /* Products */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | F8CB9E8E1E8CD0CE00431C16 /* AnnotationKitDemo.app */, 84 | ); 85 | name = Products; 86 | sourceTree = ""; 87 | }; 88 | F8CB9E901E8CD0CE00431C16 /* AnnotationKitDemo */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | F8CB9EA81E8CD3EC00431C16 /* ProfileController.h */, 92 | F8CB9EA91E8CD3EC00431C16 /* ProfileController.m */, 93 | 2B05EBEF21800CB800ADD2C9 /* ViewController+Counter.h */, 94 | 2B05EBEE21800CB800ADD2C9 /* ViewController+Counter.m */, 95 | F8CB9E941E8CD0CE00431C16 /* AppDelegate.h */, 96 | F8CB9E951E8CD0CE00431C16 /* AppDelegate.m */, 97 | F8CB9E971E8CD0CE00431C16 /* ViewController.h */, 98 | F8CB9E981E8CD0CE00431C16 /* ViewController.m */, 99 | F8CB9E9A1E8CD0CE00431C16 /* Main.storyboard */, 100 | F8CB9E9D1E8CD0CE00431C16 /* Assets.xcassets */, 101 | F8CB9E9F1E8CD0CE00431C16 /* LaunchScreen.storyboard */, 102 | F8CB9EA21E8CD0CE00431C16 /* Info.plist */, 103 | F8CB9E911E8CD0CE00431C16 /* Supporting Files */, 104 | ); 105 | path = AnnotationKitDemo; 106 | sourceTree = ""; 107 | }; 108 | F8CB9E911E8CD0CE00431C16 /* Supporting Files */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | F8CB9E921E8CD0CE00431C16 /* main.m */, 112 | ); 113 | name = "Supporting Files"; 114 | sourceTree = ""; 115 | }; 116 | /* End PBXGroup section */ 117 | 118 | /* Begin PBXNativeTarget section */ 119 | F8CB9E8D1E8CD0CE00431C16 /* AnnotationKitDemo */ = { 120 | isa = PBXNativeTarget; 121 | buildConfigurationList = F8CB9EA51E8CD0CE00431C16 /* Build configuration list for PBXNativeTarget "AnnotationKitDemo" */; 122 | buildPhases = ( 123 | 8DC4A498180D187A10C40AA9 /* [CP] Check Pods Manifest.lock */, 124 | 951E0F4C6007CE0DFA01C0B9 /* Check Pods Manifest.lock */, 125 | F8CB9E8A1E8CD0CE00431C16 /* Sources */, 126 | F8CB9E8B1E8CD0CE00431C16 /* Frameworks */, 127 | F8CB9E8C1E8CD0CE00431C16 /* Resources */, 128 | 417B97208DE00036F2EB2760 /* Embed Pods Frameworks */, 129 | DF045EBCE6CB7AD596A5F656 /* Copy Pods Resources */, 130 | 0DE83E1173559F305EC8E98D /* [CP] Embed Pods Frameworks */, 131 | 0AA25ADA42DF7C9285D09C5A /* [CP] Copy Pods Resources */, 132 | ); 133 | buildRules = ( 134 | ); 135 | dependencies = ( 136 | ); 137 | name = AnnotationKitDemo; 138 | productName = AnnotationKitDemo; 139 | productReference = F8CB9E8E1E8CD0CE00431C16 /* AnnotationKitDemo.app */; 140 | productType = "com.apple.product-type.application"; 141 | }; 142 | /* End PBXNativeTarget section */ 143 | 144 | /* Begin PBXProject section */ 145 | F8CB9E861E8CD0CE00431C16 /* Project object */ = { 146 | isa = PBXProject; 147 | attributes = { 148 | LastUpgradeCheck = 0830; 149 | ORGANIZATIONNAME = com.luoqisheng.annotationkit; 150 | TargetAttributes = { 151 | F8CB9E8D1E8CD0CE00431C16 = { 152 | CreatedOnToolsVersion = 8.3; 153 | DevelopmentTeam = UV49443356; 154 | ProvisioningStyle = Automatic; 155 | }; 156 | }; 157 | }; 158 | buildConfigurationList = F8CB9E891E8CD0CE00431C16 /* Build configuration list for PBXProject "AnnotationKitDemo" */; 159 | compatibilityVersion = "Xcode 3.2"; 160 | developmentRegion = English; 161 | hasScannedForEncodings = 0; 162 | knownRegions = ( 163 | en, 164 | Base, 165 | ); 166 | mainGroup = F8CB9E851E8CD0CE00431C16; 167 | productRefGroup = F8CB9E8F1E8CD0CE00431C16 /* Products */; 168 | projectDirPath = ""; 169 | projectRoot = ""; 170 | targets = ( 171 | F8CB9E8D1E8CD0CE00431C16 /* AnnotationKitDemo */, 172 | ); 173 | }; 174 | /* End PBXProject section */ 175 | 176 | /* Begin PBXResourcesBuildPhase section */ 177 | F8CB9E8C1E8CD0CE00431C16 /* Resources */ = { 178 | isa = PBXResourcesBuildPhase; 179 | buildActionMask = 2147483647; 180 | files = ( 181 | F8CB9EA11E8CD0CE00431C16 /* LaunchScreen.storyboard in Resources */, 182 | F8CB9E9E1E8CD0CE00431C16 /* Assets.xcassets in Resources */, 183 | F8CB9E9C1E8CD0CE00431C16 /* Main.storyboard in Resources */, 184 | ); 185 | runOnlyForDeploymentPostprocessing = 0; 186 | }; 187 | /* End PBXResourcesBuildPhase section */ 188 | 189 | /* Begin PBXShellScriptBuildPhase section */ 190 | 0AA25ADA42DF7C9285D09C5A /* [CP] Copy Pods Resources */ = { 191 | isa = PBXShellScriptBuildPhase; 192 | buildActionMask = 2147483647; 193 | files = ( 194 | ); 195 | inputFileListPaths = ( 196 | ); 197 | inputPaths = ( 198 | ); 199 | name = "[CP] Copy Pods Resources"; 200 | outputFileListPaths = ( 201 | ); 202 | outputPaths = ( 203 | ); 204 | runOnlyForDeploymentPostprocessing = 0; 205 | shellPath = /bin/sh; 206 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AnnotationKitDemo/Pods-AnnotationKitDemo-resources.sh\"\n"; 207 | showEnvVarsInLog = 0; 208 | }; 209 | 0DE83E1173559F305EC8E98D /* [CP] Embed Pods Frameworks */ = { 210 | isa = PBXShellScriptBuildPhase; 211 | buildActionMask = 2147483647; 212 | files = ( 213 | ); 214 | inputFileListPaths = ( 215 | ); 216 | inputPaths = ( 217 | "${SRCROOT}/Pods/Target Support Files/Pods-AnnotationKitDemo/Pods-AnnotationKitDemo-frameworks.sh", 218 | "${BUILT_PRODUCTS_DIR}/AnnotationKit/AnnotationKit.framework", 219 | "${BUILT_PRODUCTS_DIR}/BussinessOneDylib/BussinessOneDylib.framework", 220 | "${BUILT_PRODUCTS_DIR}/BussinessTwoDylib/BussinessTwoDylib.framework", 221 | "${BUILT_PRODUCTS_DIR}/HHRouter/HHRouter.framework", 222 | ); 223 | name = "[CP] Embed Pods Frameworks"; 224 | outputFileListPaths = ( 225 | ); 226 | outputPaths = ( 227 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AnnotationKit.framework", 228 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BussinessOneDylib.framework", 229 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BussinessTwoDylib.framework", 230 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/HHRouter.framework", 231 | ); 232 | runOnlyForDeploymentPostprocessing = 0; 233 | shellPath = /bin/sh; 234 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AnnotationKitDemo/Pods-AnnotationKitDemo-frameworks.sh\"\n"; 235 | showEnvVarsInLog = 0; 236 | }; 237 | 417B97208DE00036F2EB2760 /* Embed Pods Frameworks */ = { 238 | isa = PBXShellScriptBuildPhase; 239 | buildActionMask = 2147483647; 240 | files = ( 241 | ); 242 | inputPaths = ( 243 | ); 244 | name = "Embed Pods Frameworks"; 245 | outputPaths = ( 246 | ); 247 | runOnlyForDeploymentPostprocessing = 0; 248 | shellPath = /bin/sh; 249 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AnnotationKitDemo/Pods-AnnotationKitDemo-frameworks.sh\"\n"; 250 | showEnvVarsInLog = 0; 251 | }; 252 | 8DC4A498180D187A10C40AA9 /* [CP] Check Pods Manifest.lock */ = { 253 | isa = PBXShellScriptBuildPhase; 254 | buildActionMask = 2147483647; 255 | files = ( 256 | ); 257 | inputFileListPaths = ( 258 | ); 259 | inputPaths = ( 260 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 261 | "${PODS_ROOT}/Manifest.lock", 262 | ); 263 | name = "[CP] Check Pods Manifest.lock"; 264 | outputFileListPaths = ( 265 | ); 266 | outputPaths = ( 267 | "$(DERIVED_FILE_DIR)/Pods-AnnotationKitDemo-checkManifestLockResult.txt", 268 | ); 269 | runOnlyForDeploymentPostprocessing = 0; 270 | shellPath = /bin/sh; 271 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 272 | showEnvVarsInLog = 0; 273 | }; 274 | 951E0F4C6007CE0DFA01C0B9 /* Check Pods Manifest.lock */ = { 275 | isa = PBXShellScriptBuildPhase; 276 | buildActionMask = 2147483647; 277 | files = ( 278 | ); 279 | inputPaths = ( 280 | ); 281 | name = "Check Pods Manifest.lock"; 282 | outputPaths = ( 283 | ); 284 | runOnlyForDeploymentPostprocessing = 0; 285 | shellPath = /bin/sh; 286 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 287 | showEnvVarsInLog = 0; 288 | }; 289 | DF045EBCE6CB7AD596A5F656 /* Copy Pods Resources */ = { 290 | isa = PBXShellScriptBuildPhase; 291 | buildActionMask = 2147483647; 292 | files = ( 293 | ); 294 | inputPaths = ( 295 | ); 296 | name = "Copy Pods Resources"; 297 | outputPaths = ( 298 | ); 299 | runOnlyForDeploymentPostprocessing = 0; 300 | shellPath = /bin/sh; 301 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AnnotationKitDemo/Pods-AnnotationKitDemo-resources.sh\"\n"; 302 | showEnvVarsInLog = 0; 303 | }; 304 | /* End PBXShellScriptBuildPhase section */ 305 | 306 | /* Begin PBXSourcesBuildPhase section */ 307 | F8CB9E8A1E8CD0CE00431C16 /* Sources */ = { 308 | isa = PBXSourcesBuildPhase; 309 | buildActionMask = 2147483647; 310 | files = ( 311 | F8CB9E991E8CD0CE00431C16 /* ViewController.m in Sources */, 312 | F8CB9E961E8CD0CE00431C16 /* AppDelegate.m in Sources */, 313 | 2B05EBF021800CB800ADD2C9 /* ViewController+Counter.m in Sources */, 314 | F8CB9E931E8CD0CE00431C16 /* main.m in Sources */, 315 | F8CB9EAA1E8CD3EC00431C16 /* ProfileController.m in Sources */, 316 | ); 317 | runOnlyForDeploymentPostprocessing = 0; 318 | }; 319 | /* End PBXSourcesBuildPhase section */ 320 | 321 | /* Begin PBXVariantGroup section */ 322 | F8CB9E9A1E8CD0CE00431C16 /* Main.storyboard */ = { 323 | isa = PBXVariantGroup; 324 | children = ( 325 | F8CB9E9B1E8CD0CE00431C16 /* Base */, 326 | ); 327 | name = Main.storyboard; 328 | sourceTree = ""; 329 | }; 330 | F8CB9E9F1E8CD0CE00431C16 /* LaunchScreen.storyboard */ = { 331 | isa = PBXVariantGroup; 332 | children = ( 333 | F8CB9EA01E8CD0CE00431C16 /* Base */, 334 | ); 335 | name = LaunchScreen.storyboard; 336 | sourceTree = ""; 337 | }; 338 | /* End PBXVariantGroup section */ 339 | 340 | /* Begin XCBuildConfiguration section */ 341 | F8CB9EA31E8CD0CE00431C16 /* Debug */ = { 342 | isa = XCBuildConfiguration; 343 | buildSettings = { 344 | ALWAYS_SEARCH_USER_PATHS = NO; 345 | CLANG_ANALYZER_NONNULL = YES; 346 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 347 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 348 | CLANG_CXX_LIBRARY = "libc++"; 349 | CLANG_ENABLE_MODULES = YES; 350 | CLANG_ENABLE_OBJC_ARC = YES; 351 | CLANG_WARN_BOOL_CONVERSION = YES; 352 | CLANG_WARN_CONSTANT_CONVERSION = YES; 353 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 354 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 355 | CLANG_WARN_EMPTY_BODY = YES; 356 | CLANG_WARN_ENUM_CONVERSION = YES; 357 | CLANG_WARN_INFINITE_RECURSION = YES; 358 | CLANG_WARN_INT_CONVERSION = YES; 359 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 360 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 361 | CLANG_WARN_UNREACHABLE_CODE = YES; 362 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 363 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 364 | COPY_PHASE_STRIP = NO; 365 | DEBUG_INFORMATION_FORMAT = dwarf; 366 | ENABLE_STRICT_OBJC_MSGSEND = YES; 367 | ENABLE_TESTABILITY = YES; 368 | GCC_C_LANGUAGE_STANDARD = gnu99; 369 | GCC_DYNAMIC_NO_PIC = NO; 370 | GCC_NO_COMMON_BLOCKS = YES; 371 | GCC_OPTIMIZATION_LEVEL = 0; 372 | GCC_PREPROCESSOR_DEFINITIONS = ( 373 | "DEBUG=1", 374 | "$(inherited)", 375 | ); 376 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 377 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 378 | GCC_WARN_UNDECLARED_SELECTOR = YES; 379 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 380 | GCC_WARN_UNUSED_FUNCTION = YES; 381 | GCC_WARN_UNUSED_VARIABLE = YES; 382 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 383 | MTL_ENABLE_DEBUG_INFO = YES; 384 | ONLY_ACTIVE_ARCH = YES; 385 | SDKROOT = iphoneos; 386 | }; 387 | name = Debug; 388 | }; 389 | F8CB9EA41E8CD0CE00431C16 /* Release */ = { 390 | isa = XCBuildConfiguration; 391 | buildSettings = { 392 | ALWAYS_SEARCH_USER_PATHS = NO; 393 | CLANG_ANALYZER_NONNULL = YES; 394 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 395 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 396 | CLANG_CXX_LIBRARY = "libc++"; 397 | CLANG_ENABLE_MODULES = YES; 398 | CLANG_ENABLE_OBJC_ARC = YES; 399 | CLANG_WARN_BOOL_CONVERSION = YES; 400 | CLANG_WARN_CONSTANT_CONVERSION = YES; 401 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 402 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 403 | CLANG_WARN_EMPTY_BODY = YES; 404 | CLANG_WARN_ENUM_CONVERSION = YES; 405 | CLANG_WARN_INFINITE_RECURSION = YES; 406 | CLANG_WARN_INT_CONVERSION = YES; 407 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 408 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 409 | CLANG_WARN_UNREACHABLE_CODE = YES; 410 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 411 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 412 | COPY_PHASE_STRIP = NO; 413 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 414 | ENABLE_NS_ASSERTIONS = NO; 415 | ENABLE_STRICT_OBJC_MSGSEND = YES; 416 | GCC_C_LANGUAGE_STANDARD = gnu99; 417 | GCC_NO_COMMON_BLOCKS = YES; 418 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 419 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 420 | GCC_WARN_UNDECLARED_SELECTOR = YES; 421 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 422 | GCC_WARN_UNUSED_FUNCTION = YES; 423 | GCC_WARN_UNUSED_VARIABLE = YES; 424 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 425 | MTL_ENABLE_DEBUG_INFO = NO; 426 | SDKROOT = iphoneos; 427 | VALIDATE_PRODUCT = YES; 428 | }; 429 | name = Release; 430 | }; 431 | F8CB9EA61E8CD0CE00431C16 /* Debug */ = { 432 | isa = XCBuildConfiguration; 433 | baseConfigurationReference = 2E9C89D8FCC017BA82ED3885 /* Pods-AnnotationKitDemo.debug.xcconfig */; 434 | buildSettings = { 435 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 436 | DEVELOPMENT_TEAM = UV49443356; 437 | INFOPLIST_FILE = AnnotationKitDemo/Info.plist; 438 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 439 | PRODUCT_BUNDLE_IDENTIFIER = com.luoqisheng.annotationkit.AnnotationKitDemo; 440 | PRODUCT_NAME = "$(TARGET_NAME)"; 441 | }; 442 | name = Debug; 443 | }; 444 | F8CB9EA71E8CD0CE00431C16 /* Release */ = { 445 | isa = XCBuildConfiguration; 446 | baseConfigurationReference = AAECAFBC6F58FE01A32A007A /* Pods-AnnotationKitDemo.release.xcconfig */; 447 | buildSettings = { 448 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 449 | DEVELOPMENT_TEAM = UV49443356; 450 | INFOPLIST_FILE = AnnotationKitDemo/Info.plist; 451 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 452 | PRODUCT_BUNDLE_IDENTIFIER = com.luoqisheng.annotationkit.AnnotationKitDemo; 453 | PRODUCT_NAME = "$(TARGET_NAME)"; 454 | }; 455 | name = Release; 456 | }; 457 | /* End XCBuildConfiguration section */ 458 | 459 | /* Begin XCConfigurationList section */ 460 | F8CB9E891E8CD0CE00431C16 /* Build configuration list for PBXProject "AnnotationKitDemo" */ = { 461 | isa = XCConfigurationList; 462 | buildConfigurations = ( 463 | F8CB9EA31E8CD0CE00431C16 /* Debug */, 464 | F8CB9EA41E8CD0CE00431C16 /* Release */, 465 | ); 466 | defaultConfigurationIsVisible = 0; 467 | defaultConfigurationName = Release; 468 | }; 469 | F8CB9EA51E8CD0CE00431C16 /* Build configuration list for PBXNativeTarget "AnnotationKitDemo" */ = { 470 | isa = XCConfigurationList; 471 | buildConfigurations = ( 472 | F8CB9EA61E8CD0CE00431C16 /* Debug */, 473 | F8CB9EA71E8CD0CE00431C16 /* Release */, 474 | ); 475 | defaultConfigurationIsVisible = 0; 476 | defaultConfigurationName = Release; 477 | }; 478 | /* End XCConfigurationList section */ 479 | }; 480 | rootObject = F8CB9E861E8CD0CE00431C16 /* Project object */; 481 | } 482 | -------------------------------------------------------------------------------- /AnnotationKitDemo/AnnotationKitDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // AnnotationKitDemo 4 | // 5 | // Created by luoqihsneg on 2016/11/23. 6 | // Copyright © 2016年 com.luoqihsneg. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /AnnotationKitDemo/AnnotationKitDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // AnnotationKitDemo 4 | // 5 | // Created by luoqihsneg on 2016/11/23. 6 | // Copyright © 2016年 com.luoqihsneg. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import 11 | #import 12 | #import "ViewController.h" 13 | @interface AppDelegate () 14 | 15 | @end 16 | @implementation AppDelegate 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | //set up AnnotationKit 21 | [[AKEngine sharedAKEngine]setUp]; 22 | UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:[ViewController new]]; 23 | self.window.rootViewController = nav; 24 | return YES; 25 | } 26 | 27 | - (void)applicationWillResignActive:(UIApplication *)application { 28 | // 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. 29 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 30 | } 31 | 32 | 33 | - (void)applicationDidEnterBackground:(UIApplication *)application { 34 | // 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. 35 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 36 | } 37 | 38 | 39 | - (void)applicationWillEnterForeground:(UIApplication *)application { 40 | // 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. 41 | } 42 | 43 | 44 | - (void)applicationDidBecomeActive:(UIApplication *)application { 45 | // 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. 46 | } 47 | 48 | 49 | - (void)applicationWillTerminate:(UIApplication *)application { 50 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 51 | } 52 | 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /AnnotationKitDemo/AnnotationKitDemo/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 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /AnnotationKitDemo/AnnotationKitDemo/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 | -------------------------------------------------------------------------------- /AnnotationKitDemo/AnnotationKitDemo/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 | -------------------------------------------------------------------------------- /AnnotationKitDemo/AnnotationKitDemo/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 | 38 | 39 | -------------------------------------------------------------------------------- /AnnotationKitDemo/AnnotationKitDemo/ProfileController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileController.h 3 | // AnnotationKitDemo 4 | // 5 | // Created by luoqihsneg on 2016/11/23. 6 | // Copyright © 2016年 com.luoqihsneg. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ProfileController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /AnnotationKitDemo/AnnotationKitDemo/ProfileController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileController.m 3 | // AnnotationKitDemo 4 | // 5 | // Created by luoqihsneg on 2016/11/23. 6 | // Copyright © 2016年 com.luoqihsneg. All rights reserved. 7 | // 8 | 9 | #import "ProfileController.h" 10 | #import 11 | #import 12 | @interface ProfileController () 13 | @property (nonatomic,strong)NSString *userId; 14 | @property (nonatomic,strong)UIButton *jumpIndex; 15 | @end 16 | 17 | @RequestMapping(ProfileController, "demo://profile/:userId/") 18 | @implementation ProfileController 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | // Do any additional setup after loading the view. 23 | self.title = [NSString stringWithFormat:@"Profile:%@",[self.params objectForKey:@"userId"]]; 24 | self.view.backgroundColor = [UIColor whiteColor]; 25 | 26 | [self.view addSubview:self.jumpIndex]; 27 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.jumpIndex 28 | attribute:NSLayoutAttributeCenterX 29 | relatedBy:NSLayoutRelationEqual 30 | toItem:self.view 31 | attribute:NSLayoutAttributeCenterX 32 | multiplier:1 constant:0]]; 33 | 34 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.jumpIndex 35 | attribute:NSLayoutAttributeCenterY 36 | relatedBy:NSLayoutRelationEqual 37 | toItem:self.view 38 | attribute:NSLayoutAttributeCenterY 39 | multiplier:1 constant:0]]; 40 | 41 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.jumpIndex 42 | attribute:NSLayoutAttributeWidth 43 | relatedBy:NSLayoutRelationEqual 44 | toItem:nil 45 | attribute:NSLayoutAttributeWidth 46 | multiplier:1 constant:100]]; 47 | 48 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.jumpIndex 49 | attribute:NSLayoutAttributeHeight 50 | relatedBy:NSLayoutRelationEqual 51 | toItem:nil 52 | attribute:NSLayoutAttributeHeight 53 | multiplier:1 constant:30]]; 54 | 55 | } 56 | 57 | - (void)didReceiveMemoryWarning { 58 | [super didReceiveMemoryWarning]; 59 | // Dispose of any resources that can be recreated. 60 | } 61 | 62 | #pragma mark - getter 63 | - (UIButton *)jumpIndex 64 | { 65 | if (!_jumpIndex) { 66 | _jumpIndex = [UIButton buttonWithType:UIButtonTypeCustom]; 67 | _jumpIndex.translatesAutoresizingMaskIntoConstraints = NO; 68 | [_jumpIndex setTitle:@"To Biz1" forState:UIControlStateNormal]; 69 | [_jumpIndex setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 70 | _jumpIndex.layer.borderColor = [UIColor blueColor].CGColor; 71 | _jumpIndex.layer.borderWidth = 1; 72 | [_jumpIndex addTarget:self action:@selector(onClick:) forControlEvents:UIControlEventTouchUpInside]; 73 | } 74 | return _jumpIndex; 75 | } 76 | 77 | #pragma mark - action 78 | - (void)onClick:(id)sender 79 | { 80 | // route to the BizOneController in BussinessOneDylib.dylib 81 | [[AKRouter shared] routeTo:@"demo://demo/biz1/"]; 82 | } 83 | @end 84 | -------------------------------------------------------------------------------- /AnnotationKitDemo/AnnotationKitDemo/ViewController+Counter.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController+Counter.h 3 | // AnnotationKitDemo 4 | // 5 | // Created by bytedance on 2018/10/24. 6 | // Copyright © 2018 com.luoqisheng.annotationkit. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ViewController (Counter) 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /AnnotationKitDemo/AnnotationKitDemo/ViewController+Counter.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController+Counter.m 3 | // AnnotationKitDemo 4 | // 5 | // Created by bytedance on 2018/10/24. 6 | // Copyright © 2018 com.luoqisheng.annotationkit. All rights reserved. 7 | // 8 | 9 | #import "ViewController+Counter.h" 10 | #import 11 | 12 | @implementation ViewController (Counter) 13 | 14 | @When(AppLaunched, ViewController, @selector(counterExample:)) 15 | + (void)counterExample:(NSNotification *)note { 16 | NSLog(@"counterExample"); 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /AnnotationKitDemo/AnnotationKitDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // AnnotationKitDemo 4 | // 5 | // Created by luoqihsneg on 2016/11/23. 6 | // Copyright © 2016年 com.luoqihsneg. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /AnnotationKitDemo/AnnotationKitDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // AnnotationKitDemo 4 | // 5 | // Created by luoqihsneg on 2016/11/23. 6 | // Copyright © 2016年 com.luoqihsneg. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | #import 12 | #import 13 | #import 14 | 15 | @interface ViewController (test) 16 | 17 | @end 18 | @implementation ViewController (test) 19 | 20 | @When(AppLaunched,ViewController, @selector(doLaunchedCategory:)) 21 | + (void)doLaunchedCategory:(NSNotification *)note 22 | { 23 | NSLog(@"%@",note); 24 | } 25 | 26 | @end 27 | 28 | @interface ViewController () 29 | @property (nonatomic,strong) UIButton *jumpProfile; 30 | @end 31 | 32 | @RequestMapping(ViewController, "demo://demo/index/") 33 | @implementation ViewController 34 | 35 | @When(AppLaunched,ViewController,@selector(doLaunched:)) 36 | + (void)doLaunched:(NSNotification *)note 37 | { 38 | NSLog(@"%@",note); 39 | } 40 | 41 | @When(AppEnterForeground,ViewController,@selector(doEnterForeground:)) 42 | + (void)doEnterForeground:(NSNotification *)note 43 | { 44 | NSLog(@"%@",note); 45 | } 46 | 47 | @When(AppEnterBackground,ViewController,@selector(doEnterBackground:)) 48 | + (void)doEnterBackground:(NSNotification *)note 49 | { 50 | NSLog(@"%@",note); 51 | } 52 | 53 | @When(AppResignActive,ViewController,@selector(doResignActive:)) 54 | + (void)doResignActive:(NSNotification *)note 55 | { 56 | NSLog(@"%@",note); 57 | } 58 | 59 | @When(AppBecameActive,ViewController,@selector(doBecameActive:)) 60 | + (void)doBecameActive:(NSNotification *)note 61 | { 62 | NSLog(@"%@",note); 63 | } 64 | 65 | - (void)viewDidLoad { 66 | [super viewDidLoad]; 67 | // Do any additional setup after loading the view, typically from a nib. 68 | self.title = @"Mian"; 69 | self.view.backgroundColor = [UIColor whiteColor]; 70 | 71 | [self.view addSubview:self.jumpProfile]; 72 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.jumpProfile 73 | attribute:NSLayoutAttributeCenterX 74 | relatedBy:NSLayoutRelationEqual 75 | toItem:self.view 76 | attribute:NSLayoutAttributeCenterX 77 | multiplier:1 constant:0]]; 78 | 79 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.jumpProfile 80 | attribute:NSLayoutAttributeCenterY 81 | relatedBy:NSLayoutRelationEqual 82 | toItem:self.view 83 | attribute:NSLayoutAttributeCenterY 84 | multiplier:1 constant:0]]; 85 | 86 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.jumpProfile 87 | attribute:NSLayoutAttributeWidth 88 | relatedBy:NSLayoutRelationEqual 89 | toItem:nil 90 | attribute:NSLayoutAttributeWidth 91 | multiplier:1 constant:100]]; 92 | 93 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.jumpProfile 94 | attribute:NSLayoutAttributeHeight 95 | relatedBy:NSLayoutRelationEqual 96 | toItem:nil 97 | attribute:NSLayoutAttributeHeight 98 | multiplier:1 constant:30]]; 99 | } 100 | 101 | 102 | - (void)didReceiveMemoryWarning { 103 | [super didReceiveMemoryWarning]; 104 | // Dispose of any resources that can be recreated. 105 | } 106 | #pragma mark - getter 107 | - (UIButton *)jumpProfile 108 | { 109 | if (!_jumpProfile) { 110 | _jumpProfile = [UIButton buttonWithType:UIButtonTypeCustom]; 111 | _jumpProfile.translatesAutoresizingMaskIntoConstraints = NO; 112 | [_jumpProfile setTitle:@"To Profile" forState:UIControlStateNormal]; 113 | [_jumpProfile setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 114 | _jumpProfile.layer.borderColor = [UIColor blueColor].CGColor; 115 | _jumpProfile.layer.borderWidth = 1; 116 | [_jumpProfile addTarget:self action:@selector(onClick:) forControlEvents:UIControlEventTouchUpInside]; 117 | } 118 | return _jumpProfile; 119 | } 120 | 121 | #pragma mark - action 122 | - (void)onClick:(id)sender 123 | { 124 | // route to the ProfileController in main bundle 125 | [[AKRouter shared] routeTo:@"demo://profile/1024/"]; 126 | } 127 | 128 | @end 129 | -------------------------------------------------------------------------------- /AnnotationKitDemo/AnnotationKitDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // AnnotationKitDemo 4 | // 5 | // Created by 寻峰 on 2017/3/30. 6 | // Copyright © 2017年 com.luoqisheng.annotationkit. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /AnnotationKitDemo/BussinessOneDylib/BizOneController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // AnnotationKitDemo 4 | // 5 | // Created by luoqihsneg on 2016/11/23. 6 | // Copyright © 2016年 com.luoqihsneg. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BizOneController : UIViewController 12 | @end 13 | 14 | -------------------------------------------------------------------------------- /AnnotationKitDemo/BussinessOneDylib/BizOneController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // AnnotationKitDemo 4 | // 5 | // Created by luoqihsneg on 2016/11/23. 6 | // Copyright © 2016年 com.luoqihsneg. All rights reserved. 7 | // 8 | 9 | #import "BizOneController.h" 10 | 11 | #import 12 | #import 13 | #import 14 | 15 | @interface BizOneController (test) 16 | @end 17 | 18 | @implementation BizOneController (test) 19 | 20 | @When(AppLaunched,BizOneController,@selector(doLaunchedCategory:)) 21 | + (void)doLaunchedCategory:(NSNotification *)note 22 | { 23 | NSLog(@"%@",note); 24 | } 25 | 26 | @end 27 | 28 | @interface BizOneController () 29 | @property (nonatomic,strong) UIButton *jumpProfile; 30 | @end 31 | 32 | @RequestMapping(BizOneController, "demo://demo/biz1/") 33 | @implementation BizOneController 34 | 35 | @When(AppLaunched,BizOneController,@selector(doLaunched:)) 36 | + (void)doLaunched:(NSNotification *)note 37 | { 38 | NSLog(@"%@",note); 39 | } 40 | 41 | @When(AppEnterForeground,BizOneController,@selector(doEnterForeground:)) 42 | + (void)doEnterForeground:(NSNotification *)note 43 | { 44 | NSLog(@"%@",note); 45 | } 46 | 47 | @When(AppEnterBackground,BizOneController,@selector(doEnterBackground:)) 48 | + (void)doEnterBackground:(NSNotification *)note 49 | { 50 | NSLog(@"%@",note); 51 | } 52 | 53 | @When(AppResignActive,BizOneController,@selector(doResignActive:)) 54 | + (void)doResignActive:(NSNotification *)note 55 | { 56 | NSLog(@"%@",note); 57 | } 58 | 59 | @When(AppBecameActive,BizOneController,@selector(doBecameActive:)) 60 | + (void)doBecameActive:(NSNotification *)note 61 | { 62 | NSLog(@"%@",note); 63 | } 64 | 65 | - (void)viewDidLoad { 66 | [super viewDidLoad]; 67 | // Do any additional setup after loading the view, typically from a nib. 68 | self.title = @"Biz1"; 69 | self.view.backgroundColor = [UIColor whiteColor]; 70 | 71 | [self.view addSubview:self.jumpProfile]; 72 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.jumpProfile 73 | attribute:NSLayoutAttributeCenterX 74 | relatedBy:NSLayoutRelationEqual 75 | toItem:self.view 76 | attribute:NSLayoutAttributeCenterX 77 | multiplier:1 constant:0]]; 78 | 79 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.jumpProfile 80 | attribute:NSLayoutAttributeCenterY 81 | relatedBy:NSLayoutRelationEqual 82 | toItem:self.view 83 | attribute:NSLayoutAttributeCenterY 84 | multiplier:1 constant:0]]; 85 | 86 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.jumpProfile 87 | attribute:NSLayoutAttributeWidth 88 | relatedBy:NSLayoutRelationEqual 89 | toItem:nil 90 | attribute:NSLayoutAttributeWidth 91 | multiplier:1 constant:100]]; 92 | 93 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.jumpProfile 94 | attribute:NSLayoutAttributeHeight 95 | relatedBy:NSLayoutRelationEqual 96 | toItem:nil 97 | attribute:NSLayoutAttributeHeight 98 | multiplier:1 constant:30]]; 99 | } 100 | 101 | 102 | - (void)didReceiveMemoryWarning { 103 | [super didReceiveMemoryWarning]; 104 | // Dispose of any resources that can be recreated. 105 | } 106 | 107 | #pragma mark - getter 108 | - (UIButton *)jumpProfile 109 | { 110 | if (!_jumpProfile) { 111 | _jumpProfile = [UIButton buttonWithType:UIButtonTypeCustom]; 112 | _jumpProfile.translatesAutoresizingMaskIntoConstraints = NO; 113 | [_jumpProfile setTitle:@"To biz2" forState:UIControlStateNormal]; 114 | [_jumpProfile setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 115 | _jumpProfile.layer.borderColor = [UIColor blueColor].CGColor; 116 | _jumpProfile.layer.borderWidth = 1; 117 | [_jumpProfile addTarget:self action:@selector(onClick:) forControlEvents:UIControlEventTouchUpInside]; 118 | } 119 | return _jumpProfile; 120 | } 121 | 122 | #pragma mark - action 123 | - (void)onClick:(id)sender 124 | { 125 | // route to the BizTwoController in BussinessTwoDylib.dylib 126 | [[AKRouter shared] routeTo:@"demo://demo/biz2/"]; 127 | } 128 | 129 | @end 130 | -------------------------------------------------------------------------------- /AnnotationKitDemo/BussinessOneDylib/BussinessOneDylib.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "BussinessOneDylib" 4 | s.version = "1.0.0" 5 | s.summary = "A short description of BussinessOneDylib." 6 | 7 | s.description = <<-DESC 8 | 业务模块一的动态库 9 | DESC 10 | 11 | s.homepage = "https://github.com/luoqisheng/AnnotationKit" 12 | s.license = "MIT" 13 | s.author = { "luoqisheng" => "540025011@qq.com" } 14 | s.source = { :git => 'https://github.com/luoqisheng/AnnotationKit/blob/master/AnnotationKitDemo/BussinessOneDylib', :tag => 'v1.0.1' } 15 | 16 | s.platform = :ios, "7.0" 17 | s.requires_arc = true 18 | s.source_files = "*.{h,m,mm}" 19 | s.dependency "AnnotationKit" 20 | s.xcconfig = { 21 | 'CLANG_CXX_LANGUAGE_STANDARD' => 'compiler-default', 22 | 'CLANG_CXX_LIBRARY' => 'compiler-default', 23 | 'GCC_C_LANGUAGE_STANDARD' => 'compiler-default' 24 | } 25 | 26 | 27 | end 28 | -------------------------------------------------------------------------------- /AnnotationKitDemo/BussinessTwoDylib/BizTwoController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // AnnotationKitDemo 4 | // 5 | // Created by luoqihsneg on 2016/11/23. 6 | // Copyright © 2016年 com.luoqihsneg. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BizTwoController : UIViewController 12 | @end 13 | 14 | -------------------------------------------------------------------------------- /AnnotationKitDemo/BussinessTwoDylib/BizTwoController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // AnnotationKitDemo 4 | // 5 | // Created by luoqihsneg on 2016/11/23. 6 | // Copyright © 2016年 com.luoqihsneg. All rights reserved. 7 | // 8 | 9 | #import "BizTwoController.h" 10 | 11 | #import 12 | #import 13 | #import 14 | 15 | @interface BizTwoController (test) 16 | @end 17 | 18 | @implementation BizTwoController (test) 19 | 20 | @When(AppLaunched,BizTwoController,@selector(doLaunchedCategory:)) 21 | + (void)doLaunchedCategory:(NSNotification *)note 22 | { 23 | NSLog(@"%@",note); 24 | } 25 | 26 | @end 27 | 28 | @interface BizTwoController () 29 | @property (nonatomic,strong) UIButton *jumpProfile; 30 | @end 31 | 32 | @RequestMapping(BizTwoController, "demo://demo/biz2/") 33 | @implementation BizTwoController 34 | 35 | @When(AppLaunched,BizTwoController,@selector(doLaunched:)) 36 | + (void)doLaunched:(NSNotification *)note 37 | { 38 | NSLog(@"%@",note); 39 | } 40 | 41 | @When(AppEnterForeground,BizTwoController,@selector(doEnterForeground:)) 42 | + (void)doEnterForeground:(NSNotification *)note 43 | { 44 | NSLog(@"%@",note); 45 | } 46 | 47 | @When(AppEnterBackground,BizTwoController,@selector(doEnterBackground:)) 48 | + (void)doEnterBackground:(NSNotification *)note 49 | { 50 | NSLog(@"%@",note); 51 | } 52 | 53 | @When(AppResignActive,BizTwoController,@selector(doResignActive:)) 54 | + (void)doResignActive:(NSNotification *)note 55 | { 56 | NSLog(@"%@",note); 57 | } 58 | 59 | @When(AppBecameActive,BizTwoController,@selector(doBecameActive:)) 60 | + (void)doBecameActive:(NSNotification *)note 61 | { 62 | NSLog(@"%@",note); 63 | } 64 | 65 | - (void)viewDidLoad { 66 | [super viewDidLoad]; 67 | // Do any additional setup after loading the view, typically from a nib. 68 | self.title = @"Biz2"; 69 | self.view.backgroundColor = [UIColor whiteColor]; 70 | 71 | [self.view addSubview:self.jumpProfile]; 72 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.jumpProfile 73 | attribute:NSLayoutAttributeCenterX 74 | relatedBy:NSLayoutRelationEqual 75 | toItem:self.view 76 | attribute:NSLayoutAttributeCenterX 77 | multiplier:1 constant:0]]; 78 | 79 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.jumpProfile 80 | attribute:NSLayoutAttributeCenterY 81 | relatedBy:NSLayoutRelationEqual 82 | toItem:self.view 83 | attribute:NSLayoutAttributeCenterY 84 | multiplier:1 constant:0]]; 85 | 86 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.jumpProfile 87 | attribute:NSLayoutAttributeWidth 88 | relatedBy:NSLayoutRelationEqual 89 | toItem:nil 90 | attribute:NSLayoutAttributeWidth 91 | multiplier:1 constant:100]]; 92 | 93 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.jumpProfile 94 | attribute:NSLayoutAttributeHeight 95 | relatedBy:NSLayoutRelationEqual 96 | toItem:nil 97 | attribute:NSLayoutAttributeHeight 98 | multiplier:1 constant:30]]; 99 | } 100 | 101 | 102 | - (void)didReceiveMemoryWarning { 103 | [super didReceiveMemoryWarning]; 104 | // Dispose of any resources that can be recreated. 105 | } 106 | 107 | #pragma mark - getter 108 | - (UIButton *)jumpProfile 109 | { 110 | if (!_jumpProfile) { 111 | _jumpProfile = [UIButton buttonWithType:UIButtonTypeCustom]; 112 | _jumpProfile.translatesAutoresizingMaskIntoConstraints = NO; 113 | [_jumpProfile setTitle:@"To Main" forState:UIControlStateNormal]; 114 | [_jumpProfile setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 115 | _jumpProfile.layer.borderColor = [UIColor blueColor].CGColor; 116 | _jumpProfile.layer.borderWidth = 1; 117 | [_jumpProfile addTarget:self action:@selector(onClick:) forControlEvents:UIControlEventTouchUpInside]; 118 | } 119 | return _jumpProfile; 120 | } 121 | 122 | #pragma mark - action 123 | - (void)onClick:(id)sender 124 | { 125 | // route to the ViewController in main bundle 126 | [[AKRouter shared] routeTo:@"demo://demo/index/"]; 127 | } 128 | 129 | @end 130 | -------------------------------------------------------------------------------- /AnnotationKitDemo/BussinessTwoDylib/BussinessTwoDylib.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "BussinessTwoDylib" 4 | s.version = "1.0.0" 5 | s.summary = "A short description of BussinessTwoDylib." 6 | 7 | s.description = <<-DESC 8 | 业务模块二的动态库 9 | DESC 10 | 11 | s.homepage = "https://github.com/luoqisheng/AnnotationKit" 12 | s.license = "MIT" 13 | s.author = { "luoqisheng" => "540025011@qq.com" } 14 | 15 | s.source = { :git => 'https://github.com/luoqisheng/AnnotationKit/blob/master/AnnotationKitDemo/BussinessTwoDylib', :tag => 'v1.0.1' } 16 | s.platform = :ios, "7.0" 17 | s.requires_arc = true 18 | s.source_files = "*.{h,m,mm}" 19 | s.dependency "AnnotationKit" 20 | s.xcconfig = { 21 | 'CLANG_CXX_LANGUAGE_STANDARD' => 'compiler-default', 22 | 'CLANG_CXX_LIBRARY' => 'compiler-default', 23 | 'GCC_C_LANGUAGE_STANDARD' => 'compiler-default' 24 | } 25 | 26 | 27 | end 28 | -------------------------------------------------------------------------------- /AnnotationKitDemo/Podfile: -------------------------------------------------------------------------------- 1 | #source 'https://github.com/CocoaPods/Old-Specs.git' 2 | source 'https://github.com/CocoaPods/Specs.git' 3 | 4 | platform :ios 5 | xcodeproj 'AnnotationKitDemo.xcodeproj' 6 | target 'AnnotationKitDemo' do 7 | platform:ios, '8.0' 8 | use_frameworks! 9 | 10 | pod 'AnnotationKit', :path=> '../AnnotationKit.podspec' 11 | 12 | pod 'BussinessOneDylib', :path=> './BussinessOneDylib' 13 | pod 'BussinessTwoDylib', :path=> './BussinessTwoDylib' 14 | end 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 luoqisheng 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AnnotationKit 2 | The annotation implementation using Objective-C 3 | 4 | #### 0x00 Abstract 5 | 6 | an annotation is a form of syntactic metadata that can be added to Objective-C source code, like the java annotation. 7 | 8 | #### 0x01 What can it do? 9 | 10 | * @when for event dispatch. 11 | 12 | ```objective-c 13 | @When(AppLaunched,ViewController,@selector(doLaunched:)) 14 | + (void)doLaunched:(NSNotification *)note 15 | { 16 | NSLog(@"%@",note); 17 | } 18 | 19 | @When(AppEnterForeground,ViewController,@selector(doEnterForeground:)) 20 | + (void)doEnterForeground:(NSNotification *)note 21 | { 22 | NSLog(@"%@",note); 23 | } 24 | 25 | @When(AppEnterBackground,ViewController,@selector(doEnterBackground:)) 26 | + (void)doEnterBackground:(NSNotification *)note 27 | { 28 | NSLog(@"%@",note); 29 | } 30 | 31 | @When(AppResignActive,ViewController,@selector(doResignActive:)) 32 | + (void)doResignActive:(NSNotification *)note 33 | { 34 | NSLog(@"%@",note); 35 | } 36 | 37 | @When(AppBecameActive,ViewController,@selector(doBecameActive:)) 38 | + (void)doBecameActive:(NSNotification *)note 39 | { 40 | NSLog(@"%@",note); 41 | } 42 | ``` 43 | 44 | 45 | 46 | * @RequestMapping for url route. 47 | 48 | ```objective-c 49 | //ViewController.m 50 | @RequestMapping(ViewController, "demo://demo/index/") 51 | @implementation ViewController 52 | @end 53 | 54 | ``` 55 | 56 | 57 | 58 | #### 0x03 extendable 59 | 60 | 1. Subclass the PHAnnotationHandler 61 | 62 | 2. use @DefineAnnotation() to define your annotation. 63 | 64 | 3. override `-(void)handleAnnotationConfig:(NSArray*)configs;` to gain your meta data 65 | 66 | 4. an example : Use HHRoute to impl my @RequestMapping 67 | 68 | ```objective-c 69 | //AKRouteAnnotation.h 70 | #import 71 | #import "AKEngine.h" 72 | 73 | //provides the @RequestMapping 74 | #ifndef RequestMapping 75 | #define RequestMapping(name,url) \ 76 | class AKEngine; char *const NameGen(name,_url) AnnotationDATA(route) = "{\""#name"\":"#url"}"; 77 | #endif 78 | 79 | @interface AKRouteAnnotation : PHAnnotationHandler 80 | @end 81 | ``` 82 | 83 | ​ 84 | 85 | ```objective-c 86 | //AKRouteAnnotaion.m 87 | #import "AKRouteAnnotaion.h" 88 | #import "NSDictionary+AnnotationKit.h" 89 | #import 90 | @interface AKRouteAnnotaion () 91 | @end 92 | //arg0 :AKRouteAnnotaion for class name, arg1: route which is defined in AnnotationDATA , 93 | @DefineAnnotation(AKRouteAnnotaion,route) 94 | @implementation AKRouteAnnotaion 95 | - (void)handleAnnotationConfig:(NSArray *)configs { 96 | for (NSString *map in configs) { 97 | NSData *jsonData = [map dataUsingEncoding:NSUTF8StringEncoding]; 98 | NSError *error = nil; 99 | id json = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; 100 | if (!error) { 101 | 102 | if ([json isKindOfClass:[NSDictionary class]] && [json allKeys].count == 1) { 103 | NSString *clsName = [[json allKeys] firstObject]; 104 | NSString *url = [json akSafeObjectForKey:clsName]; 105 | if (clsName && url) { 106 | [[HHRouter shared]map:url toControllerClass:NSClassFromString(clsName)]; 107 | [self.configs addObject:@{url:clsName}]; 108 | } 109 | } 110 | 111 | } 112 | } 113 | } 114 | @end 115 | ``` 116 | 117 | #### 0x04 License 118 | 119 | * AnnotationKit 120 | 121 | ``` 122 | MIT License 123 | 124 | Copyright (c) 2017 luoqisheng 125 | 126 | Permission is hereby granted, free of charge, to any person obtaining a copy 127 | of this software and associated documentation files (the "Software"), to deal 128 | in the Software without restriction, including without limitation the rights 129 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 130 | copies of the Software, and to permit persons to whom the Software is 131 | furnished to do so, subject to the following conditions: 132 | 133 | The above copyright notice and this permission notice shall be included in all 134 | copies or substantial portions of the Software. 135 | 136 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 137 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 138 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 139 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 140 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 141 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 142 | SOFTWARE. 143 | 144 | ``` 145 | 146 | ​ 147 | 148 | 149 | * libextobjc 150 | 151 | ``` 152 | Copyright (c) Justin Spahr-Summers 153 | 154 | 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: 155 | 156 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 157 | 158 | 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. 159 | ``` 160 | 161 | ​ 162 | --------------------------------------------------------------------------------