更改bundleid后蚂蚁金服MPSafeKeyboard的安全键盘不显示的解决办法

先看看安全键盘静态库的目录结构

MPSafeKeyboard.framework

使用上和其他公司推出的安全键盘相比。MPSafeKeyboard仅仅是一个键盘,其他公司的则是一个UITextField和键盘绑定在一起的。

在MPSafeKeyboardThemeManager这个类中可以自定义一些键盘的样式颜色,其他键盘则没有。

//
//  MPSafeKeyboardThemeManager.h
//  MPSafeKeyboard
//
//  Created by wenzhao on 2018/10/12.
//  Copyright © 2018 Alipay. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

#define MPSafeKeyboardThemeManagerInstance [MPSafeKeyboardThemeManager sharedInstace]

@interface MPSafeKeyboardThemeManager : NSObject

// key 颜色
@property (strong, nonatomic) UIColor *keyTextColor;

// 普通 key 背景色
@property (strong, nonatomic) UIColor *keyNormalBgColor;

// 功能 key 背景色
@property (strong, nonatomic) UIColor *keySpecialBgColor;

// ASCII 键盘普通 key 背景图片
@property (strong, nonatomic) UIImage *keyASCIIBGImage;

// ASCII 键盘特殊 key 背景图片
@property (strong, nonatomic) UIImage *keyASCIISpecialBGImage;

// 数字键盘分割线颜色
@property (strong, nonatomic) UIColor *keySplitLineColor;

// 键盘上方 bar 的背景色
@property (strong, nonatomic) UIColor *keyboardBarBgColor;

// 键盘背景色
@property (strong, nonatomic) UIColor *keyboardBgColor;

// 键盘上方 bar 完成按钮文字颜色
@property (strong, nonatomic) UIColor *keyboardBarDoneColor;

// 键盘上方 bar Logo 文字颜色
@property (strong, nonatomic) UIColor *keyboardBarLogoColor;

// 键盘上方 bar logo icon
@property (strong, nonatomic) UIImage *keyboardBarLogoIcon;

// 键盘上方 bar logo 文案
@property (strong, nonatomic) NSString *keyboardBarLogoText;

// 键盘上方 bar 完成按钮文案
@property (strong, nonatomic) NSString *keyboardBarDoneText;

// 重置为默认配置
- (void)useDefault;

+ (instancetype)sharedInstace;

@end

NS_ASSUME_NONNULL_END

 

然后开始正文

 

更换bundleid后打包发现安全键盘输入框弹出了一个普通的系统键盘,bundleid恢复后没有问题。问题一定是在获取bundleid的地方。

获取bundleid有三个办法:

1.NSBundle的bundleIdentifier方法

2.直接读取Info.plist这个文件

3.NSBundle的infoDictionary方法

 

验证:

1.替换bundleIdentifier

#import "NSBundle+yyy.h"
#import <objc/runtime.h>
@implementation NSBundle (yyy)
+ (void)load{
        Method originalMethod = class_getInstanceMethod([NSBundle class], @selector(bundleIdentifierS));
        Method swizzledMethod = class_getInstanceMethod([NSBundle class], @selector(bundleIdentifier));
        method_exchangeImplementations(originalMethod, swizzledMethod);
        }
}
- (NSString *)bundleIdentifierS{
    return @"没问题的bundleid";
}

一般情况下,这样改就行,但是发现更换后无效果

 

 

2.替换Info.plist这个文件

先创建一个InfoYYY.plist,只将其中的唯一标识改一下

int main(int argc, char * argv[]) {

        。。。其他原来代码。。。

        rebind_symbols((struct rebinding[2]){{"close", my_close, (void *)&orig_close}, {"open", my_open, (void *)&orig_open}}, 2);
        
        // Open our own binary and print out first 4 bytes (which is the same
        // for all Mach-O binaries on a given architecture)
        int fd = open(argv[0], O_RDONLY);
        uint32_t magic_number = 0;
        read(fd, &magic_number, 4);
        printf("Mach-O Magic Number: %x \n", magic_number);
        close(fd);

        。。。其他原来代码。。。
}
int my_open(const char *path, int oflag, ...) {
    va_list ap = {0};
    mode_t mode = 0;
    
    if ((oflag & O_CREAT) != 0) {
        // mode only applies to O_CREAT
        va_start(ap, oflag);
        mode = va_arg(ap, int);
        va_end(ap);

        printf("Calling real open('%s', %d, %d)\n", path, oflag, mode);

        return orig_open(path, oflag, mode);
    } else {
        
        NSString *pathOri = [[NSString alloc]initWithUTF8String:path];
        if([pathOri rangeOfString:@"XXX.app/Info.plist"].length > 0){
            path = [[pathOri stringByReplacingOccurrencesOfString:@"Info.plist" withString:@"InfoYYY.plist"] UTF8String];
            printf("Calling real open('%s', %d)\n", path, oflag);

        }
        
        
        return orig_open(path, oflag, mode);
    }
}

发现这个办法也不行

3.交换infoDictionary方法

#import "NSBundle+yyy.h"
#import <objc/runtime.h>
@implementation NSBundle (yyy)

+ (void)load{
    {
        Method originalMethod = class_getInstanceMethod([NSBundle class], @selector(infoDictionaryS));
        Method swizzledMethod = class_getInstanceMethod([NSBundle class], @selector(infoDictionary));
        method_exchangeImplementations(originalMethod, swizzledMethod);
        
    }
}
- (NSDictionary*)infoDictionaryS{
    
    NSMutableDictionary *dicc = [self infoDictionaryS].mutableCopy;
    [dicc setObject:@"正式的" forKey:@"CFBundleIdentifier"];
    return dicc;
}

这个方法有用。看来就是这个方法。

然后用模拟器跑一下,将有nil值的地方改一下,能够正常登录,但是界面图片展示不正常,因为系统自己也调用了这个方法。

蚂蚁框架里面调用的也不少,还需要继续查看是调用的哪个。

 

蚂蚁框架里面调用的比如:

-[APLogAdditions clientVersion]:

-[DTSyncInterface productVersion]:

+[APSyncUtils productID]:

-[DynamicReleaseInterface productId]:

-[MPImageBaker checkAppVersionChanged]:

 

这些都不用管

 

在创建安全键盘的时候 是一个c的方法verifyLicense调用的infodic方法。先不对其hook。

直接在安全键盘创建前后添加全局变量useHookBundleid 来控制何时替换bundleid.

全局变量声明
@property (nonatomic,assign)BOOL useHookBundleid;


infoDictionaryS修改

- (NSDictionary*)infoDictionaryS{
    NSMutableDictionary *dicc = [self infoDictionaryS].mutableCopy;
    if ([Global sharedD].useHookBundleid == YES) {
        [dicc setObject:@"正式的" forKey:@"CFBundleIdentifier"];
    }
    return dicc;
}


安全键盘创建的前后设置开关


    [Global sharedData].useHookBundleid = YES;
    
    [MPEncrySafeKeyboard keyboardWithType:MPSafeKeyboardTypeASCIICapable encryType:MPEncrySafeKeyboardEcryTypeSM2
                                publicKey:sm2PubKey
                              resultBlock:^(NSString *result, NSUInteger inputAmount, BOOL isConfirmed) {
                                                        
                                                        
                                  
                              }];
    [Global sharedData].useHookBundleid = NO;

 

 

这样既保证其他功能正常使用,也可以正常弹出键盘。

 

 

20191108补充

但是还有一个问题  多少个地方使用了安全键盘 就得在多少个地方添加

代码很分散,所以

一劳永逸就是 hook创建键盘方法,加上判断逻辑,只改一个地方即可

//
//  MPEncrySafeKeyboard+YYY.h
// 
//
//  Created by YYY on 2019/11/8.
//  Copyright © 2019 Alibaba. All rights reserved.
//

#import <MPSafeKeyboard/MPSafeKeyboard.h>

NS_ASSUME_NONNULL_BEGIN

@interface MPEncrySafeKeyboard (YYY)

@end

NS_ASSUME_NONNULL_END

 

//
//  MPEncrySafeKeyboard+YYY.m
// 
//
//  Created by YYY on 2019/11/8.
//  Copyright © 2019 Alibaba. All rights reserved.
//

#import "MPEncrySafeKeyboard+YYY.h"
#import <objc/runtime.h>

@implementation MPEncrySafeKeyboard (YYY)
+ (void)load{
    Method originalMethod = class_getClassMethod([self class], @selector(keyboardWithType:encryType:publicKey:resultBlock:));
    Method swizzledMethod = class_getClassMethod([self class], @selector(keyboardWithType:encryType:publicKey:resultBlockS:));
    method_exchangeImplementations(originalMethod, swizzledMethod);
}
 
+ (instancetype)keyboardWithType:(MPSafeKeyboardType)keyboardType
                   encryType:(MPEncrySafeKeyboardEcryType)encryType
                   publicKey:(nullable NSString *)publicKey
                 resultBlockS:(MPEncrySafeKeyboardResultBlock)resultBlock;{

    [Global sharedData].useHookBundleid = YES;
    id ss = [self keyboardWithType:keyboardType encryType:encryType publicKey:publicKey resultBlockS:resultBlock];
    [Global sharedData].useHookBundleid = NO;

    return ss;
}

@end

 

 

😊😊😊

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值