iOS: 跟随系统的核心数据模式
iOS: Core data schema for follow system
我在 mysql 和 php 中有一个跟随系统,它只使用一个 table 如下:
正在关注
id|用户id|followerid
(还有一个用户table:id|username|pass)
每当一个用户关注另一个用户时,就会在关注栏中输入关注者 ID,在用户 ID 栏中输入被关注的人。
我现在正尝试使用 Web 服务从 iOS 应用程序访问它。
对于 VC,我希望能够列出用户,但是通过链接 NSPredicate 在用户的关注者和用户关注的人之间切换。使用 php/sql 这是微不足道的,但我有时间转换为 CoreData。
现在我在核心数据中有具有以下属性的用户实体:
id|用户名|密码
并复制 mysql 架构,我还有一个关注实体
fid|fuserid|fflowerid
反过来,我为用户与关注者创建了一对多关系,并为用户与关注者创建了反向一对多关系,因为给定用户(例如应用程序的用户)可以有很多关注者,也关注很多人。
Web 服务当前设置为为用户和每个用户提供一组关注者 ID,如下所示
id:1
name:bob
追随者:2,3,4
此时我被难住了。我可以填充用户实体。我还可以用所有关注用户的人和用户正在关注的所有人填充关注者实体。
但是,我不知道要与 Core data 通信哪些关注者与哪个用户相关,而且我也不知道如何编写谓词,例如,只拉取用户的关注者申请
如有任何建议,我们将不胜感激。
现在我的 NSManagedObjects 如下所示:
//User.h
#import "Following.h"
@class Following;
@interface User : NSManagedObject
//in user entity
@property (nonatomic, retain) NSNumber * uid;
@property (nonatomic, retain) NSString * uname;
@property (nonatomic, retain) NSString *upass;
//this is relationship
@property (nonatomic, retain) Following *following;
@end
//and Following.h
#import "User.h"
@class User;
@interface Following : NSManagedObject
@property (nonatomic, retain) NSNumber * fid;
@property (nonatomic, retain) NSNumber * fuserid;
@property (nonatomic, retain) NSNumber * followerid;
//this is relationship
@property (nonatomic) User *user;
@end
从 Web 服务导入并保存用户后,我尝试在 Following 实体中保存一些有关关注者的信息,但不确定我在这里做什么....
NSSet*followerids = importUser.followerids;
NSInteger *folnum =[followerids count];
if (folnum>0) {
for (id item in followerids) {
Following *newFollowing = [NSEntityDescription insertNewObjectForEntityForName:@"Following" inManagedObjectContext:self.managedObjectContext];
newFollowing.fuserid = useridnum;
NSNumber *itemnum = [NSNumber numberWithInt:[item intValue]];
newFollowing.followerid = itemnum;
newFollowing.user = record; //where record is a user just created
}
那么这里的关系就有问题了。根据您的解释,这里应该是多对多关系。
因此您的用户 class 应该 属性 喜欢
//this is relationship
@property (nonatomic, retain) NSSet *following;
您的关注 class 应该有一个 属性 喜欢
@property (nonatomic) NSSet *users;
然后您可以开始将从网络服务接收到的一组关注者 ID 分配给它。
您实际上拥有多对多关系(每个 User
可以跟随许多其他 Users
,并且可以跟随许多 Users
)。您可以直接在 CoreData 中对此进行建模,而无需创建额外的实体,方法是具有 两个 对多关系,followedByUsers
和 usersBeingFollowed
,其中一个是另一个。生成的模型如下所示:
您的 User
class 定义将如下所示:
@interface User : NSManagedObject
//in user entity
@property (nonatomic, retain) NSNumber *uid;
@property (nonatomic, retain) NSString *uname;
@property (nonatomic, retain) NSString *upass;
//this is relationship
@property (nonatomic, retain) NSSet *followedByUsers;
@property (nonatomic, retain) NSSet *usersBeingFollowed;
@end
如果你的网络服务提供了一个userid
、name
和一组followerids
,我会先创建所有的Users
,而不设置任何关系,然后通过获取对应于 followerids
:
的 User
记录来循环并建立关系
NSPredicate *userPredicate = [NSPredicate predicateWithFormat:@"uid == %@",importUser.userid];
NSFetchRequest *fetchUser = [NSFetchRequest fetchRequestWithEntityName:@"User"];
fetchUser.predicate = userPredicate;
NSArray *results = [context executeFetchRequest:fetchUser error:nil];
User *record = results[0];
NSSet *followerids = importUser.followerids;
NSInteger folnum =[followerids count];
if (folnum>0) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"uid IN %@",followerids];
NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:@"User"];
fetch.predicate = predicate;
NSArray *resultsArray = [context executeFetchRequest:fetch error:nil];
if ([results count] > 0) {
NSSet *followers = [NSSet setWithArray:resultsArray];
record.followedByUsers = followers;
}
}
(为简单起见,我省略了通常的错误检查。)建立关系后,您可以确定哪些用户关注给定用户:
givenUser.followedByUsers
或者,如果您想使用谓词(例如,对于 fetchedResultsController),请使用:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"usersBeingFollowed CONTAINS %@",givenUser];
相反,要获取 givenUser
关注的用户,请使用
givenUser.usersBeingFollowed
或
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"followedByUsers CONTAINS %@",givenUser];
我在 mysql 和 php 中有一个跟随系统,它只使用一个 table 如下:
正在关注
id|用户id|followerid
(还有一个用户table:id|username|pass)
每当一个用户关注另一个用户时,就会在关注栏中输入关注者 ID,在用户 ID 栏中输入被关注的人。
我现在正尝试使用 Web 服务从 iOS 应用程序访问它。
对于 VC,我希望能够列出用户,但是通过链接 NSPredicate 在用户的关注者和用户关注的人之间切换。使用 php/sql 这是微不足道的,但我有时间转换为 CoreData。
现在我在核心数据中有具有以下属性的用户实体:
id|用户名|密码
并复制 mysql 架构,我还有一个关注实体 fid|fuserid|fflowerid
反过来,我为用户与关注者创建了一对多关系,并为用户与关注者创建了反向一对多关系,因为给定用户(例如应用程序的用户)可以有很多关注者,也关注很多人。
Web 服务当前设置为为用户和每个用户提供一组关注者 ID,如下所示 id:1 name:bob 追随者:2,3,4
此时我被难住了。我可以填充用户实体。我还可以用所有关注用户的人和用户正在关注的所有人填充关注者实体。
但是,我不知道要与 Core data 通信哪些关注者与哪个用户相关,而且我也不知道如何编写谓词,例如,只拉取用户的关注者申请
如有任何建议,我们将不胜感激。
现在我的 NSManagedObjects 如下所示:
//User.h
#import "Following.h"
@class Following;
@interface User : NSManagedObject
//in user entity
@property (nonatomic, retain) NSNumber * uid;
@property (nonatomic, retain) NSString * uname;
@property (nonatomic, retain) NSString *upass;
//this is relationship
@property (nonatomic, retain) Following *following;
@end
//and Following.h
#import "User.h"
@class User;
@interface Following : NSManagedObject
@property (nonatomic, retain) NSNumber * fid;
@property (nonatomic, retain) NSNumber * fuserid;
@property (nonatomic, retain) NSNumber * followerid;
//this is relationship
@property (nonatomic) User *user;
@end
从 Web 服务导入并保存用户后,我尝试在 Following 实体中保存一些有关关注者的信息,但不确定我在这里做什么....
NSSet*followerids = importUser.followerids;
NSInteger *folnum =[followerids count];
if (folnum>0) {
for (id item in followerids) {
Following *newFollowing = [NSEntityDescription insertNewObjectForEntityForName:@"Following" inManagedObjectContext:self.managedObjectContext];
newFollowing.fuserid = useridnum;
NSNumber *itemnum = [NSNumber numberWithInt:[item intValue]];
newFollowing.followerid = itemnum;
newFollowing.user = record; //where record is a user just created
}
那么这里的关系就有问题了。根据您的解释,这里应该是多对多关系。
因此您的用户 class 应该 属性 喜欢
//this is relationship
@property (nonatomic, retain) NSSet *following;
您的关注 class 应该有一个 属性 喜欢
@property (nonatomic) NSSet *users;
然后您可以开始将从网络服务接收到的一组关注者 ID 分配给它。
您实际上拥有多对多关系(每个 User
可以跟随许多其他 Users
,并且可以跟随许多 Users
)。您可以直接在 CoreData 中对此进行建模,而无需创建额外的实体,方法是具有 两个 对多关系,followedByUsers
和 usersBeingFollowed
,其中一个是另一个。生成的模型如下所示:
您的 User
class 定义将如下所示:
@interface User : NSManagedObject
//in user entity
@property (nonatomic, retain) NSNumber *uid;
@property (nonatomic, retain) NSString *uname;
@property (nonatomic, retain) NSString *upass;
//this is relationship
@property (nonatomic, retain) NSSet *followedByUsers;
@property (nonatomic, retain) NSSet *usersBeingFollowed;
@end
如果你的网络服务提供了一个userid
、name
和一组followerids
,我会先创建所有的Users
,而不设置任何关系,然后通过获取对应于 followerids
:
User
记录来循环并建立关系
NSPredicate *userPredicate = [NSPredicate predicateWithFormat:@"uid == %@",importUser.userid];
NSFetchRequest *fetchUser = [NSFetchRequest fetchRequestWithEntityName:@"User"];
fetchUser.predicate = userPredicate;
NSArray *results = [context executeFetchRequest:fetchUser error:nil];
User *record = results[0];
NSSet *followerids = importUser.followerids;
NSInteger folnum =[followerids count];
if (folnum>0) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"uid IN %@",followerids];
NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:@"User"];
fetch.predicate = predicate;
NSArray *resultsArray = [context executeFetchRequest:fetch error:nil];
if ([results count] > 0) {
NSSet *followers = [NSSet setWithArray:resultsArray];
record.followedByUsers = followers;
}
}
(为简单起见,我省略了通常的错误检查。)建立关系后,您可以确定哪些用户关注给定用户:
givenUser.followedByUsers
或者,如果您想使用谓词(例如,对于 fetchedResultsController),请使用:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"usersBeingFollowed CONTAINS %@",givenUser];
相反,要获取 givenUser
关注的用户,请使用
givenUser.usersBeingFollowed
或
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"followedByUsers CONTAINS %@",givenUser];