一、場景
H5經常會需要選擇手機照片來完善自身內容;比如上傳身份證照片痹雅、資產照片等等等。有時候這些照片經常需要app處理完后才上傳給H5糊识,那么這時候作為app的你就必須先處理好H5選擇的手機照片绩社,再上傳給他。所以本文接下來將講解如何攔截處理H5選擇的手機照片赂苗;
二愉耙、基礎知識準備
普及基礎知識:
H5選擇手機照片的方式主要有兩種:
- 1、通過與app的JS交互拌滋,選擇手機照片朴沿;
- 2、通過H5自身的<input>標簽败砂,選擇手機照片悯仙;
第一種JS交互的,圖片數據的獲取太容易處理了吠卷,就不再這里講了锡垄。我們這邊主要講H5通過H5自身的<input>標簽,選擇手機照片祭隔。
三货岭、攔截方法
這里我們先講怎么實現,下一點再介紹思路疾渴。
實現方式很簡單
1千贯、添加已CJFileUploadPanel類
pod 'CJHook/CJFileUploadPanel'
CJFileUploadPanel類源碼
image.png
2、建立DemoFileUploadPanel
類搞坝,使用CJFileUploadPanel
提供的接口實現你攔截后的圖片處理搔谴。
DemoFileUploadPanel.h
#import <Foundation/Foundation.h>
@interface DemoFileUploadPanel : NSObject
+ (void)startHook;
+ (void)stopHook;
@end
DemoFileUploadPanel.m
#import "DemoFileUploadPanel.h"
#import <CJHook/CJFileUploadPanel.h>
#import "DemoCacheUtil.h"
@implementation DemoFileUploadPanel
+ (void)startHook {
__weak typeof(self)weakSelf = self;
[CJFileUploadPanel startHookWithAbsoluteFilePathHandle:^NSString *(UIImage *originImage) {
NSData *newImageData = [weakSelf dealImage:originImage];![分割圖1.jpg](https://upload-images.jianshu.io/upload_images/6214155-49f701e7162b8ec8.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
// 保存圖片到本地
NSString *absoluteFilePath = [DemoCacheUtil saveImageData:newImageData forModuleType:DemoModuleTypeIot];
sleep(5); //用來測試是否主線程是否會被阻塞(請在選擇圖片后,選擇返回桩撮,看是否卡住)
return absoluteFilePath;
}];
}
+ (void)stopHook {
[CJFileUploadPanel stopHook];
}
+ (NSData *)dealImage:(UIImage *)image {
UIImage *newImage = [UIImage imageNamed:@"飲品2.jpg"];
NSData *newImageData = UIImagePNGRepresentation(newImage);
return newImageData;
}
@end
3敦第、調用
略。
如果你還想了解思路或者原理店量,請往下看芜果,如果只是想使用的話,到這里就可以了融师。
四右钾、攔截的思路分析
攔截的思路:1、攔截、替換系統(tǒng)方法舀射;2窘茁、在新方法中按產品需求處理圖片;
詳細步驟如下脆烟。
1山林、攔截、替換系統(tǒng)方法
即:將在WKFileUploadPanel
中實現的UIImagePickerController
代理方法imagePickerController:didFinishPickingMediaWithInfo:
替換為你在其他類中寫的其他方法浩淘。因為系統(tǒng)沒提供WKFileUploadPanel
這個類給你來讓你在該類中直接寫交換的方法。
所以我們這里是將其替換為你在CJHookFileUploadPanel類中實現的- (void)swizzled_imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
方法吴攒。
通過此步张抄,你就能夠在新寫的方法- (void)swizzled_imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
里面獲取到圖片選擇器選取到的圖片數據了。
@implementation CJHookFileUploadPanel
+ (void)hookFileUploadPanel:(BOOL)hook {
SEL originalSelector = @selector(imagePickerController:didFinishPickingMediaWithInfo:);
SEL swizzledSelector = @selector(swizzled_imagePickerController:didFinishPickingMediaWithInfo:);
Class originalClass = NSClassFromString(@"WKFileUploadPanel");
Class otherClass = [CJHookFileUploadPanel class];
if (hook) {
bool success = HookCJHelper_exchangeOriMethodToNewMethodWhichAddFromDiffClass(originalClass, originalSelector, otherClass, swizzledSelector);
NSLog(@"exchangeOriMethodToNewMethod:%@", success ? @"success": @"failure");
} else {
bool success = HookCJHelper_recoverOriMethodToNewMethodWhichAddFromDiffClass(originalClass, originalSelector, otherClass, swizzledSelector);
NSLog(@"recoverOriMethodToNewMethod:%@", success ? @"success": @"failure");
}
}
- (void)swizzled_imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
NSMutableDictionary *new_info = [[NSMutableDictionary alloc] initWithDictionary:info];
// 在這里按產品需求處理圖片得到新new_info......
[self swizzled_imagePickerController:picker didFinishPickingMediaWithInfo:new_info];
}
@end
上述為某類添加另一個類中的方法的實現代碼詳見HookCJHelper
HookCJHelper源碼
image.png
結束語
感謝閱讀洼怔!