问题描述
我有一个 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!