NSManagedObjectModel mà ở đó bạn sẽ định nghĩa cho sơ đồ Core Data. Trong cái model của bạn, bạn định nghĩa Entities, hay những lớp dữ liệu trong sơ đồ. Trong những cái Entities của bạn, bạn thiết lập những cái Attribute, cái này là cái chi tiết dữ liệu của bạn. Cuối cùng, bạn có thể liên kết những cái Entity với nhau thông qua những cái Relationship.
Ví dụ, bạn có thể tạo một model với một entity Label mà nó định nghĩa một nhãn của music, một entity Artist mô tả nghệ sĩ, là một phần của label, và một entity Album mô tả những album được thu âm bới những nghệ sĩ. Mỗi entity sẽ có những thuộc tính chi tiết; tất cả 3 entity sẽ được kết nối thông qua relationships.
Mở Xcode và tạo mới một dự án. Chọn “Empty Application” và click “Next”.
Chúng ta sẽ đặt tên cho dự án này là “MusicLabel” và đặt tên class prefix “MLBL”. Hãy chắc chắn rằng bạn chọn “Use Core Data”. Uncheck “Include Unit Tests”, khi chúng ta không muốn kiểm thử ứng dụng của mình.
Bây giờ chúng ta hãy tập trung vào data model. Chọn file “MusicLabel.xcdatamodeld”, và đảm bảo rằng editor style được thiết lập đến table.
Click “Add Entity” ở dưới màn hình Xcode và đặt tên nó là “Label”. Với entity được chọn, click “Add Atrribute”. Chúng ta sẽ gọi attribute này là “name”, và thiết lập type cho nó là “String”.
Thêm những attribute sau và kiểu tương ứng đến “Label” entity:
Thêm entity khác, “Artist”, và thêm những attribute sau:
Thêm một entity nửa là “Album”, và thêm những attribute sau:
Chuyển đổi Editor Style sang chế độ đồ họa ở phía dưới bên phải của màn hình Xcode.
Với entity “Label” được chọn, click và giữ “Add Attribute” cho đến khi bạn nhìn thấy option “Add Relationship”.
Chọn Add Relationship. Cho nó một cái tên là “artists” và thiết lập những điểm đích đến entity “Artist”. Bằng cách thiết lập relationship này, chúng ta nói rằng “mỗi Label có một Artist”. Label của có nhiều hơn một artist, do đó chúng ta sẽ tạo một relationship “To-Many Relationship”. Tiếp theo, thiêt lập delete rule đến “Cascade”; điều này sẽ đảm bảo rằng khi một đối tượng được xóa, đối tượng con của nó cũng bị xóa theo.
Bây giờ, chúng ta muốn tạo một relationship ngược về lại cha nó. Chọn “Artist” entity và click “Add Relationship”. Đặt tên cho relationship “label” và thiết lập đích cho “Label” entity. Set the inverse to the “artists” relationship.
Sử dụng cùng những bước này để thiết lập relationship giữa “Artist” và “Album” entities. Tạo một relationship từ “Artist” entity đến “Album” entity titled “album”. Tạo cho nó một relationship “To-Many Relationship” và thiết lập delete rule thành “Cascade”. Tạo một relationship từ “Album entity” đến “Artist” entity với tên là “artist” và tạo một cái relationship ngược về “albums”
Use this table for reference:
Tham khảo bảng sau:
Khi nào bạn hoàn thành, model của bạn nên giống như sau:
Cuối cùng, chọn “Label” entity, và click File>New>File. Chọn mẫu “NSManagedObject subclass”.
Việc này sẽ tạo tệp lớp Objective-C cho entity “Label”; bạn nên xem file “Label.h” cũng như file “Label.m”. Sử dụng cùng những bước để tạo những file class cho “Artist” và “Album” entity (đảm bảo rằng để làm nó theo thứ tự Label>Artist>Album). Với file class được tạo cho mỗi entity, những thiết lập của chúng ta sẽ hoàn thành.
NSManagedObjectContext &
NSPersistentStoreCoordinator
NSManagedObjectModel chỉ là 1/3 của
bức tranh Core Data. Bạn có nghĩ NSManagedObjectContext giống như “scratch pad”
mà ở đó xảy ta mọi sự thay đổi. Ở đây bạn tạo, đọc, cập nhật và xóa những đối
tượng từ database của bạn. Không có trong số những thay đổi mà bạn tạo thực sự
tồn tại cho đến khi bạn gọi phương thức “save” trên những thể hiện của object
context được quản lý của bạn.
Do đó khi một lời gọi để save được
gọi, điều gì sẽ xảy ta tiếp theo? Ở giữa managed object context và database là NSPersistentStoreCoordinator. Điều phối hoạt động
như là một giao diện cho database mà ở đó dữ liệu của bạn đang được tồn tại. Sự
điều phối này sẽ lấy bất kì đối tượng nào mà sẽ được lưu từ managed object
context và xác minh những tên và kiểu có phù hợp với managed object model. Sau
đó nó sẽ gửi những đối tượng theo cách của chúng đến database.
Tạo một đối tượng
Mở file “MLBLAppDelegate.m”. Trong
đó, bạn sẽ nhìn thấy những phương thức để cài đặt context, model và persistent
store coordinator. Import “Label.h”, “Artist.h”, và “Album.h”. Thêm phương thức
sau:
- (void) create {
// Grab the
context
NSManagedObjectContext *context = [self managedObjectContext];
// Grab the Label
entity
Label *label =
[NSEntityDescription insertNewObjectForEntityForName:@"Label"
inManagedObjectContext:context];
// Set label name
label.name =
@"Diplomat Records";
// Create a Date
NSDateFormatter
*dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter
setDateFormat:@"YYYY"];
NSDate *dateFounded
= [dateFormatter dateFromString:@"2003"];
// Set the year
founded for the label
label.founded =
dateFounded;
// Set the label
genre
label.genre =
@"Rap/Hip-hop";
// Insert the
Artist entity
Artist *artist =
[NSEntityDescription insertNewObjectForEntityForName:@"Artist"
inManagedObjectContext:context];
// Set the artist
attributes
artist.name =
@"Cam'Ron";
artist.hometown =
@"Harlem, NY";
// Insert Album
entity
Album *album =
[NSEntityDescription insertNewObjectForEntityForName:@"Album"
inManagedObjectContext:context];
// Set album
attributes
album.title =
@"Come Home With Me";
NSDate
*releaseDate = [dateFormatter dateFromString:@"2002"];
album.released =
releaseDate;
// Set relationships
[label
addArtistsObject:artist];
[artist
setLabel:label];
[artist
addAlbumsObject:album];
[album
setArtist:artist];
// Save
everything
NSError *error =
nil;
if ([context
save:&error]) {
NSLog(@"The save was successful!");
} else {
NSLog(@"The save wasn't successful: %@", [error userInfo]);
}
}
|
Make sure to call [self create] in the application:didFinishLaunchingWithOptions: method. Build your project and run it. Check the output in
the log navigator to see if it saved properly. You should see this output:
Đảm bảo rằng là gọi [self create] trong phương thức application:didFinishLaunchingWithOptions:. Build dự án của bạn và chạy nó. Kiểm tra output trong màn
hình log để thấy nếu nó được lưu thành công hay không.
It worked? Great, now let’s walk
through reading data.
Nó đã làm việc? Tuyệt, bây giờ hãy
tham quan việc đọc dữ liệu nào.
Đọc một đối tượng
With Core Data, you perform “fetch
requests” to access saved objects. These objects are always returned as
instances of NSManagedObject. Check out NSFetchRequest for more info. Add the following
method to the “MLBLAppDelegate.m” file:
Với Core Data, bạn thực hiện “fetch
requests” để truy cập những đối tượng được lưu. Những đối tượng này luôn luôn
return những thể hiện của lớp NSManagedObject. Kiểm tra NSFetchRequest để thêm
thông tin. Thêm phương thức sau đến file “MLBLAppDelegate.m”:
- (void) read {
NSManagedObjectContext *context = [self managedObjectContext];
// Construct a
fetch request
NSFetchRequest
*fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"Label"
inManagedObjectContext:context];
[fetchRequest
setEntity:entity];
NSError *error =
nil;
NSArray
*fetchedObjects = [context executeFetchRequest:fetchRequest
error:&error];
for (Label *label
in fetchedObjects) {
// Log the
label details
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"YYYY"];
NSLog(@"%@, est. %@ (%@)", label.name, [dateFormatter stringFromDate:label.founded],
label.genre);
NSLog(@"\tArtists:");
NSSet
*artists = label.artists;
for (Artist
*artist in artists) {
// Log
the artist details
NSLog(@"\t\t%@ (%@)", artist.name, artist.hometown);
NSLog(@"\t\t\tAlbums:");
NSSet
*albums = artist.albums;
for
(Album *album in albums) {
//
Log the album details
NSLog(@"\t\t\t\t%@ (%@)", album.title, [dateFormatter
stringFromDate:album.released]);
}
}
}
}
|
Replace [self create] with [self
read] in the application:didFinishLaunchingWithOptions: method. Build and run, and voila! A printout of the objects
should appear in the log navigator.
Thay [self create] thành [self read]
trong phương thức application:didFinishLaunchingWithOptions:.
Build và chạy, một bản in của những
đối nên xuất hiện trong màn hình log.
Cập nhật một đối tượng
Hãy cập nhật label của chúng ta và
thêm một vài artists và albums. Thêm phương thức này:
- (void) update {
// Grab the
context
NSManagedObjectContext *context = [self managedObjectContext];
// Perform fetch
request
NSFetchRequest
*fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"Label"
inManagedObjectContext:context];
[fetchRequest
setEntity:entity];
NSError *error =
nil;
NSArray
*fetchedObjects = [context executeFetchRequest:fetchRequest
error:&error];
// Date formatter
comes in handy
NSDateFormatter
*dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter
setDateFormat:@"YYYY"];
// Grab the label
Label *label =
[fetchedObjects objectAtIndex:0];
// Juelz Santana
Artist *juelz =
[NSEntityDescription insertNewObjectForEntityForName:@"Artist"
inManagedObjectContext:context];
juelz.name =
@"Juelz Santana";
juelz.hometown =
@"Harlem, NY";
// Juelz Santana
albums
Album *juelzAlbum
= [NSEntityDescription insertNewObjectForEntityForName:@"Album"
inManagedObjectContext:context];
juelzAlbum.title
= @"From Me to U";
juelzAlbum.released = [dateFormatter dateFromString:@"2003"];
[juelzAlbum
setArtist:juelz];
Album
*juelzAlbum2 = [NSEntityDescription
insertNewObjectForEntityForName:@"Album"
inManagedObjectContext:context];
juelzAlbum2.title
= @"What The Game's Been Missing!";
juelzAlbum2.released = [dateFormatter
dateFromString:@"2005"];
[juelzAlbum2
setArtist:juelz];
// Set
relationships
[juelz
addAlbums:[NSSet setWithObjects:juelzAlbum, juelzAlbum2, nil]];
// Jim Jones
Artist *jimmy =
[NSEntityDescription insertNewObjectForEntityForName:@"Artist"
inManagedObjectContext:context];
jimmy.name =
@"Jim Jones";
jimmy.hometown =
@"Harlem, NY";
// Jim Jones
albums
Album *jimmyAlbum
= [NSEntityDescription insertNewObjectForEntityForName:@"Album"
inManagedObjectContext:context];
jimmyAlbum.title
= @"On My Way to Church";
jimmyAlbum.released = [dateFormatter
dateFromString:@"2004"];
[jimmyAlbum
setArtist:jimmy];
Album
*jimmyAlbum2 = [NSEntityDescription
insertNewObjectForEntityForName:@"Album" inManagedObjectContext:context];
jimmyAlbum2.title
= @"Harlem: Diary of a Summer";
jimmyAlbum2.released = [dateFormatter
dateFromString:@"2005"];
[jimmyAlbum2
setArtist:jimmy];
Album
*jimmyAlbum3 = [NSEntityDescription insertNewObjectForEntityForName:@"Album"
inManagedObjectContext:context];
jimmyAlbum3.title
= @"Hustler's P.O.M.E. (Product of My Environment)";
jimmyAlbum3.released = [dateFormatter
dateFromString:@"2006"];
[jimmyAlbum3
setArtist:jimmy];
// Set
relationships
[jimmy
addAlbums:[NSSet setWithObjects:jimmyAlbum, jimmyAlbum2, jimmyAlbum3, nil]];
// Freekey Zekey
Artist *freekey =
[NSEntityDescription insertNewObjectForEntityForName:@"Artist"
inManagedObjectContext:context];
freekey.name =
@"Freekey Zekey";
freekey.hometown
= @"Harlem, NY";
Album
*freekeyAlbum = [NSEntityDescription
insertNewObjectForEntityForName:@"Album"
inManagedObjectContext:context];
freekeyAlbum.title = @"Book of Ezekiel";
freekeyAlbum.released = [dateFormatter dateFromString:@"2007"];
[freekeyAlbum
setArtist:freekey];
[freekey
addAlbumsObject:freekeyAlbum];
// Set
relationships
[label
addArtists:[NSSet setWithObjects:juelz, jimmy, freekey, nil]];
// Save
everything
if ([context
save:&error]) {
NSLog(@"The save was successful!");
} else {
NSLog(@"The save wasn't successful: %@", [error
localizedDescription]);
}
}
|
Replace [self read] with [self
update] in the application:didFinishLaunchingWithOptions: method. Build and run, and check the log navigator for a
successful save. Now let’s print them to the log again; replace [self update] with [self
read]. Build and run, and you should see
all the artists/albums under the label. Run it a few more times and compare the
log output each time. The order will vary almost every time. Fetch requests
return objects unordered, unless specified otherwise. To do so, you need to use
NSSortDescriptor to organize your results. Use NSPredicate to grab specific objects.
Thay [self read] thành [self update]
trong phương thức application:didFinishLaunchingWithOptions
:.Build và chạy, kiểm tra màn hình log
để biết nó được lưu thành công hay không. Bây giờ hãy in chúng lên màn hình log
một lần nửa; thay [self update] thành [self read]. Build và chạy, bạn nên nhìn
thấy tất cả artists/albums phía dưới label. Chạy nó thêm một vài lần và so sánh
output ở màn hình log. Thứ tự sẽ khác hầu như mỗi lần. Fetch requests return
những đối tượng chưa được sắp xếp, trì khi có gì đặc biệt. Để làm điều này bạn
cần sử dụng NSSortDescriptor để tổ chức lại những kết quả của bạn. Sử dụng
NSPredicate để lấy những đối tượng xác định.
Xóa một đối tượng
Cuối cùng, chúng ta sẽ xóa một đối
tượng. Hãy thêm phương thức này:
|
- (void) delete {
// Grab the
context
NSManagedObjectContext *context = [self managedObjectContext];
// We're looking to grab an artist
NSFetchRequest
*fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"Artist"
inManagedObjectContext:context];
[fetchRequest
setEntity:entity];
// We specify
that we only want Freekey Zekey
NSPredicate
*predicate = [NSPredicate predicateWithFormat:@"name == %@",
@"Freekey Zekey"];
[fetchRequest
setPredicate:predicate];
NSError *error =
nil;
NSArray
*fetchedObjects = [context executeFetchRequest:fetchRequest
error:&error];
// Grab the
artist and delete
Artist *freekey =
[fetchedObjects objectAtIndex:0];
[freekey.label
removeArtistsObject:freekey];
// Save
everything
if ([context
save:&error]) {
NSLog(@"The save was successful!");
} else {
NSLog(@"The save wasn't successful: %@", [error
localizedDescription]);
}
}
|
Thêm dòng [self delete] bên phải
trước [self read] trong phương thức application:didFinishLaunchingWithOptions. Build và chạy, bạn nên thấy Freekey Zekey biến mất từ những
kết quả. Album của anh ấy nên “đi” quá, giống như chúng ta thiết lập delete
rule cho relationship là Cascade.
Source: https://blog.stackmob.com/2012/11/iphone-database-tutorial-part-1-learning-core-data/
No comments:
Post a Comment