0%

中文English

New Release Version Available: V2.0 Definitive Edition(Updated on 2021-7-6)

Update Log

2.0(Definitive Edition) 2021-7-5

1 EFUtils: The conversion utils gets new methods to encode NSData to Base64 strings and decode NSData from them. New methods for UI utils. The DES encryption and decryption method is removed.
2 EFBase:
2.1 EFBaseViewController: Custom back and custom cancel solution improvements, new methods for request locations, new methods for select photos, new method for request recording permission, and embedded tableView is supported, just use like the EFBaseTableViewController own tableView, data refresh and pageable with display no data view during animations, solution of input focus improvement.
2.2 EFBaseTableViewController: Custom back and custom cancel solution improvements, new methods for request locations, new methods for select photos, new method for request recording permission, data refresh and pageable with display no data view during animations, solution of input focus improvement.
2.3 EFBaseModalDialogViewController: Modal dialog base class, now provides the most commonly used three modal dialog.
2.4 EFBaseWebViewController: Replace UIWebView with WKWebView.
2.5 BaseDataModel: Added support for archive and unarchive automatic .
3 EFUIKit:
3.1 EFNavigationBar: The gradient background is removed. The navigation style is applied by the theme color. In addition to the bar button item and title color, it also applied to the background color.
3.2 EFModulalDialog: It provides the three most commonly used modal dialogs: list option with single or multiple selection, select date(or date and time), and level-able options up to two levels.
3.3 EFButton: Customized border, corner radius, and gradient background. it provides a lot of display styles such as horizontal content center, icon on the left and icon on the top.
3.4 EFVIEW: Customized border, corner radius or shadow.
3.5 EFImageView: Customized border, corners radius or shadow, and image content mode.
3.6 EFlabel: Customized border, corners radius, it provides a lot of methods to init label with NSString, and display all text in pop-over view when the text is not displayed completely just simply by a single tap.
3.7 EFTextField: Customized border, corner radius, placeholder text color, and text display position offset.
4 AFHTTPTool: The AFHTTPConfig error code is upgraded to status code, and authorization is no longer required when get AFHTTPSessionManager, just handle by each request instead.
5 EFFMDBTool: Read from or save to sqlite automatic just by models based on BaseDataModel.
6 The demo App is upgraded at the same time, and the navigation style is applied by the theme color.
7 Compatible with iOS 14, and the project is successfully compiled by Xcode12.

阅读全文 »

中文 | English

新的正式版可用: V2.0 最终版(更新于2021-7-6)

更新内容

2.0(最终版) 2021-7-5

1 EFUtils: 转换工具添加了新的方法,添加了编码为 base64字符串和解码为 NSData的方法,UI工具添加了新的方法,取消了 DES加解密方法。
2 EFBase:
2.1 EFBaseViewController: 自定义返回与自定义取消方案改进,获取位置添加了新的方法,获取照片添加了新的方法,添加了获取录音权限的方法,添加了嵌入式 tableView的支持,可以像 EFBaseTableViewController中自带的 tableView一样使用,添加了数据刷新与分页和无数据显示的联动显示效果,输入聚焦方案改进。
2.2 EFBaseTableViewController: 自定义返回与自定义取消方案改进,获取位置添加了新的方法,获取照片添加了新的方法,添加了获取录音权限的方法,添加了数据刷新与分页和无数据显示的联动显示效果,输入聚焦方案改进。
2.3 EFBaseModalDialogViewController: 弹出式对话框基类,目前提供了最常用的三种弹出式对话框。
2.4 EFBaseWebViewController: UIWebView替换为 WKWebView。
2.5 BaseDataModel: 添加了自动归解档的支持。
3 EFUIKit:
3.1 EFNavigationBar: 取消了渐变色背景,深浅模式现在对应主题色,除了按钮、标题颜色,现在也作用于背景色。
3.2 EFModalDialog: 提供了最常用的三种弹出式对话框:列表单选或者多选、日期(时间可选)选择、最多两级的级联选项。
3.3 EFButton: 提供了边框、圆角、渐变背景自定义,内容水平居中、图标居左、图标居上多种显示风格。
3.4 EFView: 提供了边框、圆角、阴影效果自定义。
3.5 EFImageView: 提供了边框、圆角、阴影效果、图像填充方式自定义。
3.6 EFLabel: 提供了边框、圆角自定义,添加了通过 NSString实例化的方法,添加了文字显示不全时,点击以浮动提示方式显示全部文字的效果,默认不启用。
3.7 EFTextField: 提供了边框、圆角、占位文字颜色、文字显示位置偏移量自定义。
4 AFHTTPTool: AFHTTPConfig 错误码升级为状态码,获取 AFHTTPSessionManager时不再要求提供授权,改由各请求处理。
5 EFFMDBTool: 基于 BaseDataModel的模型sqlite自动存取。
6 演示 App同步更新,通过导航的深浅风格改变主题色。
7 适配了 iOS14系统,项目通过 Xcode12成功编译。

阅读全文 »

日期格式字符串格式化 Date fomartter

1
2
3
4
5
NSDate *date = [NSDate date];
LOG_FORMAT(@"1: %@", [EFUtils stringFromDateFormattedString:@"2020/08/30" dateFormatIn:@"yyyy/MM/dd" dateFormatOut:@"yyyy年MM月dd日"]);
LOG_FORMAT(@"2: %@", [EFUtils dateFromDateFormattedString:@"2020-08-30"]);
LOG_FORMAT(@"3: %@", [EFUtils dateFromDateFormattedString:@"2020-08-30 10:00:00" dateTime:YES]);
LOG_FORMAT(@"4: %@", [EFUtils dateFromDateFormattedString:@"2020年8月30日" dateFormatIn:@"yyyy年MM月dd日"]);

输出结果

1: 2020年08月30日

相关

iOS中获取相机/照片图库权限只需一行代码

1

话不多说。

1
2
3
4
5
6
7
8
9
// 获取相机权限
[self privacyCameraAuthorizationWithCompletionHandler:^{
// do something when you get camera authorization
}];

// 获取照片图库权限
[self privacyPhotoLibraryAuthorizationWithCompletionHandler:^{
// do something when you get photos authorization
}];

2

有人说 iOS 14可以选择指定照片来供 App访问,没问题,安排。

1
2
3
4
5
[self privacyPhotoLibraryAuthorizationWithLimitedPhotosHandler:^{
// do something when you get limited photos authorization
} authorizedHandler:^{
// do something when you get full photos authorization
}];

3

只不过这么做后,默认会在每次重新启动App后再次需要获取照片图库权限时自动弹出受限照片权限选择照片的提醒。如果你不想发生这样的情况,可以做如下设置:

在项目配置窗口的 Info一栏添加“Privacy - Location Default Accuracy Reduced”,值设为 YES

在你需要打开受限照片权限选择照片界面的时候,也可以。调用以下方法

1
[self presentLimitedLibraryPicker];

最后别忘了实现 -PHPhotoLibraryChangeObserver:代理方法,在代理方法中处理因受限照片权限选择照片内容变更的情况。

相关

更新内容

新增了 iOS14中获取受限照片权限的方法。

iOS中选取照片其实可以很简单

1.5

在1.5版本中,你仅需在基于 EFBaseViewController的控制器中添加如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
- (IBAction)selectPhoto:(id)sender {
[self showPhotoPickerWithMessage:@"上传头像" sourceView:sender.view completion:nil];
}

// 选取照片的处理
@WeakObj(self);
self.photoPickerResult = ^(UIImagePickerController *_Nonnull imagePicker, NSDictionary *_Nonnull mediaInfo) {
@StrongObj(self);
[self dismissViewControllerAnimated:YES completion:nil];

[self.avatar_imageView setImage:[mediaInfo objectForKey:UIImagePickerControllerOriginalImage]];// 本地演示
};

解析:和其它需要获取隐私权限的功能一样,极致框架很好的封装了获取相机/照片图库隐私权限的代码,并对开发者隐藏了具体的实现,开发者仅需要把注意力投入到怎么对选取的照片处理即可。

在1.5最终版中,可以设定使用相机拍照时默认开始前置还是后置摄像头了,这对于诸如“选取头像”这种功能很有必要。

1
[self showPhotoPickerWithMessage:@"上传头像" isFront:YES sourceView:sender.view completion:nil];

2.0~

新的改进:
iOS 14开始倡导使用 PHPicker来替代 UIImagePickerController,而无需获得用户的照片图库权限,因为全新的 PHPicker采用沙盒机制,App无法直接获取照片图库中的数据,而用户可以看到,并可决定 App可以访问哪些数据。极致框架在2.0最终版中响应了这一举动,不过我们保留了 UIImagePickerController来兼容比 iOS 14更早的软件系统,而开发者无需把精力投入在这个上面,此外,我们还统一了新的选取照片的回调。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (IBAction)selectPhoto:(id)sender {
[self showPhotoPickerWithMessage:@"上传头像" isCameraDeviceFront:YES]; // sourceView 在版本2.0中可选
}

// 选取照片的处理
@WeakObject(self);
self.photoPickerFinishHandler = ^(id _Nonnull photoPicker, NSArray<UIImage *> *_Nonnull selectPhotos) {
@StrongObject(self);
if (@available(iOS 14, *)) {
if ([photoPicker isMemberOfClass:[UIImagePickerController class]] && UIImagePickerControllerSourceTypeCamera==((UIImagePickerController *)photoPicker).sourceType) {
[self dismissViewControllerAnimated:YES completion:nil];
}
// PHPickerViewController will dismiss automatically
} else {
[self dismissViewControllerAnimated:YES completion:nil];
}

[self.avatar_imageView setImage:selectPhotos.firstObject];// 本地演示
};

上面的代码只能单选照片,当然怎么少的了多选照片呢,你可以限制选择照片的最大数量,当然也可以不设限制。注意:以下方法只支持 iOS 14及以上版本的系统。

1
2
3
4
5
// 限制最多选择9张照片
[self showPhotoPickerWithMessage:@"上传头像" photoSelectionLimit:9];

// 选择照片没有限制
[self showPhotoPickerNoPhotoSelectionLimitWithMessage:@"上传头像"];

相关

更新内容

  1. 新增 iOS 14及以上版本系统选取照片更多的方法。
  2. 统一的选取照片回调。

iOS中使用定位轻松几步搞定-获取用户的位置信息 Request location

基本使用与一次定位 Basic use and location once

总所周知,iOS的权限控制非常地优秀,在提高安全性的同时,也提高了用户的使用门槛,如何能让用户优雅地正常使用位置信息,正是我们开发者需要做的。

1、请求定位权限
限制位置信息使用的情况有:定位功能未开启、内容和隐私访问限制中定位服务项不允许修改、用户拒绝了位置信息访问等。应当在定位功能开启时才请求定位权限,若未开启,应当给予适当提醒。

2、检查定位权限
在你准备正式请求定位时,还是应该先确保你拥有了位置信息访问的权限。

3、请求定位
终于可以请求定位了,别忘了实现代理方法来处理位置信息,如果定位失败也别忘了给予适当提醒,或者提出建议的操作等。

在基于 BaseViewController的控制器中添加以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
- (void)viewDidLoad {
[super viewDidLoad];

// 1、请求定位权限
[self requestLocationAuthorization:YES];
}

// 2、检查定位权限
[self requestLocationSuccessHandler:^(CLLocationManager *locationManager) {
locationManager.delegate = self;
// 3、请求定位
[locationManager requestLocation];
} failureHandler:^(CLLocationManager *locationManager, CLAuthorizationStatus authorizationStatus) {
NSString *message;
switch (authorizationStatus) {
case kCLAuthorizationStatusRestricted:
message = @"定位失败:访问限制已开启";
break;

case kCLAuthorizationStatusDenied:
message = @"定位失败:定位权限已禁止";
break;

default:
message = @"定位失败:其它错误";
break;
}
[SVProgressHUD showErrorWithStatus:message];
}];

#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
LOG_FORMAT(@"location: %g, %g", locations.firstObject.coordinate.latitude, locations.firstObject.coordinate.longitude);
}

- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error {
[SVProgressHUD showErrorWithStatus:error.localizedDescription];
}
阅读全文 »

iOS中一句话获取定位权限 A statement in iOS to request location permission

从 iOS 8开始需要用户分别给予在使用 App期间(When in use)和始终(Always)的位置使用权限,而在最新的 iOS系统中每个新使用的 App中用户只能做出一次选择,选择了“使用 App期间”,那么后续你也选择不了“始终”,选择了“始终”,那么无论你在使用 App期间还是 App为非当前使用 App时均能使用你的位置(注意:这个时候在设置中 App位置权限选择界面,你貌似有“使用 App期间”和“始终”两个选项可选,然而无论你选择哪个选项效果都是一样的)。

在基于 BaseViewController的控制器的 -viewDidLoad中先使用以下的任何一行代码来获取定位权限,不过需要注意的是,这个代码只会生效一次:

剩下的见证奇迹吧。


Starting from iOS 8, users are required to give permission of access to the location of “When in use” and “Always”. However, in the latest iOS system, each new App user can only make a choice once. If you choose “When in use”, then you cannot choose “Always” in the future. And if you choose “Always”, you can use your location whether you are using the App or not (Note: If you choose “Always”, in the Settings of the App privacy location selection, you seem to have two options to choose between “When in use” and “Always”, however, no matter which option you choose, the effect is the same).

On the -viewDidLoad of the BaseViewControler based controller, use any line of the following codes first to request the location permission, but note that this code will only work once:

Just enjoy.

阅读全文 »

基于BaseDataModel的模型在sqlite中存入与取出 Write or read model based on BaseDataModel with sqlite

极致框架中的 EFFMDBTool可以非常简单方便的进行这一操作。只需要你采用基于BaseDataModel的模型即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
@interface ContactModel : BaseDataModel

@end

@protocol ContactModel <NSObject>

@end

@interface UserModel : BaseDataModel

@property (copy, nonatomic, nullable) NSString<Optional> *name;
@property (strong, nonatomic, nullable) NSArray<ContactModel, Optional> *contacts;

@end


@implementation ContactModel

+(JSONKeyMapper*)keyMapper
{
return [[JSONKeyMapper alloc] initWithModelToJSONDictionary:@{
@"dataID": @"ID", // dataID用作ID
@"dataName": @"data" // dataName用作data
}];
}

@end

@implementation UserModel

+(JSONKeyMapper*)keyMapper
{
return [[JSONKeyMapper alloc] initWithModelToJSONDictionary:@{
@"dataID": @"ID", // dataID用作ID
@"dataName": @"nick" // dataName用作name
}];
}

@end
阅读全文 »

基于BaseDataModel的模型自动归档解档,支持嵌入式基于BaseDataModel的模型 Model based on BaseDataModel archive and unarchive automatically, whether it embed model based on BaseDataModel or not

要实现这个需求,需要满足两个条件:
1、要支持归档解归档,要实现 NSCoding 协议里面的方法。
2、要支持自动归档解归档,需要自动完成自定义模型及其下包含的所有自定义模型的 NSCoding 协议方法,为了支持 secureCoding,还必须要让自定义模型及其下包含的所有自定义模型的 +supportsSecureCoding都返回 YES。

我们提供了两个 NSObject的类 Class和 Coding,以此实现了这个需求。BaseDataModel 已包含了这些实现,自然也继承了这一特性。

尽情享用吧!


To implement this requirement, two conditions need to be met:

  1. To support archive unarchive, to implement the methods in the NSCoding protocol.

  2. To support automatic archiving and unarchiving, it is necessary to automatically complete the NSCoding protocol methods of the custom model and all the other custom models contained. In order to support secureCoding, You must also make sure the +supportsSecureCoding method of the custom model and all the other custom models contained return YES.

We provide two NSObject categories, the Class and Coding, to implement the requirement. BaseDataModel also inherits this feature by referring to this implmentation.

Enjoy the follow time!

阅读全文 »

基于的模型和继承的模型 Base model and inherited model

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@interface BaseUser : BaseDataModel

@property (copy, nonatomic, nullable) NSString<Optional> *nick;
@property (strong, nonatomic, nullable) NSNumber<Optional> *age;
@property (strong, nonatomic, nullable) NSNumber<Optional> *sex;
@property (strong, nonatomic, nullable) NSNumber<Optional> *level;
@property (strong, nonatomic, nullable) NSNumber<Optional> *score;

@end

@interface Staff : BaseUser

@property (strong, nonatomic, nullable) NSNumber<Optional> *memberLevel;
@property (strong, nonatomic, nullable) NSNumber<Optional> *memberScore;

@end

@interface Customer : BaseUser

@end
阅读全文 »