嘗試:runtime取到類方法,遍歷調用類方法,
結論:如果方法參數(shù)沒有問題的話,是可以的。由于后期改變,最后參數(shù)沒有測。
http://www.lxweimin.com/p/47375bd248a8
還需注意參數(shù)匹配
背景:
1.APP原來支持門店角色登錄,需求代理商也能使用。
2.APP功能描述:
門店可以向上進貨,向下銷貨,同時具備營銷(針對會員),其他增值功能(商學院(視頻IM)已移除,分銷,收款等)
代理商同時可以向上進貨,向下銷貨,同時具備營銷(針對門店)
so 業(yè)務整體相似
共用頁面,共用API?猜測https域名貴,so不考慮域名不同。
前期溝通可能由于溝通不充分的原因,我這邊嘗試了三種方法。
最笨的方法,一開始溝通時,后臺未知接口統(tǒng)計,說沒有規(guī)律。
好,沒規(guī)則,那我整理吧
項目原來是網(wǎng)絡請求是從第一版的SDK移出來的,類方法請求。
可以使用runtime,遍歷調用,保存接口到plist文件中作映射?
unsigned int outCount = 0;
Method *methodList = class_copyMethodList(object_getClass([CMBXXX class]) , &outCount);
for (int i = 0; i < outCount; i++) {
Method method = methodList[i];
SEL selName = method_getName(method);
[CMBXXX performSelector:<#(SEL)#>];
}
可以由于參數(shù)的緣故最后嘗試失敗(以前sdk的坑,后期也沒注意,參數(shù)其中有block參數(shù),網(wǎng)絡請求基本有回調,所以就沒有判斷這個block存在與否)
// 使用NSInvocation
SEL aSelector = NSSelectorFromString(@"doSoming:argument2:");
NSInteger argument1 = 10;
NSString *argument2 = @"argument2";
if([self respondsToSelector:aSelector]) {
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:aSelector]];
[inv setSelector:aSelector];
[inv setTarget:self];
[inv setArgument:&(argument1) atIndex:2];
[inv setArgument:&(argument2) atIndex:3];
[inv performSelector:@selector(invoke) withObject:nil afterDelay:15.0];
}
上述方法也許可以實現(xiàn)填坑,不過仔細想想不對,我整理那么多,后臺也需要整理那么多修改,真的沒規(guī)則?不可能!
逼著后臺,給我一個規(guī)則,老大的要求是原來API加前綴(即規(guī)則修改),寫了一個接口用于根據(jù)原API修改返回最新的API,接口內部需要后臺提供規(guī)則,最后幾百個接口,目錄有不同,后臺無法提供,最后還是不了了只。
最后后臺說API接口基本相同,部分可能映射
用戶管理類(類似單例,注意不要gcd的once)
static NSString *userProfile = @"userProfile";
static UserProfile *instance = nil;
+ (instancetype)shareInstance {
@synchronized(self) {
if (instance == nil) {
instance = [[UserProfile alloc] initWithSqlite];
}
}
return instance;
}
附帶一個字典屬性及角色枚舉,映射字典從plist讀取,字典添加使用分類添加一個方法- (NSString *)apiForKey:(NSString *)key;
plist文件
這部分測試肯定在測試環(huán)境需要測通,所以異常只在DEBUG模式
- (NSString *)apiForKey:(NSString *)key {
id value = [self objectForKey:key];
if (value == nil || value == [NSNull null])
{
#if DEBUG
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"接口未處理%@", key] userInfo:nil];
#else
return key;
#endif
}
return value;
}
一下子需要測試那么多接口,然后沒有接口測試,沒有測試了。
so,APP調試的時候需要把post和get的格式轉一下,直接復制到postman使用,返回沒有參數(shù)是為了醒目一點
+ (NSString*)changeToLogPostParameterStrWithDic:(NSDictionary*)dic {
if (!dic.count) {
return @"沒有參數(shù)";
}
NSString* parameterStr = [dic mj_JSONString];
if (parameterStr.length) {
parameterStr = [parameterStr stringByReplacingOccurrencesOfString:@"{" withString:@""];
parameterStr = [parameterStr stringByReplacingOccurrencesOfString:@"}" withString:@""];
parameterStr = [parameterStr stringByReplacingOccurrencesOfString:@"\"" withString:@""];
parameterStr = [parameterStr stringByReplacingOccurrencesOfString:@"," withString:@"\n"];
return parameterStr;
}
return parameterStr;
}
+ (NSString*)changeToLogGetParameterStrWithDic:(NSDictionary*)dic {
if (!dic.count) {
return @"沒有參數(shù)";
}
NSString* parameterStr = [NSString buildQueryWithDictionary:dic];
return parameterStr;
}
+ (NSString *)buildQueryWithDictionary:(NSDictionary *) dictionary {
NSMutableArray *query = [NSMutableArray array];
for (NSString *key in [dictionary allKeys]) {
id value = dictionary[key];
[query addObject:[NSString stringWithFormat:@"%@=%@",
[key description],
[value description]]];
}
return [query componentsJoinedByString:@"&"];
}