KSReason 1.6.1

KSReason 1.6.1

测试测试中
语言语言 Obj-CObjective C
授权协议 MIT
发布日期最后发布日期2015年9月

维护者:Kevin Sylvestre.



KSReason 1.6.1

  • 作者:
  • Kevin Sylvestre

Reason

使用方法

要运行示例项目,先从仓库中克隆,然后从 Example 目录运行 pod install

安装

KSReason 通过 CocoaPods 提供。要安装它,请在您的 Podfile 添加以下行

pod "KSReason"

使用方法

Backbone

Backbone 是一个组件,用于实现模型和集合(受同名网络框架的启发)。

模型

模型 可扩展,包括序列化、验证、获取器、设置器、存档和复制功能

KSModel *model = [KSModel new];
[model parse:@{ @"id": @"...", @"title": @"...", @"description": @"..." }];
[model get:@"title"];
[model get:@"description"];

集合

集合 是有序的模型组,包括序列化、枚举、存档和复制功能

KSCollection *collection = [KSCollection new];
[collection parse:@[@{ @"id": @"...", @"title": @"...", @"description": @"..." }]];
collection.models;

事件

事件 可以应用于模型和集合,以便轻松跟踪修改

KSModel *model = [KSModel new];

void (^callback)(KSModel *) = ^(KSModel *model) {
  // ...
};

[model on:@"change" callback:callback];
[model parse:@{ @"id": @"...", @"title": @"...", @"description": @"..." }];
[model off:@"change" callback:callback];
KSCollection *collection = [KSCollection new];

void (^callback)(KSCollection *) = ^(KSCollection *collection) {
  // ...
};

[collection on:@"reset" callback:callback];
[model parse:@[@{ @"id": @"...", @"title": @"...", @"description": @"..." }]];
[collection off:@"reset" callback:callback];

有状态

有状态 是一个组件,用于实现有限状态机。它支持状态、转换、守卫和回调。

配置

配置 有限状态机是通过配置状态、转换、守卫和回调来完成的

__block typeof(self) bself = self;

KSFSM *fsm = [KSFSM new];

// States:

KSState *sleeping = [KSState named:@"sleeping"];
KSState *working = [KSState named:@"working"];
KSState *resting = [KSState named:@"resting"];
KSState *dead = [KSState named:@"dead"];

[fsm.states add:sleeping];
[fsm.states add:working];
[fsm.states add:resting];
[fsm.states add:dead];

fsm.states.initial = resting;

// Transitions:

[fsm.transitions add:[KSTransition named:@"work" from:sleeping to:working]];
[fsm.transitions add:[KSTransition named:@"rest" from:sleeping to:resting]];
[fsm.transitions add:[KSTransition named:@"sleep" from:@[working,resting] to:sleeping]];
[fsm.transitions add:[KSTransition named:@"sleep" from:@[sleeping,working,resting] to:dead]];

// Guards:

[work enterable:^BOOL {
  // i.e. return bself.weekday;
}];

[rest enterable:^BOOL {
  // i.e. return bself.weekend;
}];

[sleep exitable:^BOOL {
  // i.e. return bself.daytime;
}];

// Callbacks:

[sleeping entered:^(KSState *state, KSTransition *transition) {
  // i.e. ZZZ ZZZ ZZZ
}];

[sleeping exited:^(KSState *state, KSTransition *transition) {
  // i.e. BEEP BEEP BEEP
}];

使用方法

使用方法 是通过执行转换并检查错误来使用有状态对象的

NSError *error;
[fsm reset]; // Optional.

[fsm transition:@"work" error:&error].execute;
fsm.state; // working;

[fsm transition:@"sleep" error:&error].execute;
fsm.state; // sleeping;

[fsm transition:@"rest" error:&error].execute;
fsm.state; // resting;

[fsm transition:@"sleep" error:&error].execute;
fsm.state; // sleeping;

[fsm transitionable:@"sleep"]; // i.e. YES or NO

if (![fsm transition:@"sleep" error:&error].execute);
  error; // <NSError @"invalid transition 'sleep' from 'sleeping' to 'sleeping">;

可枚举

可枚举 为数组和字典提供了许多扩展,以支持更好的枚举

每个

每个 对集合的每个条目执行一次代码块

集合

NSSet *collection = [NSSet setWithObjects:@"Canada", @"Greece", @"Russia", NULL];
[collection ks_each:^(NSString *object) {
  // ...
}];

数组

NSArray *collection = [NSArray arrayWithObjects;@"Canada", @"Greece", @"Russia", NULL];
[collection ks_each:^(NSString *object) {
  // ...
}];

字典

NSDictionary *collection = @{ @"Canada": @"Victoria", @"Russia": @"Moscow", @"Greece": @"Athens" };
[collection ks_each:^(NSString *key, NSString *value) {
  // ...
}];

映射

映射 在集合的每个元素上执行一次代码块,并返回一个同一类型的包含代码块结果的集合

集合

NSSet *collection = [NSSet setWithObjects:@"Canada", @"Greece", @"Russia", NULL];
NSSet *mapping = [collection ks_map:^NSString *(NSString *object) {
  // ex: NSString *mapping = [object reverse];
  return mapping;
}];

数组

NSArray *collection = [NSArray arrayWithObjects;@"Canada", @"Greece", @"Russia", NULL];
NSArray *mapping = [collection ks_map:^NSString *(NSString *object) {
  // ex: NSString *mapping = [object reverse];
  return mapping;
}];

字典

NSDictionary *collection = @{ @"Canada": @"Victoria", @"Russia": @"Moscow", @"Greece": @"Athens" };
NSDictionary *mapping = [collection ks_map:^NSString *(NSString *key, NSString *value) {
  // ex: NSString *mapping = [value reverse];
  return mapping;
}];

归约

Reduce 对集合中的每个元素执行一次操作,并在遍历过程中返回备忘录

集合

NSSet *collection = [NSSet setWithObjects:@"Canada", @"Greece", @"Russia", NULL];
NSString *reduction = [collection ks_reduce:^NSString *(NSString *memo, NSString *object){
  return [NSString stringWithFormat:@"%@ %@", memo, object];
} memo:@"reduction:"];

数组

NSArray *collection = [NSArray arrayWithObjects;@"Canada", @"Greece", @"Russia", NULL];
NSString *reduction = [collection ks_reduce:^NSString *(NSString *memo, NSString *object){
  return [NSString stringWithFormat:@"%@ %@", memo, object];
} memo:@"reduction:"];

字典

NSArray *collection = [NSArray arrayWithObjects;@"Canada", @"Greece", @"Russia", NULL];
NSString *reduction = [collection ks_reduce:^NSString *(NSString *memo, NSString *key, NSString *value){
  return [NSString stringWithFormat:@"%@ %@", memo, value];
} memo:@"reduction:"];

查找

查找 遍历集合中的每个元素,并返回符合条件的那一个元素

集合

NSSet *collection = [NSSet setWithObjects:@"Canada", @"Greece", @"Russia", NULL];
NSString *element = [collection ks_find:^BOOL (NSString *object) {
  return [object isEqualToString:@"..."];
}];

数组

NSArray *collection = [NSArray arrayWithObjects:@"Canada", @"Greece", @"Russia", NULL];
NSString *element = [collection ks_find:^BOOL (NSString *object) {
  return [object isEqualToString:@"..."];
}];

字典

NSDictionary *collection = @{ @"Canada" : @"Victoria", @"Greece": @"Athens", @"Russia": @"Moscow" };
NSString *element = [collection ks_find:^BOOL (NSString *key, NSString *value) {
  return [key isEqualToString:@"..."];
}];

任意元素

任意元素 将集合中的每个元素传递给指定的操作块,并返回一个布尔值,表示操作块是否匹配任何元素

集合

NSSet *collection = [NSSet setWithObjects:@"Canada", @"Greece", @"Russia", NULL];
BOOL any = [collection ks_any:^BOOL (NSString *object) {
  return [object isEqualToString:@"..."];
}];

数组

NSArray *collection = [NSArray arrayWithObjects:@"Canada", @"Greece", @"Russia", NULL];
BOOL any = [collection ks_any:^BOOL (NSString *object) {
  return [object isEqualToString:@"..."];
}];

字典

NSDictionary *collection = @{ @"Canada" : @"Victoria", @"Greece": @"Athens", @"Russia": @"Moscow" };
BOOL any = [collection ks_any:^BOOL (NSString *key, NSString *value) {
  return [key isEqualToString:@"..."];
}];

所有元素

所有元素 将集合中的每个元素传递给指定的操作块,并返回一个布尔值,表示操作块是否一直匹配每一个元素

集合

NSSet *collection = [NSSet setWithObjects:@"Canada", @"Greece", @"Russia", NULL];
BOOL all = [collection ks_all:^BOOL (NSString *object) {
  return [object isEqualToString:@"..."];
}];

数组

NSArray *collection = [NSArray arrayWithObjects:@"Canada", @"Greece", @"Russia", NULL];
BOOL all = [collection ks_all:^BOOL (NSString *object) {
  return [object isEqualToString:@"..."];
}];

字典

NSDictionary *collection = @{ @"Canada" : @"Victoria", @"Greece": @"Athens", @"Russia": @"Moscow" };
BOOL all = [collection ks_all:^BOOL (NSString *key, NSString *value) {
  return [key isEqualToString:@"..."];
}];

过滤

过滤 将集合中的每个元素传递给指定的操作块,并返回匹配操作块过滤后的元素

集合

NSSet *collection = [NSSet setWithObjects:@"Canada", @"Greece", @"Russia", NULL];
NSSet *filter = [collection ks_filter:^BOOL (NSString *object) {
  // ex.: BOOL match = [object isEqualToString:@"..."];
  return match;
}];

数组

NSArray *collection = [NSArray arrayWithObjects:@"Canada", @"Greece", @"Russia", NULL];
NSArray *filtered = [collection ks_filter:^BOOL (NSString *object) {
  // ex.: BOOL match = [object isEqualToString:@"..."];
  return match;
}];

字典

NSDictionary *collection = @{ @"Canada" : @"Victoria", @"Greece": @"Athens", @"Russia": @"Moscow" };
NSDictionary *filtered = [collection ks_filter:^BOOL (NSString *key, NSString *value) {
  // ex.: BOOL match = [key isEqualToString:@"..."] || [value isEqualToString:@"..."];
  return match;
}];

拒绝

拒绝 将集合中的每个元素传递给指定的操作块,并返回不匹配操作块的过滤后的元素

集合

NSSet *collection = [NSSet setWithObjects:@"Canada", @"Greece", @"Russia", NULL];
NSSet *filter = [collection ks_reject:^BOOL (NSString *object) {
  // ex.: BOOL match = [object isEqualToString:@"..."];
  return match;
}];

数组

NSArray *collection = [NSArray arrayWithObjects:@"Canada", @"Greece", @"Russia", NULL];
NSArray *filtered = [collection ks_reject:^BOOL (NSString *object) {
  // ex.: BOOL match = [object isEqualToString:@"..."];
  return match;
}];

字典

NSDictionary *collection = @{ @"Canada" : @"Victoria", @"Greece": @"Athens", @"Russia": @"Moscow" };
NSDictionary *filtered = [collection ks_reject:^BOOL (NSString *key, NSString *value) {
  // ex.: BOOL match = [key isEqualToString:@"..."] || [value isEqualToString:@"..."];
  return match;
}];

并集

并集 生成目标集合和参数集合的并集

集合

NSSet *alpha = [NSSet setWithObjects:@"A", @"B", NULL];
NSSet *omega = [NSSet setWithObjects:@"B", @"C", NULL];
[alpha ks_union:omega]; // [NSSet setWithObjects:@"A", @"B", @"C", NULL];

数组

NSArray *alpha = [NSArray arrayWithObjects:@"A", @"B", NULL];
NSArray *omega = [NSArray arrayWithObjects:@"B", @"C", NULL];
[alpha ks_union:omega]; // [NSArray arrayWithObjects:@"A", @"B", @"C", NULL];

字典

NSDictionary *alpha = @{ @"A": @"A", @"B": @"B" };
NSDictionary *omega = @{ @"B": @"B", @"C": @"C" };
[alpha ks_union:omega]; // @{ @"A": @"A", @"B": @"B", @"C": @"C" };

交集

交集 生成目标集合和参数集合的交集

集合

NSSet *alpha = [NSSet setWithObjects:@"A", @"B", NULL];
NSSet *omega = [NSSet setWithObjects:@"B", @"C", NULL];
[alpha ks_intersection:omega]; // [NSSet setWithObjects:@"B", NULL];

数组

NSArray *alpha = [NSArray arrayWithObjects:@"A", @"B", NULL];
NSArray *omega = [NSArray arrayWithObjects:@"B", @"C", NULL];
[alpha ks_intersection:omega]; // [NSArray arrayWithObjects:@"B", NULL];

字典

NSDictionary *alpha = @{ @"A": @"A", @"B": @"B" };
NSDictionary *omega = @{ @"B": @"B", @"C": @"C" };
[alpha ks_intersection:omega]; // @{ @"B": @"B" };

差集

差集 生成目标集合与参数集合的差集

集合

NSSet *alpha = [NSSet setWithObjects:@"A", @"B", NULL];
NSSet *omega = [NSSet setWithObjects:@"B", @"C", NULL];
[alpha ks_difference:omega]; // [NSSet setWithObjects:@"A", @"C", NULL];

数组

NSArray *alpha = [NSArray arrayWithObjects:@"A", @"B", NULL];
NSArray *omega = [NSArray arrayWithObjects:@"B", @"C", NULL];
[alpha ks_difference:omega]; // [NSArray arrayWithObjects:@"A", @"C", NULL];

字典

NSDictionary *alpha = @{ @"A": @"A", @"B": @"B" };
NSDictionary *omega = @{ @"B": @"B", @"C": @"C" };
[alpha ks_difference:omega]; // @{ @"A": @"A", @"C": @"C" };

最小值

最小值 使用 compare: 在集合中搜索以获取最小元素(元素必须实现 compare:

集合

NSSet *collection = [NSSet setWithObjects:@1.0, @1.25, @0.75, NULL];
collection.ks_minimum; //0.75

数组

NSArray *collection = [NSArray arrayWithObjects:@1.00, @1.25, @0.75, NULL];
collection.ks_minimum; // 0.75;

字典

NSDictionary *collection = @{ @"USD": @1.00, @"CDN": @1.25, @"EUR": @0.75 };
collection.ks_minimum; // 0.75

最大值

最大值 使用 compare: 在集合中搜索以获取最大元素(元素必须实现 compare:

集合

it (@"exposes the maximum in an set", ^{
NSSet *collection = [NSSet setWithObjects:@1.00, @1.25, @0.75, NULL];
collection.ks_maximum; // 1.25

数组

it (@"exposes the maximum in an array", ^{
NSArray *collection = [NSArray arrayWithObjects:@1.0, @1.25, @0.75, NULL];
collection.ks_maximum; //1.25);

字典

NSDictionary *collection = @{ @"USD": @1.0, @"CDN": @1.25, @"EUR": @0.75 };
collection.ks_maximum; //1.25

样本

样本 从集合中随机抓取一个元素。

集合

NSSet *collection = [NSSet setWithObjects:@1.0, @1.25, @0.75, NULL];
collection.ks_sample; // (1.0 | 1.25 | 0.75)

数组

NSArray *collection = [NSArray arrayWithObjects:@1.0, @1.25, @0.75, NULL];
collection.ks_sample; // (1.0 | 1.25 | 0.75)

字典

NSDictionary *collection = @{ @"USD": @1.0, @"CDN": @1.25, @"EUR": @0.75 };
collection.ks_sample; // (1.0 | 1.25 | 0.75)

函数

函数 提供了一些处理操作块的帮助函数

防抖

防抖 延迟执行操作块,直到经过一定的时间间隔

KSDebounce *debounce = [KSDebounce new];

__block typeof(self) bself;
[debounce debounce:0.2 block: ^{
  [bself search:self.mainSearchBar.text];
}];

验证

验证

NSDictionary *attributes = @{ @"name": @"John Smith", @"email": @"[email protected]", @"phone": @"+1 555-555-5555" };
NSDictionary *validations = @{
  @"name": @{ KSValidate.presence: @{ KSValidate.message: @"must be entered" } },
  @"tagline": @{ KSValidate.length: @{ KSValidate.minimum: @20, KSValidate.maximum: @80 } },
  @"email": @{ KSValidate.format: @{ KSValidate.with: KSValidateFormatEmail } },
  @"phone": @{ KSValidate.format: @{ KSValidate.with: KSValidateFormatPhone } },
  @"country": @{ KSValidate.inclusion: @{ KSValidate.of: @[@"Canada"] } },
  @"region": @{ KSValidate.exclusion: @{ KSValidate.of: @[@"PEI"] } },
};

KSValidator *validator = [KSValidator validator:validations];
[validator validate:attributes];

validator.errors;
// ex.:
// @{
//   @"tagline": @[@"must be between 20 and 80 characters", @"cannot contain inappriate language"],
//   @"email": @[@"is formatted wrong"], @"phone": @[@"is formatted wrong"]
// };

validator.humanize;
// @"tagline must be between 20 and 80 characters, tagline cannot contain inapproriate language, email is formatted wrong, phone is formatted wrong and name can't be blank"

长度

[KSValidator length:@"test" is:8]; // NO
[KSValidator length:@"test" is:4]; // YES

[KSValidator length:@"test" minimum:5]; // NO
[KSValidator length:@"test" minimum:4]; // YES
[KSValidator length:@"test" minimum:3]; // YES

[KSValidator length:@"test" maximum:3]; // NO
[KSValidator length:@"test" maximum:4]; // YES
[KSValidator length:@"test" maximum:5]; // YES

格式

[KSValidator format:@"tester" with:KSValidationEmail]; // NO
[KSValidator format:@"[email protected]" with:KSValidationEmail]; // YES

[KSValidator format:@"tester" with:KSValidationPhone]; // NO
[KSValidator format:@"+1 555-555-5555" with:KSValidationPhone]; // YES

[KSValidator format:@"..." with:@"\\...\\"]; // NO
[KSValidator format:@"abcdefghijklmnopqrstuvwxyz" with:@"\\..\\"]; // YES

包含

[KSValidator inclusion:@"blue" collection:@[@"blue"]]; // YES
[KSValidator inclusion:@"pink" collection:@[@"blue"]]; // NO

排除

[KSValidator exclusion:@"blue" collection:@[@"blue"]]; // YES
[KSValidator exclusion:@"pink" collection:@[@"blue"]]; // NO

存在

[KSValidator presence:@"Greetings!"]; // YES

不存在

[KSValidator absence:@"Greetings!"]; // NO

属性名称还可以添加到 Localizable.strings

本地化

消息

"is invalid": "...";
"can't be blank": "...";
"can't be present": "...";
"must be exactly %@ characters": "...";
"must be between %@ and %@ characters": "...";
"must be a minimum of %@ characters": "...";
"must be a maximum of %@ characters": "...";

属性

"ssn" = "social security number";

词形变化

复数化

[@"cookie" ks_pluralize]; // "cookies"
[@"cherry" ks_pluralize]; // "cherries"
[@"potato" ks_pluralize]; // "potatoes"

单数化

[@"cookies" ks_singularize]; // "cookie"
[@"cherries" ks_singularize]; // "cherry"
[@"potatoes" ks_singularize]; // "potato"

词性变形

[KSInflector.shared inflect:1 string:@"star"]; // "1 star" [KSInflector.shared inflect:2 string:@"star"]; // "2 stars" [KSInflector.shared inflect:3 string:@"star"]; // "3 stars"

高级功能

[KSInflector config:^(KSInflector *inflector) {
  [inflector singular:@"oxen$" replacement:@"ox"];
  [inflector plural:@"ox$" replacement:@"oxen"];
}];

存在主义

对象

[NSNull null].ks_exists; // NO
[NSObject new].ks_exists; // YES

集合

[NSSet set].ks_exists; // NO
[NSSet setWithObject:object].ks_exists; // YES

数组

[NSArray set].ks_exists; // NO
[NSArray setWithObject:object].ks_exists; // YES

字典

@{}.ks_exists; // NO
@{ key: value }.ks_exists; // YES

字符串

@"".ks_exists; // NO
@"Greetings!".ks_exists; // YES

作者

Kevin Sylvestre, [email protected]

许可证

KSReason遵循MIT许可证。更多信息请参阅LICENSE文件。