Commit 6c06a697 authored by 乔金柱's avatar 乔金柱

Merge branch 'jz/master' into 'master'

Jz/master

See merge request !3
parents 0ffb5668 6dbb618a
......@@ -34,4 +34,4 @@ Carthage/Build
# Note: if you ignore the Pods directory, make sure to uncomment
# `pod install` in .travis.yml
#
# Pods/
Pods/
......@@ -324,13 +324,27 @@
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-GMRouter_Example/Pods-GMRouter_Example-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/GMCache/GMCache.framework",
"${BUILT_PRODUCTS_DIR}/GMKit/GMKit.framework",
"${BUILT_PRODUCTS_DIR}/GMPhobos/GMPhobos.framework",
"${BUILT_PRODUCTS_DIR}/GMRouter/GMRouter.framework",
"${BUILT_PRODUCTS_DIR}/MJExtension/MJExtension.framework",
"${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework",
"${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework",
"${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework",
"${BUILT_PRODUCTS_DIR}/TMCache/TMCache.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GMCache.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GMKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GMPhobos.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GMRouter.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MJExtension.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Masonry.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TMCache.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
......
use_frameworks!
platform :ios, '8.0'
#require 'pry'
#open source
source 'https://github.com/CocoaPods/Specs.git'
#our company
source 'git@git.wanmeizhensuo.com:gengmeiios/GMSpecs.git'
target 'GMRouter_Example' do
pod 'GMRouter', :path => '../'
......
PODS:
- GMRouter (0.1.2):
- GMCache (1.0.1):
- TMCache (= 2.1.0)
- GMKit (1.2.5):
- GMKit/Category (= 1.2.5)
- GMKit/Color (= 1.2.5)
- GMKit/Constant (= 1.2.5)
- GMKit/FDFullscreenPopGesture (= 1.2.5)
- GMKit/Kit (= 1.2.5)
- GMKit/Protocol (= 1.2.5)
- Masonry
- SDWebImage
- SnapKit
- GMKit/Category (1.2.5):
- GMKit/Color (= 1.2.5)
- GMKit/Constant (= 1.2.5)
- GMKit/Protocol (= 1.2.5)
- Masonry
- SDWebImage
- SnapKit
- GMKit/Color (1.2.5):
- Masonry
- SDWebImage
- SnapKit
- GMKit/Constant (1.2.5):
- Masonry
- SDWebImage
- SnapKit
- GMKit/FDFullscreenPopGesture (1.2.5):
- Masonry
- SDWebImage
- SnapKit
- GMKit/Kit (1.2.5):
- GMKit/Category (= 1.2.5)
- GMKit/Color (= 1.2.5)
- GMKit/Constant (= 1.2.5)
- GMKit/Protocol (= 1.2.5)
- Masonry
- SDWebImage
- SnapKit
- GMKit/Protocol (1.2.5):
- Masonry
- SDWebImage
- SnapKit
- GMPhobos (1.3.5):
- GMCache
- GMKit
- GMRouter (0.1.5):
- GMPhobos
- MJExtension
- Masonry (1.1.0)
- MJExtension (3.2.1)
- SDWebImage (5.6.1):
- SDWebImage/Core (= 5.6.1)
- SDWebImage/Core (5.6.1)
- SnapKit (4.2.0)
- TMCache (2.1.0)
DEPENDENCIES:
- GMRouter (from `../`)
SPEC REPOS:
https://github.com/cocoapods/specs.git:
"git@git.wanmeizhensuo.com:gengmeiios/GMSpecs.git":
- GMCache
- GMKit
- GMPhobos
https://github.com/CocoaPods/Specs.git:
- Masonry
- MJExtension
- SDWebImage
- SnapKit
- TMCache
EXTERNAL SOURCES:
GMRouter:
:path: "../"
SPEC CHECKSUMS:
GMRouter: e5ee4c93aee2f94f977a847f13ec1371a5fbd372
GMCache: b78d8e46db864405e91d226ce640cc80d966c611
GMKit: 239609b2a4ea4d36d34fc74f08210ad47e260bd3
GMPhobos: 1e2d68c456b69bf156276d7242877498107474db
GMRouter: 347439b99a04d744714992d439d70a7d0afa80e9
Masonry: 678fab65091a9290e40e2832a55e7ab731aad201
MJExtension: 635f2c663dcb1bf76fa4b715b2570a5710aec545
SDWebImage: 7edb9c3ea661e77a66661f7f044de8c1b55d1120
SnapKit: fe8a619752f3f27075cc9a90244d75c6c3f27e2a
TMCache: 95ebcc9b3c7e90fb5fd8fc3036cba3aa781c9bed
PODFILE CHECKSUM: bcbc555b81a3b21a917383786de0d49ebef33013
PODFILE CHECKSUM: ea22114f5446c23313cc25de2cf84ff760e403e0
COCOAPODS: 1.7.4
COCOAPODS: 1.9.0
{
"name": "GMRouter",
"version": "0.1.2",
"summary": "A short description of GMRouter.",
"description": "TODO: Add long description of the pod here.",
"homepage": "http://git.wanmeizhensuo.com/gengmeiios/GMRouter.git",
"license": {
"type": "MIT",
"file": "LICENSE"
},
"authors": {
"Q14": "qiaojinzhu@igengmei.com"
},
"source": {
"git": "git@git.wanmeizhensuo.com:gengmeiios/GMRouter.git",
"tag": "0.1.2"
},
"platforms": {
"ios": "8.0"
},
"source_files": "GMRouter/Classes/**/*",
"dependencies": {
"MJExtension": [
]
}
}
Copyright (c) 2013-2019 MJExtension (https://github.com/CoderMJLee/MJExtension)
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:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
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.
//
// MJExtension.h
// MJExtension
//
// Created by mj on 14-1-15.
// Copyright (c) 2014年 小码哥. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "NSObject+MJCoding.h"
#import "NSObject+MJProperty.h"
#import "NSObject+MJClass.h"
#import "NSObject+MJKeyValue.h"
#import "NSString+MJExtension.h"
#import "MJExtensionConst.h"
#import "MJFoundation.h"
//! Project version number for MJExtension.
FOUNDATION_EXPORT double MJExtensionVersionNumber;
//! Project version string for MJExtension.
FOUNDATION_EXPORT const unsigned char MJExtensionVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <MJExtension/PublicHeader.h>
#ifndef __MJExtensionConst__H__
#define __MJExtensionConst__H__
#import <Foundation/Foundation.h>
#ifndef MJ_LOCK
#define MJ_LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
#endif
#ifndef MJ_UNLOCK
#define MJ_UNLOCK(lock) dispatch_semaphore_signal(lock);
#endif
// 信号量
#define MJExtensionSemaphoreCreate \
static dispatch_semaphore_t signalSemaphore; \
static dispatch_once_t onceTokenSemaphore; \
dispatch_once(&onceTokenSemaphore, ^{ \
signalSemaphore = dispatch_semaphore_create(1); \
});
#define MJExtensionSemaphoreWait MJ_LOCK(signalSemaphore)
#define MJExtensionSemaphoreSignal MJ_UNLOCK(signalSemaphore)
// 过期
#define MJExtensionDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead)
// 构建错误
#define MJExtensionBuildError(clazz, msg) \
NSError *error = [NSError errorWithDomain:msg code:250 userInfo:nil]; \
[clazz setMj_error:error];
// 日志输出
#ifdef DEBUG
#define MJExtensionLog(...) NSLog(__VA_ARGS__)
#else
#define MJExtensionLog(...)
#endif
/**
* 断言
* @param condition 条件
* @param returnValue 返回值
*/
#define MJExtensionAssertError(condition, returnValue, clazz, msg) \
[clazz setMj_error:nil]; \
if ((condition) == NO) { \
MJExtensionBuildError(clazz, msg); \
return returnValue;\
}
#define MJExtensionAssert2(condition, returnValue) \
if ((condition) == NO) return returnValue;
/**
* 断言
* @param condition 条件
*/
#define MJExtensionAssert(condition) MJExtensionAssert2(condition, )
/**
* 断言
* @param param 参数
* @param returnValue 返回值
*/
#define MJExtensionAssertParamNotNil2(param, returnValue) \
MJExtensionAssert2((param) != nil, returnValue)
/**
* 断言
* @param param 参数
*/
#define MJExtensionAssertParamNotNil(param) MJExtensionAssertParamNotNil2(param, )
/**
* 打印所有的属性
*/
#define MJLogAllIvars \
- (NSString *)description \
{ \
return [self mj_keyValues].description; \
}
#define MJExtensionLogAllProperties MJLogAllIvars
/** 仅在 Debugger 展示所有的属性 */
#define MJImplementDebugDescription \
- (NSString *)debugDescription \
{ \
return [self mj_keyValues].debugDescription; \
}
/**
* 类型(属性类型)
*/
FOUNDATION_EXPORT NSString *const MJPropertyTypeInt;
FOUNDATION_EXPORT NSString *const MJPropertyTypeShort;
FOUNDATION_EXPORT NSString *const MJPropertyTypeFloat;
FOUNDATION_EXPORT NSString *const MJPropertyTypeDouble;
FOUNDATION_EXPORT NSString *const MJPropertyTypeLong;
FOUNDATION_EXPORT NSString *const MJPropertyTypeLongLong;
FOUNDATION_EXPORT NSString *const MJPropertyTypeChar;
FOUNDATION_EXPORT NSString *const MJPropertyTypeBOOL1;
FOUNDATION_EXPORT NSString *const MJPropertyTypeBOOL2;
FOUNDATION_EXPORT NSString *const MJPropertyTypePointer;
FOUNDATION_EXPORT NSString *const MJPropertyTypeIvar;
FOUNDATION_EXPORT NSString *const MJPropertyTypeMethod;
FOUNDATION_EXPORT NSString *const MJPropertyTypeBlock;
FOUNDATION_EXPORT NSString *const MJPropertyTypeClass;
FOUNDATION_EXPORT NSString *const MJPropertyTypeSEL;
FOUNDATION_EXPORT NSString *const MJPropertyTypeId;
#endif
#ifndef __MJExtensionConst__M__
#define __MJExtensionConst__M__
#import <Foundation/Foundation.h>
/**
* 成员变量类型(属性类型)
*/
NSString *const MJPropertyTypeInt = @"i";
NSString *const MJPropertyTypeShort = @"s";
NSString *const MJPropertyTypeFloat = @"f";
NSString *const MJPropertyTypeDouble = @"d";
NSString *const MJPropertyTypeLong = @"l";
NSString *const MJPropertyTypeLongLong = @"q";
NSString *const MJPropertyTypeChar = @"c";
NSString *const MJPropertyTypeBOOL1 = @"c";
NSString *const MJPropertyTypeBOOL2 = @"b";
NSString *const MJPropertyTypePointer = @"*";
NSString *const MJPropertyTypeIvar = @"^{objc_ivar=}";
NSString *const MJPropertyTypeMethod = @"^{objc_method=}";
NSString *const MJPropertyTypeBlock = @"@?";
NSString *const MJPropertyTypeClass = @"#";
NSString *const MJPropertyTypeSEL = @":";
NSString *const MJPropertyTypeId = @"@";
#endif
\ No newline at end of file
//
// MJFoundation.h
// MJExtensionExample
//
// Created by MJ Lee on 14/7/16.
// Copyright (c) 2014年 小码哥. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface MJFoundation : NSObject
+ (BOOL)isClassFromFoundation:(Class)c;
+ (BOOL)isFromNSObjectProtocolProperty:(NSString *)propertyName;
@end
//
// MJFoundation.m
// MJExtensionExample
//
// Created by MJ Lee on 14/7/16.
// Copyright (c) 2014年 小码哥. All rights reserved.
//
#import "MJFoundation.h"
#import "MJExtensionConst.h"
#import <CoreData/CoreData.h>
#import "objc/runtime.h"
@implementation MJFoundation
+ (BOOL)isClassFromFoundation:(Class)c
{
if (c == [NSObject class] || c == [NSManagedObject class]) return YES;
static NSSet *foundationClasses;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 集合中没有NSObject,因为几乎所有的类都是继承自NSObject,具体是不是NSObject需要特殊判断
foundationClasses = [NSSet setWithObjects:
[NSURL class],
[NSDate class],
[NSValue class],
[NSData class],
[NSError class],
[NSArray class],
[NSDictionary class],
[NSString class],
[NSAttributedString class], nil];
});
__block BOOL result = NO;
[foundationClasses enumerateObjectsUsingBlock:^(Class foundationClass, BOOL *stop) {
if ([c isSubclassOfClass:foundationClass]) {
result = YES;
*stop = YES;
}
}];
return result;
}
+ (BOOL)isFromNSObjectProtocolProperty:(NSString *)propertyName
{
if (!propertyName) return NO;
static NSSet<NSString *> *objectProtocolPropertyNames;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
unsigned int count = 0;
objc_property_t *propertyList = protocol_copyPropertyList(@protocol(NSObject), &count);
NSMutableSet *propertyNames = [NSMutableSet setWithCapacity:count];
for (int i = 0; i < count; i++) {
objc_property_t property = propertyList[i];
NSString *propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
if (propertyName) {
[propertyNames addObject:propertyName];
}
}
objectProtocolPropertyNames = [propertyNames copy];
free(propertyList);
});
return [objectProtocolPropertyNames containsObject:propertyName];
}
@end
//
// MJProperty.h
// MJExtensionExample
//
// Created by MJ Lee on 15/4/17.
// Copyright (c) 2015年 小码哥. All rights reserved.
// 包装一个成员属性
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import "MJPropertyType.h"
#import "MJPropertyKey.h"
/**
* 包装一个成员
*/
@interface MJProperty : NSObject
/** 成员属性 */
@property (nonatomic, assign) objc_property_t property;
/** 成员属性的名字 */
@property (nonatomic, readonly) NSString *name;
/** 成员属性的类型 */
@property (nonatomic, readonly) MJPropertyType *type;
/** 成员属性来源于哪个类(可能是父类) */
@property (nonatomic, assign) Class srcClass;
/**** 同一个成员属性 - 父类和子类的行为可能不一致(originKey、propertyKeys、objectClassInArray) ****/
/** 设置最原始的key */
- (void)setOriginKey:(id)originKey forClass:(Class)c;
/** 对应着字典中的多级key(里面存放的数组,数组里面都是MJPropertyKey对象) */
- (NSArray *)propertyKeysForClass:(Class)c;
/** 模型数组中的模型类型 */
- (void)setObjectClassInArray:(Class)objectClass forClass:(Class)c;
- (Class)objectClassInArrayForClass:(Class)c;
/**** 同一个成员变量 - 父类和子类的行为可能不一致(key、keys、objectClassInArray) ****/
/**
* 设置object的成员变量值
*/
- (void)setValue:(id)value forObject:(id)object;
/**
* 得到object的成员属性值
*/
- (id)valueForObject:(id)object;
/**
* 初始化
*/
+ (instancetype)cachedPropertyWithProperty:(objc_property_t)property;
@end
//
// MJProperty.m
// MJExtensionExample
//
// Created by MJ Lee on 15/4/17.
// Copyright (c) 2015年 小码哥. All rights reserved.
//
#import "MJProperty.h"
#import "MJFoundation.h"
#import "MJExtensionConst.h"
#import <objc/message.h>
#include "TargetConditionals.h"
@interface MJProperty()
@property (strong, nonatomic) NSMutableDictionary *propertyKeysDict;
@property (strong, nonatomic) NSMutableDictionary *objectClassInArrayDict;
@property (strong, nonatomic) dispatch_semaphore_t propertyKeysLock;
@property (strong, nonatomic) dispatch_semaphore_t objectClassInArrayLock;
@end
@implementation MJProperty
#pragma mark - 初始化
- (instancetype)init
{
if (self = [super init]) {
_propertyKeysDict = [NSMutableDictionary dictionary];
_objectClassInArrayDict = [NSMutableDictionary dictionary];
_propertyKeysLock = dispatch_semaphore_create(1);
_objectClassInArrayLock = dispatch_semaphore_create(1);
}
return self;
}
#pragma mark - 缓存
+ (instancetype)cachedPropertyWithProperty:(objc_property_t)property
{
MJProperty *propertyObj = objc_getAssociatedObject(self, property);
if (propertyObj == nil) {
propertyObj = [[self alloc] init];
propertyObj.property = property;
objc_setAssociatedObject(self, property, propertyObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return propertyObj;
}
#pragma mark - 公共方法
- (void)setProperty:(objc_property_t)property
{
_property = property;
MJExtensionAssertParamNotNil(property);
// 1.属性名
_name = @(property_getName(property));
// 2.成员类型
NSString *attrs = @(property_getAttributes(property));
NSUInteger dotLoc = [attrs rangeOfString:@","].location;
NSString *code = nil;
NSUInteger loc = 1;
if (dotLoc == NSNotFound) { // 没有,
code = [attrs substringFromIndex:loc];
} else {
code = [attrs substringWithRange:NSMakeRange(loc, dotLoc - loc)];
}
_type = [MJPropertyType cachedTypeWithCode:code];
}
/**
* 获得成员变量的值
*/
- (id)valueForObject:(id)object
{
if (self.type.KVCDisabled) return [NSNull null];
id value = [object valueForKey:self.name];
// 32位BOOL类型转换json后成Int类型
/** https://github.com/CoderMJLee/MJExtension/issues/545 */
// 32 bit device OR 32 bit Simulator
#if defined(__arm__) || (TARGET_OS_SIMULATOR && !__LP64__)
if (self.type.isBoolType) {
value = @([(NSNumber *)value boolValue]);
}
#endif
return value;
}
/**
* 设置成员变量的值
*/
- (void)setValue:(id)value forObject:(id)object
{
if (self.type.KVCDisabled || value == nil) return;
[object setValue:value forKey:self.name];
}
/**
* 通过字符串key创建对应的keys
*/
- (NSArray *)propertyKeysWithStringKey:(NSString *)stringKey
{
if (stringKey.length == 0) return nil;
NSMutableArray *propertyKeys = [NSMutableArray array];
// 如果有多级映射
NSArray *oldKeys = [stringKey componentsSeparatedByString:@"."];
for (NSString *oldKey in oldKeys) {
NSUInteger start = [oldKey rangeOfString:@"["].location;
if (start != NSNotFound) { // 有索引的key
NSString *prefixKey = [oldKey substringToIndex:start];
NSString *indexKey = prefixKey;
if (prefixKey.length) {
MJPropertyKey *propertyKey = [[MJPropertyKey alloc] init];
propertyKey.name = prefixKey;
[propertyKeys addObject:propertyKey];
indexKey = [oldKey stringByReplacingOccurrencesOfString:prefixKey withString:@""];
}
/** 解析索引 **/
// 元素
NSArray *cmps = [[indexKey stringByReplacingOccurrencesOfString:@"[" withString:@""] componentsSeparatedByString:@"]"];
for (NSInteger i = 0; i<cmps.count - 1; i++) {
MJPropertyKey *subPropertyKey = [[MJPropertyKey alloc] init];
subPropertyKey.type = MJPropertyKeyTypeArray;
subPropertyKey.name = cmps[i];
[propertyKeys addObject:subPropertyKey];
}
} else { // 没有索引的key
MJPropertyKey *propertyKey = [[MJPropertyKey alloc] init];
propertyKey.name = oldKey;
[propertyKeys addObject:propertyKey];
}
}
return propertyKeys;
}
/** 对应着字典中的key */
- (void)setOriginKey:(id)originKey forClass:(Class)c
{
if ([originKey isKindOfClass:[NSString class]]) { // 字符串类型的key
NSArray *propertyKeys = [self propertyKeysWithStringKey:originKey];
if (propertyKeys.count) {
[self setPorpertyKeys:@[propertyKeys] forClass:c];
}
} else if ([originKey isKindOfClass:[NSArray class]]) {
NSMutableArray *keyses = [NSMutableArray array];
for (NSString *stringKey in originKey) {
NSArray *propertyKeys = [self propertyKeysWithStringKey:stringKey];
if (propertyKeys.count) {
[keyses addObject:propertyKeys];
}
}
if (keyses.count) {
[self setPorpertyKeys:keyses forClass:c];
}
}
}
/** 对应着字典中的多级key */
- (void)setPorpertyKeys:(NSArray *)propertyKeys forClass:(Class)c
{
if (propertyKeys.count == 0) return;
NSString *key = NSStringFromClass(c);
if (!key) return;
MJ_LOCK(self.propertyKeysLock);
self.propertyKeysDict[key] = propertyKeys;
MJ_UNLOCK(self.propertyKeysLock);
}
- (NSArray *)propertyKeysForClass:(Class)c
{
NSString *key = NSStringFromClass(c);
if (!key) return nil;
MJ_LOCK(self.propertyKeysLock);
NSArray *propertyKeys = self.propertyKeysDict[key];
MJ_UNLOCK(self.propertyKeysLock);
return propertyKeys;
}
/** 模型数组中的模型类型 */
- (void)setObjectClassInArray:(Class)objectClass forClass:(Class)c
{
if (!objectClass) return;
NSString *key = NSStringFromClass(c);
if (!key) return;
MJ_LOCK(self.objectClassInArrayLock);
self.objectClassInArrayDict[key] = objectClass;
MJ_UNLOCK(self.objectClassInArrayLock);
}
- (Class)objectClassInArrayForClass:(Class)c
{
NSString *key = NSStringFromClass(c);
if (!key) return nil;
MJ_LOCK(self.objectClassInArrayLock);
Class objectClass = self.objectClassInArrayDict[key];
MJ_UNLOCK(self.objectClassInArrayLock);
return objectClass;
}
@end
//
// MJPropertyKey.h
// MJExtensionExample
//
// Created by MJ Lee on 15/8/11.
// Copyright (c) 2015年 小码哥. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef enum {
MJPropertyKeyTypeDictionary = 0, // 字典的key
MJPropertyKeyTypeArray // 数组的key
} MJPropertyKeyType;
/**
* 属性的key
*/
@interface MJPropertyKey : NSObject
/** key的名字 */
@property (copy, nonatomic) NSString *name;
/** key的种类,可能是@"10",可能是@"age" */
@property (assign, nonatomic) MJPropertyKeyType type;
/**
* 根据当前的key,也就是name,从object(字典或者数组)中取值
*/
- (id)valueInObject:(id)object;
@end
//
// MJPropertyKey.m
// MJExtensionExample
//
// Created by MJ Lee on 15/8/11.
// Copyright (c) 2015年 小码哥. All rights reserved.
//
#import "MJPropertyKey.h"
@implementation MJPropertyKey
- (id)valueInObject:(id)object
{
if ([object isKindOfClass:[NSDictionary class]] && self.type == MJPropertyKeyTypeDictionary) {
return object[self.name];
} else if ([object isKindOfClass:[NSArray class]] && self.type == MJPropertyKeyTypeArray) {
NSArray *array = object;
NSUInteger index = self.name.intValue;
if (index < array.count) return array[index];
return nil;
}
return nil;
}
@end
//
// MJPropertyType.h
// MJExtension
//
// Created by mj on 14-1-15.
// Copyright (c) 2014年 小码哥. All rights reserved.
// 包装一种类型
#import <Foundation/Foundation.h>
/**
* 包装一种类型
*/
@interface MJPropertyType : NSObject
/** 类型标识符 */
@property (nonatomic, copy) NSString *code;
/** 是否为id类型 */
@property (nonatomic, readonly, getter=isIdType) BOOL idType;
/** 是否为基本数字类型:int、float等 */
@property (nonatomic, readonly, getter=isNumberType) BOOL numberType;
/** 是否为BOOL类型 */
@property (nonatomic, readonly, getter=isBoolType) BOOL boolType;
/** 对象类型(如果是基本数据类型,此值为nil) */
@property (nonatomic, readonly) Class typeClass;
/** 类型是否来自于Foundation框架,比如NSString、NSArray */
@property (nonatomic, readonly, getter = isFromFoundation) BOOL fromFoundation;
/** 类型是否不支持KVC */
@property (nonatomic, readonly, getter = isKVCDisabled) BOOL KVCDisabled;
/**
* 获得缓存的类型对象
*/
+ (instancetype)cachedTypeWithCode:(NSString *)code;
@end
\ No newline at end of file
//
// MJPropertyType.m
// MJExtension
//
// Created by mj on 14-1-15.
// Copyright (c) 2014年 小码哥. All rights reserved.
//
#import "MJPropertyType.h"
#import "MJExtension.h"
#import "MJFoundation.h"
#import "MJExtensionConst.h"
@implementation MJPropertyType
+ (instancetype)cachedTypeWithCode:(NSString *)code
{
MJExtensionAssertParamNotNil2(code, nil);
static NSMutableDictionary *types;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
types = [NSMutableDictionary dictionary];
});
MJPropertyType *type = types[code];
if (type == nil) {
type = [[self alloc] init];
type.code = code;
types[code] = type;
}
return type;
}
#pragma mark - 公共方法
- (void)setCode:(NSString *)code
{
_code = code;
MJExtensionAssertParamNotNil(code);
if ([code isEqualToString:MJPropertyTypeId]) {
_idType = YES;
} else if (code.length == 0) {
_KVCDisabled = YES;
} else if (code.length > 3 && [code hasPrefix:@"@\""]) {
// 去掉@"和",截取中间的类型名称
_code = [code substringWithRange:NSMakeRange(2, code.length - 3)];
_typeClass = NSClassFromString(_code);
_fromFoundation = [MJFoundation isClassFromFoundation:_typeClass];
_numberType = [_typeClass isSubclassOfClass:[NSNumber class]];
} else if ([code isEqualToString:MJPropertyTypeSEL] ||
[code isEqualToString:MJPropertyTypeIvar] ||
[code isEqualToString:MJPropertyTypeMethod]) {
_KVCDisabled = YES;
}
// 是否为数字类型
NSString *lowerCode = _code.lowercaseString;
NSArray *numberTypes = @[MJPropertyTypeInt, MJPropertyTypeShort, MJPropertyTypeBOOL1, MJPropertyTypeBOOL2, MJPropertyTypeFloat, MJPropertyTypeDouble, MJPropertyTypeLong, MJPropertyTypeLongLong, MJPropertyTypeChar];
if ([numberTypes containsObject:lowerCode]) {
_numberType = YES;
if ([lowerCode isEqualToString:MJPropertyTypeBOOL1]
|| [lowerCode isEqualToString:MJPropertyTypeBOOL2]) {
_boolType = YES;
}
}
}
@end
//
// NSObject+MJClass.h
// MJExtensionExample
//
// Created by MJ Lee on 15/8/11.
// Copyright (c) 2015年 小码哥. All rights reserved.
//
#import <Foundation/Foundation.h>
/**
* 遍历所有类的block(父类)
*/
typedef void (^MJClassesEnumeration)(Class c, BOOL *stop);
/** 这个数组中的属性名才会进行字典和模型的转换 */
typedef NSArray * (^MJAllowedPropertyNames)(void);
/** 这个数组中的属性名才会进行归档 */
typedef NSArray * (^MJAllowedCodingPropertyNames)(void);
/** 这个数组中的属性名将会被忽略:不进行字典和模型的转换 */
typedef NSArray * (^MJIgnoredPropertyNames)(void);
/** 这个数组中的属性名将会被忽略:不进行归档 */
typedef NSArray * (^MJIgnoredCodingPropertyNames)(void);
/**
* 类相关的扩展
*/
@interface NSObject (MJClass)
/**
* 遍历所有的类
*/
+ (void)mj_enumerateClasses:(MJClassesEnumeration)enumeration;
+ (void)mj_enumerateAllClasses:(MJClassesEnumeration)enumeration;
#pragma mark - 属性白名单配置
/**
* 这个数组中的属性名才会进行字典和模型的转换
*
* @param allowedPropertyNames 这个数组中的属性名才会进行字典和模型的转换
*/
+ (void)mj_setupAllowedPropertyNames:(MJAllowedPropertyNames)allowedPropertyNames;
/**
* 这个数组中的属性名才会进行字典和模型的转换
*/
+ (NSMutableArray *)mj_totalAllowedPropertyNames;
#pragma mark - 属性黑名单配置
/**
* 这个数组中的属性名将会被忽略:不进行字典和模型的转换
*
* @param ignoredPropertyNames 这个数组中的属性名将会被忽略:不进行字典和模型的转换
*/
+ (void)mj_setupIgnoredPropertyNames:(MJIgnoredPropertyNames)ignoredPropertyNames;
/**
* 这个数组中的属性名将会被忽略:不进行字典和模型的转换
*/
+ (NSMutableArray *)mj_totalIgnoredPropertyNames;
#pragma mark - 归档属性白名单配置
/**
* 这个数组中的属性名才会进行归档
*
* @param allowedCodingPropertyNames 这个数组中的属性名才会进行归档
*/
+ (void)mj_setupAllowedCodingPropertyNames:(MJAllowedCodingPropertyNames)allowedCodingPropertyNames;
/**
* 这个数组中的属性名才会进行字典和模型的转换
*/
+ (NSMutableArray *)mj_totalAllowedCodingPropertyNames;
#pragma mark - 归档属性黑名单配置
/**
* 这个数组中的属性名将会被忽略:不进行归档
*
* @param ignoredCodingPropertyNames 这个数组中的属性名将会被忽略:不进行归档
*/
+ (void)mj_setupIgnoredCodingPropertyNames:(MJIgnoredCodingPropertyNames)ignoredCodingPropertyNames;
/**
* 这个数组中的属性名将会被忽略:不进行归档
*/
+ (NSMutableArray *)mj_totalIgnoredCodingPropertyNames;
#pragma mark - 内部使用
+ (void)mj_setupBlockReturnValue:(id (^)(void))block key:(const char *)key;
@end
//
// NSObject+MJClass.m
// MJExtensionExample
//
// Created by MJ Lee on 15/8/11.
// Copyright (c) 2015年 小码哥. All rights reserved.
//
#import "NSObject+MJClass.h"
#import "NSObject+MJCoding.h"
#import "NSObject+MJKeyValue.h"
#import "MJFoundation.h"
#import <objc/runtime.h>
static const char MJAllowedPropertyNamesKey = '\0';
static const char MJIgnoredPropertyNamesKey = '\0';
static const char MJAllowedCodingPropertyNamesKey = '\0';
static const char MJIgnoredCodingPropertyNamesKey = '\0';
@implementation NSObject (MJClass)
+ (NSMutableDictionary *)mj_classDictForKey:(const void *)key
{
static NSMutableDictionary *allowedPropertyNamesDict;
static NSMutableDictionary *ignoredPropertyNamesDict;
static NSMutableDictionary *allowedCodingPropertyNamesDict;
static NSMutableDictionary *ignoredCodingPropertyNamesDict;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
allowedPropertyNamesDict = [NSMutableDictionary dictionary];
ignoredPropertyNamesDict = [NSMutableDictionary dictionary];
allowedCodingPropertyNamesDict = [NSMutableDictionary dictionary];
ignoredCodingPropertyNamesDict = [NSMutableDictionary dictionary];
});
if (key == &MJAllowedPropertyNamesKey) return allowedPropertyNamesDict;
if (key == &MJIgnoredPropertyNamesKey) return ignoredPropertyNamesDict;
if (key == &MJAllowedCodingPropertyNamesKey) return allowedCodingPropertyNamesDict;
if (key == &MJIgnoredCodingPropertyNamesKey) return ignoredCodingPropertyNamesDict;
return nil;
}
+ (void)mj_enumerateClasses:(MJClassesEnumeration)enumeration
{
// 1.没有block就直接返回
if (enumeration == nil) return;
// 2.停止遍历的标记
BOOL stop = NO;
// 3.当前正在遍历的类
Class c = self;
// 4.开始遍历每一个类
while (c && !stop) {
// 4.1.执行操作
enumeration(c, &stop);
// 4.2.获得父类
c = class_getSuperclass(c);
if ([MJFoundation isClassFromFoundation:c]) break;
}
}
+ (void)mj_enumerateAllClasses:(MJClassesEnumeration)enumeration
{
// 1.没有block就直接返回
if (enumeration == nil) return;
// 2.停止遍历的标记
BOOL stop = NO;
// 3.当前正在遍历的类
Class c = self;
// 4.开始遍历每一个类
while (c && !stop) {
// 4.1.执行操作
enumeration(c, &stop);
// 4.2.获得父类
c = class_getSuperclass(c);
}
}
#pragma mark - 属性黑名单配置
+ (void)mj_setupIgnoredPropertyNames:(MJIgnoredPropertyNames)ignoredPropertyNames
{
[self mj_setupBlockReturnValue:ignoredPropertyNames key:&MJIgnoredPropertyNamesKey];
}
+ (NSMutableArray *)mj_totalIgnoredPropertyNames
{
return [self mj_totalObjectsWithSelector:@selector(mj_ignoredPropertyNames) key:&MJIgnoredPropertyNamesKey];
}
#pragma mark - 归档属性黑名单配置
+ (void)mj_setupIgnoredCodingPropertyNames:(MJIgnoredCodingPropertyNames)ignoredCodingPropertyNames
{
[self mj_setupBlockReturnValue:ignoredCodingPropertyNames key:&MJIgnoredCodingPropertyNamesKey];
}
+ (NSMutableArray *)mj_totalIgnoredCodingPropertyNames
{
return [self mj_totalObjectsWithSelector:@selector(mj_ignoredCodingPropertyNames) key:&MJIgnoredCodingPropertyNamesKey];
}
#pragma mark - 属性白名单配置
+ (void)mj_setupAllowedPropertyNames:(MJAllowedPropertyNames)allowedPropertyNames;
{
[self mj_setupBlockReturnValue:allowedPropertyNames key:&MJAllowedPropertyNamesKey];
}
+ (NSMutableArray *)mj_totalAllowedPropertyNames
{
return [self mj_totalObjectsWithSelector:@selector(mj_allowedPropertyNames) key:&MJAllowedPropertyNamesKey];
}
#pragma mark - 归档属性白名单配置
+ (void)mj_setupAllowedCodingPropertyNames:(MJAllowedCodingPropertyNames)allowedCodingPropertyNames
{
[self mj_setupBlockReturnValue:allowedCodingPropertyNames key:&MJAllowedCodingPropertyNamesKey];
}
+ (NSMutableArray *)mj_totalAllowedCodingPropertyNames
{
return [self mj_totalObjectsWithSelector:@selector(mj_allowedCodingPropertyNames) key:&MJAllowedCodingPropertyNamesKey];
}
#pragma mark - block和方法处理:存储block的返回值
+ (void)mj_setupBlockReturnValue:(id (^)(void))block key:(const char *)key
{
if (block) {
objc_setAssociatedObject(self, key, block(), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
} else {
objc_setAssociatedObject(self, key, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
// 清空数据
MJExtensionSemaphoreCreate
MJExtensionSemaphoreWait
[[self mj_classDictForKey:key] removeAllObjects];
MJExtensionSemaphoreSignal
}
+ (NSMutableArray *)mj_totalObjectsWithSelector:(SEL)selector key:(const char *)key
{
MJExtensionSemaphoreCreate
MJExtensionSemaphoreWait
NSMutableArray *array = [self mj_classDictForKey:key][NSStringFromClass(self)];
if (array == nil) {
// 创建、存储
[self mj_classDictForKey:key][NSStringFromClass(self)] = array = [NSMutableArray array];
if ([self respondsToSelector:selector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
NSArray *subArray = [self performSelector:selector];
#pragma clang diagnostic pop
if (subArray) {
[array addObjectsFromArray:subArray];
}
}
[self mj_enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
NSArray *subArray = objc_getAssociatedObject(c, key);
[array addObjectsFromArray:subArray];
}];
}
MJExtensionSemaphoreSignal
return array;
}
@end
//
// NSObject+MJCoding.h
// MJExtension
//
// Created by mj on 14-1-15.
// Copyright (c) 2014年 小码哥. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MJExtensionConst.h"
/**
* Codeing协议
*/
@protocol MJCoding <NSObject>
@optional
/**
* 这个数组中的属性名才会进行归档
*/
+ (NSArray *)mj_allowedCodingPropertyNames;
/**
* 这个数组中的属性名将会被忽略:不进行归档
*/
+ (NSArray *)mj_ignoredCodingPropertyNames;
@end
@interface NSObject (MJCoding) <MJCoding>
/**
* 解码(从文件中解析对象)
*/
- (void)mj_decode:(NSCoder *)decoder;
/**
* 编码(将对象写入文件中)
*/
- (void)mj_encode:(NSCoder *)encoder;
@end
/**
归档的实现
*/
#define MJCodingImplementation \
- (id)initWithCoder:(NSCoder *)decoder \
{ \
if (self = [super init]) { \
[self mj_decode:decoder]; \
} \
return self; \
} \
\
- (void)encodeWithCoder:(NSCoder *)encoder \
{ \
[self mj_encode:encoder]; \
}
#define MJExtensionCodingImplementation MJCodingImplementation
\ No newline at end of file
//
// NSObject+MJCoding.m
// MJExtension
//
// Created by mj on 14-1-15.
// Copyright (c) 2014年 小码哥. All rights reserved.
//
#import "NSObject+MJCoding.h"
#import "NSObject+MJClass.h"
#import "NSObject+MJProperty.h"
#import "MJProperty.h"
@implementation NSObject (MJCoding)
- (void)mj_encode:(NSCoder *)encoder
{
Class clazz = [self class];
NSArray *allowedCodingPropertyNames = [clazz mj_totalAllowedCodingPropertyNames];
NSArray *ignoredCodingPropertyNames = [clazz mj_totalIgnoredCodingPropertyNames];
[clazz mj_enumerateProperties:^(MJProperty *property, BOOL *stop) {
// 检测是否被忽略
if (allowedCodingPropertyNames.count && ![allowedCodingPropertyNames containsObject:property.name]) return;
if ([ignoredCodingPropertyNames containsObject:property.name]) return;
id value = [property valueForObject:self];
if (value == nil) return;
[encoder encodeObject:value forKey:property.name];
}];
}
- (void)mj_decode:(NSCoder *)decoder
{
Class clazz = [self class];
NSArray *allowedCodingPropertyNames = [clazz mj_totalAllowedCodingPropertyNames];
NSArray *ignoredCodingPropertyNames = [clazz mj_totalIgnoredCodingPropertyNames];
[clazz mj_enumerateProperties:^(MJProperty *property, BOOL *stop) {
// 检测是否被忽略
if (allowedCodingPropertyNames.count && ![allowedCodingPropertyNames containsObject:property.name]) return;
if ([ignoredCodingPropertyNames containsObject:property.name]) return;
id value = [decoder decodeObjectForKey:property.name];
if (value == nil) { // 兼容以前的MJExtension版本
value = [decoder decodeObjectForKey:[@"_" stringByAppendingString:property.name]];
}
if (value == nil) return;
[property setValue:value forObject:self];
}];
}
@end
//
// NSObject+MJKeyValue.h
// MJExtension
//
// Created by mj on 13-8-24.
// Copyright (c) 2013年 小码哥. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MJExtensionConst.h"
#import <CoreData/CoreData.h>
#import "MJProperty.h"
/**
* KeyValue协议
*/
@protocol MJKeyValue <NSObject>
@optional
/**
* 只有这个数组中的属性名才允许进行字典和模型的转换
*/
+ (NSArray *)mj_allowedPropertyNames;
/**
* 这个数组中的属性名将会被忽略:不进行字典和模型的转换
*/
+ (NSArray *)mj_ignoredPropertyNames;
/**
* 将属性名换为其他key去字典中取值
*
* @return 字典中的key是属性名,value是从字典中取值用的key
*/
+ (NSDictionary *)mj_replacedKeyFromPropertyName;
/**
* 将属性名换为其他key去字典中取值
*
* @return 从字典中取值用的key
*/
+ (id)mj_replacedKeyFromPropertyName121:(NSString *)propertyName;
/**
* 数组中需要转换的模型类
*
* @return 字典中的key是数组属性名,value是数组中存放模型的Class(Class类型或者NSString类型)
*/
+ (NSDictionary *)mj_objectClassInArray;
/** 特殊地区在字符串格式化数字时使用 */
+ (NSLocale *)mj_numberLocale;
/**
* 旧值换新值,用于过滤字典中的值
*
* @param oldValue 旧值
*
* @return 新值
*/
- (id)mj_newValueFromOldValue:(id)oldValue property:(MJProperty *)property;
/**
* 当字典转模型完毕时调用
*/
- (void)mj_keyValuesDidFinishConvertingToObject MJExtensionDeprecated("请使用`mj_didConvertToObjectWithKeyValues:`替代");
- (void)mj_keyValuesDidFinishConvertingToObject:(NSDictionary *)keyValues MJExtensionDeprecated("请使用`mj_didConvertToObjectWithKeyValues:`替代");
- (void)mj_didConvertToObjectWithKeyValues:(NSDictionary *)keyValues;
/**
* 当模型转字典完毕时调用
*/
- (void)mj_objectDidFinishConvertingToKeyValues MJExtensionDeprecated("请使用`mj_objectDidConvertToKeyValues:`替代");
- (void)mj_objectDidConvertToKeyValues:(NSDictionary *)keyValues;
@end
@interface NSObject (MJKeyValue) <MJKeyValue>
#pragma mark - 类方法
/**
* 字典转模型过程中遇到的错误
*/
+ (NSError *)mj_error;
/**
* 模型转字典时,字典的key是否参考replacedKeyFromPropertyName等方法(父类设置了,子类也会继承下来)
*/
+ (void)mj_referenceReplacedKeyWhenCreatingKeyValues:(BOOL)reference;
#pragma mark - 对象方法
/**
* 将字典的键值对转成模型属性
* @param keyValues 字典(可以是NSDictionary、NSData、NSString)
*/
- (instancetype)mj_setKeyValues:(id)keyValues;
/**
* 将字典的键值对转成模型属性
* @param keyValues 字典(可以是NSDictionary、NSData、NSString)
* @param context CoreData上下文
*/
- (instancetype)mj_setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context;
/**
* 将模型转成字典
* @return 字典
*/
- (NSMutableDictionary *)mj_keyValues;
- (NSMutableDictionary *)mj_keyValuesWithKeys:(NSArray *)keys;
- (NSMutableDictionary *)mj_keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys;
/**
* 通过模型数组来创建一个字典数组
* @param objectArray 模型数组
* @return 字典数组
*/
+ (NSMutableArray *)mj_keyValuesArrayWithObjectArray:(NSArray *)objectArray;
+ (NSMutableArray *)mj_keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys;
+ (NSMutableArray *)mj_keyValuesArrayWithObjectArray:(NSArray *)objectArray ignoredKeys:(NSArray *)ignoredKeys;
#pragma mark - 字典转模型
/**
* 通过字典来创建一个模型
* @param keyValues 字典(可以是NSDictionary、NSData、NSString)
* @return 新建的对象
*/
+ (instancetype)mj_objectWithKeyValues:(id)keyValues;
/**
* 通过字典来创建一个CoreData模型
* @param keyValues 字典(可以是NSDictionary、NSData、NSString)
* @param context CoreData上下文
* @return 新建的对象
*/
+ (instancetype)mj_objectWithKeyValues:(id)keyValues context:(NSManagedObjectContext *)context;
/**
* 通过plist来创建一个模型
* @param filename 文件名(仅限于mainBundle中的文件)
* @return 新建的对象
*/
+ (instancetype)mj_objectWithFilename:(NSString *)filename;
/**
* 通过plist来创建一个模型
* @param file 文件全路径
* @return 新建的对象
*/
+ (instancetype)mj_objectWithFile:(NSString *)file;
#pragma mark - 字典数组转模型数组
/**
* 通过字典数组来创建一个模型数组
* @param keyValuesArray 字典数组(可以是NSDictionary、NSData、NSString)
* @return 模型数组
*/
+ (NSMutableArray *)mj_objectArrayWithKeyValuesArray:(id)keyValuesArray;
/**
* 通过字典数组来创建一个模型数组
* @param keyValuesArray 字典数组(可以是NSDictionary、NSData、NSString)
* @param context CoreData上下文
* @return 模型数组
*/
+ (NSMutableArray *)mj_objectArrayWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context;
/**
* 通过plist来创建一个模型数组
* @param filename 文件名(仅限于mainBundle中的文件)
* @return 模型数组
*/
+ (NSMutableArray *)mj_objectArrayWithFilename:(NSString *)filename;
/**
* 通过plist来创建一个模型数组
* @param file 文件全路径
* @return 模型数组
*/
+ (NSMutableArray *)mj_objectArrayWithFile:(NSString *)file;
#pragma mark - 转换为JSON
/**
* 转换为JSON Data
*/
- (NSData *)mj_JSONData;
/**
* 转换为字典或者数组
*/
- (id)mj_JSONObject;
/**
* 转换为JSON 字符串
*/
- (NSString *)mj_JSONString;
@end
//
// NSObject+MJKeyValue.m
// MJExtension
//
// Created by mj on 13-8-24.
// Copyright (c) 2013年 小码哥. All rights reserved.
//
#import "NSObject+MJKeyValue.h"
#import "NSObject+MJProperty.h"
#import "NSString+MJExtension.h"
#import "MJProperty.h"
#import "MJPropertyType.h"
#import "MJExtensionConst.h"
#import "MJFoundation.h"
#import "NSString+MJExtension.h"
#import "NSObject+MJClass.h"
@implementation NSDecimalNumber(MJKeyValue)
- (id)standardValueWithTypeCode:(NSString *)typeCode {
// 由于这里涉及到编译器问题, 暂时保留 Long, 实际上在 64 位系统上, 这 2 个精度范围相同,
// 32 位略有不同, 其余都可使用 Double 进行强转不丢失精度
if ([typeCode isEqualToString:MJPropertyTypeLongLong]) {
return @(self.longLongValue);
} else if ([typeCode isEqualToString:MJPropertyTypeLongLong.uppercaseString]) {
return @(self.unsignedLongLongValue);
} else if ([typeCode isEqualToString:MJPropertyTypeLong]) {
return @(self.longValue);
} else if ([typeCode isEqualToString:MJPropertyTypeLong.uppercaseString]) {
return @(self.unsignedLongValue);
} else {
return @(self.doubleValue);
}
}
@end
@implementation NSObject (MJKeyValue)
#pragma mark - 错误
static const char MJErrorKey = '\0';
+ (NSError *)mj_error
{
return objc_getAssociatedObject(self, &MJErrorKey);
}
+ (void)setMj_error:(NSError *)error
{
objc_setAssociatedObject(self, &MJErrorKey, error, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
#pragma mark - 模型 -> 字典时的参考
/** 模型转字典时,字典的key是否参考replacedKeyFromPropertyName等方法(父类设置了,子类也会继承下来) */
static const char MJReferenceReplacedKeyWhenCreatingKeyValuesKey = '\0';
+ (void)mj_referenceReplacedKeyWhenCreatingKeyValues:(BOOL)reference
{
objc_setAssociatedObject(self, &MJReferenceReplacedKeyWhenCreatingKeyValuesKey, @(reference), OBJC_ASSOCIATION_ASSIGN);
}
+ (BOOL)mj_isReferenceReplacedKeyWhenCreatingKeyValues
{
__block id value = objc_getAssociatedObject(self, &MJReferenceReplacedKeyWhenCreatingKeyValuesKey);
if (!value) {
[self mj_enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
value = objc_getAssociatedObject(c, &MJReferenceReplacedKeyWhenCreatingKeyValuesKey);
if (value) *stop = YES;
}];
}
return [value boolValue];
}
#pragma mark - --常用的对象--
+ (void)load
{
// 默认设置
[self mj_referenceReplacedKeyWhenCreatingKeyValues:YES];
}
#pragma mark - --公共方法--
#pragma mark - 字典 -> 模型
- (instancetype)mj_setKeyValues:(id)keyValues
{
return [self mj_setKeyValues:keyValues context:nil];
}
/**
核心代码:
*/
- (instancetype)mj_setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context
{
// 获得JSON对象
keyValues = [keyValues mj_JSONObject];
MJExtensionAssertError([keyValues isKindOfClass:[NSDictionary class]], self, [self class], @"keyValues参数不是一个字典");
Class clazz = [self class];
NSArray *allowedPropertyNames = [clazz mj_totalAllowedPropertyNames];
NSArray *ignoredPropertyNames = [clazz mj_totalIgnoredPropertyNames];
NSLocale *numberLocale = nil;
if ([self.class respondsToSelector:@selector(mj_numberLocale)]) {
numberLocale = self.class.mj_numberLocale;
}
//通过封装的方法回调一个通过运行时编写的,用于返回属性列表的方法。
[clazz mj_enumerateProperties:^(MJProperty *property, BOOL *stop) {
@try {
// 0.检测是否被忽略
if (allowedPropertyNames.count && ![allowedPropertyNames containsObject:property.name]) return;
if ([ignoredPropertyNames containsObject:property.name]) return;
// 1.取出属性值
id value;
NSArray *propertyKeyses = [property propertyKeysForClass:clazz];
for (NSArray *propertyKeys in propertyKeyses) {
value = keyValues;
for (MJPropertyKey *propertyKey in propertyKeys) {
value = [propertyKey valueInObject:value];
}
if (value) break;
}
// 值的过滤
id newValue = [clazz mj_getNewValueFromObject:self oldValue:value property:property];
if (newValue != value) { // 有过滤后的新值
[property setValue:newValue forObject:self];
return;
}
// 如果没有值,就直接返回
if (!value || value == [NSNull null]) return;
// 2.复杂处理
MJPropertyType *type = property.type;
Class propertyClass = type.typeClass;
Class objectClass = [property objectClassInArrayForClass:[self class]];
// 不可变 -> 可变处理
if (propertyClass == [NSMutableArray class] && [value isKindOfClass:[NSArray class]]) {
value = [NSMutableArray arrayWithArray:value];
} else if (propertyClass == [NSMutableDictionary class] && [value isKindOfClass:[NSDictionary class]]) {
value = [NSMutableDictionary dictionaryWithDictionary:value];
} else if (propertyClass == [NSMutableString class] && [value isKindOfClass:[NSString class]]) {
value = [NSMutableString stringWithString:value];
} else if (propertyClass == [NSMutableData class] && [value isKindOfClass:[NSData class]]) {
value = [NSMutableData dataWithData:value];
}
if (!type.isFromFoundation && propertyClass) { // 模型属性
value = [propertyClass mj_objectWithKeyValues:value context:context];
} else if (objectClass) {
if (objectClass == [NSURL class] && [value isKindOfClass:[NSArray class]]) {
// string array -> url array
NSMutableArray *urlArray = [NSMutableArray array];
for (NSString *string in value) {
if (![string isKindOfClass:[NSString class]]) continue;
[urlArray addObject:string.mj_url];
}
value = urlArray;
} else { // 字典数组-->模型数组
value = [objectClass mj_objectArrayWithKeyValuesArray:value context:context];
}
} else if (propertyClass == [NSString class]) {
if ([value isKindOfClass:[NSNumber class]]) {
// NSNumber -> NSString
value = [value description];
} else if ([value isKindOfClass:[NSURL class]]) {
// NSURL -> NSString
value = [value absoluteString];
}
} else if ([value isKindOfClass:[NSString class]]) {
if (propertyClass == [NSURL class]) {
// NSString -> NSURL
// 字符串转码
value = [value mj_url];
} else if (type.isNumberType) {
NSString *oldValue = value;
// NSString -> NSDecimalNumber, 使用 DecimalNumber 来转换数字, 避免丢失精度以及溢出
NSDecimalNumber *decimalValue = [NSDecimalNumber decimalNumberWithString:oldValue
locale:numberLocale];
// 检查特殊情况
if (decimalValue == NSDecimalNumber.notANumber) {
value = @(0);
}else if (propertyClass != [NSDecimalNumber class]) {
value = [decimalValue standardValueWithTypeCode:type.code];
} else {
value = decimalValue;
}
// 如果是BOOL
if (type.isBoolType) {
// 字符串转BOOL(字符串没有charValue方法)
// 系统会调用字符串的charValue转为BOOL类型
NSString *lower = [oldValue lowercaseString];
if ([lower isEqualToString:@"yes"] || [lower isEqualToString:@"true"]) {
value = @YES;
} else if ([lower isEqualToString:@"no"] || [lower isEqualToString:@"false"]) {
value = @NO;
}
}
}
} else if ([value isKindOfClass:[NSNumber class]] && propertyClass == [NSDecimalNumber class]){
// 过滤 NSDecimalNumber类型
if (![value isKindOfClass:[NSDecimalNumber class]]) {
value = [NSDecimalNumber decimalNumberWithDecimal:[((NSNumber *)value) decimalValue]];
}
}
// 经过转换后, 最终检查 value 与 property 是否匹配
if (propertyClass && ![value isKindOfClass:propertyClass]) {
value = nil;
}
// 3.赋值
[property setValue:value forObject:self];
} @catch (NSException *exception) {
MJExtensionBuildError([self class], exception.reason);
MJExtensionLog(@"%@", exception);
}
}];
// 转换完毕
if ([self respondsToSelector:@selector(mj_didConvertToObjectWithKeyValues:)]) {
[self mj_didConvertToObjectWithKeyValues:keyValues];
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored"-Wdeprecated-declarations"
if ([self respondsToSelector:@selector(mj_keyValuesDidFinishConvertingToObject)]) {
[self mj_keyValuesDidFinishConvertingToObject];
}
if ([self respondsToSelector:@selector(mj_keyValuesDidFinishConvertingToObject:)]) {
[self mj_keyValuesDidFinishConvertingToObject:keyValues];
}
#pragma clang diagnostic pop
return self;
}
+ (instancetype)mj_objectWithKeyValues:(id)keyValues
{
return [self mj_objectWithKeyValues:keyValues context:nil];
}
+ (instancetype)mj_objectWithKeyValues:(id)keyValues context:(NSManagedObjectContext *)context
{
// 获得JSON对象
keyValues = [keyValues mj_JSONObject];
MJExtensionAssertError([keyValues isKindOfClass:[NSDictionary class]], nil, [self class], @"keyValues参数不是一个字典");
if ([self isSubclassOfClass:[NSManagedObject class]] && context) {
NSString *entityName = [NSStringFromClass(self) componentsSeparatedByString:@"."].lastObject;
return [[NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:context] mj_setKeyValues:keyValues context:context];
}
return [[[self alloc] init] mj_setKeyValues:keyValues];
}
+ (instancetype)mj_objectWithFilename:(NSString *)filename
{
MJExtensionAssertError(filename != nil, nil, [self class], @"filename参数为nil");
return [self mj_objectWithFile:[[NSBundle mainBundle] pathForResource:filename ofType:nil]];
}
+ (instancetype)mj_objectWithFile:(NSString *)file
{
MJExtensionAssertError(file != nil, nil, [self class], @"file参数为nil");
return [self mj_objectWithKeyValues:[NSDictionary dictionaryWithContentsOfFile:file]];
}
#pragma mark - 字典数组 -> 模型数组
+ (NSMutableArray *)mj_objectArrayWithKeyValuesArray:(NSArray *)keyValuesArray
{
return [self mj_objectArrayWithKeyValuesArray:keyValuesArray context:nil];
}
+ (NSMutableArray *)mj_objectArrayWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context
{
// 如果是JSON字符串
keyValuesArray = [keyValuesArray mj_JSONObject];
// 1.判断真实性
MJExtensionAssertError([keyValuesArray isKindOfClass:[NSArray class]], nil, [self class], @"keyValuesArray参数不是一个数组");
// 如果数组里面放的是NSString、NSNumber等数据
if ([MJFoundation isClassFromFoundation:self]) return [NSMutableArray arrayWithArray:keyValuesArray];
// 2.创建数组
NSMutableArray *modelArray = [NSMutableArray array];
// 3.遍历
for (NSDictionary *keyValues in keyValuesArray) {
if ([keyValues isKindOfClass:[NSArray class]]){
[modelArray addObject:[self mj_objectArrayWithKeyValuesArray:keyValues context:context]];
} else {
id model = [self mj_objectWithKeyValues:keyValues context:context];
if (model) [modelArray addObject:model];
}
}
return modelArray;
}
+ (NSMutableArray *)mj_objectArrayWithFilename:(NSString *)filename
{
MJExtensionAssertError(filename != nil, nil, [self class], @"filename参数为nil");
return [self mj_objectArrayWithFile:[[NSBundle mainBundle] pathForResource:filename ofType:nil]];
}
+ (NSMutableArray *)mj_objectArrayWithFile:(NSString *)file
{
MJExtensionAssertError(file != nil, nil, [self class], @"file参数为nil");
return [self mj_objectArrayWithKeyValuesArray:[NSArray arrayWithContentsOfFile:file]];
}
#pragma mark - 模型 -> 字典
- (NSMutableDictionary *)mj_keyValues
{
return [self mj_keyValuesWithKeys:nil ignoredKeys:nil];
}
- (NSMutableDictionary *)mj_keyValuesWithKeys:(NSArray *)keys
{
return [self mj_keyValuesWithKeys:keys ignoredKeys:nil];
}
- (NSMutableDictionary *)mj_keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys
{
return [self mj_keyValuesWithKeys:nil ignoredKeys:ignoredKeys];
}
- (NSMutableDictionary *)mj_keyValuesWithKeys:(NSArray *)keys ignoredKeys:(NSArray *)ignoredKeys
{
// 如果自己不是模型类, 那就返回自己
// 模型类过滤掉 NSNull
// 唯一一个不返回自己的
if ([self isMemberOfClass:NSNull.class]) { return nil; }
// 这里虽然返回了自己, 但是其实是有报错信息的.
// TODO: 报错机制不好, 需要重做
MJExtensionAssertError(![MJFoundation isClassFromFoundation:[self class]], (NSMutableDictionary *)self, [self class], @"不是自定义的模型类")
id keyValues = [NSMutableDictionary dictionary];
Class clazz = [self class];
NSArray *allowedPropertyNames = [clazz mj_totalAllowedPropertyNames];
NSArray *ignoredPropertyNames = [clazz mj_totalIgnoredPropertyNames];
[clazz mj_enumerateProperties:^(MJProperty *property, BOOL *stop) {
@try {
// 0.检测是否被忽略
if (allowedPropertyNames.count && ![allowedPropertyNames containsObject:property.name]) return;
if ([ignoredPropertyNames containsObject:property.name]) return;
if (keys.count && ![keys containsObject:property.name]) return;
if ([ignoredKeys containsObject:property.name]) return;
// 1.取出属性值
id value = [property valueForObject:self];
if (!value) return;
// 2.如果是模型属性
MJPropertyType *type = property.type;
Class propertyClass = type.typeClass;
if (!type.isFromFoundation && propertyClass) {
value = [value mj_keyValues];
} else if ([value isKindOfClass:[NSArray class]]) {
// 3.处理数组里面有模型的情况
value = [NSObject mj_keyValuesArrayWithObjectArray:value];
} else if (propertyClass == [NSURL class]) {
value = [value absoluteString];
}
// 4.赋值
if ([clazz mj_isReferenceReplacedKeyWhenCreatingKeyValues]) {
NSArray *propertyKeys = [[property propertyKeysForClass:clazz] firstObject];
NSUInteger keyCount = propertyKeys.count;
// 创建字典
__block id innerContainer = keyValues;
[propertyKeys enumerateObjectsUsingBlock:^(MJPropertyKey *propertyKey, NSUInteger idx, BOOL *stop) {
// 下一个属性
MJPropertyKey *nextPropertyKey = nil;
if (idx != keyCount - 1) {
nextPropertyKey = propertyKeys[idx + 1];
}
if (nextPropertyKey) { // 不是最后一个key
// 当前propertyKey对应的字典或者数组
id tempInnerContainer = [propertyKey valueInObject:innerContainer];
if (tempInnerContainer == nil || [tempInnerContainer isKindOfClass:[NSNull class]]) {
if (nextPropertyKey.type == MJPropertyKeyTypeDictionary) {
tempInnerContainer = [NSMutableDictionary dictionary];
} else {
tempInnerContainer = [NSMutableArray array];
}
if (propertyKey.type == MJPropertyKeyTypeDictionary) {
innerContainer[propertyKey.name] = tempInnerContainer;
} else {
innerContainer[propertyKey.name.intValue] = tempInnerContainer;
}
}
if ([tempInnerContainer isKindOfClass:[NSMutableArray class]]) {
NSMutableArray *tempInnerContainerArray = tempInnerContainer;
int index = nextPropertyKey.name.intValue;
while (tempInnerContainerArray.count < index + 1) {
[tempInnerContainerArray addObject:[NSNull null]];
}
}
innerContainer = tempInnerContainer;
} else { // 最后一个key
if (propertyKey.type == MJPropertyKeyTypeDictionary) {
innerContainer[propertyKey.name] = value;
} else {
innerContainer[propertyKey.name.intValue] = value;
}
}
}];
} else {
keyValues[property.name] = value;
}
} @catch (NSException *exception) {
MJExtensionBuildError([self class], exception.reason);
MJExtensionLog(@"%@", exception);
}
}];
// 转换完毕
if ([self respondsToSelector:@selector(mj_objectDidConvertToKeyValues:)]) {
[self mj_objectDidConvertToKeyValues:keyValues];
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored"-Wdeprecated-declarations"
if ([self respondsToSelector:@selector(mj_objectDidFinishConvertingToKeyValues)]) {
[self mj_objectDidFinishConvertingToKeyValues];
}
#pragma clang diagnostic pop
return keyValues;
}
#pragma mark - 模型数组 -> 字典数组
+ (NSMutableArray *)mj_keyValuesArrayWithObjectArray:(NSArray *)objectArray
{
return [self mj_keyValuesArrayWithObjectArray:objectArray keys:nil ignoredKeys:nil];
}
+ (NSMutableArray *)mj_keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys
{
return [self mj_keyValuesArrayWithObjectArray:objectArray keys:keys ignoredKeys:nil];
}
+ (NSMutableArray *)mj_keyValuesArrayWithObjectArray:(NSArray *)objectArray ignoredKeys:(NSArray *)ignoredKeys
{
return [self mj_keyValuesArrayWithObjectArray:objectArray keys:nil ignoredKeys:ignoredKeys];
}
+ (NSMutableArray *)mj_keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys ignoredKeys:(NSArray *)ignoredKeys
{
// 0.判断真实性
MJExtensionAssertError([objectArray isKindOfClass:[NSArray class]], nil, [self class], @"objectArray参数不是一个数组");
// 1.创建数组
NSMutableArray *keyValuesArray = [NSMutableArray array];
for (id object in objectArray) {
if (keys) {
id convertedObj = [object mj_keyValuesWithKeys:keys];
if (!convertedObj) { continue; }
[keyValuesArray addObject:convertedObj];
} else {
id convertedObj = [object mj_keyValuesWithIgnoredKeys:ignoredKeys];
if (!convertedObj) { continue; }
[keyValuesArray addObject:convertedObj];
}
}
return keyValuesArray;
}
#pragma mark - 转换为JSON
- (NSData *)mj_JSONData
{
if ([self isKindOfClass:[NSString class]]) {
return [((NSString *)self) dataUsingEncoding:NSUTF8StringEncoding];
} else if ([self isKindOfClass:[NSData class]]) {
return (NSData *)self;
}
return [NSJSONSerialization dataWithJSONObject:[self mj_JSONObject] options:kNilOptions error:nil];
}
- (id)mj_JSONObject
{
if ([self isKindOfClass:[NSString class]]) {
return [NSJSONSerialization JSONObjectWithData:[((NSString *)self) dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil];
} else if ([self isKindOfClass:[NSData class]]) {
return [NSJSONSerialization JSONObjectWithData:(NSData *)self options:kNilOptions error:nil];
}
return self.mj_keyValues;
}
- (NSString *)mj_JSONString
{
if ([self isKindOfClass:[NSString class]]) {
return (NSString *)self;
} else if ([self isKindOfClass:[NSData class]]) {
return [[NSString alloc] initWithData:(NSData *)self encoding:NSUTF8StringEncoding];
}
return [[NSString alloc] initWithData:[self mj_JSONData] encoding:NSUTF8StringEncoding];
}
@end
//
// NSObject+MJProperty.h
// MJExtensionExample
//
// Created by MJ Lee on 15/4/17.
// Copyright (c) 2015年 小码哥. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MJExtensionConst.h"
@class MJProperty;
/**
* 遍历成员变量用的block
*
* @param property 成员的包装对象
* @param stop YES代表停止遍历,NO代表继续遍历
*/
typedef void (^MJPropertiesEnumeration)(MJProperty *property, BOOL *stop);
/** 将属性名换为其他key去字典中取值 */
typedef NSDictionary * (^MJReplacedKeyFromPropertyName)(void);
typedef id (^MJReplacedKeyFromPropertyName121)(NSString *propertyName);
/** 数组中需要转换的模型类 */
typedef NSDictionary * (^MJObjectClassInArray)(void);
/** 用于过滤字典中的值 */
typedef id (^MJNewValueFromOldValue)(id object, id oldValue, MJProperty *property);
/**
* 成员属性相关的扩展
*/
@interface NSObject (MJProperty)
#pragma mark - 遍历
/**
* 遍历所有的成员
*/
+ (void)mj_enumerateProperties:(MJPropertiesEnumeration)enumeration;
#pragma mark - 新值配置
/**
* 用于过滤字典中的值
*
* @param newValueFormOldValue 用于过滤字典中的值
*/
+ (void)mj_setupNewValueFromOldValue:(MJNewValueFromOldValue)newValueFormOldValue;
+ (id)mj_getNewValueFromObject:(__unsafe_unretained id)object oldValue:(__unsafe_unretained id)oldValue property:(__unsafe_unretained MJProperty *)property;
#pragma mark - key配置
/**
* 将属性名换为其他key去字典中取值
*
* @param replacedKeyFromPropertyName 将属性名换为其他key去字典中取值
*/
+ (void)mj_setupReplacedKeyFromPropertyName:(MJReplacedKeyFromPropertyName)replacedKeyFromPropertyName;
/**
* 将属性名换为其他key去字典中取值
*
* @param replacedKeyFromPropertyName121 将属性名换为其他key去字典中取值
*/
+ (void)mj_setupReplacedKeyFromPropertyName121:(MJReplacedKeyFromPropertyName121)replacedKeyFromPropertyName121;
#pragma mark - array model class配置
/**
* 数组中需要转换的模型类
*
* @param objectClassInArray 数组中需要转换的模型类
*/
+ (void)mj_setupObjectClassInArray:(MJObjectClassInArray)objectClassInArray;
@end
//
// NSObject+MJProperty.m
// MJExtensionExample
//
// Created by MJ Lee on 15/4/17.
// Copyright (c) 2015年 小码哥. All rights reserved.
//
#import "NSObject+MJProperty.h"
#import "NSObject+MJKeyValue.h"
#import "NSObject+MJCoding.h"
#import "NSObject+MJClass.h"
#import "MJProperty.h"
#import "MJFoundation.h"
#import <objc/runtime.h>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
static const char MJReplacedKeyFromPropertyNameKey = '\0';
static const char MJReplacedKeyFromPropertyName121Key = '\0';
static const char MJNewValueFromOldValueKey = '\0';
static const char MJObjectClassInArrayKey = '\0';
static const char MJCachedPropertiesKey = '\0';
@implementation NSObject (Property)
+ (NSMutableDictionary *)mj_propertyDictForKey:(const void *)key
{
static NSMutableDictionary *replacedKeyFromPropertyNameDict;
static NSMutableDictionary *replacedKeyFromPropertyName121Dict;
static NSMutableDictionary *newValueFromOldValueDict;
static NSMutableDictionary *objectClassInArrayDict;
static NSMutableDictionary *cachedPropertiesDict;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
replacedKeyFromPropertyNameDict = [NSMutableDictionary dictionary];
replacedKeyFromPropertyName121Dict = [NSMutableDictionary dictionary];
newValueFromOldValueDict = [NSMutableDictionary dictionary];
objectClassInArrayDict = [NSMutableDictionary dictionary];
cachedPropertiesDict = [NSMutableDictionary dictionary];
});
if (key == &MJReplacedKeyFromPropertyNameKey) return replacedKeyFromPropertyNameDict;
if (key == &MJReplacedKeyFromPropertyName121Key) return replacedKeyFromPropertyName121Dict;
if (key == &MJNewValueFromOldValueKey) return newValueFromOldValueDict;
if (key == &MJObjectClassInArrayKey) return objectClassInArrayDict;
if (key == &MJCachedPropertiesKey) return cachedPropertiesDict;
return nil;
}
#pragma mark - --私有方法--
+ (id)mj_propertyKey:(NSString *)propertyName
{
MJExtensionAssertParamNotNil2(propertyName, nil);
__block id key = nil;
// 查看有没有需要替换的key
if ([self respondsToSelector:@selector(mj_replacedKeyFromPropertyName121:)]) {
key = [self mj_replacedKeyFromPropertyName121:propertyName];
}
// 调用block
if (!key) {
[self mj_enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
MJReplacedKeyFromPropertyName121 block = objc_getAssociatedObject(c, &MJReplacedKeyFromPropertyName121Key);
if (block) {
key = block(propertyName);
}
if (key) *stop = YES;
}];
}
// 查看有没有需要替换的key
if ((!key || [key isEqual:propertyName]) && [self respondsToSelector:@selector(mj_replacedKeyFromPropertyName)]) {
key = [self mj_replacedKeyFromPropertyName][propertyName];
}
if (!key || [key isEqual:propertyName]) {
[self mj_enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
NSDictionary *dict = objc_getAssociatedObject(c, &MJReplacedKeyFromPropertyNameKey);
if (dict) {
key = dict[propertyName];
}
if (key && ![key isEqual:propertyName]) *stop = YES;
}];
}
// 2.用属性名作为key
if (!key) key = propertyName;
return key;
}
+ (Class)mj_propertyObjectClassInArray:(NSString *)propertyName
{
__block id clazz = nil;
if ([self respondsToSelector:@selector(mj_objectClassInArray)]) {
clazz = [self mj_objectClassInArray][propertyName];
}
if (!clazz) {
[self mj_enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
NSDictionary *dict = objc_getAssociatedObject(c, &MJObjectClassInArrayKey);
if (dict) {
clazz = dict[propertyName];
}
if (clazz) *stop = YES;
}];
}
// 如果是NSString类型
if ([clazz isKindOfClass:[NSString class]]) {
clazz = NSClassFromString(clazz);
}
return clazz;
}
#pragma mark - --公共方法--
+ (void)mj_enumerateProperties:(MJPropertiesEnumeration)enumeration
{
// 获得成员变量
MJExtensionSemaphoreCreate
MJExtensionSemaphoreWait
NSArray *cachedProperties = [self mj_properties];
MJExtensionSemaphoreSignal
// 遍历成员变量
BOOL stop = NO;
for (MJProperty *property in cachedProperties) {
enumeration(property, &stop);
if (stop) break;
}
}
#pragma mark - 公共方法
+ (NSMutableArray *)mj_properties
{
NSMutableArray *cachedProperties = [self mj_propertyDictForKey:&MJCachedPropertiesKey][NSStringFromClass(self)];
if (cachedProperties == nil) {
if (cachedProperties == nil) {
cachedProperties = [NSMutableArray array];
[self mj_enumerateClasses:^(__unsafe_unretained Class c, BOOL *stop) {
// 1.获得所有的成员变量
unsigned int outCount = 0;
objc_property_t *properties = class_copyPropertyList(c, &outCount);
// 2.遍历每一个成员变量
for (unsigned int i = 0; i<outCount; i++) {
MJProperty *property = [MJProperty cachedPropertyWithProperty:properties[i]];
// 过滤掉Foundation框架类里面的属性
if ([MJFoundation isClassFromFoundation:property.srcClass]) continue;
// 过滤掉`hash`, `superclass`, `description`, `debugDescription`
if ([MJFoundation isFromNSObjectProtocolProperty:property.name]) continue;
property.srcClass = c;
[property setOriginKey:[self mj_propertyKey:property.name] forClass:self];
[property setObjectClassInArray:[self mj_propertyObjectClassInArray:property.name] forClass:self];
[cachedProperties addObject:property];
}
// 3.释放内存
free(properties);
}];
[self mj_propertyDictForKey:&MJCachedPropertiesKey][NSStringFromClass(self)] = cachedProperties;
}
}
return cachedProperties;
}
#pragma mark - 新值配置
+ (void)mj_setupNewValueFromOldValue:(MJNewValueFromOldValue)newValueFormOldValue
{
objc_setAssociatedObject(self, &MJNewValueFromOldValueKey, newValueFormOldValue, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
+ (id)mj_getNewValueFromObject:(__unsafe_unretained id)object oldValue:(__unsafe_unretained id)oldValue property:(MJProperty *__unsafe_unretained)property{
// 如果有实现方法
if ([object respondsToSelector:@selector(mj_newValueFromOldValue:property:)]) {
return [object mj_newValueFromOldValue:oldValue property:property];
}
// 查看静态设置
__block id newValue = oldValue;
[self mj_enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
MJNewValueFromOldValue block = objc_getAssociatedObject(c, &MJNewValueFromOldValueKey);
if (block) {
newValue = block(object, oldValue, property);
*stop = YES;
}
}];
return newValue;
}
#pragma mark - array model class配置
+ (void)mj_setupObjectClassInArray:(MJObjectClassInArray)objectClassInArray
{
[self mj_setupBlockReturnValue:objectClassInArray key:&MJObjectClassInArrayKey];
MJExtensionSemaphoreCreate
MJExtensionSemaphoreWait
[[self mj_propertyDictForKey:&MJCachedPropertiesKey] removeAllObjects];
MJExtensionSemaphoreSignal
}
#pragma mark - key配置
+ (void)mj_setupReplacedKeyFromPropertyName:(MJReplacedKeyFromPropertyName)replacedKeyFromPropertyName
{
[self mj_setupBlockReturnValue:replacedKeyFromPropertyName key:&MJReplacedKeyFromPropertyNameKey];
MJExtensionSemaphoreCreate
MJExtensionSemaphoreWait
[[self mj_propertyDictForKey:&MJCachedPropertiesKey] removeAllObjects];
MJExtensionSemaphoreSignal
}
+ (void)mj_setupReplacedKeyFromPropertyName121:(MJReplacedKeyFromPropertyName121)replacedKeyFromPropertyName121
{
objc_setAssociatedObject(self, &MJReplacedKeyFromPropertyName121Key, replacedKeyFromPropertyName121, OBJC_ASSOCIATION_COPY_NONATOMIC);
MJExtensionSemaphoreCreate
MJExtensionSemaphoreWait
[[self mj_propertyDictForKey:&MJCachedPropertiesKey] removeAllObjects];
MJExtensionSemaphoreSignal
}
@end
#pragma clang diagnostic pop
//
// NSString+MJExtension.h
// MJExtensionExample
//
// Created by MJ Lee on 15/6/7.
// Copyright (c) 2015年 小码哥. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MJExtensionConst.h"
@interface NSString (MJExtension)
/**
* 驼峰转下划线(loveYou -> love_you)
*/
- (NSString *)mj_underlineFromCamel;
/**
* 下划线转驼峰(love_you -> loveYou)
*/
- (NSString *)mj_camelFromUnderline;
/**
* 首字母变大写
*/
- (NSString *)mj_firstCharUpper;
/**
* 首字母变小写
*/
- (NSString *)mj_firstCharLower;
- (BOOL)mj_isPureInt;
- (NSURL *)mj_url;
@end
//
// NSString+MJExtension.m
// MJExtensionExample
//
// Created by MJ Lee on 15/6/7.
// Copyright (c) 2015年 小码哥. All rights reserved.
//
#import "NSString+MJExtension.h"
@implementation NSString (MJExtension)
- (NSString *)mj_underlineFromCamel
{
if (self.length == 0) return self;
NSMutableString *string = [NSMutableString string];
for (NSUInteger i = 0; i<self.length; i++) {
unichar c = [self characterAtIndex:i];
NSString *cString = [NSString stringWithFormat:@"%c", c];
NSString *cStringLower = [cString lowercaseString];
if ([cString isEqualToString:cStringLower]) {
[string appendString:cStringLower];
} else {
[string appendString:@"_"];
[string appendString:cStringLower];
}
}
return string;
}
- (NSString *)mj_camelFromUnderline
{
if (self.length == 0) return self;
NSMutableString *string = [NSMutableString string];
NSArray *cmps = [self componentsSeparatedByString:@"_"];
for (NSUInteger i = 0; i<cmps.count; i++) {
NSString *cmp = cmps[i];
if (i && cmp.length) {
[string appendString:[NSString stringWithFormat:@"%c", [cmp characterAtIndex:0]].uppercaseString];
if (cmp.length >= 2) [string appendString:[cmp substringFromIndex:1]];
} else {
[string appendString:cmp];
}
}
return string;
}
- (NSString *)mj_firstCharLower
{
if (self.length == 0) return self;
NSMutableString *string = [NSMutableString string];
[string appendString:[NSString stringWithFormat:@"%c", [self characterAtIndex:0]].lowercaseString];
if (self.length >= 2) [string appendString:[self substringFromIndex:1]];
return string;
}
- (NSString *)mj_firstCharUpper
{
if (self.length == 0) return self;
NSMutableString *string = [NSMutableString string];
[string appendString:[NSString stringWithFormat:@"%c", [self characterAtIndex:0]].uppercaseString];
if (self.length >= 2) [string appendString:[self substringFromIndex:1]];
return string;
}
- (BOOL)mj_isPureInt
{
NSScanner *scan = [NSScanner scannerWithString:self];
int val;
return [scan scanInt:&val] && [scan isAtEnd];
}
- (NSURL *)mj_url
{
// [self stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"!$&'()*+,-./:;=?@_~%#[]"]];
#pragma clang diagnostic push
#pragma clang diagnostic ignored"-Wdeprecated-declarations"
return [NSURL URLWithString:(NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)self, (CFStringRef)@"!$&'()*+,-./:;=?@_~%#[]", NULL,kCFStringEncodingUTF8))];
#pragma clang diagnostic pop
}
@end
MJExtension
===
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
![podversion](https://img.shields.io/cocoapods/v/MJExtension.svg)
- A fast, convenient and nonintrusive conversion framework between JSON and model.
- 转换速度快、使用简单方便的字典转模型框架
## ‼️ 纯Swift版的JSON与Model转换框架已经开源上架 ‼️
- [KakaJSON](https://github.com/kakaopensource/KakaJSON)
- [中文教程](https://www.cnblogs.com/mjios/p/11352776.html)
- 如果你的项目是用Swift写的Model,墙裂推荐使用[KakaJSON](https://github.com/kakaopensource/KakaJSON)
- 已经对各种常用的数据场景进行了大量的单元测试
- 简单易用、功能丰富、转换快速
## 关于在Swift中使用MJExtension ‼️
### ‼️ 在 Swift4 之后, 请在属性前加 `@objc` 修饰. 以保证 Swift 的属性能够暴露给 Objc 使用. ‼️
### ‼️ 请勿使用 `Bool` 类型, 因为在 Swift 中并没有桥接该类型, 不能显式的对应 `BOOL`, 请使用 `NSNumber` 替代 ‼️
## Contents
* [Getting Started 【开始使用】](#Getting_Started)
* [Features 【能做什么】](#Features)
* [Installation 【安装】](#Installation)
* [Examples 【示例】](#Examples)
* [JSON -> Model](#JSON_Model)
* [JSONString -> Model](#JSONString_Model)
* [Model contains model](#Model_contains_model)
* [Model contains model-array](#Model_contains_model_array)
* [Model name - JSON key mapping](#Model_name_JSON_key_mapping)
* [JSON array -> model array](#JSON_array_model_array)
* [Model -> JSON](#Model_JSON)
* [Model array -> JSON array](#Model_array_JSON_array)
* [Core Data](#Core_Data)
* [Coding](#Coding)
* [Camel -> underline](#Camel_underline)
* [NSString -> NSDate, nil -> @""](#NSString_NSDate)
* [More use cases](#More_use_cases)
---
# <a id="Getting_Started"></a> Getting Started【开始使用】
## <a id="Features"></a> Features【能做什么】
- MJExtension是一套字典和模型之间互相转换的超轻量级框架
* `JSON` --> `Model``Core Data Model`
* `JSONString` --> `Model``Core Data Model`
* `Model``Core Data Model` --> `JSON`
* `JSON Array` --> `Model Array``Core Data Model Array`
* `JSONString` --> `Model Array``Core Data Model Array`
* `Model Array``Core Data Model Array` --> `JSON Array`
* Coding all properties of a model with only one line of code.
* 只需要一行代码,就能实现模型的所有属性进行Coding(归档和解档)
## <a id="Installation"></a> Installation【安装】
### From CocoaPods【使用CocoaPods】
```ruby
pod 'MJExtension'
```
### Manually【手动导入】
- Drag all source files under folder `MJExtension` to your project.【将`MJExtension`文件夹中的所有源代码拽入项目中】
- Import the main header file:`#import "MJExtension.h"`【导入主头文件:`#import "MJExtension.h"`
```objc
MJExtension.h
MJConst.h MJConst.m
MJFoundation.h MJFoundation.m
MJProperty.h MJProperty.m
MJType.h MJType.m
NSObject+MJCoding.h NSObject+MJCoding.m
NSObject+MJProperty.h NSObject+MJProperty.m
NSObject+MJKeyValue.h NSObject+MJKeyValue.m
```
# <a id="Examples"></a> Examples【示例】
### <a id="JSON_Model"></a> The most simple JSON -> Model【最简单的字典转模型】
```objc
typedef enum {
SexMale,
SexFemale
} Sex;
@interface User : NSObject
@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *icon;
@property (assign, nonatomic) unsigned int age;
@property (copy, nonatomic) NSString *height;
@property (strong, nonatomic) NSNumber *money;
@property (assign, nonatomic) Sex sex;
@property (assign, nonatomic, getter=isGay) BOOL gay;
@end
/***********************************************/
NSDictionary *dict = @{
@"name" : @"Jack",
@"icon" : @"lufy.png",
@"age" : @20,
@"height" : @"1.55",
@"money" : @100.9,
@"sex" : @(SexFemale),
@"gay" : @"true"
// @"gay" : @"1"
// @"gay" : @"NO"
};
// JSON -> User
User *user = [User mj_objectWithKeyValues:dict];
NSLog(@"name=%@, icon=%@, age=%zd, height=%@, money=%@, sex=%d, gay=%d", user.name, user.icon, user.age, user.height, user.money, user.sex, user.gay);
// name=Jack, icon=lufy.png, age=20, height=1.550000, money=100.9, sex=1
```
### <a id="JSONString_Model"></a> JSONString -> Model【JSON字符串转模型】
```objc
// 1.Define a JSONString
NSString *jsonString = @"{\"name\":\"Jack\", \"icon\":\"lufy.png\", \"age\":20}";
// 2.JSONString -> User
User *user = [User mj_objectWithKeyValues:jsonString];
// 3.Print user's properties
NSLog(@"name=%@, icon=%@, age=%d", user.name, user.icon, user.age);
// name=Jack, icon=lufy.png, age=20
```
### <a id="Model_contains_model"></a> Model contains model【模型中嵌套模型】
```objc
@interface Status : NSObject
@property (copy, nonatomic) NSString *text;
@property (strong, nonatomic) User *user;
@property (strong, nonatomic) Status *retweetedStatus;
@end
/***********************************************/
NSDictionary *dict = @{
@"text" : @"Agree!Nice weather!",
@"user" : @{
@"name" : @"Jack",
@"icon" : @"lufy.png"
},
@"retweetedStatus" : @{
@"text" : @"Nice weather!",
@"user" : @{
@"name" : @"Rose",
@"icon" : @"nami.png"
}
}
};
// JSON -> Status
Status *status = [Status mj_objectWithKeyValues:dict];
NSString *text = status.text;
NSString *name = status.user.name;
NSString *icon = status.user.icon;
NSLog(@"text=%@, name=%@, icon=%@", text, name, icon);
// text=Agree!Nice weather!, name=Jack, icon=lufy.png
NSString *text2 = status.retweetedStatus.text;
NSString *name2 = status.retweetedStatus.user.name;
NSString *icon2 = status.retweetedStatus.user.icon;
NSLog(@"text2=%@, name2=%@, icon2=%@", text2, name2, icon2);
// text2=Nice weather!, name2=Rose, icon2=nami.png
```
### <a id="Model_contains_model_array"></a> Model contains model-array【模型中有个数组属性,数组里面又要装着其他模型】
```objc
@interface Ad : NSObject
@property (copy, nonatomic) NSString *image;
@property (copy, nonatomic) NSString *url;
@end
@interface StatusResult : NSObject
/** Contatins status model */
@property (strong, nonatomic) NSMutableArray *statuses;
/** Contatins ad model */
@property (strong, nonatomic) NSArray *ads;
@property (strong, nonatomic) NSNumber *totalNumber;
@end
/***********************************************/
// Tell MJExtension what type of model will be contained in statuses and ads.
[StatusResult mj_setupObjectClassInArray:^NSDictionary *{
return @{
@"statuses" : @"Status",
// @"statuses" : [Status class],
@"ads" : @"Ad"
// @"ads" : [Ad class]
};
}];
// Equals: StatusResult.m implements +mj_objectClassInArray method.
NSDictionary *dict = @{
@"statuses" : @[
@{
@"text" : @"Nice weather!",
@"user" : @{
@"name" : @"Rose",
@"icon" : @"nami.png"
}
},
@{
@"text" : @"Go camping tomorrow!",
@"user" : @{
@"name" : @"Jack",
@"icon" : @"lufy.png"
}
}
],
@"ads" : @[
@{
@"image" : @"ad01.png",
@"url" : @"http://www.ad01.com"
},
@{
@"image" : @"ad02.png",
@"url" : @"http://www.ad02.com"
}
],
@"totalNumber" : @"2014"
};
// JSON -> StatusResult
StatusResult *result = [StatusResult mj_objectWithKeyValues:dict];
NSLog(@"totalNumber=%@", result.totalNumber);
// totalNumber=2014
// Printing
for (Status *status in result.statuses) {
NSString *text = status.text;
NSString *name = status.user.name;
NSString *icon = status.user.icon;
NSLog(@"text=%@, name=%@, icon=%@", text, name, icon);
}
// text=Nice weather!, name=Rose, icon=nami.png
// text=Go camping tomorrow!, name=Jack, icon=lufy.png
// Printing
for (Ad *ad in result.ads) {
NSLog(@"image=%@, url=%@", ad.image, ad.url);
}
// image=ad01.png, url=http://www.ad01.com
// image=ad02.png, url=http://www.ad02.com
```
### <a id="Model_name_JSON_key_mapping"></a> Model name - JSON key mapping【模型中的属性名和字典中的key不相同(或者需要多级映射)】
```objc
@interface Bag : NSObject
@property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) double price;
@end
@interface Student : NSObject
@property (copy, nonatomic) NSString *ID;
@property (copy, nonatomic) NSString *desc;
@property (copy, nonatomic) NSString *nowName;
@property (copy, nonatomic) NSString *oldName;
@property (copy, nonatomic) NSString *nameChangedTime;
@property (strong, nonatomic) Bag *bag;
@end
/***********************************************/
// How to map
[Student mj_setupReplacedKeyFromPropertyName:^NSDictionary *{
return @{
@"ID" : @"id",
@"desc" : @"description",
@"oldName" : @"name.oldName",
@"nowName" : @"name.newName",
@"nameChangedTime" : @"name.info[1].nameChangedTime",
@"bag" : @"other.bag"
};
}];
// Equals: Student.m implements +mj_replacedKeyFromPropertyName method.
NSDictionary *dict = @{
@"id" : @"20",
@"description" : @"kids",
@"name" : @{
@"newName" : @"lufy",
@"oldName" : @"kitty",
@"info" : @[
@"test-data",
@{
@"nameChangedTime" : @"2013-08"
}
]
},
@"other" : @{
@"bag" : @{
@"name" : @"a red bag",
@"price" : @100.7
}
}
};
// JSON -> Student
Student *stu = [Student mj_objectWithKeyValues:dict];
// Printing
NSLog(@"ID=%@, desc=%@, oldName=%@, nowName=%@, nameChangedTime=%@",
stu.ID, stu.desc, stu.oldName, stu.nowName, stu.nameChangedTime);
// ID=20, desc=kids, oldName=kitty, nowName=lufy, nameChangedTime=2013-08
NSLog(@"bagName=%@, bagPrice=%f", stu.bag.name, stu.bag.price);
// bagName=a red bag, bagPrice=100.700000
```
### <a id="JSON_array_model_array"></a> JSON array -> model array【将一个字典数组转成模型数组】
```objc
NSArray *dictArray = @[
@{
@"name" : @"Jack",
@"icon" : @"lufy.png"
},
@{
@"name" : @"Rose",
@"icon" : @"nami.png"
}
];
// JSON array -> User array
NSArray *userArray = [User mj_objectArrayWithKeyValuesArray:dictArray];
// Printing
for (User *user in userArray) {
NSLog(@"name=%@, icon=%@", user.name, user.icon);
}
// name=Jack, icon=lufy.png
// name=Rose, icon=nami.png
```
### <a id="Model_JSON"></a> Model -> JSON【将一个模型转成字典】
```objc
// New model
User *user = [[User alloc] init];
user.name = @"Jack";
user.icon = @"lufy.png";
Status *status = [[Status alloc] init];
status.user = user;
status.text = @"Nice mood!";
// Status -> JSON
NSDictionary *statusDict = status.mj_keyValues;
NSLog(@"%@", statusDict);
/*
{
text = "Nice mood!";
user = {
icon = "lufy.png";
name = Jack;
};
}
*/
// More complex situation
Student *stu = [[Student alloc] init];
stu.ID = @"123";
stu.oldName = @"rose";
stu.nowName = @"jack";
stu.desc = @"handsome";
stu.nameChangedTime = @"2018-09-08";
Bag *bag = [[Bag alloc] init];
bag.name = @"a red bag";
bag.price = 205;
stu.bag = bag;
NSDictionary *stuDict = stu.mj_keyValues;
NSLog(@"%@", stuDict);
/*
{
ID = 123;
bag = {
name = "\U5c0f\U4e66\U5305";
price = 205;
};
desc = handsome;
nameChangedTime = "2018-09-08";
nowName = jack;
oldName = rose;
}
*/
```
### <a id="Model_array_JSON_array"></a> Model array -> JSON array【将一个模型数组转成字典数组】
```objc
// New model array
User *user1 = [[User alloc] init];
user1.name = @"Jack";
user1.icon = @"lufy.png";
User *user2 = [[User alloc] init];
user2.name = @"Rose";
user2.icon = @"nami.png";
NSArray *userArray = @[user1, user2];
// Model array -> JSON array
NSArray *dictArray = [User mj_keyValuesArrayWithObjectArray:userArray];
NSLog(@"%@", dictArray);
/*
(
{
icon = "lufy.png";
name = Jack;
},
{
icon = "nami.png";
name = Rose;
}
)
*/
```
### <a id="Core_Data"></a> Core Data
```objc
NSDictionary *dict = @{
@"name" : @"Jack",
@"icon" : @"lufy.png",
@"age" : @20,
@"height" : @1.55,
@"money" : @"100.9",
@"sex" : @(SexFemale),
@"gay" : @"true"
};
// This demo just provide simple steps
NSManagedObjectContext *context = nil;
User *user = [User mj_objectWithKeyValues:dict context:context];
[context save:nil];
```
### <a id="Coding"></a> Coding
```objc
#import "MJExtension.h"
@implementation Bag
// NSCoding Implementation
MJExtensionCodingImplementation
@end
/***********************************************/
// what properties not to be coded
[Bag mj_setupIgnoredCodingPropertyNames:^NSArray *{
return @[@"name"];
}];
// Equals: Bag.m implements +mj_ignoredCodingPropertyNames method.
// Create model
Bag *bag = [[Bag alloc] init];
bag.name = @"Red bag";
bag.price = 200.8;
NSString *file = [NSHomeDirectory() stringByAppendingPathComponent:@"Desktop/bag.data"];
// Encoding
[NSKeyedArchiver archiveRootObject:bag toFile:file];
// Decoding
Bag *decodedBag = [NSKeyedUnarchiver unarchiveObjectWithFile:file];
NSLog(@"name=%@, price=%f", decodedBag.name, decodedBag.price);
// name=(null), price=200.800000
```
### <a id="Camel_underline"></a> Camel -> underline【统一转换属性名(比如驼峰转下划线)】
```objc
// Dog
#import "MJExtension.h"
@implementation Dog
+ (NSString *)mj_replacedKeyFromPropertyName121:(NSString *)propertyName
{
// nickName -> nick_name
return [propertyName mj_underlineFromCamel];
}
@end
// NSDictionary
NSDictionary *dict = @{
@"nick_name" : @"旺财",
@"sale_price" : @"10.5",
@"run_speed" : @"100.9"
};
// NSDictionary -> Dog
Dog *dog = [Dog mj_objectWithKeyValues:dict];
// printing
NSLog(@"nickName=%@, scalePrice=%f runSpeed=%f", dog.nickName, dog.salePrice, dog.runSpeed);
```
### <a id="NSString_NSDate"></a> NSString -> NSDate, nil -> @""【过滤字典的值(比如字符串日期处理为NSDate、字符串nil处理为@"")】
```objc
// Book
#import "MJExtension.h"
@implementation Book
- (id)mj_newValueFromOldValue:(id)oldValue property:(MJProperty *)property
{
if ([property.name isEqualToString:@"publisher"]) {
if (oldValue == nil) return @"";
} else if (property.type.typeClass == [NSDate class]) {
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.dateFormat = @"yyyy-MM-dd";
return [fmt dateFromString:oldValue];
}
return oldValue;
}
@end
// NSDictionary
NSDictionary *dict = @{
@"name" : @"5分钟突破iOS开发",
@"publishedTime" : @"2011-09-10"
};
// NSDictionary -> Book
Book *book = [Book mj_objectWithKeyValues:dict];
// printing
NSLog(@"name=%@, publisher=%@, publishedTime=%@", book.name, book.publisher, book.publishedTime);
```
### <a id="More_use_cases"></a> More use cases【更多用法】
- Please reference to `NSObject+MJKeyValue.h` and `NSObject+MJCoding.h`
## 期待
* 如果在使用过程中遇到BUG,希望你能Issues我,谢谢(或者尝试下载最新的框架代码看看BUG修复没有)
* 如果在使用过程中发现功能不够用,希望你能Issues我,我非常想为这个框架增加更多好用的功能,谢谢
* 如果你想为MJExtension输出代码,请拼命Pull Requests我
PODS:
- GMRouter (0.1.2):
- MJExtension
- MJExtension (3.2.1)
DEPENDENCIES:
- GMRouter (from `../`)
SPEC REPOS:
https://github.com/cocoapods/specs.git:
- MJExtension
EXTERNAL SOURCES:
GMRouter:
:path: "../"
SPEC CHECKSUMS:
GMRouter: e5ee4c93aee2f94f977a847f13ec1371a5fbd372
MJExtension: 635f2c663dcb1bf76fa4b715b2570a5710aec545
PODFILE CHECKSUM: bcbc555b81a3b21a917383786de0d49ebef33013
COCOAPODS: 1.7.4
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
019EC0A77E8BD66C992685194EABB4AB /* UIViewController+Router.h in Headers */ = {isa = PBXBuildFile; fileRef = DCB712894FEE5C910EEF563F03445407 /* UIViewController+Router.h */; settings = {ATTRIBUTES = (Public, ); }; };
0527C56AC3D875371F2C95AA50DB05DB /* Pods-GMRouter_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B61A08547E5EC761DC6A55EE9533598 /* Pods-GMRouter_Example-dummy.m */; };
07BFFC265907A63B0B21810B25A858FC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E04AC621D1A86F2AC40200FFAD16DBAA /* Foundation.framework */; };
0A9F462A77BA08483DB425A367CA2A87 /* MJExtensionConst.h in Headers */ = {isa = PBXBuildFile; fileRef = 23077A4E0B13FB264EC009F2BFE320F0 /* MJExtensionConst.h */; settings = {ATTRIBUTES = (Public, ); }; };
0E63A963A24E12D1799F27CB24FFF8C1 /* NSObject+MJCoding.m in Sources */ = {isa = PBXBuildFile; fileRef = 9522F6F7E1E6A959DBFE548F7A5F5756 /* NSObject+MJCoding.m */; };
0F07CB32DCBA606D2BC743909D349C71 /* GMRouter-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 1BB55C467B7C1F3E8E7292B26195A3A8 /* GMRouter-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
13342761565C85749EFA82BF1D28C51B /* MJExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7ABEF07C065DAA1093F386E0864101B0 /* MJExtension.framework */; };
15AE6A6F9DA5BC8C3BF7C7343D6E5CDD /* MJProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EBFC8B09F9FEE9C01B6AC97758F30CF /* MJProperty.m */; };
16E446F9D7AB9549778AB5D1E22925E2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E04AC621D1A86F2AC40200FFAD16DBAA /* Foundation.framework */; };
270B9ABCAB46D05E565D920BCFD48E1C /* MJPropertyKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FDE02E7D2A4B3EF44B4BC31D93EAF80 /* MJPropertyKey.m */; };
27EBA7C52C5123EB2809A95222981674 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E04AC621D1A86F2AC40200FFAD16DBAA /* Foundation.framework */; };
294DDF5F7DC031467925B291ECFE674F /* Pods-GMRouter_Tests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 12D481E6E4C4A19B7BD3862F2A6E29D5 /* Pods-GMRouter_Tests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
2C84135F712FCAEE66926E643AE9FCA3 /* NSObject+MJProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 28E782F8259378AD0DBF815F97964885 /* NSObject+MJProperty.m */; };
3420C4C4734E984B1BB50BA0D736FDFD /* GMRouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 0735DB78CD51E8CA4E2233CB2A89B49A /* GMRouter.m */; };
387A0C305463D54BE40AC267A65B055F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E04AC621D1A86F2AC40200FFAD16DBAA /* Foundation.framework */; };
3E18C28477C5E35C8FFA3D70D921875F /* Target_commons.m in Sources */ = {isa = PBXBuildFile; fileRef = ADD75F77659E02147B562148228B6E0C /* Target_commons.m */; };
4592DE2F5F8EE4709F6D426F3C3A31AD /* UIViewController+Router.m in Sources */ = {isa = PBXBuildFile; fileRef = 06D9BFA3BE399816CC59931F71896708 /* UIViewController+Router.m */; };
460720A95ACEB66DDD1BCAAD5DCE0BB2 /* MJExtension-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 33DDF0C319CDAACEB3E84130FD4CE911 /* MJExtension-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
46E24D7E3C1A59D2FE1FA9D0054D5C0D /* MJPropertyType.h in Headers */ = {isa = PBXBuildFile; fileRef = A7666F58E72D21414F1583523F1C8B57 /* MJPropertyType.h */; settings = {ATTRIBUTES = (Public, ); }; };
5285406C13A9E71CDE5AB61616AB2913 /* GMRouter.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C0E8C79ECDA09BD952A39D389DE8ACC /* GMRouter.h */; settings = {ATTRIBUTES = (Public, ); }; };
5433D3DA1D49B8D279EE201FFA78458C /* MJExtension-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 86A47CD1E58E6134E1BE14A48CF6D849 /* MJExtension-dummy.m */; };
5650CF3D8AA1A1E5D69512C7AB70E376 /* NSObject+MJKeyValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 265191AF18ABA408F7AEAC2C6D7DD57B /* NSObject+MJKeyValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
6393BAB05CA48264D1269B1858420643 /* NSString+MJExtension.h in Headers */ = {isa = PBXBuildFile; fileRef = D8D8512A56DCE8FDA31BB1A013D8D389 /* NSString+MJExtension.h */; settings = {ATTRIBUTES = (Public, ); }; };
67090786DF309DB0815FA55826BEABC6 /* NSObject+MJClass.h in Headers */ = {isa = PBXBuildFile; fileRef = EBB759E373C7D4DBAF91077141CA3CD3 /* NSObject+MJClass.h */; settings = {ATTRIBUTES = (Public, ); }; };
7247F380D9328B5CB771D6BB0741EC96 /* Pods-GMRouter_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = FBB3A3B369EDE2F015451781EFFABF86 /* Pods-GMRouter_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
75732A92416970FE9B64BD67ACD8F3FF /* MJPropertyType.m in Sources */ = {isa = PBXBuildFile; fileRef = 7CA71C2F02E2C8122DA187D3B07A3EC4 /* MJPropertyType.m */; };
7592C5571EF43C7727EA8B82D742CFBB /* NSString+MJExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = F0AA3B72E288A985348053635E8928CD /* NSString+MJExtension.m */; };
7835580FED1D9E6F2FB5BD0820AD6144 /* MJPropertyKey.h in Headers */ = {isa = PBXBuildFile; fileRef = FB16CB4E95C7E7CA54B8BFD76D6C8BD5 /* MJPropertyKey.h */; settings = {ATTRIBUTES = (Public, ); }; };
785C6962C48206791172B777BDAFF232 /* MJExtensionConst.m in Sources */ = {isa = PBXBuildFile; fileRef = 9970287FB8A59D6CE66509205219E52C /* MJExtensionConst.m */; };
7BBE98925FE19657E562BCDA852843C4 /* NSObject+MJKeyValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E5BC3441D59A15FDCB85329B9C0627A /* NSObject+MJKeyValue.m */; };
80C3E4064EAB808CDFC2E4F1CAC5B835 /* GMRouter+gm.h in Headers */ = {isa = PBXBuildFile; fileRef = 03E19CF7FD15283B0783FA1EC30FF359 /* GMRouter+gm.h */; settings = {ATTRIBUTES = (Public, ); }; };
97F8FE3528A90D2E5A8E21B1B4E553E1 /* MJFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AEBA70958F3E94E8D543C846C797059 /* MJFoundation.h */; settings = {ATTRIBUTES = (Public, ); }; };
AA1AD654929A963496941AC01D3E7442 /* NSObject+MJClass.m in Sources */ = {isa = PBXBuildFile; fileRef = E2C393B9E214DB9289DFDC5EC4D66BF0 /* NSObject+MJClass.m */; };
AE1932FDD4234B769F5DC9BE56614027 /* MJFoundation.m in Sources */ = {isa = PBXBuildFile; fileRef = 72BFC4AFACD9ACAC3C9F00947646B7F2 /* MJFoundation.m */; };
BB45E881DB25A140211647D717BF88F2 /* NSObject+MJProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = D16CA9A56E4FB7F2F2814981B63B7029 /* NSObject+MJProperty.h */; settings = {ATTRIBUTES = (Public, ); }; };
C137212F59D97581AB6EB2A3BA0EF524 /* GMRouter+gm.m in Sources */ = {isa = PBXBuildFile; fileRef = 852E5AFCC4B1A772B115C73EABD68C8D /* GMRouter+gm.m */; };
C5B2C027DCE500280E59DD0079C840F2 /* Pods-GMRouter_Tests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B06D1FEE9ED45063AD65F75D09194D4 /* Pods-GMRouter_Tests-dummy.m */; };
CEA7F8468B77B10357CDBB7772CE3E0E /* Target_commons.h in Headers */ = {isa = PBXBuildFile; fileRef = 1219F47879ABBCDC018B54B1EA6B6FFE /* Target_commons.h */; settings = {ATTRIBUTES = (Public, ); }; };
D0A6F2B2988F1B0CEE597364DB35D675 /* MJExtension.h in Headers */ = {isa = PBXBuildFile; fileRef = 05023A0B1898974DA5A7AB5B4E829619 /* MJExtension.h */; settings = {ATTRIBUTES = (Public, ); }; };
D0C5AE306468898A7BC2F304805791F4 /* MJProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E619AA937826CB4BD6272654B693F79 /* MJProperty.h */; settings = {ATTRIBUTES = (Public, ); }; };
E070ACC3A29A8298F71984F8B48102CE /* NSObject+MJCoding.h in Headers */ = {isa = PBXBuildFile; fileRef = BFA31624F5336DD08F70A4C8F06D756E /* NSObject+MJCoding.h */; settings = {ATTRIBUTES = (Public, ); }; };
F1BE26FAA860C11F7EEC1641F7787082 /* GMRouter-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A0B024A2B577156FF46E41925F8E1DE /* GMRouter-dummy.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
07EF1C704D3F314444E4E0B433521E0A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 4B36B03DEB212F49D4D7ED9BFCE5C831;
remoteInfo = "Pods-GMRouter_Example";
};
4DF65C341EBF3DAC05C6906DC1B03C97 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 4D3BA58D0583DF37575CACAB3DDADC85;
remoteInfo = MJExtension;
};
A9005644F436F41BC3F356B6A1C835F4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 75956ED72576558B6E846FD2A08311F6;
remoteInfo = GMRouter;
};
D03E2F5B7FA39CAA2A8A3A097E9611FC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 4D3BA58D0583DF37575CACAB3DDADC85;
remoteInfo = MJExtension;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
0282F6B57578F509AB21A267736170B1 /* MJExtension.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = MJExtension.modulemap; sourceTree = "<group>"; };
03E19CF7FD15283B0783FA1EC30FF359 /* GMRouter+gm.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "GMRouter+gm.h"; path = "GMRouter/Classes/GMRouter+gm.h"; sourceTree = "<group>"; };
05023A0B1898974DA5A7AB5B4E829619 /* MJExtension.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJExtension.h; path = MJExtension/MJExtension.h; sourceTree = "<group>"; };
06D9BFA3BE399816CC59931F71896708 /* UIViewController+Router.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIViewController+Router.m"; path = "GMRouter/Classes/UIViewController+Router.m"; sourceTree = "<group>"; };
0735DB78CD51E8CA4E2233CB2A89B49A /* GMRouter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GMRouter.m; path = GMRouter/Classes/GMRouter.m; sourceTree = "<group>"; };
07545AF0CC480D5D105E73861C12603E /* GMRouter.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = GMRouter.framework; path = GMRouter.framework; sourceTree = BUILT_PRODUCTS_DIR; };
0A4688F4F0ECD415C54743F178C6F7E4 /* Pods-GMRouter_Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-GMRouter_Tests.modulemap"; sourceTree = "<group>"; };
10244FCEEFB43378EE67C12A814124A0 /* Pods-GMRouter_Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-GMRouter_Example.modulemap"; sourceTree = "<group>"; };
1219F47879ABBCDC018B54B1EA6B6FFE /* Target_commons.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Target_commons.h; path = GMRouter/Classes/Target_commons.h; sourceTree = "<group>"; };
12D481E6E4C4A19B7BD3862F2A6E29D5 /* Pods-GMRouter_Tests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-GMRouter_Tests-umbrella.h"; sourceTree = "<group>"; };
1A0B024A2B577156FF46E41925F8E1DE /* GMRouter-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "GMRouter-dummy.m"; sourceTree = "<group>"; };
1BB55C467B7C1F3E8E7292B26195A3A8 /* GMRouter-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GMRouter-umbrella.h"; sourceTree = "<group>"; };
1BEFCEE973346B62813C4A206D411726 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = "<group>"; };
1EBFC8B09F9FEE9C01B6AC97758F30CF /* MJProperty.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJProperty.m; path = MJExtension/MJProperty.m; sourceTree = "<group>"; };
23077A4E0B13FB264EC009F2BFE320F0 /* MJExtensionConst.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJExtensionConst.h; path = MJExtension/MJExtensionConst.h; sourceTree = "<group>"; };
265191AF18ABA408F7AEAC2C6D7DD57B /* NSObject+MJKeyValue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSObject+MJKeyValue.h"; path = "MJExtension/NSObject+MJKeyValue.h"; sourceTree = "<group>"; };
28E782F8259378AD0DBF815F97964885 /* NSObject+MJProperty.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSObject+MJProperty.m"; path = "MJExtension/NSObject+MJProperty.m"; sourceTree = "<group>"; };
29743AEC1DC80D1A00A308973743E479 /* Pods-GMRouter_Example-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-GMRouter_Example-Info.plist"; sourceTree = "<group>"; };
2B276B0A79173A1D6E83C9B4FB9A4A57 /* MJExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = MJExtension.framework; path = MJExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; };
33ACD3930E0BC2F49FC4111CF4668169 /* Pods-GMRouter_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-GMRouter_Example.release.xcconfig"; sourceTree = "<group>"; };
33DDF0C319CDAACEB3E84130FD4CE911 /* MJExtension-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MJExtension-umbrella.h"; sourceTree = "<group>"; };
3876DEAC1052E76429FB56F7F41B5658 /* Pods-GMRouter_Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-GMRouter_Example-acknowledgements.plist"; sourceTree = "<group>"; };
40982CAA4B36CFC7C32FD87BAC8E169E /* Pods_GMRouter_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_GMRouter_Tests.framework; path = "Pods-GMRouter_Tests.framework"; sourceTree = BUILT_PRODUCTS_DIR; };
4AD1579E1B3E67AABCCF5F0049E1891B /* Pods-GMRouter_Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-GMRouter_Example-acknowledgements.markdown"; sourceTree = "<group>"; };
4B3837D74A20D74C0AD204332FDE568A /* Pods-GMRouter_Tests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-GMRouter_Tests-acknowledgements.plist"; sourceTree = "<group>"; };
5AEBA70958F3E94E8D543C846C797059 /* MJFoundation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJFoundation.h; path = MJExtension/MJFoundation.h; sourceTree = "<group>"; };
5E619AA937826CB4BD6272654B693F79 /* MJProperty.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJProperty.h; path = MJExtension/MJProperty.h; sourceTree = "<group>"; };
617877158CAEC3ECDA245F61A3B4E876 /* Pods-GMRouter_Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-GMRouter_Example-frameworks.sh"; sourceTree = "<group>"; };
6AE8E2A476705DCA9AEC318672B5549F /* GMRouter.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = GMRouter.podspec; sourceTree = "<group>"; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
6B61A08547E5EC761DC6A55EE9533598 /* Pods-GMRouter_Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-GMRouter_Example-dummy.m"; sourceTree = "<group>"; };
6E5BC3441D59A15FDCB85329B9C0627A /* NSObject+MJKeyValue.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSObject+MJKeyValue.m"; path = "MJExtension/NSObject+MJKeyValue.m"; sourceTree = "<group>"; };
6FDE02E7D2A4B3EF44B4BC31D93EAF80 /* MJPropertyKey.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJPropertyKey.m; path = MJExtension/MJPropertyKey.m; sourceTree = "<group>"; };
72BFC4AFACD9ACAC3C9F00947646B7F2 /* MJFoundation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJFoundation.m; path = MJExtension/MJFoundation.m; sourceTree = "<group>"; };
73BDA5DE02867E1F38E53E3C47F2E64F /* GMRouter.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = GMRouter.modulemap; sourceTree = "<group>"; };
7ABEF07C065DAA1093F386E0864101B0 /* MJExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MJExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; };
7C0E8C79ECDA09BD952A39D389DE8ACC /* GMRouter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GMRouter.h; path = GMRouter/Classes/GMRouter.h; sourceTree = "<group>"; };
7CA71C2F02E2C8122DA187D3B07A3EC4 /* MJPropertyType.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJPropertyType.m; path = MJExtension/MJPropertyType.m; sourceTree = "<group>"; };
809BD1364D2D6D9C1F5F65822A5CD5B7 /* GMRouter-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GMRouter-prefix.pch"; sourceTree = "<group>"; };
852E5AFCC4B1A772B115C73EABD68C8D /* GMRouter+gm.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "GMRouter+gm.m"; path = "GMRouter/Classes/GMRouter+gm.m"; sourceTree = "<group>"; };
86A47CD1E58E6134E1BE14A48CF6D849 /* MJExtension-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "MJExtension-dummy.m"; sourceTree = "<group>"; };
8AB8B1BA3BA2E2CC233E96FADDF264F5 /* GMRouter-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "GMRouter-Info.plist"; sourceTree = "<group>"; };
9522F6F7E1E6A959DBFE548F7A5F5756 /* NSObject+MJCoding.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSObject+MJCoding.m"; path = "MJExtension/NSObject+MJCoding.m"; sourceTree = "<group>"; };
9970287FB8A59D6CE66509205219E52C /* MJExtensionConst.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJExtensionConst.m; path = MJExtension/MJExtensionConst.m; sourceTree = "<group>"; };
9B06D1FEE9ED45063AD65F75D09194D4 /* Pods-GMRouter_Tests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-GMRouter_Tests-dummy.m"; sourceTree = "<group>"; };
9B63B9BE61CAA13EA3E4A6C62A8823DE /* MJExtension.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MJExtension.xcconfig; sourceTree = "<group>"; };
9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
A7438C725C49090EE92CED3A16DA316B /* MJExtension-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "MJExtension-Info.plist"; sourceTree = "<group>"; };
A7666F58E72D21414F1583523F1C8B57 /* MJPropertyType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJPropertyType.h; path = MJExtension/MJPropertyType.h; sourceTree = "<group>"; };
ADD75F77659E02147B562148228B6E0C /* Target_commons.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Target_commons.m; path = GMRouter/Classes/Target_commons.m; sourceTree = "<group>"; };
B851DB4DC8EB267EFB7C4D404977444D /* GMRouter.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GMRouter.xcconfig; sourceTree = "<group>"; };
BFA31624F5336DD08F70A4C8F06D756E /* NSObject+MJCoding.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSObject+MJCoding.h"; path = "MJExtension/NSObject+MJCoding.h"; sourceTree = "<group>"; };
CDA098AE466F3401888380FA1240F066 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = "<group>"; };
CFAAB8C43015BCEB85A0C0ECF1A3CD4F /* Pods-GMRouter_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-GMRouter_Example.debug.xcconfig"; sourceTree = "<group>"; };
D052A7830930288BFD6D3207CED09506 /* Pods-GMRouter_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-GMRouter_Tests.release.xcconfig"; sourceTree = "<group>"; };
D16CA9A56E4FB7F2F2814981B63B7029 /* NSObject+MJProperty.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSObject+MJProperty.h"; path = "MJExtension/NSObject+MJProperty.h"; sourceTree = "<group>"; };
D5507E9033B874004DC41E326D339A79 /* Pods-GMRouter_Tests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-GMRouter_Tests-acknowledgements.markdown"; sourceTree = "<group>"; };
D684E878B62617F575399094A559A8F3 /* Pods_GMRouter_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_GMRouter_Example.framework; path = "Pods-GMRouter_Example.framework"; sourceTree = BUILT_PRODUCTS_DIR; };
D73D5257B1CBA064371CE13DE2B14EB5 /* Pods-GMRouter_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-GMRouter_Tests.debug.xcconfig"; sourceTree = "<group>"; };
D8D8512A56DCE8FDA31BB1A013D8D389 /* NSString+MJExtension.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSString+MJExtension.h"; path = "MJExtension/NSString+MJExtension.h"; sourceTree = "<group>"; };
DCB712894FEE5C910EEF563F03445407 /* UIViewController+Router.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIViewController+Router.h"; path = "GMRouter/Classes/UIViewController+Router.h"; sourceTree = "<group>"; };
E04AC621D1A86F2AC40200FFAD16DBAA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
E2C393B9E214DB9289DFDC5EC4D66BF0 /* NSObject+MJClass.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSObject+MJClass.m"; path = "MJExtension/NSObject+MJClass.m"; sourceTree = "<group>"; };
EBB759E373C7D4DBAF91077141CA3CD3 /* NSObject+MJClass.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSObject+MJClass.h"; path = "MJExtension/NSObject+MJClass.h"; sourceTree = "<group>"; };
F0AA3B72E288A985348053635E8928CD /* NSString+MJExtension.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSString+MJExtension.m"; path = "MJExtension/NSString+MJExtension.m"; sourceTree = "<group>"; };
F474769DF05520EE99C71EA610BA6AF7 /* MJExtension-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MJExtension-prefix.pch"; sourceTree = "<group>"; };
F7021D5FA182A99E9BE842763E70B46A /* Pods-GMRouter_Tests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-GMRouter_Tests-Info.plist"; sourceTree = "<group>"; };
FB16CB4E95C7E7CA54B8BFD76D6C8BD5 /* MJPropertyKey.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJPropertyKey.h; path = MJExtension/MJPropertyKey.h; sourceTree = "<group>"; };
FBB3A3B369EDE2F015451781EFFABF86 /* Pods-GMRouter_Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-GMRouter_Example-umbrella.h"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
0483EE3666459540325EE724C6CBD019 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
27EBA7C52C5123EB2809A95222981674 /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
9E48985ACA4BF8953EF86F33B974DAF5 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
387A0C305463D54BE40AC267A65B055F /* Foundation.framework in Frameworks */,
13342761565C85749EFA82BF1D28C51B /* MJExtension.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
B8579A6AA2B0CFCD58B77F045B616608 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
07BFFC265907A63B0B21810B25A858FC /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
EB9EA797F5CDFB396875C95412C7D1EF /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
16E446F9D7AB9549778AB5D1E22925E2 /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
00B697D04654CC21F44925CD553B59EE /* Support Files */ = {
isa = PBXGroup;
children = (
73BDA5DE02867E1F38E53E3C47F2E64F /* GMRouter.modulemap */,
B851DB4DC8EB267EFB7C4D404977444D /* GMRouter.xcconfig */,
1A0B024A2B577156FF46E41925F8E1DE /* GMRouter-dummy.m */,
8AB8B1BA3BA2E2CC233E96FADDF264F5 /* GMRouter-Info.plist */,
809BD1364D2D6D9C1F5F65822A5CD5B7 /* GMRouter-prefix.pch */,
1BB55C467B7C1F3E8E7292B26195A3A8 /* GMRouter-umbrella.h */,
);
name = "Support Files";
path = "Example/Pods/Target Support Files/GMRouter";
sourceTree = "<group>";
};
1BE342ADF33B00D6EB9875C6CA02EFB0 /* MJExtension */ = {
isa = PBXGroup;
children = (
05023A0B1898974DA5A7AB5B4E829619 /* MJExtension.h */,
23077A4E0B13FB264EC009F2BFE320F0 /* MJExtensionConst.h */,
9970287FB8A59D6CE66509205219E52C /* MJExtensionConst.m */,
5AEBA70958F3E94E8D543C846C797059 /* MJFoundation.h */,
72BFC4AFACD9ACAC3C9F00947646B7F2 /* MJFoundation.m */,
5E619AA937826CB4BD6272654B693F79 /* MJProperty.h */,
1EBFC8B09F9FEE9C01B6AC97758F30CF /* MJProperty.m */,
FB16CB4E95C7E7CA54B8BFD76D6C8BD5 /* MJPropertyKey.h */,
6FDE02E7D2A4B3EF44B4BC31D93EAF80 /* MJPropertyKey.m */,
A7666F58E72D21414F1583523F1C8B57 /* MJPropertyType.h */,
7CA71C2F02E2C8122DA187D3B07A3EC4 /* MJPropertyType.m */,
EBB759E373C7D4DBAF91077141CA3CD3 /* NSObject+MJClass.h */,
E2C393B9E214DB9289DFDC5EC4D66BF0 /* NSObject+MJClass.m */,
BFA31624F5336DD08F70A4C8F06D756E /* NSObject+MJCoding.h */,
9522F6F7E1E6A959DBFE548F7A5F5756 /* NSObject+MJCoding.m */,
265191AF18ABA408F7AEAC2C6D7DD57B /* NSObject+MJKeyValue.h */,
6E5BC3441D59A15FDCB85329B9C0627A /* NSObject+MJKeyValue.m */,
D16CA9A56E4FB7F2F2814981B63B7029 /* NSObject+MJProperty.h */,
28E782F8259378AD0DBF815F97964885 /* NSObject+MJProperty.m */,
D8D8512A56DCE8FDA31BB1A013D8D389 /* NSString+MJExtension.h */,
F0AA3B72E288A985348053635E8928CD /* NSString+MJExtension.m */,
858B930326AD76BB2F53D253D52E220D /* Support Files */,
);
name = MJExtension;
path = MJExtension;
sourceTree = "<group>";
};
49B219C8B627D91DDBA361D37555B275 /* Targets Support Files */ = {
isa = PBXGroup;
children = (
AB4239B8E10BD35306D69C1AAEE3F9AD /* Pods-GMRouter_Example */,
B453FE7EBF08DF7BDD412B04C2BB44F7 /* Pods-GMRouter_Tests */,
);
name = "Targets Support Files";
sourceTree = "<group>";
};
858B930326AD76BB2F53D253D52E220D /* Support Files */ = {
isa = PBXGroup;
children = (
0282F6B57578F509AB21A267736170B1 /* MJExtension.modulemap */,
9B63B9BE61CAA13EA3E4A6C62A8823DE /* MJExtension.xcconfig */,
86A47CD1E58E6134E1BE14A48CF6D849 /* MJExtension-dummy.m */,
A7438C725C49090EE92CED3A16DA316B /* MJExtension-Info.plist */,
F474769DF05520EE99C71EA610BA6AF7 /* MJExtension-prefix.pch */,
33DDF0C319CDAACEB3E84130FD4CE911 /* MJExtension-umbrella.h */,
);
name = "Support Files";
path = "../Target Support Files/MJExtension";
sourceTree = "<group>";
};
9628847C933BC19C7F230E9DD94C66E2 /* GMRouter */ = {
isa = PBXGroup;
children = (
7C0E8C79ECDA09BD952A39D389DE8ACC /* GMRouter.h */,
0735DB78CD51E8CA4E2233CB2A89B49A /* GMRouter.m */,
03E19CF7FD15283B0783FA1EC30FF359 /* GMRouter+gm.h */,
852E5AFCC4B1A772B115C73EABD68C8D /* GMRouter+gm.m */,
1219F47879ABBCDC018B54B1EA6B6FFE /* Target_commons.h */,
ADD75F77659E02147B562148228B6E0C /* Target_commons.m */,
DCB712894FEE5C910EEF563F03445407 /* UIViewController+Router.h */,
06D9BFA3BE399816CC59931F71896708 /* UIViewController+Router.m */,
DB0D6C4B74A39705FB986B0A9C40FE72 /* Pod */,
00B697D04654CC21F44925CD553B59EE /* Support Files */,
);
name = GMRouter;
path = ../..;
sourceTree = "<group>";
};
98254C63E096C42740938CF63ED1D89D /* Frameworks */ = {
isa = PBXGroup;
children = (
7ABEF07C065DAA1093F386E0864101B0 /* MJExtension.framework */,
D72DBDC52C068CF1A6EDD7F19C21FC94 /* iOS */,
);
name = Frameworks;
sourceTree = "<group>";
};
AB4239B8E10BD35306D69C1AAEE3F9AD /* Pods-GMRouter_Example */ = {
isa = PBXGroup;
children = (
10244FCEEFB43378EE67C12A814124A0 /* Pods-GMRouter_Example.modulemap */,
4AD1579E1B3E67AABCCF5F0049E1891B /* Pods-GMRouter_Example-acknowledgements.markdown */,
3876DEAC1052E76429FB56F7F41B5658 /* Pods-GMRouter_Example-acknowledgements.plist */,
6B61A08547E5EC761DC6A55EE9533598 /* Pods-GMRouter_Example-dummy.m */,
617877158CAEC3ECDA245F61A3B4E876 /* Pods-GMRouter_Example-frameworks.sh */,
29743AEC1DC80D1A00A308973743E479 /* Pods-GMRouter_Example-Info.plist */,
FBB3A3B369EDE2F015451781EFFABF86 /* Pods-GMRouter_Example-umbrella.h */,
CFAAB8C43015BCEB85A0C0ECF1A3CD4F /* Pods-GMRouter_Example.debug.xcconfig */,
33ACD3930E0BC2F49FC4111CF4668169 /* Pods-GMRouter_Example.release.xcconfig */,
);
name = "Pods-GMRouter_Example";
path = "Target Support Files/Pods-GMRouter_Example";
sourceTree = "<group>";
};
B453FE7EBF08DF7BDD412B04C2BB44F7 /* Pods-GMRouter_Tests */ = {
isa = PBXGroup;
children = (
0A4688F4F0ECD415C54743F178C6F7E4 /* Pods-GMRouter_Tests.modulemap */,
D5507E9033B874004DC41E326D339A79 /* Pods-GMRouter_Tests-acknowledgements.markdown */,
4B3837D74A20D74C0AD204332FDE568A /* Pods-GMRouter_Tests-acknowledgements.plist */,
9B06D1FEE9ED45063AD65F75D09194D4 /* Pods-GMRouter_Tests-dummy.m */,
F7021D5FA182A99E9BE842763E70B46A /* Pods-GMRouter_Tests-Info.plist */,
12D481E6E4C4A19B7BD3862F2A6E29D5 /* Pods-GMRouter_Tests-umbrella.h */,
D73D5257B1CBA064371CE13DE2B14EB5 /* Pods-GMRouter_Tests.debug.xcconfig */,
D052A7830930288BFD6D3207CED09506 /* Pods-GMRouter_Tests.release.xcconfig */,
);
name = "Pods-GMRouter_Tests";
path = "Target Support Files/Pods-GMRouter_Tests";
sourceTree = "<group>";
};
BBE7F25BDF6E2ECE64867498D8902AF4 /* Pods */ = {
isa = PBXGroup;
children = (
1BE342ADF33B00D6EB9875C6CA02EFB0 /* MJExtension */,
);
name = Pods;
sourceTree = "<group>";
};
CF1408CF629C7361332E53B88F7BD30C = {
isa = PBXGroup;
children = (
9D940727FF8FB9C785EB98E56350EF41 /* Podfile */,
DA7A2BB1AD084F83B56A9EF62AD624F8 /* Development Pods */,
98254C63E096C42740938CF63ED1D89D /* Frameworks */,
BBE7F25BDF6E2ECE64867498D8902AF4 /* Pods */,
E2F287BBF9FACD48DECB5BD36578B359 /* Products */,
49B219C8B627D91DDBA361D37555B275 /* Targets Support Files */,
);
sourceTree = "<group>";
};
D72DBDC52C068CF1A6EDD7F19C21FC94 /* iOS */ = {
isa = PBXGroup;
children = (
E04AC621D1A86F2AC40200FFAD16DBAA /* Foundation.framework */,
);
name = iOS;
sourceTree = "<group>";
};
DA7A2BB1AD084F83B56A9EF62AD624F8 /* Development Pods */ = {
isa = PBXGroup;
children = (
9628847C933BC19C7F230E9DD94C66E2 /* GMRouter */,
);
name = "Development Pods";
sourceTree = "<group>";
};
DB0D6C4B74A39705FB986B0A9C40FE72 /* Pod */ = {
isa = PBXGroup;
children = (
6AE8E2A476705DCA9AEC318672B5549F /* GMRouter.podspec */,
CDA098AE466F3401888380FA1240F066 /* LICENSE */,
1BEFCEE973346B62813C4A206D411726 /* README.md */,
);
name = Pod;
sourceTree = "<group>";
};
E2F287BBF9FACD48DECB5BD36578B359 /* Products */ = {
isa = PBXGroup;
children = (
07545AF0CC480D5D105E73861C12603E /* GMRouter.framework */,
2B276B0A79173A1D6E83C9B4FB9A4A57 /* MJExtension.framework */,
D684E878B62617F575399094A559A8F3 /* Pods_GMRouter_Example.framework */,
40982CAA4B36CFC7C32FD87BAC8E169E /* Pods_GMRouter_Tests.framework */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
22470D5A9AE9C851D7662F4B06E5D572 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
80C3E4064EAB808CDFC2E4F1CAC5B835 /* GMRouter+gm.h in Headers */,
0F07CB32DCBA606D2BC743909D349C71 /* GMRouter-umbrella.h in Headers */,
5285406C13A9E71CDE5AB61616AB2913 /* GMRouter.h in Headers */,
CEA7F8468B77B10357CDBB7772CE3E0E /* Target_commons.h in Headers */,
019EC0A77E8BD66C992685194EABB4AB /* UIViewController+Router.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
276B1E645EA3CFF48125EECCF041CBC3 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
294DDF5F7DC031467925B291ECFE674F /* Pods-GMRouter_Tests-umbrella.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
4A504F5ABD613B5555FC3D882066B962 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
7247F380D9328B5CB771D6BB0741EC96 /* Pods-GMRouter_Example-umbrella.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
758100767AED95BACE987CED8F01E67B /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
460720A95ACEB66DDD1BCAAD5DCE0BB2 /* MJExtension-umbrella.h in Headers */,
D0A6F2B2988F1B0CEE597364DB35D675 /* MJExtension.h in Headers */,
0A9F462A77BA08483DB425A367CA2A87 /* MJExtensionConst.h in Headers */,
97F8FE3528A90D2E5A8E21B1B4E553E1 /* MJFoundation.h in Headers */,
D0C5AE306468898A7BC2F304805791F4 /* MJProperty.h in Headers */,
7835580FED1D9E6F2FB5BD0820AD6144 /* MJPropertyKey.h in Headers */,
46E24D7E3C1A59D2FE1FA9D0054D5C0D /* MJPropertyType.h in Headers */,
67090786DF309DB0815FA55826BEABC6 /* NSObject+MJClass.h in Headers */,
E070ACC3A29A8298F71984F8B48102CE /* NSObject+MJCoding.h in Headers */,
5650CF3D8AA1A1E5D69512C7AB70E376 /* NSObject+MJKeyValue.h in Headers */,
BB45E881DB25A140211647D717BF88F2 /* NSObject+MJProperty.h in Headers */,
6393BAB05CA48264D1269B1858420643 /* NSString+MJExtension.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
4B36B03DEB212F49D4D7ED9BFCE5C831 /* Pods-GMRouter_Example */ = {
isa = PBXNativeTarget;
buildConfigurationList = 4099C8D6A094CC39E6BEBC8016626175 /* Build configuration list for PBXNativeTarget "Pods-GMRouter_Example" */;
buildPhases = (
4A504F5ABD613B5555FC3D882066B962 /* Headers */,
D443C137311B04A61DCCCB5AA49D0337 /* Sources */,
B8579A6AA2B0CFCD58B77F045B616608 /* Frameworks */,
965CD34E4F9C76239301AFFCC6F7C0F4 /* Resources */,
);
buildRules = (
);
dependencies = (
7CBFE35C998286B4464A68BE9EB86C82 /* PBXTargetDependency */,
EEB0ACBA7250F1C7A2515669F27AC6FD /* PBXTargetDependency */,
);
name = "Pods-GMRouter_Example";
productName = "Pods-GMRouter_Example";
productReference = D684E878B62617F575399094A559A8F3 /* Pods_GMRouter_Example.framework */;
productType = "com.apple.product-type.framework";
};
4D3BA58D0583DF37575CACAB3DDADC85 /* MJExtension */ = {
isa = PBXNativeTarget;
buildConfigurationList = E9973E27B9A82A922588E42EA019A46F /* Build configuration list for PBXNativeTarget "MJExtension" */;
buildPhases = (
758100767AED95BACE987CED8F01E67B /* Headers */,
92971A45DDBA8DB6D735C309760227BE /* Sources */,
0483EE3666459540325EE724C6CBD019 /* Frameworks */,
5857451A2363C5E14DCFDCEB6C7C73BD /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = MJExtension;
productName = MJExtension;
productReference = 2B276B0A79173A1D6E83C9B4FB9A4A57 /* MJExtension.framework */;
productType = "com.apple.product-type.framework";
};
75956ED72576558B6E846FD2A08311F6 /* GMRouter */ = {
isa = PBXNativeTarget;
buildConfigurationList = 2BB69AB14DA1458D75C814C6D99138F2 /* Build configuration list for PBXNativeTarget "GMRouter" */;
buildPhases = (
22470D5A9AE9C851D7662F4B06E5D572 /* Headers */,
B20163176D76B6BFCE7AB7AD9BB0433D /* Sources */,
9E48985ACA4BF8953EF86F33B974DAF5 /* Frameworks */,
003857546CD995F623F7E17BB16B6A91 /* Resources */,
);
buildRules = (
);
dependencies = (
8C69EB48F8AA67B298C87C0C4BFFACD1 /* PBXTargetDependency */,
);
name = GMRouter;
productName = GMRouter;
productReference = 07545AF0CC480D5D105E73861C12603E /* GMRouter.framework */;
productType = "com.apple.product-type.framework";
};
CAA35E933D605DB16055F20631CCC99D /* Pods-GMRouter_Tests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 27E973FB214CB5EF8561F0CDC232FD40 /* Build configuration list for PBXNativeTarget "Pods-GMRouter_Tests" */;
buildPhases = (
276B1E645EA3CFF48125EECCF041CBC3 /* Headers */,
797ABD0E0DEAC34497A207FB90EBC1BB /* Sources */,
EB9EA797F5CDFB396875C95412C7D1EF /* Frameworks */,
6601B4B07DBA75F1D314022064D60EA5 /* Resources */,
);
buildRules = (
);
dependencies = (
39F89FABC110AD3EFF291980AD16559D /* PBXTargetDependency */,
);
name = "Pods-GMRouter_Tests";
productName = "Pods-GMRouter_Tests";
productReference = 40982CAA4B36CFC7C32FD87BAC8E169E /* Pods_GMRouter_Tests.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
BFDFE7DC352907FC980B868725387E98 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1100;
LastUpgradeCheck = 1100;
};
buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = CF1408CF629C7361332E53B88F7BD30C;
productRefGroup = E2F287BBF9FACD48DECB5BD36578B359 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
75956ED72576558B6E846FD2A08311F6 /* GMRouter */,
4D3BA58D0583DF37575CACAB3DDADC85 /* MJExtension */,
4B36B03DEB212F49D4D7ED9BFCE5C831 /* Pods-GMRouter_Example */,
CAA35E933D605DB16055F20631CCC99D /* Pods-GMRouter_Tests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
003857546CD995F623F7E17BB16B6A91 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
5857451A2363C5E14DCFDCEB6C7C73BD /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
6601B4B07DBA75F1D314022064D60EA5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
965CD34E4F9C76239301AFFCC6F7C0F4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
797ABD0E0DEAC34497A207FB90EBC1BB /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C5B2C027DCE500280E59DD0079C840F2 /* Pods-GMRouter_Tests-dummy.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
92971A45DDBA8DB6D735C309760227BE /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
5433D3DA1D49B8D279EE201FFA78458C /* MJExtension-dummy.m in Sources */,
785C6962C48206791172B777BDAFF232 /* MJExtensionConst.m in Sources */,
AE1932FDD4234B769F5DC9BE56614027 /* MJFoundation.m in Sources */,
15AE6A6F9DA5BC8C3BF7C7343D6E5CDD /* MJProperty.m in Sources */,
270B9ABCAB46D05E565D920BCFD48E1C /* MJPropertyKey.m in Sources */,
75732A92416970FE9B64BD67ACD8F3FF /* MJPropertyType.m in Sources */,
AA1AD654929A963496941AC01D3E7442 /* NSObject+MJClass.m in Sources */,
0E63A963A24E12D1799F27CB24FFF8C1 /* NSObject+MJCoding.m in Sources */,
7BBE98925FE19657E562BCDA852843C4 /* NSObject+MJKeyValue.m in Sources */,
2C84135F712FCAEE66926E643AE9FCA3 /* NSObject+MJProperty.m in Sources */,
7592C5571EF43C7727EA8B82D742CFBB /* NSString+MJExtension.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
B20163176D76B6BFCE7AB7AD9BB0433D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C137212F59D97581AB6EB2A3BA0EF524 /* GMRouter+gm.m in Sources */,
F1BE26FAA860C11F7EEC1641F7787082 /* GMRouter-dummy.m in Sources */,
3420C4C4734E984B1BB50BA0D736FDFD /* GMRouter.m in Sources */,
3E18C28477C5E35C8FFA3D70D921875F /* Target_commons.m in Sources */,
4592DE2F5F8EE4709F6D426F3C3A31AD /* UIViewController+Router.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D443C137311B04A61DCCCB5AA49D0337 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0527C56AC3D875371F2C95AA50DB05DB /* Pods-GMRouter_Example-dummy.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
39F89FABC110AD3EFF291980AD16559D /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "Pods-GMRouter_Example";
target = 4B36B03DEB212F49D4D7ED9BFCE5C831 /* Pods-GMRouter_Example */;
targetProxy = 07EF1C704D3F314444E4E0B433521E0A /* PBXContainerItemProxy */;
};
7CBFE35C998286B4464A68BE9EB86C82 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = GMRouter;
target = 75956ED72576558B6E846FD2A08311F6 /* GMRouter */;
targetProxy = A9005644F436F41BC3F356B6A1C835F4 /* PBXContainerItemProxy */;
};
8C69EB48F8AA67B298C87C0C4BFFACD1 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = MJExtension;
target = 4D3BA58D0583DF37575CACAB3DDADC85 /* MJExtension */;
targetProxy = D03E2F5B7FA39CAA2A8A3A097E9611FC /* PBXContainerItemProxy */;
};
EEB0ACBA7250F1C7A2515669F27AC6FD /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = MJExtension;
target = 4D3BA58D0583DF37575CACAB3DDADC85 /* MJExtension */;
targetProxy = 4DF65C341EBF3DAC05C6906DC1B03C97 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
2A21A5B11BF6C33368836BAEC8257D65 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = D052A7830930288BFD6D3207CED09506 /* Pods-GMRouter_Tests.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = "Target Support Files/Pods-GMRouter_Tests/Pods-GMRouter_Tests-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
MODULEMAP_FILE = "Target Support Files/Pods-GMRouter_Tests/Pods-GMRouter_Tests.modulemap";
OTHER_LDFLAGS = "";
OTHER_LIBTOOLFLAGS = "";
PODS_ROOT = "$(SRCROOT)";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
44AE331CB5CE7FFC4EC540ECEA6440A4 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9B63B9BE61CAA13EA3E4A6C62A8823DE /* MJExtension.xcconfig */;
buildSettings = {
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_PREFIX_HEADER = "Target Support Files/MJExtension/MJExtension-prefix.pch";
INFOPLIST_FILE = "Target Support Files/MJExtension/MJExtension-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MODULEMAP_FILE = "Target Support Files/MJExtension/MJExtension.modulemap";
PRODUCT_MODULE_NAME = MJExtension;
PRODUCT_NAME = MJExtension;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
4BE66A09A74FD25164AAB3C2645B9B93 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"POD_CONFIGURATION_RELEASE=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
STRIP_INSTALLED_PRODUCT = NO;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
SYMROOT = "${SRCROOT}/../build";
};
name = Release;
};
54A4A3DC6E90E6F8917211334D9AF689 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = D73D5257B1CBA064371CE13DE2B14EB5 /* Pods-GMRouter_Tests.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = "Target Support Files/Pods-GMRouter_Tests/Pods-GMRouter_Tests-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
MODULEMAP_FILE = "Target Support Files/Pods-GMRouter_Tests/Pods-GMRouter_Tests.modulemap";
OTHER_LDFLAGS = "";
OTHER_LIBTOOLFLAGS = "";
PODS_ROOT = "$(SRCROOT)";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
6090A93BF4B502CE20540B28D89D662C /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = B851DB4DC8EB267EFB7C4D404977444D /* GMRouter.xcconfig */;
buildSettings = {
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_PREFIX_HEADER = "Target Support Files/GMRouter/GMRouter-prefix.pch";
INFOPLIST_FILE = "Target Support Files/GMRouter/GMRouter-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MODULEMAP_FILE = "Target Support Files/GMRouter/GMRouter.modulemap";
PRODUCT_MODULE_NAME = GMRouter;
PRODUCT_NAME = GMRouter;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
7EF7227D9B20A1D549000096ACCB23D7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"POD_CONFIGURATION_DEBUG=1",
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
STRIP_INSTALLED_PRODUCT = NO;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
SYMROOT = "${SRCROOT}/../build";
};
name = Debug;
};
A3520C14AFF95DB46E07FB61B0D9EB5C /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9B63B9BE61CAA13EA3E4A6C62A8823DE /* MJExtension.xcconfig */;
buildSettings = {
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_PREFIX_HEADER = "Target Support Files/MJExtension/MJExtension-prefix.pch";
INFOPLIST_FILE = "Target Support Files/MJExtension/MJExtension-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MODULEMAP_FILE = "Target Support Files/MJExtension/MJExtension.modulemap";
PRODUCT_MODULE_NAME = MJExtension;
PRODUCT_NAME = MJExtension;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
C7A600A084F6580DC1801AF566E5BD79 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = CFAAB8C43015BCEB85A0C0ECF1A3CD4F /* Pods-GMRouter_Example.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = "Target Support Files/Pods-GMRouter_Example/Pods-GMRouter_Example-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
MODULEMAP_FILE = "Target Support Files/Pods-GMRouter_Example/Pods-GMRouter_Example.modulemap";
OTHER_LDFLAGS = "";
OTHER_LIBTOOLFLAGS = "";
PODS_ROOT = "$(SRCROOT)";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
C88E03A3E2962E878EEA29D5F5E66116 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 33ACD3930E0BC2F49FC4111CF4668169 /* Pods-GMRouter_Example.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = "Target Support Files/Pods-GMRouter_Example/Pods-GMRouter_Example-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
MODULEMAP_FILE = "Target Support Files/Pods-GMRouter_Example/Pods-GMRouter_Example.modulemap";
OTHER_LDFLAGS = "";
OTHER_LIBTOOLFLAGS = "";
PODS_ROOT = "$(SRCROOT)";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
D7AE3AF550933BB7728DDE35FAA60705 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = B851DB4DC8EB267EFB7C4D404977444D /* GMRouter.xcconfig */;
buildSettings = {
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_PREFIX_HEADER = "Target Support Files/GMRouter/GMRouter-prefix.pch";
INFOPLIST_FILE = "Target Support Files/GMRouter/GMRouter-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MODULEMAP_FILE = "Target Support Files/GMRouter/GMRouter.modulemap";
PRODUCT_MODULE_NAME = GMRouter;
PRODUCT_NAME = GMRouter;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
27E973FB214CB5EF8561F0CDC232FD40 /* Build configuration list for PBXNativeTarget "Pods-GMRouter_Tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
54A4A3DC6E90E6F8917211334D9AF689 /* Debug */,
2A21A5B11BF6C33368836BAEC8257D65 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
2BB69AB14DA1458D75C814C6D99138F2 /* Build configuration list for PBXNativeTarget "GMRouter" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D7AE3AF550933BB7728DDE35FAA60705 /* Debug */,
6090A93BF4B502CE20540B28D89D662C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
4099C8D6A094CC39E6BEBC8016626175 /* Build configuration list for PBXNativeTarget "Pods-GMRouter_Example" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C7A600A084F6580DC1801AF566E5BD79 /* Debug */,
C88E03A3E2962E878EEA29D5F5E66116 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7EF7227D9B20A1D549000096ACCB23D7 /* Debug */,
4BE66A09A74FD25164AAB3C2645B9B93 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
E9973E27B9A82A922588E42EA019A46F /* Build configuration list for PBXNativeTarget "MJExtension" */ = {
isa = XCConfigurationList;
buildConfigurations = (
44AE331CB5CE7FFC4EC540ECEA6440A4 /* Debug */,
A3520C14AFF95DB46E07FB61B0D9EB5C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */;
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.1.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
#import <Foundation/Foundation.h>
@interface PodsDummy_GMRouter : NSObject
@end
@implementation PodsDummy_GMRouter
@end
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
#import "GMRouter+gm.h"
#import "GMRouter.h"
#import "Target_commons.h"
#import "UIViewController+Router.h"
FOUNDATION_EXPORT double GMRouterVersionNumber;
FOUNDATION_EXPORT const unsigned char GMRouterVersionString[];
framework module GMRouter {
umbrella header "GMRouter-umbrella.h"
export *
module * { export * }
}
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/GMRouter
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>0.1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>3.2.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
#import <Foundation/Foundation.h>
@interface PodsDummy_MJExtension : NSObject
@end
@implementation PodsDummy_MJExtension
@end
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
#import "MJExtension.h"
#import "MJExtensionConst.h"
#import "MJFoundation.h"
#import "MJProperty.h"
#import "MJPropertyKey.h"
#import "MJPropertyType.h"
#import "NSObject+MJClass.h"
#import "NSObject+MJCoding.h"
#import "NSObject+MJKeyValue.h"
#import "NSObject+MJProperty.h"
#import "NSString+MJExtension.h"
FOUNDATION_EXPORT double MJExtensionVersionNumber;
FOUNDATION_EXPORT const unsigned char MJExtensionVersionString[];
framework module MJExtension {
umbrella header "MJExtension-umbrella.h"
export *
module * { export * }
}
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/MJExtension
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/MJExtension
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
# Acknowledgements
This application makes use of the following third party libraries:
## GMRouter
Copyright (c) 2019 Q14 <qiaojinzhu@igengmei.com>
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:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
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.
## MJExtension
Copyright (c) 2013-2019 MJExtension (https://github.com/CoderMJLee/MJExtension)
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:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
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.
Generated by CocoaPods - https://cocoapods.org
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>FooterText</key>
<string>This application makes use of the following third party libraries:</string>
<key>Title</key>
<string>Acknowledgements</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Copyright (c) 2019 Q14 &lt;qiaojinzhu@igengmei.com&gt;
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:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
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.
</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>GMRouter</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Copyright (c) 2013-2019 MJExtension (https://github.com/CoderMJLee/MJExtension)
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:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
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.
</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>MJExtension</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Generated by CocoaPods - https://cocoapods.org</string>
<key>Title</key>
<string></string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
</array>
<key>StringsTable</key>
<string>Acknowledgements</string>
<key>Title</key>
<string>Acknowledgements</string>
</dict>
</plist>
#import <Foundation/Foundation.h>
@interface PodsDummy_Pods_GMRouter_Example : NSObject
@end
@implementation PodsDummy_Pods_GMRouter_Example
@end
#!/bin/sh
set -e
set -u
set -o pipefail
function on_error {
echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
}
trap 'on_error $LINENO' ERR
if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
# If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
# frameworks to, so exit 0 (signalling the script phase was successful).
exit 0
fi
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
# Used as a return value for each invocation of `strip_invalid_archs` function.
STRIP_BINARY_RETVAL=0
# This protects against multiple targets copying the same framework dependency at the same time. The solution
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
# Copies and strips a vendored framework
install_framework()
{
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
local source="${BUILT_PRODUCTS_DIR}/$1"
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
elif [ -r "$1" ]; then
local source="$1"
fi
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -L "${source}" ]; then
echo "Symlinked..."
source="$(readlink "${source}")"
fi
# Use filter instead of exclude so missing patterns don't throw errors.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
local basename
basename="$(basename -s .framework "$1")"
binary="${destination}/${basename}.framework/${basename}"
if ! [ -r "$binary" ]; then
binary="${destination}/${basename}"
elif [ -L "${binary}" ]; then
echo "Destination binary is symlinked..."
dirname="$(dirname "${binary}")"
binary="${dirname}/$(readlink "${binary}")"
fi
# Strip invalid architectures so "fat" simulator / device frameworks work on device
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
strip_invalid_archs "$binary"
fi
# Resign the code if required by the build settings to avoid unstable apps
code_sign_if_enabled "${destination}/$(basename "$1")"
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
local swift_runtime_libs
swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u)
for lib in $swift_runtime_libs; do
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
code_sign_if_enabled "${destination}/${lib}"
done
fi
}
# Copies and strips a vendored dSYM
install_dsym() {
local source="$1"
if [ -r "$source" ]; then
# Copy the dSYM into a the targets temp dir.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
local basename
basename="$(basename -s .framework.dSYM "$source")"
binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}"
# Strip invalid architectures so "fat" simulator / device frameworks work on device
if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
strip_invalid_archs "$binary"
fi
if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
# Move the stripped file into its final destination.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
else
# The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM"
fi
fi
}
# Copies the bcsymbolmap files of a vendored framework
install_bcsymbolmap() {
local bcsymbolmap_path="$1"
local destination="${BUILT_PRODUCTS_DIR}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
}
# Signs a framework with the provided identity
code_sign_if_enabled() {
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
# Use the current code_sign_identity
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
code_sign_cmd="$code_sign_cmd &"
fi
echo "$code_sign_cmd"
eval "$code_sign_cmd"
fi
}
# Strip invalid architectures
strip_invalid_archs() {
binary="$1"
# Get architectures for current target binary
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
# Intersect them with the architectures we are building for
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
# If there are no archs supported by this binary then warn the user
if [[ -z "$intersected_archs" ]]; then
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
STRIP_BINARY_RETVAL=0
return
fi
stripped=""
for arch in $binary_archs; do
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary"
stripped="$stripped $arch"
fi
done
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
STRIP_BINARY_RETVAL=1
}
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/GMRouter/GMRouter.framework"
install_framework "${BUILT_PRODUCTS_DIR}/MJExtension/MJExtension.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/GMRouter/GMRouter.framework"
install_framework "${BUILT_PRODUCTS_DIR}/MJExtension/MJExtension.framework"
fi
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
fi
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double Pods_GMRouter_ExampleVersionNumber;
FOUNDATION_EXPORT const unsigned char Pods_GMRouter_ExampleVersionString[];
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GMRouter" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GMRouter/GMRouter.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension/MJExtension.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_LDFLAGS = $(inherited) -framework "GMRouter" -framework "MJExtension"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
framework module Pods_GMRouter_Example {
umbrella header "Pods-GMRouter_Example-umbrella.h"
export *
module * { export * }
}
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GMRouter" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GMRouter/GMRouter.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension/MJExtension.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_LDFLAGS = $(inherited) -framework "GMRouter" -framework "MJExtension"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
# Acknowledgements
This application makes use of the following third party libraries:
Generated by CocoaPods - https://cocoapods.org
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>FooterText</key>
<string>This application makes use of the following third party libraries:</string>
<key>Title</key>
<string>Acknowledgements</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Generated by CocoaPods - https://cocoapods.org</string>
<key>Title</key>
<string></string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
</array>
<key>StringsTable</key>
<string>Acknowledgements</string>
<key>Title</key>
<string>Acknowledgements</string>
</dict>
</plist>
#import <Foundation/Foundation.h>
@interface PodsDummy_Pods_GMRouter_Tests : NSObject
@end
@implementation PodsDummy_Pods_GMRouter_Tests
@end
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double Pods_GMRouter_TestsVersionNumber;
FOUNDATION_EXPORT const unsigned char Pods_GMRouter_TestsVersionString[];
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GMRouter" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GMRouter/GMRouter.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension/MJExtension.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "GMRouter" -framework "MJExtension"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
framework module Pods_GMRouter_Tests {
umbrella header "Pods-GMRouter_Tests-umbrella.h"
export *
module * { export * }
}
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GMRouter" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GMRouter/GMRouter.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension/MJExtension.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "GMRouter" -framework "MJExtension"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
......@@ -37,6 +37,7 @@ TODO: Add long description of the pod here.
# }
s.dependency 'MJExtension'
s.dependency 'GMPhobos'
# s.public_header_files = 'Pod/Classes/**/*.h'
# s.frameworks = 'UIKit', 'MapKit'
# s.dependency 'AFNetworking', '~> 2.3'
......
......@@ -6,6 +6,7 @@
//
#import "GMRouter+gm.h"
#import <GMPhobos/GMPhobos-umbrella.h>
#import <objc/message.h>
#import <objc/runtime.h>
......@@ -134,8 +135,30 @@ static NSMutableDictionary *routeMap = nil;
NSString *host = url.host;
NSString *targetName = [routeMap objectForKey:host];
NSDictionary *params = [self getParams:encodeUrlScheme withHost:host];
host = [self getHostWithEncodeUrlScheme:encodeUrlScheme host:host];
return [self performTarget:targetName action:host params:params shouldCacheTarget:NO];
id vc = [self performTarget:targetName action:host params:params shouldCacheTarget:NO];
if ([vc isKindOfClass:[UIViewController class]]) {
//#ifdef DEBUG
// 测试代码
// NSMutableDictionary *muDict = [NSMutableDictionary dictionaryWithDictionary:params];
// muDict[@"ispush"] = @"1";
// [self vcAutoIsPushWith:vc params:muDict];
//#else
[self vcAutoIsPushWith:vc params:params];
//#endif
}
return vc;
}
- (void)vcAutoIsPushWith:(UIViewController *)vc params:(NSDictionary *)params {
if (vc != nil && ([params.allKeys containsObject:@"ispush"])) {
// 区分是否是推送,指定页面:日记本详情页、讨论帖、问答详情页、回答详情页
// 不支持third_webview和common_webview
vc.isPush = params[@"ispush"];
} else if (vc != nil && [params[@"url"] containsString:@"ispush=1"]) { // 推送的更美协议为conmon_webView的时候 添加ispush埋点参数
vc.isPush = @"1";
}
}
- (NSDictionary *)getParams:(NSString *)encodeUrlScheme withHost:(NSString *)host {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment