Próbuję przechowywać NSMutableAttributedString
w CoreData
, ale mam problemy, ponieważ niektóre z atrybutów moich NSMutableAttributedString
zawierają obiekty Core Foundation, których nie można zarchiwizować. Czy istnieje prosty sposób, aby ten obiekt był przechowywany w CoreData bez konieczności ręcznego robienia bałaganu?Prosty sposób na przechowywanie NSMutableAttributedString w CoreData
Odpowiedz
Zacząłem używać CoreText
, gdy system iOS5 był niedostępny, a tym samym używał wartości Core Foundation jako atrybutów. Jednak teraz zdaję sobie sprawę, że odkąd wyszedł iOS6, mogę teraz używać w słowniku atrybutów: NSForegroundColorAttributeName
, itd. Do klawiszy tych dołączone są takie obiekty, jak UIColor
, NSMutableParagraphStyle
i UIFont
, które można archiwizować.
NSMutableAttributedString
jest zgodny z NSCoding
, co oznacza, że wie, jak przekonwertować się na/z NSData
i robi to za pośrednictwem protokołu, który Core Data wie, jak używać.
Utwórz atrybut "przekształcalny", a następnie po prostu przypisz do niego przypisane łańcuchy. Ponieważ jest to przekształcalne, Core Data użyje NSCoding
, aby przekonwertować go na NSData
po przypisaniu wartości i przekonwertować ją z powrotem na przypisany ciąg, gdy go przeczytasz.
Uwaga: nie można użyć predykatu do filtrowania wyników w tym polu. Ale przechowywanie i pobieranie jest proste.
Jest zgodny z NSCoding, ale możliwe, że jego właściwości nie będą (atrybuty). –
Więc nie jestem pewien, co chce zrobić z przypisywanego ciąg, ale jeśli jest to tekst sformatowany wtedy nie można użyć NSFont, etc ..
Spójrz tutaj http://ossh.com.au/design-and-technology/software-development, napisałem parę rzeczy na temat formatowania stylów i obrazów za pomocą uitextview i nstextview, ale w większości chodzi o przypisane ciągi.
Wszystko to jest przechowywane w danych podstawowych.
Chociaż powyższa odpowiedź jest dobra, to ma jedną wielką wadę:
nie jest możliwe zbudowanie pobrać wniosek/predykat że kwerendy zawartości obiektu NSAttributedString!
Predykat tak spowoduje wyjątek, kiedy wykonywane: jest to potrzebne
[NSPredicate predicateWithFormat:@"(content CONTAINS[cd] %@)", @"test"]];
aby przechowywać „fetchable” NSAttributedString w podstawowych danych do rozlał NSAttributedString na dwie części: po stronie NSString (który może być pobrane) i stronę NSData, która przechowuje atrybuty.
Podział ten może być osiągnięty poprzez utworzenie trzech atrybutów jednostki DANE PODSTAWOWE:
- atrybut cień NSString („contentString”)
- cień NSData atrybutu („contentAttributes”)
- 'undefined' transient attributed ('content')
W niestandardowej klasie encji "treść" przypisana do utworzonej z cienia i zmiany do atrybutu są również lustrem jego cienie.
plik nagłówka: plik
/**
MMTopic
*/
@interface MMTopic : _MMTopic {}
@property (strong, nonatomic) NSAttributedString* content;
@end
Realizacja:
/**
MMTopic (PrimitiveAccessors)
*/
@interface MMTopic (PrimitiveAccessors)
- (NSAttributedString *)primitiveContent;
- (void)setPrimitiveContent:(NSAttributedString *)pContent;
@end
/**
MMTopic
*/
@implementation MMTopic
static NSString const* kAttributesDictionaryKey = @"AttributesDictionary";
static NSString const* kAttributesRangeKey = @"AttributesRange";
/*
awakeFromFetch
*/
- (void)awakeFromFetch {
[super awakeFromFetch];
// Build 'content' from its shadows 'contentString' and 'contentAttributes'
NSString* string = self.contentString;
NSMutableAttributedString* content = [[NSMutableAttributedString alloc] initWithString:string];
NSData* attributesData = self.contentAttributes;
NSArray* attributesArray = nil;
if (attributesData) {
NSKeyedUnarchiver* decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:attributesData];
attributesArray = [[NSArray alloc] initWithCoder:decoder];
}
if ((content) &&
(attributesArray.count)) {
for (NSDictionary* attributesDictionary in attributesArray) {
//NSLog(@"%@: %@", NSStringFromRange(((NSValue*)attributesDictionary[kAttributesRangeKey]).rangeValue), attributesDictionary[kAttributesDictionaryKey]);
[content addAttributes:attributesDictionary[kAttributesDictionaryKey]
range:((NSValue*)attributesDictionary[kAttributesRangeKey]).rangeValue];
}
[self setPrimitiveContent:content];
}
}
/*
content
*/
@dynamic content;
/*
content (getter)
*/
- (NSAttributedString *)content {
[self willAccessValueForKey:@"content"];
NSAttributedString* content = [self primitiveContent];
[self didAccessValueForKey:@"content"];
return content;
}
/*
content (setter)
*/
- (void)setContent:(NSAttributedString *)pContent {
[self willChangeValueForKey:@"content"];
[self setPrimitiveValue:pContent forKey:@"content"];
[self didChangeValueForKey:@"content"];
// Update the shadows
// contentString
[self setValue:pContent.string
forKey:@"contentString"];
// contentAttributes
NSMutableData* data = [NSMutableData data];
NSKeyedArchiver* coder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
NSMutableArray* attributesArray = [NSMutableArray array];
[pContent enumerateAttributesInRange:NSMakeRange(0, pContent.length)
options:0
usingBlock:^(NSDictionary* pAttributesDictionary, NSRange pRange, BOOL* prStop) {
//NSLog(@"%@: %@", NSStringFromRange(pRange), pAttributesDictionary);
[attributesArray addObject:@{
kAttributesDictionaryKey: pAttributesDictionary,
kAttributesRangeKey: [NSValue valueWithRange:pRange],
}];
}];
[attributesArray encodeWithCoder:coder];
[coder finishEncoding];
[self setValue:data
forKey:@"contentAttributes"];
}
@end
Pobieranie mogą być teraz wykonywane przez:
[NSPredicate predicateWithFormat:@"(contentString CONTAINS[cd] %@)", @"test"]];
Chociaż każdy dostęp do NSAttributedString idzie tak:
textField.attributedText = pTopic.content;
Zasady pracy z „atrybutów Non-standard” w danych Core są udokumentowane tutaj: Apple docs
- 1. Konwertuj NSMutableAttributedString na NSString
- 2. Najlepszy sposób na przechowywanie obrazów w iOS
- 3. Najlepszy sposób na przechowywanie danych w BoltDB
- 4. Prosty sposób na zainstalowanie RabbitMQ w Ubuntu?
- 5. Przechowywanie właściwości wyliczeniowej wewnątrz CoreData i wygodnej jej obsługi.
- 6. Najlepszy sposób na przechowywanie uprawnień użytkownika?
- 7. Znajdź zadzwonił podciągu w NSMutableAttributedString
- 8. Atrybut odstępów między wierszami iOS na NSMutableAttributedString
- 9. Prosty sposób na stworzenie macierzy liczb losowych
- 10. Prosty sposób na porównanie 2 ArrayLists
- 11. NSMutableAttributedString vertical aligment
- 12. XSLT: Prosty sposób na połączenie plików XML
- 13. Niepoprawna redeclaration na klasach CoreData
- 14. Najlepszy sposób na przechowywanie "dodatkowych" danych użytkownika w MySQL?
- 15. Najlepszy sposób na przechowywanie danych hierarchicznych w hbase
- 16. Najlepszy sposób na przechowywanie klucza => tablica wartości w JavaScript?
- 17. Najlepszy sposób na przechowywanie tablicy w bazie danych MySQL?
- 18. Najlepszy sposób na przechowywanie haseł w bazie danych MySQL
- 19. Najlepszy sposób na przechowywanie listy obiektów java w Redis
- 20. Najlepszy sposób na przechowywanie uporządkowanych list w bazie danych?
- 21. Najlepszy sposób na przechowywanie wielu flag w bazie danych
- 22. Prosty sposób na odtwarzanie pojedynczej częstotliwości w java?
- 23. Prosty i szybki sposób na wprowadzenie danych użytkownika w WPF?
- 24. Najlepszy sposób na prosty efekt dźwiękowy w iOS
- 25. Czy istnieje prosty sposób na ocenę JavaScript w WebStorm?
- 26. Czy istnieje prosty sposób na autouzupełnianie bloków zmiennych w Xcode?
- 27. Czy istnieje prosty sposób na uzyskanie wymiarów obrazu w Ruby?
- 28. Prosty sposób na przeciążenie złożonego operatora przypisania w C#?
- 29. Prosty sposób na uzyskanie elementu według identyfikatora w znaczniku div?
- 30. prosty sposób na sumowanie wyniku z UNION w MySql
Jak proponujecie przechowywania rzeczy, które nie mogą być archiwizowane? –
@DuncanGroenewald - O to pytam, zgadnij, że to niemożliwe? –
Jakie są konkretne rzeczy, które zawarłeś we właściwościach? Nie możesz ich podklasować i dodać archiwizacji do własnej podklasy. –