JEToolkit
JEToolkit为一组用于iOS开发的省时宝贝。
(我在生产代码中使用这个库,因此此仓库是活跃维护的。)
现在支持Swift 2.0!
- 为一些在Swift代码中也很有意义的方法/宏(Objective-C)添加了Swift函数版本。
- 所有内容都已审核nullability(可空、不可空等)。
- 仅Objective-C项目的项目也将从所有可用功能中受益!
模块摘要
JEToolkit/JEToolkit
:提供有用的类别、函数和宏,以提供安全性、便捷性和可读性。JEToolkit/JEDebugging
:一个性能良好、可配置的调试框架,可以将输出输送到调试控制台、应用程序内控制台视图和/或日志文件。JEToolkit/JESettings
:用于封装NSUserDefaults
和密钥链访问的类封装器。通过仅声明属性即可访问键值。JEToolkit/JEOrderedDictionary
:一个NSMutableDictionary
子类,可以记住插入键的顺序。如果您想维护按时间顺序或键的固定顺序的信息,这很有用。JEToolkit/JEWeakCache
:一个线程安全的缓存机制,类似于NSCache
。不同之处在于JEWeakCache
只保留对象的弱引用,即它只保留那些没有任何其他引用的对象的引用。
可以独立使用每个子模块(通过 cocoapods)或将所有内容作为一个整体包链接!
JEToolkit/JEToolkit
JEToolkit
模块包含一些一旦开始使用,编程中就离不开的工具。它们非常有用!
NSNotification
(Objective-C 和 Swift)
更安全地处理 厌烦了在 dealloc
中编写对应的 [NSNotificationCenter removeObserver:self]
吗?现在您可以为 NSNotificationCenter
添加观察者,这些观察者会在析构时自动注销。以下是一个使用示例
// Obj-C
[self registerForNotificationsWithName:UIApplicationDidEnterBackgroundNotification
targetBlock:^(NSNotification *note) {
// do something...
}];
// Swift
self.registerForNotificationsWithName(UIApplicationDidEnterBackgroundNotification) { (note) in
// do something...
}
还有其他可以让您传递其他参数(如 object
、targetQueue
)的变体!
为类别添加属性(仅限 Objective-C)
Objective-C 通常不允许在类别中声明 @properties
。通过声明适当的访问器(getter)和设置器(setter)方法,JESynthesize()
宏让您可以精确地做到这一点,具体取决于您设置的数据类型和访问修饰符(如 assign
、strong
等)。作为关联对象的扩展,JESynthesize
也支持 weak
(!!)。
- 提供类别中属性的声明的一行代码
- 支持所有访问修饰符(包括
assign
、strong
等),包括weak
! - 因为方法是在编译时生成的,所以您可以完全不声明任何
@property
's。 - 编译时错误检查,以防止访问修饰符和数据类型不匹配(例如,不允许对
CGRect
类型设置strong
)
// Obj-C
@implementation // ...
JESynthesize(assign, CGRect, frame, setFrame);
JESynthesize(strong, NSString *, name, setName);
JESynthesize(copy, void(^)(void), completion, setCompletion);
JESynthesize(unsafe_unretained, id, unsafeObject, setUnsafeObject);
JESynthesize(weak, id<UITableViewDelegate>, delegate, setDelegate);
JESynthesize(strong, NSString *, readonlyID, changeReadonlyID);
// ...
断言本地化字符串(Objective-C 和 Swift)
JEL10n()
函数是NSLocalizedString()
的替代品,它会在运行时断言在.strings文件中存在一个本地化(l10n)字符串。
// Obj-C
label.text = JEL10n(@"myviewcontroller.label.title"); // load from Localizable.strings
label.text = JEL10nFromTable(@"CustomStrings", @"myviewcontroller.label.title"); // load from CustomStrings.strings
// Swift
label.text = JEL10n("myviewcontroller.label.title") // load from Localizable.strings
label.text = JEL10nFromTable("CustomStrings", "myviewcontroller.label.title") // load from CustomStrings.strings
在Objective-C中KVC键的编译时检查
JEKeypath(...)
宏在编译时返回并检查KVC(或KVO)键路径的存在。对于KVC运算符,您还可以使用JEKeypathOperator(...)
变体。如果键路径不存在,编译将失败。
// Obj-C
[obj setValue:@"John" forKey:JEKeypath(Person *, name)];
[obj setValue:@"John" forKey:JEKeypath(typeof(self), name)]; // typeof() operator
[obj setValue:@"John" forKey:JEKeypath(Person *, friend.name)]; // dot notation
NSArray *names = [friends valueForKeypath:JEKeypathOperator(unionOfObjects, Person *, name)];
重构属性名称再也不可怕了!
优雅地处理弱-强块捕获(Objective-C仅限)
厌倦了写weakSelf
、strongSelf
、weakSomething
、strongSomething
等等?使用JEScopeWeak()
和JEScopeStrong()
,你可以这样做
// Obj-C
typeof(self) __weak weakSelf = self;
[request downloadSomethingWithCompletion:^{
typeof(self) __strong strongSelf = weakSelf;
[strongSelf doSomethingElse];
}];
变成这样
// Obj-C
JEScopeWeak(self);
[request downloadSomethingWithCompletion:^{
JEScopeStrong(self);
[self doSomethingElse];
}];
打破保留循环,不使代码杂乱无章!
为scrollviews自动处理键盘事件(Objective-C和Swift)
UIScrollView
类别允许自动处理键盘事件,包括自动滚动到子视图的firstResponder
。您只需以这种方式设置scrollViews(或更常见地,表格视图):
// Obj-C
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.scrollView addKeyboardObserver];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.scrollView removeKeyboardObserver];
}
// Swift
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.scrollView.addKeyboardObserver()
}
override func viewWillDisappea(animated: Bool) {
super.viewWillDisappear(animated)
self.scrollView.removeKeyboardObserver()
}
还有更多!
NSCache
类似于NSDictionary
的索引支持NSDate
、NSNumber
、NSString
和NSDate
的实用工具,用于在已知数据类型之间转换NSURL
API用于获取和设置扩展属性UIColor
从RGB或hex值创建UILabel
和UITextView
实用工具,用于计算显示字符串的大小和高度UITableView
和UICollectionView
实用工具,用于类型安全地分列单元格- 以及,仍然还有很多!
JEToolkit/JEDebugging
JEDebugging
模块是一个日志框架,将有助于您和您的团队(包括服务器人员以及测试人员!)
主要特性
- 提供清晰、易读的日志。日志消息具有缩进并带有特定日志级别的标记。此代码
// Obj-C
JELog(@"This is a sample log");
JELogNotice(@"This is a notice-level log");
JELogAlert(@"This is an alert-level log");
JEAssert(100 > 900, @"This is an assert failure log");
// Swift
JELog("This is a sample log")
JELogNotice("This is a notice-level log")
JELogAlert("This is an alert-level log")
JEAssert(100 > 900, "This is an assert failure log")
- 更丰富的
debugDescription
为常见的 NSFoundation 对象。例如,使用 lldb 的po
命令检查字典时,也会显示键和值的类型(注意,NSNumber
显示存储值的实际数据类型) - 令人惊叹的
JEDump(...)
宏可以让你检查和记录抛给它的任何内容:整数、C 数组、结构体、对象、块等。查看 JEToolkitTests 单元测试或 JEToolkitDemo 项目以查看更多示例输出和示例用法。 - 所有日志都是线程安全的。
- 可选将日志保存到文件。日志文件按日期分开,并提供 API 以枚举日志的
NSData
或NSURL
。 - 可选在应用程序内部显示轻量级、内联 HUD 控制台。
默认情况下,在发布模式下不会创建此视图。您可以使用可拖动按钮展开/折叠 HUD,并且可以调整视图的大小。HUD 也始终位于所有其他视图/窗口的顶部,即使在打开模态视图或创建自己的窗口时也是如此。还有一个按钮可以通过UIActivityViewController
发送日志文件(Air-Drop 真是个好东西!),以及一个按钮清除所有显示的日志。 - 为控制台日志记录器、文件日志记录器和 HUD 日志记录器提供可配置的设置。
JEToolkit/JESettings
JESettings
模块提供了管理 NSUserDefaults
和密钥链数据的酷基类,以及对象模型。要创建此类模型,请从 JEUserDefaults
或 JEKeychain
继承,并将要管理的数据声明为动态属性(Objective-C 中的 @dynamic
,Swift 中的 @NSManaged
)
// Obj-C
// .h
@interface MyUserDefaults: JEUserDefaults
@property (nonatomic, strong) NSString *myString;
@property (nonatomic, assign) NSInteger myNumber;
@end
// .m
@implementation MyUserDefaults
@dynamic myString;
@dynamic myNumber;
@end
// Swift
class MyUserDefaults: JEUserDefaults {
@NSManaged var myString: String?
@NSManaged var myNumber: Int
}
一旦设置了模型类,就可以立即开始使用。以下代码
// Obj-C
MyUserDefaults *defaults = [MyUserDefaults new];
defaults.myString = @"sample string";
defaults.myNumber = 42;
// Swift
let defaults = MyUserDefaults()
defaults.myString = "sample string"
defaults.myNumber = 42
将这些值保存到 NSUserDefaults
"MyUserDefaults.myString" = "sample string"
"MyUserDefaults.myNumber" = 42
这不是很酷吗?
主要功能
- 支持以下类型的所有动态属性
- Objective-C
- 所有原始整型(《short`,《int`,《NSInteger`,《NSUInteger`,《long long int`,《unsigned long long int`等)
- 所有原始布尔类型(《bool`,《BOOL`)
- 所有原始浮点类型(《float`,《double`,《CGFloat`)
NSString *
NSNumber *
NSDate *
NSData *
NSURL *
NSUUID *
id<NSCoding>
(基本上,任何遵从NSCoding
协议的实体)类
SEL
CGPoint
CGSize
CGRect
CGAffineTransform
CGVector
UIEdgeInsets
UIOffset
NSRange
- Swift
- 支持上述Objective-C的所有类型
- 所有可桥接到
NSString
的字符串类型(《NSString?,《String》,《String?) - 所有可桥接到
NSNumber
的数字类型(《NSNumber?,《Int》,《Int32》,《UInt8》,《Double》,《CGFloat》等)
- Objective-C
- 默认情况下,
JEUserDefaults
使用格式为"<class name>.<property name>"
的字符串键,但您也可以通过重写-[JEUserDefaults userDefaultsKeyForProperty:]
来配置自己的格式。 JEUserDefaults
实例以单身形式创建,每个类和suiteName
独特。有关详情,请参阅-[JEUserDefaults init]
和-[JEUserDefaults initWithSuiteName:]
的头文件文档。- 通过使用
proxyForDefaultValues
方法获取代理实例,JEUserDefaults
还允许您为在NSUserDefaults
中不存在的键设置默认值。
// Obj-C
MyUserDefaults *defaults = [MyUserDefaults new];
MyUserDefaults *fallback = [defaults proxyForDefaultValues];
fallback.myString = @"sample string";
defaults.myString = nil;
NSString *value = defaults.myString; // value is now "sample string"
// Swift
let defaults = MyUserDefaults()
let fallback = defaults.proxyForDefaultValues()
fallback.myString = "sample string"
defaults.myString = nil
let value = defaults.myString // value is now "sample string"
内部操作仅为-[NSUserDefaults registerUserDefaults:]
保存默认值;()
- 默认情况下,
JEKeychain
使用应用程序包标识符作为kSecAttrService
,但您可以向-[JEKeychain initWithService:accessGroup:]
传递首选服务名称。 - 默认情况下,
JEKeychain
使用属性名称作为kSecAttrAccount
,您也可以通过重写-[JEKeychain keychainAccountForProperty:]
来配置自己的格式。 JEKeychain
允许通过重写-[JEKeychain keychainAccessForProperty:]
为每个属性设置访问模式(例如JEKeychainAccessAfterFirstUnlock
等)。- 如果项目包含
JEDebugging
模块,则使用lldb'spo
命令打印JEUserDefaults
和JEKeychain
实例将打印所有保存的键和值。
安装
- 需要iOS 7 SDK及其以上版本
- 需要ARC
通过CocoaPods安装
在您的Podfile
中添加以下内容
pod 'JEToolkit'
然后运行 pod install
通过Carthage安装
在你的 Cartfile
中添加:
github "JohnEstropia/JEToolkit"
然后运行 carthage update
手动安装
建议以Git子模块的方式手动安装。
git submodule add https://github.com/JohnEstropia/JEToolkit.git <destination directory>
你也可以将仓库独立地克隆到app的.xcodeproj目录下,然后拖动并放置JEToolkit.xcodeproj到你的app项目中。
贡献?
欢迎报告任何问题或提出建议!也欢迎用日语联系!
许可协议
JEToolkit采用MIT许可协议发布。有关更多信息,请参见LICENSE文件。