向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

猜你喜欢

转载自blog.csdn.net/jia12216/article/details/82255402