Cocoa:如何将NSAttributedString保存为JSON [英] Cocoa: How to save NSAttributedString to JSON

查看:362
本文介绍了Cocoa:如何将NSAttributedString保存为JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 NSAttributedString 对象作为自定义对象的属性。我需要以 JSON 格式将此自定义对象保存到磁盘。后来我需要通过网络将这个JSON数据发送到Java服务器。

我不能使用 - (NSString)string NSSAttributedString 对象,因为我需要能够重建磁盘和服务器上的属性字符串。

解决方案

NSAttributedString有两个属性:




  • 字符串



  • 每个run都有:




    • 一个整数范围适用于

    • 键/值属性字典



    使用 enumerateAttributesInRange:options:usingBlock:将很容易表示为JSON。



    类似:

      {
    string:Hello World,
    runs :[
    {
    range:[0,3],
    attributes:{
    font:{
    name:Arial ,
    size:12
    }
    }
    },
    {
    range:[3,6],
    属性:{
    font:{
    name:Arial,
    size:12
    },
    color:[255 ,0,0]
    }
    },
    {
    range:[9,2],
    attributes:{
    font :{
    name:Arial,
    size:12
    }
    }
    }
    ]
    } b $ b

    EDIT:这里是一个示例实现:



    //创建基本属性字符串
    NSMutableAttributedString * attStr = [[NSMutableAttributedString alloc] initWithString:@Hello World属性:@ {NSFontAttributeName: NSFont fontWithName:@Arialsize:12]}];
    [attStr addAttribute:NSForegroundColorAttributeName value:[NSColor redColor] range:NSMakeRange(3,6)];

    //构建属性运行数组
    NSMutableArray * attributeRuns = [NSMutableArray array];
    [attStr enumerateAttributesInRange:NSMakeRange(0,attStr.length)options:0 usingBlock:^(NSDictionary * attrs,NSRange range,BOOL * stop){
    NSArray * rangeArray = @ [[NSNumber numberWithUnsignedInteger:range .location],
    [NSNumber numberWithUnsignedInteger:range.length]];

    NSMutableDictionary * runAttributes = [NSMutableDictionary dictionary];
    [attrs enumerateKeysAndObjectsUsingBlock:^(id attributeName,id attributeValue,BOOL * stop){

    if([attributeName isEqual:NSFontAttributeName]){//将字体值转换为字典和size
    attributeName = @font;
    attributeValue = @ {@name:[(NSFont *)attributeValue displayName],
    @size:[NSNumber numberWithFloat:[(NSFont *)attributeValue pointSize]

    } else if([attributeName isEqualToString:NSForegroundColorAttributeName]){//将前景颜色值转换为一个数字,将红/绿/蓝作为0到255的数字
    attributeName = @颜色;
    attributeValue = @ [[NSNumber numberWithInteger:([NSColor *)attributeValue redComponent] * 255)],
    [NSNumber numberWithInteger:([NSColor *)attributeValue greenComponent] * 255)],
    [NSNumber numberWithInteger:([(NSColor *)attributeValue blueComponent] * 255)]];

    } else {//跳过未知属性
    NSLog(@跳过未知属性%@,attributeName);
    return;
    }


    [runAttributes setObject:attributeValue forKey:attributeName];
    }];

    //保存属性(如果有的话)
    if(runAttributes.count == 0)
    return;

    [attributeRuns addObject:@ {@range:rangeArray,
    @attributes:runAttributes}];
    }];

    // build JSON output
    NSDictionary * jsonOutput = @ {@string:attStr.string,
    @runs:attributeRuns};
    NSData * jsonData = [NSJSONSerialization dataWithJSONObject:jsonOutput options:NSJSONWritingPrettyPrinted error:NULL];

    NSLog(@%@,[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]);
    exit(0);


    I have a NSAttributedString object as a property of a custom object. I need to save this custom object to the disk in JSON format. Later I need to send this JSON data across the network to a Java Server.
    I can't use the -(NSString) string method of the NSSAttributedString object because I need to be able to reconstruct the attributed string off the disk and on the server.

    解决方案

    NSAttributedString has two properties:

    • the string
    • an array of attribute "runs"

    Each "run" has:

    • an integer range that it applies to
    • a dictionary of key/value attributes

    It would be very easy to represent that as JSON, using enumerateAttributesInRange:options:usingBlock:.

    Something like:

    {
      "string" : "Hello World",
      "runs" : [
        {
          "range" : [0,3],
          "attributes" : {
            "font" : {
              "name" : "Arial",
              "size" : 12
            }
          }
        },
        {
          "range" : [3,6],
          "attributes" : {
            "font" : {
              "name" : "Arial",
              "size" : 12
            },
            "color" : [255,0,0]
          }
        },
        {
          "range" : [9,2],
          "attributes" : {
            "font" : {
              "name" : "Arial",
              "size" : 12
            }
          }
        }
      ]
    }
    

    EDIT: here's an example implementation:

    // create a basic attributed string
    NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:@"Hello World" attributes:@{NSFontAttributeName: [NSFont fontWithName:@"Arial" size:12]}];
    [attStr addAttribute:NSForegroundColorAttributeName value:[NSColor redColor] range:NSMakeRange(3, 6)];
    
    // build array of attribute runs
    NSMutableArray *attributeRuns = [NSMutableArray array];
    [attStr enumerateAttributesInRange:NSMakeRange(0, attStr.length) options:0 usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stop) {
      NSArray *rangeArray = @[[NSNumber numberWithUnsignedInteger:range.location],
                              [NSNumber numberWithUnsignedInteger:range.length]];
    
      NSMutableDictionary *runAttributes = [NSMutableDictionary dictionary];
      [attrs enumerateKeysAndObjectsUsingBlock:^(id attributeName, id attributeValue, BOOL *stop) {
    
        if ([attributeName isEqual:NSFontAttributeName]) { // convert font values into a dictionary with the name and size
          attributeName = @"font";
          attributeValue = @{@"name": [(NSFont *)attributeValue displayName],
                             @"size": [NSNumber numberWithFloat:[(NSFont *)attributeValue pointSize]]};
    
        } else if ([attributeName isEqualToString:NSForegroundColorAttributeName]) { // convert foreground colour values into an array with red/green/blue as a number from 0 to 255
          attributeName = @"color";
          attributeValue = @[[NSNumber numberWithInteger:([(NSColor *)attributeValue redComponent] * 255)],
                             [NSNumber numberWithInteger:([(NSColor *)attributeValue greenComponent] * 255)],
                             [NSNumber numberWithInteger:([(NSColor *)attributeValue blueComponent] * 255)]];
    
        } else { // skip unknown attributes
          NSLog(@"skipping unknown attribute %@", attributeName);
          return;
        }
    
    
        [runAttributes setObject:attributeValue forKey:attributeName];
      }];
    
      // save the attributes (if there are any)
      if (runAttributes.count == 0)
        return;
    
      [attributeRuns addObject:@{@"range": rangeArray,
                                 @"attributes": runAttributes}];
    }];
    
    // build JSON output
    NSDictionary *jsonOutput = @{@"string": attStr.string,
                                 @"runs": attributeRuns};
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonOutput options:NSJSONWritingPrettyPrinted error:NULL];
    
    NSLog(@"%@", [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]);
    exit(0);
    

    这篇关于Cocoa:如何将NSAttributedString保存为JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆