Я нахожусь в ситуации, когда нужно вызвать метод класса из моего контроллера представления, заставить его сделать это, но затем выполнить некоторые действия ТОЛЬКО ПОСЛЕ того, как метод класса завершил.
(Я думаю, что мне нужен блок завершения, но, пожалуйста, поправьте меня, если я ошибаюсь.)
Вот ситуация:
Я использую Parse.com для своих приложений. Когда пользователь регистрируется в учетной записи, он вводит свое имя, компанию и некоторую другую информацию во всплывающем окне, а затем нажимает кнопку "Отправить". Кнопка отправки связана с методом класса (показанным ниже), который берет их объект PFUser и название компании и создает некоторые объекты базы данных. После завершения функции всплывающее окно закрывается с использованием делегата.
Проблема в том, что мне нужно, чтобы создание этих объектов происходило в определенном порядке, потому что они зависят друг от друга. Проблема в том, что метод делегата для закрытия всплывающего окна вызывается сразу после нажатия кнопки "Отправить", поскольку он следующий в стеке.
При сохранении объекта Parse вызывается метод, который выглядит примерно так: (Это то, что я надеюсь написать, и я думаю, что это решит мою проблему)
[someParseObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
// Code here runs AFTER the method completes.
// This also happens on another thread which
// I'd like to implement as well.
}];
Итак, что мне нужно выяснить, как сделать что-то вроде следующего: (Я уверен, что все, что связано с блоком, совершенно неправильно)
SignUpViewController.m
myUserOrg *userOrg = [myUserOrg object]; // myUserOrg = Custom PFObject Subclass
// My method that takes in a user object and a string, creates
// the database objects in order.
[userOrg registerNewUserOrgWithUser:(PFUser*) andCompanyName:(NSString*) companyName withBlock(somethingHere)block {
if(error) {
NSLog(@"Unable to create org!");
} else {
NSLog(@"Created Org!");
[self.delegate dismissSignupView];
}
Пожалуйста, дайте мне знать, если вам нужна дополнительная информация или разъяснения.
Заранее спасибо!
--------- РЕДАКТИРОВАТЬ ОДИН ----------
Итак, несколько значительных единиц времени спустя, это то, что я придумал. Вся реализация могла бы быть лучше упрощена и делать намного меньше вызовов API, но будет работать над этим. Несколько других вопиющих проблем с этим также, но это первый шаг.
Вызов метода:
[testOrg registerNewUserOrgWithUser:currentUser
creatingOrgContactWithName:@"MyBigHappy Corp."
withBlock:^(BOOL succeeded, NSError *error) {
if (error) {
NSLog(@"Not working");
} else {
NSLog(@"Working!");
}
}];
Реализация метода:
@implementation MYUserOrg
@dynamic orgContact;
@dynamic orgDisplayName;
@dynamic members;
@dynamic contacts;
+ (NSString *)parseClassName {
return @"MYUserOrg";
}
dispatch_queue_t NewUserOrgRegistrationQueue;
-(void)registerNewUserOrgWithUser:(MYUser*)user
creatingOrgContactWithName:(NSString*) orgContactName
withBlock:(MYBooleanResultBlock) block {
NewUserOrgRegistrationQueue = dispatch_queue_create("com.myapp.initialOrgCreationQueue", NULL);
dispatch_async(NewUserOrgRegistrationQueue, ^{
NSMutableArray *errors = [[NSMutableArray alloc] init];
// Initial org save to generate objectId
NSError *orgSaveError = nil;
[self save:&orgSaveError];
if (orgSaveError) {
[errors addObject:@"Initial Org save Failed"];
}
// Create and Relate Org Contact
NSError *saveOrgContactError = nil;
MYontact *orgContact = [MYContact object];
[orgContact setContactType:MYContactTypeUserOrganization];
[orgContact setDisplayName:orgContactName];
[orgContact setParentOrg:self];
[orgContact save:&saveOrgContactError];
if (saveOrgContactError) {
[errors addObject:@"Saving Org Contact Failed"];
} else {
// If Org contact saved, set it;
[self setOrgContact:orgContact];
}
// Create amd Relate User Contact
NSError *saveUserContactError = nil;
MYContact *userContact = [MYContact object];
[userContact setFirstName:user.firstName];
[userContact setLastName:user.lastName];
[userContact setContactType:MYcontactTypeUser];
[userContact setParentOrg:self];
[userContact save:&saveUserContactError];
if (saveUserContactError) {
[errors addObject:@"Saving user contact failed"];
}
NSError *saveUserError = nil;
[user setParentOrg:self];
[user setUserContact:userContact];
[user save:&saveUserError];
if (saveUserError) {
[errors addObject:@"Saving User failed"];
}
// Return if block succeeded and any errors.
NSError *error = nil;
BOOL succeeded;
if (errors.count > 0) {
NSDictionary *userInfo = @{@"error" : errors};
errors = [NSError errorWithDomain:@"MyAppErrorDomain"
code:1
userInfo:userInfo];
succeeded = NO;
} else {
succeeded = YES;
}
block(succeeded, error);
});
}
@end