向js发送含有NSDictionary对象或NSArray对象的消息

简介: 向js发送含有NSDictionary对象或NSArray对象的消息

先把NSDictionary对象或NSArray对象转化为json字符串,然后去掉空格和换行符,然后拼接字符,调用WKWebView的evaluateJavaScript方法向js发送消息。

js调用WKWebView的注册函数通过特殊的格式发送消息:window.webkit.messageHandlers.WeipaiJSBridge.postMessage({title:’测试分享的标题’,content:’测试分享的内容’,url:’https://github.com/mayin1992‘});

WeipaiJSBridge是WKWebView注册的函数,括号里面的是发送的json字符串。

那么在WKWebView页面向js发送消息也是按照特别格式发送的:wxCallBack.chooseImage.success({“localIds”:[“yxLocalFile:\/\/9B445E4B-6559-4352-9186-69A82A3E5332\/L0\/001.PNG”,”yxLocalFile:\/\/3F0D46B1-A473-4020-9D3A-D55751D44163\/L0\/001.GIF”]});

其中wxCallBack是js里面的对象名,chooseImage其中的成员变量,success是方法名,括号中的是相应消息的json字符串,最后要以分号结束。这个相应消息字符串如何产生呢?里面有转义符号,不可能一个一个拼接吧。要说一个一个拼接那也太low了,iOS自带现成的转换函数为何不用呢?但是也不是所有都靠它,也要结合字符串拼接。你直接给js发送一个NSDictionary对象,js也解析不了,NSDictionary变量只是一个地址,js可没有这种类型,你向服务器发送不外乎是字符串(本问介绍的向服务器发送的消息中键值对json串)或数据流(如:《WKWebView采用HybridNSURLProtocol协议拦截图片等资源预加载》所介绍的图片预加载,返回给js就是图片的NSData数据流)。参照《WKWebView和js互调方法的实现》更便于理解。

我拼装转换这些消息时,走过很多弯路。要在拼装后去掉空格和换行符,这个茅坑我掉进去过。不能转换过为json字符串拼装字符串后再调用转换函数转换成json,这个茅坑我掉进去过。正确的做法是:把要转换的NSDictionary对象或NSArray等复合对象转换成json字符串,然后拼接字符串。若你的NSDictionary对象不是简单的键值对,而是值为一个非字符串对象,那么你就悲剧了,那么你只能把那个非字符串对象转换成json字符串,其它的你自己拼接去吧,当然你也可以采用把那个值设置一个特定字符串,把这个值修改过的NSDictionary对象转化为json字符串,把那个键值对象也转换为json字符串,别忘记去空格和换行符,然后把那个设置的特殊的字符串替换那个键值对象json字符串,然后去拼装字符就可以了。当然你那个键值对里若含有了你那个特殊字符串就乱套了,可以把那个特殊字符串设置长些,可以避免这种情况。同样处理NSArray复合对象问题。当然最好在设计上不要设计成这样的复合对象数据。

下面是我代码中一个把根据PHAsset对象数组,把取出的localIdentifier存入NSMutableArray类型组,把它转换成json字符串,拼装向服务器发送的消息。注释的部分是当时的部分测试代码:

-(void)chooseImageResponseWithPhotos:(NSArray<UIImage *> *)photos
                              assets:(NSArray *)assets
{

    if((photos.count == 0) || (assets.count == 0))
    {
        return;
    }
    NSMutableArray *localIds = [NSMutableArray array];
    for(NSUInteger i = 0; (i < assets.count) && (i < photos.count); i++)
    {
        PHAsset *phAsset = assets[i];
        NSString *localIdentifier = phAsset.localIdentifier;
        NSString*fileName=[phAsset valueForKey:@"filename"];
        NSLog(@"File name %@",fileName);
        NSArray* arr = [fileName componentsSeparatedByString:@"."];
        NSString *fileExtend = @"";
        if(arr.count != 0)
        {
            fileExtend = [NSString stringWithFormat:@".%@", arr[arr.count - 1]];
        }
        NSString *yxLocalFile = [NSString stringWithFormat:@"yxLocalFile://%@%@", localIdentifier,fileExtend];
        [localIds addSafeObject:yxLocalFile];
//        UIImage *image = photos[i];
//        [self storageImageWithFilePath:filePath image:image];
    }
    NSLog(@"localIds :%@", localIds);
    NSString *localIdsString = [localIds getJsonString];
    NSLog(@"localIdsString :%@", localIdsString);
//    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
//    [dic setSafeObject:localIds forKey:@"localIds"];
//    NSString *jsonString = [dic getJsonString];
//    NSLog(@"jsonString :%@", jsonString);

    NSString *callBackStr = @"";
//    callBackStr = @"{\"localIds\":\"[\"yxLocalFile:/var/mobile/Containers/Data/Application/5F229EFD-CABA-46C7-A292-6ED0D6863220/Documents/chooseImageDir/b63745ef93585a46aa22e270f8af285b.png\"]\"}";
//    callBackStr = [NSString stringWithFormat:@"wxCallBack.chooseImage.success(%@);", callBackStr];
    if(isEmptyString(localIdsString))
    {
        callBackStr = @"wxCallBack.chooseImage.fail();";
    }
    else
    {
//        callBackStr = [NSString stringWithFormat:@"wxCallBack.chooseImage.success(%@)};", jsonString];
    callBackStr = [NSString stringWithFormat:@"wxCallBack.chooseImage.success({\"localIds\":%@});", localIdsString];

//    callBackStr = [NSString stringWithFormat:@"wxCallBack.chooseImage.success({\"localIds\":[\"yxLocalFile:\/\/5B85924B-E238-4173-A084-CAC3E023BA12\/L0\/001\"]});"];

//    callBackStr = [NSString stringWithFormat:@"wxCallBack.chooseImage.success({\"localIds\":[\"yxLocalFile://5B85924B-E238-4173-A084-CAC3E023BA12/L0/001\"]});"];
    }
    NSLog(@"callBackStr :%@", callBackStr);

    [self callBackWithCallBackStr:callBackStr];
}

NSArray扩展类处理转换json字符串,根据下标安全获取数组元素的完成代码:

NSArray+SafeCheck.h文件

//  NSArray+SafeCheck.h
#import <Foundation/Foundation.h>

@interface NSArray (SafeCheck)

- (id)objectAtSafeIndex:(NSUInteger)index;

-(NSString *)getJsonString;
@end

NSArray+SafeCheck.m文件

//  NSArray+SafeCheck.m
#import "NSArray+SafeCheck.h"

@implementation NSArray (SafeCheck)

- (id)objectAtSafeIndex:(NSUInteger)index
{
    if (index >= self.count) {
        return nil;
    }
    return [self objectAtIndex:index];
}

-(NSString *)getJsonString
{
    NSError *error;
    NSData *infoData = [NSJSONSerialization dataWithJSONObject:self options:NSJSONWritingPrettyPrinted error:&error];
    NSString *infoString = @"";
    if (infoData) {
        infoString = [[NSString alloc] initWithData:infoData encoding:NSUTF8StringEncoding];
        infoString = [infoString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

        infoString = [infoString stringByReplacingOccurrencesOfString:@"\n" withString:@""];
        infoString = [infoString stringByReplacingOccurrencesOfString:@" " withString:@""];
    }
    return infoString;
}

@end

NSDictionary扩展类处理转换json字符串,根据key安全获取value的完成代码:

NSDictionary+SafeCheck.h文件

//NSDictionary+SafeCheck.h
#import <Foundation/Foundation.h>

@interface NSDictionary (SafeCheck)

- (id)safeObjectForKey:(NSString *)aKey;

- (NSString *)jsonString;
-(NSString *)getJsonString;

- (BOOL)containKey:(NSString *)key;

- (NSDictionary *)deepCopy;


@end

NSDictionary+SafeCheck.m文件

//  NSDictionary+SafeCheck.m
#import "NSDictionary+SafeCheck.h"

@implementation NSDictionary (SafeCheck)

- (id)safeObjectForKey:(NSString *)aKey
{
    if (![self containKey:aKey]) {
        return nil;
    }
    return [self objectForKey:aKey];
}

- (NSString *)jsonString
{
    NSData *data = [NSJSONSerialization dataWithJSONObject:self options:NSJSONWritingPrettyPrinted error:nil];
    return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}

- (BOOL)containKey:(NSString *)key
{
    return [[self allKeys] containsObject:key];
}

- (NSDictionary *)deepCopy
{
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self];
    return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}

-(NSString *)getJsonString
{
    NSError *error;
    NSData *infoData = [NSJSONSerialization dataWithJSONObject:self options:NSJSONWritingPrettyPrinted error:&error];
    NSString *infoString = @"";
    if (infoData) {
        infoString = [[NSString alloc] initWithData:infoData encoding:NSUTF8StringEncoding];
        infoString = [infoString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

        infoString = [infoString stringByReplacingOccurrencesOfString:@"\n" withString:@""];
        infoString = [infoString stringByReplacingOccurrencesOfString:@" " withString:@""];
    }
    return infoString;
}

@end
目录
相关文章
|
1天前
|
JavaScript 前端开发 Unix
Node.js 全局对象
Node.js 全局对象
7 2
|
2天前
|
JavaScript 前端开发
深入解析JavaScript中的面向对象编程,包括对象的基本概念、创建对象的方法、继承机制以及面向对象编程的优势
【6月更文挑战第12天】本文探讨JavaScript中的面向对象编程,解释了对象的基本概念,如属性和方法,以及基于原型的结构。介绍了创建对象的四种方法:字面量、构造函数、Object.create()和ES6的class关键字。还阐述了继承机制,包括原型链和ES6的class继承,并强调了面向对象编程的代码复用和模块化优势。
11 0
|
2天前
|
存储 JSON JavaScript
JavaScript基础-对象与JSON
【6月更文挑战第11天】本文介绍了JavaScript对象的创建(字面量、构造函数、Class)与操作,包括属性访问和描述符。同时讲解了JSON的性质及其与JS对象的关系,以及序列化和解析过程。文章还列举了三个常见易错点(属性访问错误、JSON格式错误、循环引用)并提供了避免策略。通过代码示例展示如何操作对象和处理JSON,强调实践对于掌握这些概念的重要性。
|
10天前
|
JSON JavaScript 数据格式
1.js动态的往json数据添加新属性和值 2.JSON 和 JS 对象互转 3.对象转化为数组
1.js动态的往json数据添加新属性和值 2.JSON 和 JS 对象互转 3.对象转化为数组
13 0
|
20天前
|
XML JavaScript 前端开发
JavaScript简介&引入方式(JavaScript基础语法、JavaScript对象、BOM、DOM、事件监听)
JavaScript简介&引入方式(JavaScript基础语法、JavaScript对象、BOM、DOM、事件监听)
14 2
|
22天前
|
Web App开发 JavaScript 前端开发
JavaScript 中的 Range 和 Selection 对象
JavaScript 中的 `Range` 和 `Selection` 对象用于处理文本选择。`Range` 表示文档中选定的区域,而 `Selection` 表示用户选择的文本或光标位置。`Range` 可以创建并设置于任何元素或文本,具有多个属性(如 `startContainer`, `endContainer`, `collapsed`)和方法(如 `cloneContents`, `deleteContents`)。`Selection` 提供了获取和操作用户选择的方法,如 `anchorNode`, `focusNode` 和 `addRange`。两者在所有现代浏览器中基本兼容。
6 1
JavaScript 中的 Range 和 Selection 对象
|
24天前
|
前端开发 JavaScript
前端 JS 经典:判断对象属性是否存在
前端 JS 经典:判断对象属性是否存在
21 0
|
27天前
|
JSON 前端开发 JavaScript
前端 JS 经典:JSON 对象
前端 JS 经典:JSON 对象
22 0
|
27天前
|
前端开发 JavaScript
前端 js 经典:原型对象和原型链
前端 js 经典:原型对象和原型链
26 1
|
28天前
|
JavaScript 前端开发 流计算
使用JavaScript 中的Math对象和勾股定理公式,计算鼠标的位置与页面图片中心点的距离,根据距离对页面上的图片进行放大或缩小处理
使用JavaScript 中的Math对象和勾股定理公式,计算鼠标的位置与页面图片中心点的距离,根据距离对页面上的图片进行放大或缩小处理