iOS之项目总结三:项目开发中遇到的一些问题及解决方案
2017-10-05 11:19:10 # 项目总结

前言:

两年多以来,基本上都是独立开发或者维护项目,不得不自嘲的说挺锻炼人的。最近的一家公司是涉足金融行列的,算是第一次踏足金融吧,过程怎样不说,确实学到了不少东西。

下面就开发第一款金融类项目遇到的问题做一下总结:

1、中文显示标题之类

我们在项目中调用相册、相机等往往默认的是显示英文,但有时候开发的项目是针对国内的,所以需要中文配合显示,这就需要我们做一下配置。
其实很简单:就是在info.plist中允许应用程序获取框架内语言即可。

1
2
Localizedresources can be mixed  YES
Localization native development region China //en

图片显示:

允许应用程序获取框架内语言图片

2、运行报错问题

报错信息:

1
ld: 4 duplicate symbols for architecture arm64 clang: error: linker command failed with exit

这个是粗心大意而差生的报错,最可能的情况是:引入【.h】文件重复。
我们知道iOS不允许在A类中重复引入相同的B类的,使用improt关键字引入头文件时,它会判断是否已经引入,如果引入了一次就不在引入。但并不能直接提示报错,所以在运行时会提示上面的报错信息。所以首先要做的是排查是否重复引入【.h】文件。

3、在使用jsonModel做项目的数据解析时,出现一个属性名字不确定是否存在的情况

这个问题是没有技术含量的,遇到了解决就行,方法如下:
在【.m】文件中添加下面的方法即可

1
2
3
4
+(BOOL)propertyIsOptional:(NSString*)propertyName
{
return YES;
}

4、AES加密遇到的和android统一加密模式问题

这种情况我以前在《Base64加密和DES加密、以及JAVA和iOS中DES加密统一性问题》这篇文章中有提到多,主要是iOS这边SDK中只提供了两种模式:

1
2
3
4
5
6
7
8
9
@constant   kCCOptionPKCS7Padding   Perform PKCS7 padding.
@constant kCCOptionECBMode Electronic Code Book Mode.
Default is CBC.
enum {
/ options for block ciphers /
kCCOptionPKCS7Padding = 0x0001,
kCCOptionECBMode = 0x0002
/ stream ciphers currently have no options /
};

但安卓的不一样,有十几种左右,所以在开发中一定要和安卓、服务器端做好统一。

  1. 如果使用CBC模式,那直接用:kCCOptionPKCS7Padding即可。
  2. 但如果是ECB模式,就需要做下转变 kCCOptionECBMode | kCCOptionPKCS7Padding

5、服务器端小数显示问题(如:1e-05)

这个做下处理即可:

1
2
NSDecimalNumber *decNumber = [NSDecimalNumber decimalNumberWithString:leastWaveStr];
NSString *numberStr = [decNumber stringValue];

金融类项目中常用到这个NSDecimalNumber ,用于货币处理 。
通过NSDecimalNumber提供的计算方式,可以很好的计算出准确的精度的数据,同时不需要使用格式化输出等。

6、自定义导航栏按钮不靠左/右问题

很简单,解决方法,添加一个空的按钮进去

1
2
3
4
5
6
7
8
9
10
UIButton *leftButton = [[UIButton alloc]init];
leftButton.frame = CGRectMake(0, 0, 20, 20);
[leftButton setBackgroundImage:[UIImage imageNamed:@"back.png"] forState:UIControlStateNormal];
[leftButton addTarget:self action:@selector(popToLastVC:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *leftBarButtonItems = [[UIBarButtonItem alloc]initWithCustomView:leftButton];
//解决按钮不靠左 靠右的问题.
UIBarButtonItem *nagetiveSpacer = [[UIBarButtonItemalloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace
target:nil action:nil];
nagetiveSpacer.width = -15;//这个值可以根据自己需要自己调整
self.navigationItem.leftBarButtonItems = @[nagetiveSpacer, leftBarButtonItems];

7、不同屏幕尺寸字体显示字体大小问题

我们应该清楚,UI设计图大多数是以iPhone6 为模版设计的,但开发中腰考虑不同的屏幕尺寸显示字体大小不同的情况。
网上给出的大多数是针对Xibstoryboard做的处理,下面我说一下针对纯代码开发的处理方法。
其实很简单,在pch文件中设置宏定义,针对不同的机型做一下简单判断,在开发中使用宏定义字体大小就可以了。
例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#define kDevice_Is_iPhone4 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 960), [[UIScreen mainScreen] currentMode].size) : NO)
#define kDevice_Is_iPhone5 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 1136), [[UIScreen mainScreen] currentMode].size) : NO)
#define kDevice_Is_iPhone6 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(750, 1334), [[UIScreen mainScreen] currentMode].size) : NO)
#define kDevice_Is_iPhone6Plus ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1242, 2208), [[UIScreen mainScreen] currentMode].size) : NO)
//字体大小(以6s为基准,以6p为判断)
#define kFontSize10 kDevice_Is_iPhone6Plus ? 12:10
#define kFontSize11 kDevice_Is_iPhone6Plus ? 13:11
#define kFontSize12 kDevice_Is_iPhone6Plus ? 14:12
#define kFontSize13 kDevice_Is_iPhone6Plus ? 15:13
#define kFontSize14 kDevice_Is_iPhone6Plus ? 16:14
#define kFontSize15 kDevice_Is_iPhone6Plus ? 17:15
#define kFontSize16 kDevice_Is_iPhone6Plus ? 18:16
#define kFontSize17 kDevice_Is_iPhone6Plus ? 19:17
#define kFontSize18 kDevice_Is_iPhone6Plus ? 20:18
#define kFontSize19 kDevice_Is_iPhone6Plus ? 21:19
#define kFontSize20 kDevice_Is_iPhone6Plus ? 22:20
#define kFontSize21 kDevice_Is_iPhone6Plus ? 23:21
#define kFontSize22 kDevice_Is_iPhone6Plus ? 24:22
#define kFontSize23 kDevice_Is_iPhone6Plus ? 25:23
#define kFontSize24 kDevice_Is_iPhone6Plus ? 26:24
#define kFontSize25 kDevice_Is_iPhone6Plus ? 27:25
#define kFontSize34 kDevice_Is_iPhone6Plus ? 35:34
#define kFontSize36 kDevice_Is_iPhone6Plus ? 38:36

使用:

1
2
3
4
5
6
UILabel *label = [UILabel new];
label.text = @"";
label.textColor = [UIColor darkGrayColor];
label.textAlignment = NSTextAlignmentCenter;
label.font = [UIFont systemFontOfSize:kFontSize16];
[self addSubview:label];

这样就不需要每次使用字体都判断不同屏幕尺寸了。

8、view上有tableView,view添加手势后与tableView手势冲突问题

解决这个问题,我们需要利用系统的方法做个判断:如果点击了tableView,就不接收Touch点击事件。

1
2
3
4
5
6
7
8
9
 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// 点击的view的类名
NSLog(@"%@", NSStringFromClass([touch.view class]));
// 点击了tableViewCell,view的类名为UITableViewCellContentView,则不接收Touch点击事件
if ([NSStringFromClass([touch.view class]) isEqualToString:@"UITableViewCellContentView"]) {
return NO;
}
return YES;
}

这种方法用来执行点击View的操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
#pragma mark - UIGestureRecognizerDelegate methods
-(void)viewtapClicked:(UITapGestureRecognizer *)tap
{
CGPoint point = [tap locationInView:self];
BOOL isTouch = CGRectContainsPoint(self.baseView.frame, point);
if (isTouch) {
NSLog(@"点击tableView");
}else{
[UIView animateWithDuration:1.0 animations:^{
[self removeFromSuperview];
}];
}
}

9、断网重连后更新界面

我们在开发项目中,网络状态的监听基本设置在appDelegate中。所以需要在这里针对网络状态做一个广播通知,在需要网络重连后更新界面的地方注册该广播进行界面的刷新

1
2
3
4
5
6
7
8
//注册网络监控通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationHandler:) name:kIsNetWork object:nil];
- (void)notificationHandler:(NSNotification *) notification
{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self requestHomeInfoData];
});
}