iOS指纹验证TouchID应用学习教程2

2025-05-29 0 77

上一篇文章简单的写了对于touchid的简单了解。因为太懒了,就没有写实例,现在就单独写一篇应用吧,这篇想做的就是一个模仿那个叫啥软件来着,某某理财类类的软件的一个指纹验证解锁。我们做出来的页面应该如下图,在app挂起到后台的时候再点击到前台的时候回出现如下页面:

app唤醒的时候出现的画面

iOS指纹验证TouchID应用学习教程2

点击取消按钮出现的页面

iOS指纹验证TouchID应用学习教程2

这里我先挂上github的链接地址,毕竟本文的篇幅较长,也没什么人有耐心有时间看到最后,顶多看下demo,快速的知道怎么调用啥的就可以了。(popviewfortouchid)

因为我之前没遇到个这种情况,所以我做的都是自己瞎搞搞出来的,也不知道平时大家做的时候是怎么做的,就搞出来这样的,这里我打算用两种方法来实现,不过这个东西放进app中貌似是需要适配的。还是有些许问题的。可能要调下。

在app被唤醒的时候,出现页面我用了两种方式,一种是present出来一个单独的页面,一种方式是自定义弹出view。

但是本文呢,主要就介绍一下弹出式view的方式,因为present的方式跟这种方式差别就是在于一个是view一个是controller,主要的思想还是一样的。

第一部分

第一步

引入需要用的文件,以及创建pch文件,因为是小demo,所以一些宏定义直接丢进去就可以了。

iOS指纹验证TouchID应用学习教程2

第二步

创建pch文件,引入一些需要用到的文件以及宏定义,这里要是有问题的话可以参照我之前一篇文章写的引入pch文件,当然也可以老老实实的每个文件里都去引入头文件啥的,这个很随意的,毕竟是demo。

?

1

2

3

4

5

6

7

8

9

10

11
#import "appdelegate.h"

#import "wjtouchid.h"

#import "mbprogresshud.h"

#import "mbprogresshud+add.h"

// 屏幕bounds

#define ylsscreenbounds [uiscreen mainscreen].bounds

//位置

#define zlrect(x, y, w, h) cgrectmake([uiscreen mainscreen].bounds.size.width * x, [uiscreen mainscreen].bounds.size.height * y, [uiscreen mainscreen].bounds.size.width * w, [uiscreen mainscreen].bounds.size.height * h)

//字体大小

#define zcfont(f) [uiscreen mainscreen].bounds.size.width * f

第三步

实现基础页面,如下图

iOS指纹验证TouchID应用学习教程2

声明变量,遵守指纹验证控件的协议

?

1

2

3

4

5

6

7
@interface viewcontroller ()<wjtouchiddelegate>

/** noticelabel */

@property (nonatomic,strong) uilabel *label;

/** uiswitch */

@property (nonatomic,strong) uiswitch *touchidswitch;

@property (nonatomic, strong) wjtouchid *touchid;

@end

懒加载

?

1

2

3

4

5

6

7

8
-(uiswitch *)touchidswitch

{

if (!_touchidswitch)

{

self.touchidswitch = [[uiswitch alloc]init];

}

return _touchidswitch;

}

添加子控件

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22
-(void)setsubviews

{

self.label = [[uilabel alloc]init];

[self.view addsubview:self.label];

[self.label setframe:zlrect(0, 100/667, 1, 20/667)];

[self.label settext:@"指纹解锁"];

[self.label settextalignment:nstextalignmentcenter];

[self.label setfont:[uifont systemfontofsize:zcfont(18/375)]];

self.touchidswitch = [[uiswitch alloc]init];

[self.touchidswitch setframe:zlrect(160/375, 200/667, 50/375, 28/667)];

[self.view addsubview:self.touchidswitch];

if ([[[nsuserdefaults standarduserdefaults]objectforkey:@"touchid"] isequaltostring:@"1"])

{

self.touchidswitch.on = yes;

}else

{

self.touchidswitch.on = no;

}

[self.touchidswitch addtarget:self action:@selector(changeswitch:) forcontrolevents:uicontroleventvaluechanged];

}

这里要说一下

[[[nsuserdefaults standarduserdefaults]objectforkey:@"touchid"] isequaltostring:@"1"]

这个我是将是否设置了指纹验证存到了本地,因为当你进入设置页面的时候,必须知道你本机是否已经设置了指纹验证,这里存在着设置与未设置的一个页面ui差别,我这边就是用switch的开关来打开关闭指纹验证,也是用开关状态来表示指纹验证是否打开。

第四步

在viewdidload方法中调用设置子控件的方法,并且实现开关切换的方法。

?

1

2

3

4
- (void)viewdidload {

[super viewdidload];

[self setsubviews];

}

切换方法里呢,就是需要调用者会问验证,一般软件设置指纹验证的时候都会要求你先验证一下子,我在这里设置成只要你开或关闭都需要验证一下。

?

1

2

3

4

5

6

7

8
-(void)changeswitch:(id)sender

{

nslog(@"------changeswitch-------");

wjtouchid *touchid = [[wjtouchid alloc]init];

[touchid startwjtouchidwithmessage:wjnotice(@"自定义信息", @"the custom message") fallbacktitle:wjnotice(@"", @"fallback title") delegate:self];

self.touchid = touchid;

}

第五步

在上述调用指纹验证成功后,必须得实现它的回调函数,在成功或者失败的方法中写上你需要执行的代码。

?

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

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85
//touchid验证成功

- (void) wjtouchidauthorizesuccess {

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

if (self.touchidswitch.on == yes)

{

[mbprogresshud showtext:@"成功开启指纹解锁" view:self.view];

[[nsuserdefaults standarduserdefaults] setobject:@"1" forkey:@"touchid"];

}else{

[mbprogresshud showtext:@"指纹解锁关闭成功" view:self.view];

[[nsuserdefaults standarduserdefaults] setobject:@"0" forkey:@"touchid"];

}

}

//touchid验证失败

- (void) wjtouchidauthorizefailure {

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

if (self.touchidswitch.on == yes){

self.touchidswitch.on = no;

[mbprogresshud showtext:@"指纹解锁开启失败" view:self.view];

[[nsuserdefaults standarduserdefaults] setobject:@"0" forkey:@"touchid"];

}else

{

self.touchidswitch.on = yes;

[mbprogresshud showtext:@"指纹解锁关闭失败" view:self.view];

[[nsuserdefaults standarduserdefaults] setobject:@"1" forkey:@"touchid"];

}

}

//取消touchid验证 (用户点击了取消)

- (void) wjtouchidauthorizeerrorusercancel {

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

if (self.touchidswitch.on == yes){

self.touchidswitch.on = no;

[[nsuserdefaults standarduserdefaults] setobject:@"0" forkey:@"touchid"];

}else

{

self.touchidswitch.on = yes;

[[nsuserdefaults standarduserdefaults] setobject:@"1" forkey:@"touchid"];

}

}

//在验证的touchid的过程中被系统取消 例如突然来电话、按了home键、锁屏

- (void) wjtouchidauthorizeerrorsystemcancel {

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

if (self.touchidswitch.on == yes){

self.touchidswitch.on = no;

[[nsuserdefaults standarduserdefaults] setobject:@"0" forkey:@"touchid"];

}else

{

self.touchidswitch.on = yes;

[[nsuserdefaults standarduserdefaults] setobject:@"1" forkey:@"touchid"];

}

}

//多次连续使用touch id失败,touch id被锁,需要用户输入密码解锁

- (void) wjtouchidauthorizelaerrortouchidlockout {

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

[mbprogresshud showtext:@"验证失败" view:self.view];

}

//当前软件被挂起取消了授权(如突然来了电话,应用进入前台)

- (void) wjtouchidauthorizelaerrorappcancel {

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

if (self.touchidswitch.on == yes){

self.touchidswitch.on = no;

[[nsuserdefaults standarduserdefaults] setobject:@"0" forkey:@"touchid"];

}else

{

self.touchidswitch.on = yes;

[[nsuserdefaults standarduserdefaults] setobject:@"1" forkey:@"touchid"];

}

}

//当前软件被挂起取消了授权 (授权过程中,lacontext对象被释)

- (void) wjtouchidauthorizelaerrorinvalidcontext {

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

if (self.touchidswitch.on == yes){

self.touchidswitch.on = no;

[[nsuserdefaults standarduserdefaults] setobject:@"0" forkey:@"touchid"];

}else

{

self.touchidswitch.on = yes;

[[nsuserdefaults standarduserdefaults] setobject:@"1" forkey:@"touchid"];

}

}

以上呢,我是没有判断是否支持touchid来写,是直接按照可以支持的来写的,大家在实际操作工程中还是需要加一下判断条件,因为现在还是有不支持touchid的机型的。然后就是要说一下下面这个。

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

这个值我也不知道我是用来干嘛的,好像就是告诉我你设置了指纹验证了,然后在app唤醒的时候要根据一个值来判断是否需要调用指纹验证服务,我后来想了想,好像只要

[[[nsuserdefaults standarduserdefaults]objectforkey:@"touchid"] isequaltostring:@"1"]

这个就可以了,但是仔细想想还是再加上一个好分辨一点,毕竟就把一个当做判断switch是否打开,一个判断唤醒的时候要不要调用的吧。在不同的回调函数里面需要写的东西还是有差别的。这样上面写完之后,就等于实现一个简单的基础页面,当然这个还不是什么大问题,因为这个很简单,下面就是要实现弹出view了。篇幅好像有点长了,我自己看的也有点烦了都。。。。。

第二部分

第一步

创建自定义的view。在.h文件中写入方法

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14
@interface ylstouchidview : uiview

/**

* 快速创建

*/

+(instancetype)touchidview;

/**

* 弹出

*/

-(void)show;

-(void)showinview:(uiview *)view;

@end

第二步

在.m文件中声明控件,设置页面大小,以及遵守协议,在页面出来的同时就要调用验证服务。

?

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
@interface ylstouchidview()<wjtouchiddelegate>

/** 指纹解锁的button */

@property (nonatomic,strong) uibutton *touchidbtn;

/** 头像 */

@property (nonatomic,strong) uiimageview *iconview;

/** 用户名 */

@property (nonatomic,strong) uilabel *namelabel;

/** 提示信息 */

@property (nonatomic,strong) uilabel *noticelabel;

/** 手机号 */

@property (nonatomic,strong) nsstring *phonenumber;

/** 退出按钮 */

@property (nonatomic,strong) uibutton *quitbtn;

@property (nonatomic, strong) wjtouchid *touchid;

@end

-(instancetype)initwithframe:(cgrect)frame

{

self = [super initwithframe:ylsscreenbounds];

if (self)

{

self.backgroundcolor = [uicolor orangecolor];

}

//调用指纹解锁

wjtouchid *touchid = [[wjtouchid alloc]init];

[touchid startwjtouchidwithmessage:wjnotice(@"自定义信息", @"the custom message") fallbacktitle:wjnotice(@"", @"fallback title") delegate:self];

self.touchid = touchid;

return self;

}

第三步

设置控件的位置大小等等属性。

?

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
- (void)layoutsubviews

{

[super layoutsubviews];

self.iconview = [[uiimageview alloc]init];

[self.iconview setframe:zlrect(128/320, 54/568, 65/320, 65/568)];

[self.iconview setimage:[uiimage imagenamed:@"icon_myinformation"]];

[self addsubview:self.iconview];

self.namelabel = [[uilabel alloc]init];

[self.namelabel setframe:zlrect(0, 125/568, 1, 28/568)];

[self.namelabel settext:@"151****1234"];

[self.namelabel setfont:[uifont systemfontofsize:zcfont(15/375)]];

[self.namelabel settextcolor:[uicolor whitecolor]];

[self.namelabel settextalignment:nstextalignmentcenter];

[self addsubview:self.namelabel];

self.touchidbtn = [[uibutton alloc]init];

[self.touchidbtn setframe:zlrect(120/320, 250/568, 80/320, 80/568)];

[self.touchidbtn setimage:[uiimage imagenamed:@"touchimg"] forstate:uicontrolstatenormal];

[self.touchidbtn addtarget:self action:@selector(clicktochecktouchid) forcontrolevents:uicontroleventtouchupinside];

[self addsubview:self.touchidbtn];

self.noticelabel = [[uilabel alloc]init];

[self.noticelabel setframe:zlrect(0, 339/568, 1, 22/568)];

[self.noticelabel settext:@"点击进行指纹解锁"];

[self.noticelabel settextcolor:[uicolor whitecolor]];

[self.noticelabel settextalignment:nstextalignmentcenter];

[self.noticelabel setfont:[uifont systemfontofsize:zcfont(16/375)]];

[self addsubview:self.noticelabel];

self.quitbtn = [[uibutton alloc]init];

[self.quitbtn setframe:zlrect(0, 520/568, 1, 30/568)];

[self.quitbtn settitle:@"退出" forstate:uicontrolstatenormal];

[self.quitbtn addtarget:self action:@selector(quitcontent) forcontrolevents:uicontroleventtouchupinside];

[self addsubview:self.quitbtn];

}

第四步

实现控件的点击方法,以及在.h文件中声明的弹出方法

?

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
//快速创建

+ (instancetype)touchidview

{

return [[self alloc]init];

}

/** 弹出 */

- (void)show

{

[self showinview:[uiapplication sharedapplication].keywindow];

}

- (void)showinview:(uiview *)view

{

// 浮现

[view addsubview:self];

}

-(void)clicktochecktouchid

{

nslog(@"点击了指纹解锁");

[self.touchid startwjtouchidwithmessage:wjnotice(@"自定义信息", @"the custom message") fallbacktitle:wjnotice(@"", @"fallback title") delegate:self];

}

-(void)quitcontent

{

nslog(@"点击了quit");

[uiview animatewithduration:3 animations:^{

self.alpha = 0;

} completion:^(bool finished) {

[self removefromsuperview];

}];

}

上面再退出的时候我还加了一个小小的特效,就是颜色渐渐变成无色,这样有时候可以遮盖你app里面的一些小问题。偷个懒。

第五步

这里也是跟第一部分一样,实现验证的回调函数。这边的回调函数呢,跟之前的差不多,但是里面的内容就不一样了。而且我这里把不支持touchid的方法加进来,按理说这边是不需要加的,但是我前面没加进来,这里就硬塞进来吧。。。大家就凑合着看,自己用的时候可以直接删掉,不删掉也没事,就是增加点代码量而已。。。

?

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

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78
/**

* touchid验证成功

*/

- (void) wjtouchidauthorizesuccess {

[mbprogresshud showtext:@"解锁成功" view:self];

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

// [self dismissviewcontrolleranimated:yes completion:nil];

[self removefromsuperview];

}

/**

* touchid验证失败

*/

- (void) wjtouchidauthorizefailure {

[mbprogresshud showtext:@"解锁失败" view:self];

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

}

/**

* 取消touchid验证 (用户点击了取消)

*/

- (void) wjtouchidauthorizeerrorusercancel {

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

}

/**

* 在验证的touchid的过程中被系统取消 例如突然来电话、按了home键、锁屏...

*/

- (void) wjtouchidauthorizeerrorsystemcancel {

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

}

/**

* 无法启用touchid,设备没有设置密码

*/

- (void) wjtouchidauthorizeerrorpasscodenotset {

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

}

/**

* 设备没有录入touchid,无法启用touchid

*/

- (void) wjtouchidauthorizeerrortouchidnotenrolled {

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

}

/**

* 该设备的touchid无效

*/

- (void) wjtouchidauthorizeerrortouchidnotavailable {

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

}

/**

* 多次连续使用touch id失败,touch id被锁,需要用户输入密码解锁

*/

- (void) wjtouchidauthorizelaerrortouchidlockout {

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

}

/**

* 当前软件被挂起取消了授权(如突然来了电话,应用进入前台)

*/

- (void) wjtouchidauthorizelaerrorappcancel {

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

}

/**

* 当前软件被挂起取消了授权 (授权过程中,lacontext对象被释)

*/

- (void) wjtouchidauthorizelaerrorinvalidcontext {

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

}

/**

* 当前设备不支持指纹识别

*/

-(void)wjtouchidisnotsupport {

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

}

第三部分

这里呢,是最重要的地方,也是最简单的地方,只要在appdelegate.m文件中加上几句话就可以实现了。
在下面这个方法里面写,下面这个方法是呢app被唤醒进入活跃状态的方法

– (void)applicationdidbecomeactive:(uiapplication *)application

这边的知识点其实还挺多的,就是一个生命周期的问题,一个app运行完成,即将进入活跃状态,已经进入活跃状态,即将进入后台,已经进入后台状态,这几种状态,在之前我还想着声明一个变量让app在后台运行的时候,也跟着运行,类似于一个计时器,但是我看了网上的一些想要让app后台挂起的时候还能运行一些东西,设置过程就好几种,而且很多都说上架的时候审核是不给过得,想着有时间的话可以好好研究下那些方法,这里我就没有弄,所以才有了上面的

[[nsuserdefaults standarduserdefaults]setobject:@"yes" forkey:@"touchidison"];

这个值,本来也是设置成计时器的,但是这样好像更方便点,就这么设置了,因为为了全局都可以取到这个值。
在唤醒方法中写下代码

?

1

2

3

4

5

6

7

8

9

10

11

12
- (void)applicationdidbecomeactive:(uiapplication *)application {

nsstring *touchidexist = [[nsuserdefaults standarduserdefaults]objectforkey:@"touchid"];

nsstring *touchison = [[nsuserdefaults standarduserdefaults]objectforkey:@"touchidison"];

if ([touchidexist isequaltostring:@"1"] && [touchison isequaltostring:@"no"])

{

ylstouchidview *yls = [[ylstouchidview alloc]init];

[yls show];

}

dispatch_after(dispatch_time(dispatch_time_now, (int64_t)(20 * nsec_per_sec)), dispatch_get_main_queue(), ^{

[[nsuserdefaults standarduserdefaults]setobject:@"no" forkey:@"touchidison"];

});

}

下面那个呢就是为了防止重复调用,因为好像当页面出现指纹验证的弹出框的时候,app似乎就是被挂起到后台了,然后唤醒的时候又要被调用,所以这里出现了一个重复调用的问题,然后我就找个不是办法的办法来解决这个问题。就是用上面这段代码来处理,具体道理我也不知道咋说,就这么迷迷糊糊的实现了功能。这样子就是完成了一个指纹验证以及app唤醒的时候指纹解锁的一个小demo。present出来一个单独的页面的方式其实跟这个差不多,但是这篇文章的篇幅好像有点太长了,估计也没什么人看到最后,所以我就不写了,啥时候想补的话再补上来吧。

#### 还有就是,本人作为新手,上面代码有啥问题的话,或者有啥可以优化的地方,希望大家可以指正,大家一起共同进步共同学习。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 iOS指纹验证TouchID应用学习教程2 https://www.kuaiidc.com/91821.html

相关文章

发表评论
暂无评论