Commit 924d6776 authored by jz's avatar jz

add files

parent 6a87e28b
This diff is collapsed.
<?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>PreviewsEnabled</key>
<false/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="u7L-eo-lZa">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="whP-gf-Uak">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15510"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
......@@ -20,27 +22,10 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<navigationItem key="navigationItem" id="p8W-46-Cyu"/>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="tc2-Qw-aMS" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="708" y="431"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="qRv-n3-5Rw">
<objects>
<navigationController id="u7L-eo-lZa" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="YtA-dW-IL4">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
<segue destination="whP-gf-Uak" kind="relationship" relationship="rootViewController" id="6WD-Sx-WDw"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="QVQ-VH-Kf2" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-124" y="447"/>
<point key="canvasLocation" x="305" y="433"/>
</scene>
</scenes>
</document>
......@@ -2,8 +2,8 @@
// GMAppDelegate.h
// GMRouter
//
// Created by jz on 11/28/2019.
// Copyright (c) 2019 jz. All rights reserved.
// Created by Q14 on 12/10/2019.
// Copyright (c) 2019 Q14. All rights reserved.
//
@import UIKit;
......
......@@ -2,8 +2,8 @@
// GMAppDelegate.m
// GMRouter
//
// Created by jz on 11/28/2019.
// Copyright (c) 2019 jz. All rights reserved.
// Created by Q14 on 12/10/2019.
// Copyright (c) 2019 Q14. All rights reserved.
//
#import "GMAppDelegate.h"
......
//
// GMTestViewController.h
// GMRouter_Example
//
// Created by Q14 on 2019/11/28.
// Copyright © 2019 jz. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface GMTestViewController : UIViewController
@end
NS_ASSUME_NONNULL_END
//
// GMTestViewController.m
// GMRouter_Example
//
// Created by Q14 on 2019/11/28.
// Copyright © 2019 jz. All rights reserved.
//
#import "GMTestViewController.h"
@interface GMTestViewController ()
@end
@implementation GMTestViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
......@@ -2,8 +2,8 @@
// GMViewController.h
// GMRouter
//
// Created by jz on 11/28/2019.
// Copyright (c) 2019 jz. All rights reserved.
// Created by Q14 on 12/10/2019.
// Copyright (c) 2019 Q14. All rights reserved.
//
@import UIKit;
......
......@@ -2,14 +2,12 @@
// GMViewController.m
// GMRouter
//
// Created by jz on 11/28/2019.
// Copyright (c) 2019 jz. All rights reserved.
// Created by Q14 on 12/10/2019.
// Copyright (c) 2019 Q14. All rights reserved.
//
#import "GMViewController.h"
#import <GMRouter/GMRouter-umbrella.h>
//@import GMRouter;
@interface GMViewController ()
@end
......@@ -20,19 +18,6 @@
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setBackgroundColor:UIColor.redColor];
[btn addTarget:self action:@selector(clickBtn) forControlEvents:UIControlEventTouchUpInside];
btn.frame = CGRectMake(0, 100, 100, 30);
[self.view addSubview:btn];
}
- (void)clickBtn {
// Target_commons *target = [[Target_commons alloc] init];
// [target push_CommonViewController:@"GMTestViewController" params:@{}];
UIViewController *vc = [[GMRouter sharedInstance] performAction:@"GMTestViewController" params:@{} shouldCacheTarget:YES];
[self.navigationController pushViewController:vc animated:YES];
}
- (void)didReceiveMemoryWarning
......
......@@ -2,8 +2,8 @@
// main.m
// GMRouter
//
// Created by jz on 11/28/2019.
// Copyright (c) 2019 jz. All rights reserved.
// Created by Q14 on 12/10/2019.
// Copyright (c) 2019 Q14. All rights reserved.
//
@import UIKit;
......
PODS:
- GMRouter (0.1.0)
- GMRouter (0.1.0):
- MJExtension
- MJExtension (3.2.1)
DEPENDENCIES:
- GMRouter (from `../`)
SPEC REPOS:
https://github.com/cocoapods/specs.git:
- MJExtension
EXTERNAL SOURCES:
GMRouter:
:path: "../"
SPEC CHECKSUMS:
GMRouter: 649720313dfcbadcc7cdbd8834896da8f59a7f96
GMRouter: d47a2a7690eea791e26374cb3c616667124aa1d8
MJExtension: 635f2c663dcb1bf76fa4b715b2570a5710aec545
PODFILE CHECKSUM: bcbc555b81a3b21a917383786de0d49ebef33013
......
......@@ -3,20 +3,30 @@
"version": "0.1.0",
"summary": "A short description of GMRouter.",
"description": "TODO: Add long description of the pod here.",
"homepage": "http://git.wanmeizhensuo.com/gengmeiios/GMRouter.git",
"homepage": "https://github.com/Q14/GMRouter",
"license": {
"type": "MIT",
"file": "LICENSE"
},
"authors": {
"jz": "qiaojinzhu@igengmei.com"
"Q14": "qiaojinzhu@igengmei.com"
},
"source": {
"git": "git@git.wanmeizhensuo.com:gengmeiios/GMRouter.git",
"git": "https://github.com/Q14/GMRouter.git",
"tag": "0.1.0"
},
"platforms": {
"ios": "8.0"
},
"source_files": "GMRouter/Classes/**/*"
"source_files": "GMRouter/Classes/**/*",
"resource_bundles": {
"GMRouter": [
"GMRouter/Assets/*"
]
},
"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
This diff is collapsed.
//
// 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
This diff is collapsed.
PODS:
- GMRouter (0.1.0)
- GMRouter (0.1.0):
- MJExtension
- MJExtension (3.2.1)
DEPENDENCIES:
- GMRouter (from `../`)
SPEC REPOS:
https://github.com/cocoapods/specs.git:
- MJExtension
EXTERNAL SOURCES:
GMRouter:
:path: "../"
SPEC CHECKSUMS:
GMRouter: 649720313dfcbadcc7cdbd8834896da8f59a7f96
GMRouter: d47a2a7690eea791e26374cb3c616667124aa1d8
MJExtension: 635f2c663dcb1bf76fa4b715b2570a5710aec545
PODFILE CHECKSUM: bcbc555b81a3b21a917383786de0d49ebef33013
......
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
<?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>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
......@@ -12,6 +12,7 @@
#import "GMRouter+gm.h"
#import "GMRouter.h"
#import "NSObject+gmKey.h"
#import "Target_commons.h"
#import "UIViewController+Router.h"
......
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)
......
<?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
......@@ -3,7 +3,30 @@ This application makes use of the following third party libraries:
## GMRouter
Copyright (c) 2019 jz <qiaojinzhu@igengmei.com>
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
......
......@@ -14,7 +14,7 @@
</dict>
<dict>
<key>FooterText</key>
<string>Copyright (c) 2019 jz &lt;qiaojinzhu@igengmei.com&gt;
<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
......@@ -41,6 +41,35 @@ THE SOFTWARE.
<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>
......
......@@ -162,9 +162,11 @@ strip_invalid_archs() {
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
......
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GMRouter"
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"
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"
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}/.
......
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GMRouter"
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"
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"
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}/.
......
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GMRouter"
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"
OTHER_LDFLAGS = $(inherited) -framework "GMRouter"
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}/.
......
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GMRouter"
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"
OTHER_LDFLAGS = $(inherited) -framework "GMRouter"
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}/.
......
......@@ -2,8 +2,8 @@
// GMRouterTests.m
// GMRouterTests
//
// Created by jz on 11/28/2019.
// Copyright (c) 2019 jz. All rights reserved.
// Created by Q14 on 12/10/2019.
// Copyright (c) 2019 Q14. All rights reserved.
//
@import XCTest;
......
......@@ -8,7 +8,7 @@
Pod::Spec.new do |s|
s.name = 'GMRouter'
s.version = '0.0.2'
s.version = '0.1.0'
s.summary = 'A short description of GMRouter.'
# This description is used to generate tags and improve search results.
......@@ -21,21 +21,22 @@ Pod::Spec.new do |s|
TODO: Add long description of the pod here.
DESC
s.homepage = 'http://git.wanmeizhensuo.com/gengmeiios/GMRouter.git'
s.homepage = 'https://github.com/Q14/GMRouter'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'jz' => 'qiaojinzhu@igengmei.com' }
s.source = { :git => 'git@git.wanmeizhensuo.com:gengmeiios/GMRouter.git', :tag => s.version.to_s }
s.author = { 'Q14' => 'qiaojinzhu@igengmei.com' }
s.source = { :git => 'https://github.com/Q14/GMRouter.git', :tag => s.version.to_s }
# s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
s.ios.deployment_target = '8.0'
s.source_files = 'GMRouter/Classes/**/*'
# s.resource_bundles = {
# 'GMRouter' => ['GMRouter/Assets/*.png']
# }
s.resource_bundles = {
'GMRouter' => ['GMRouter/Assets/*']
}
s.dependency 'MJExtension'
# s.public_header_files = 'Pod/Classes/**/*.h'
# s.frameworks = 'UIKit', 'MapKit'
# s.dependency 'AFNetworking', '~> 2.3'
......
Copyright (c) 2019 jz <qiaojinzhu@igengmei.com>
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
......
# GMRouter
[![CI Status](https://img.shields.io/travis/jz/GMRouter.svg?style=flat)](https://travis-ci.org/jz/GMRouter)
[![CI Status](https://img.shields.io/travis/Q14/GMRouter.svg?style=flat)](https://travis-ci.org/Q14/GMRouter)
[![Version](https://img.shields.io/cocoapods/v/GMRouter.svg?style=flat)](https://cocoapods.org/pods/GMRouter)
[![License](https://img.shields.io/cocoapods/l/GMRouter.svg?style=flat)](https://cocoapods.org/pods/GMRouter)
[![Platform](https://img.shields.io/cocoapods/p/GMRouter.svg?style=flat)](https://cocoapods.org/pods/GMRouter)
......@@ -22,7 +22,7 @@ pod 'GMRouter'
## Author
jz, qiaojinzhu@igengmei.com
Q14, qiaojinzhu@igengmei.com
## License
......
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