Cocoa: How to save NSAttributedString in JSON

I have an object NSAttributedStringas a property of a custom object. I need to save this custom object to disk in JSON format . Later I need to send JSON data over the network to a Java server.
I can not use the method of the -(NSString) stringobject NSSAttributedString, because I need to restore the recovered string from disk and to the server.

+4
source share
3 answers

NSAttributedString has two properties:

  • line
  • an array of attributes "works"

Each “launch” has:

  • integer range that applies to
  • key / value attribute dictionary

JSON, enumerateAttributesInRange:options:usingBlock:.

- :

{
  "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: :

// 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);
+10

RTFFromRange:

: OS X, RTF,..., . NSAttributedString.

RTF . RTFFromRange: NSData; , , , , NSString.

(, MacOS X).

+2

NSAttributedString XML NSAttributedString. JSON, .

NSAttributedString.

    let data = NSMutableData()

    let archiver = NSKeyedArchiver(forWritingWithMutableData: data)
    archiver.outputFormat = .XMLFormat_v1_0
    textView.attributedText.encodeWithCoder(archiver)
    archiver.finishEncoding()

    let textAsString = NSString(data: data, encoding: NSUTF8StringEncoding)'
+2
source

Source: https://habr.com/ru/post/1533231/


All Articles