๋๋ ์ด๊ฒ์ ์ฒ๋ฆฌํ๋ ๋ ๋ฐ์์ ์ธ ๋ฐฉ๋ฒ์ด ์์ ๊ฒ์ด๋ผ๊ณ ํ์ ํ์ง๋ง ๋๋ ๊ทธ๊ฒ์ ๋ํด ๋จธ๋ฆฌ๋ฅผ ์ธ ์ ์์ต๋๋ค.
๋๋ ํ๊ดด์ ์ธ ์์
(์ด ๊ฒฝ์ฐ ์ญ์ )์ ์ํํ๋ UIButton์ด ์์ต๋๋ค. ๋ด ๋ณด๊ธฐ ๋ชจ๋ธ์๋ ์ญ์ ๋ฅผ ์ํํ๋ ๋ช
๋ น์ ๋ฐํํ๋ deleteCommand
์์ฑ์ด ์์ผ๋ฉฐ ๋ฒํผ์ ๋ช
๋ น์ ์ฐ๊ฒฐํ๋ ๊ฒ์ ๊ฐ๋จํฉ๋๋ค.
๊ทธ๋ฌ๋ ๋ด๊ฐ ์ ๋ง๋ก ์ํ๋ ๊ฒ์ ๋ฒํผ์ ํญํ์ ๋ ํ์ธ UIAlertView
์ด ํ์๋๊ณ ์ฌ์ฉ์๊ฐ ํ์ธ์ ๋๋ฅด๋ฉด ์ญ์ ๊ฐ ์ํ๋๊ณ ์ทจ์๋ฅผ ๋๋ฅด๋ฉด ์ญ์ ๋์ง ์๋ ๊ฒ์
๋๋ค.
์ด "ํ์ธ" ๋์์ ๋ด ๋ทฐ ๋์์ ๊ธฐ๋ณธ์ ์ธ ๋ถ๋ถ์ด๋ฏ๋ก ๋ทฐ ๋ชจ๋ธ์ ์ํ๋ ๊ฒ์ฒ๋ผ ๋๊ปด์ง๋๋ค. ๋จผ์ ํ์ธ ์์ด ์ญ์ ๋ฅผ ํ์ฉํ๊ณ ์ถ์ง ์์ต๋๋ค.
๊ทธ๋ฌ๋ ํ์ธ์ ์ป๋ ๋ฐฉ๋ฒ์ ๋ํ ์ธ๋ถ ์ฌํญ(์: UIAlertView
)์ ๋ทฐ์ ๋ํด ์๋ฌด ๊ฒ๋ ์์ง ๋ชปํ๋ฏ๋ก ๋ทฐ ๋ชจ๋ธ์ ์ํ์ง ์์ต๋๋ค. ๊ฒฝ๊ณ ์ ์ค์ ํ์๋ ๋ณด๊ธฐ ์ปจํธ๋กค๋ฌ์ ์ํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
๋ฐ๋ผ์ UIButton
๋ฐ์ธ๋ฉํ ์ ์๋ค๋ ํ์ธ๊ณผ ํจ๊ป ์ญ์ ๋ฅผ ๋ํ๋ด๋ ํ๋์ RACCommand ๋ฅผ ๊ฐ์ง ์ ์๋๋ก ํ๋ ๋ฉ์ง๊ณ ์ฐ์ํ ๋ฐฉ๋ฒ์ด ์์ต๋๊น?
๋ณด๊ธฐ ๋ชจ๋ธ์์ AlertViewModel
s๋ฅผ ๋ณด๋ด๋ alerts
์ ํธ๋ฅผ ๋
ธ์ถํฉ๋๋ค. ๊ฐ ๋ฒํผ์ ์ ์ ํ ๋ช
๋ น์ ์ค์ ํฉ๋๋ค. ์ด๊ฒ์ ๋ด ์ฑ์์ ์ฌ์ฉํ๋ ์๋ฃจ์
์
๋๋ค.
์ด "ํ์ธ" ๋์์ ๋ด ๋ทฐ ๋์์ ๊ธฐ๋ณธ์ ์ธ ๋ถ๋ถ์ด๋ฏ๋ก ๋ทฐ ๋ชจ๋ธ์ ์ํ๋ ๊ฒ์ฒ๋ผ ๋๊ปด์ง๋๋ค. ๋จผ์ ํ์ธ ์์ด ์ญ์ ๋ฅผ ํ์ฉํ๊ณ ์ถ์ง ์์ต๋๋ค.
๋ณด๊ธฐ ๋ชจ๋ธ์์ "์์ ํด์ "๋ฅผ ๋ชจ๋ธ๋งํ๊ณ ์ถ์ต๋๊น? ์ด๋ฌํ ์ข ๋ฅ์ ๋ทฐ ๋ชจ๋ธ์ ํ์ํ๋ ๋ค๋ฅธ ๋ทฐ๊ฐ ์๋ ๊ฒฝ์ฐ ์ข์ ์์ด๋์ด๊ฐ ๋ ์ ์์ง๋ง ํ์ธ์ด๋ผ๋ ์์ด๋์ด๋ก ๋๋ฌด ๋ฐ์ ํ๊ฒ ๋ฌถ์ง ๋ง์ญ์์ค. ๋ชจ๋ธ์ ํ ์ด๋ธ ๋ทฐ์ ํ์ํ๋ฉด ์ผ์ชฝ์ผ๋ก ์ค์์ดํํ์ฌ ์ญ์ ๋ฒํผ์ ํ์ํ ์ ์์ต๋๋ค. ์์ ์ ์ ๊ฑฐํ๋ ์ญํ ์ ํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ํญํ ๋ ๋ค์ ํ์ธ์ ์์ฒญํ ํ์๊ฐ ์์ต๋๋ค.
๋๋ ๊ฐ์ธ์ ์ผ๋ก ๊ทธ๋ฅ ๊ฐ๋จํ ํด๊ฒฐ์ฑ
์ผ๋ก ๊ฐ ๊ฒ : ๋ฐ์ธ๋ ๋ฒํผ์ enabled
๋ช
๋ น์ ์๋ ๋ช
๋ น ์์ฒด, ์๋ ๋ช
๋ น์ ํธ์ถ -execute:
๋ก๋ถํฐ UIAlertView
.
์ ๊ธฐ๋ณธ์ ์ผ๋ก Denis๊ฐ ๋งํ ๊ฒ์
๋๋ค. ๋๋ ์ด๊ฒ์ ์ฌ๋ฌ ๋ฒ ํ๋ค.
๋ณด๊ธฐ ๋ชจ๋ธ์๋ ๋ค์์ด ์์ต๋๋ค.
์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค(ํ ์คํธ๋์ง ์์์ผ๋ฉฐ ๊ฐํ/์ฝํ ํ์ ์์).
self.deleteCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id objectToDelete) {
[return self.confirmationCommand.executionSignals
switchToLatest]
flattenMap:^id(NSNumber *confirmed) {
if(confirmed) {
return [self deleteObject:objectToDelete];
} else {
return [RACSignal error:someErrorWithAMessageMaybe];
}
}];
}];
self.confirmationRequiredSignal = [self.deleteCommand.executing
filter: ^BOOL(NSNumber *executing) {
return executing.boolValue;
}];
๋ฐ๋ผ์ ๋ทฐ ์ปจํธ๋กค๋ฌ ์์์ ์ญ์ ๋ฒํผ์ ์ฆ์ ์คํ์ ์์ํ๋ ๋ทฐ ๋ชจ๋ธ์์ deleteCommand
๋ฅผ ์คํํฉ๋๋ค. ์ญ์ ๋ช
๋ น์ ์ด์ confirmationCommand.executionSignals
๊ฐ ๊ฐ์ ์ ์กํ๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ณ ์์ต๋๋ค. ์ญ์ ๋ช
๋ น์ ์คํํ๋ฉด self.confirmationRequiredSignal
์ ๊ฐ์ด ์ ์ก๋ฉ๋๋ค.
๊ทธ๋ฐ ๋ค์ ๋ทฐ ์ปจํธ๋กค๋ฌ๋ viewModel์ confirmationRequiredSignal
๊ฐ ๊ฒฝ๊ณ ๋ณด๊ธฐ๋ฅผ ํ์ํ๊ณ ๊ฒฝ๊ณ ๋ณด๊ธฐ์ ๋ฒํผ์ ConfirmCommand์ ์ฐ๊ฒฐํ๋ ๊ฒ์ ๊ด์ฐฐํฉ๋๋ค(ํ์ธ ๋ช
๋ น์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฒํผ์ ์ธ๋ฑ์ค๋ฅผ ๊ฐ์ ธ์ค๋ฏ๋ก ๊ทธ๋ ๊ฒ ํ ๊ฒ์
๋๋ค. confirmed
๊ฐ์ ๋งคํํด์ผ ํจ). ์ฌ์ฉ์๊ฐ ๋ฒํผ์ ํญํ๋ฉด self.confirmationCommand
๊ฐ ์คํ๋๊ณ confirmed
๊ฐ์ ๋ฐํํ์ฌ ์ฃผ๊ธฐ๋ฅผ ์๋ฃํฉ๋๋ค. self.deleteCommand.errors
๋ฅผ ๊ด์ฐฐํ์ฌ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๊ฑฐ๋ ๋ญ๊ฐ๋ฅผ ๋์ง๊ณ ์ถ๋ค๋ฉด ์ฌ๊ธฐ์์ ํ๋ ๊ฒ์ฒ๋ผ ์ ํ์ ์ผ๋ก deleteCommand
์ค๋ฅ๋ฅผ ๋ฐํํ ์ ์์ต๋๋ค. ๋๋ ๋ช
๋ น ์คํ์ ์๋ฃํ๊ธฐ ์ํด ๋น ์ ํธ๋ฅผ ๋ฐํํ ์ ์์ต๋๋ค.
์ด ๋ชจ๋ธ์ ๊ฒฝ๊ณ ๋ณด๊ธฐ, ์์
์ํธ ๋ฑ๊ณผ ํจ๊ป ์๋ํฉ๋๋ค. RACCommands
๋ ์ ๋ง ๋๋จํฉ๋๋ค.
@Coneko ๋ ๊ฐ๋จํ ํ์ธ์ด ๋ฐ๋์ ๋ทฐ ๋ชจ๋ธ์ ์ํ์ง ์๋๋ค๋ ๊ฒ์ด log in with twitter
๋ฒํผ์ ํญํ๊ณ ๊ณ์(๋๋ ์ทจ์)ํ๋ ค๋ฉด ์ฌ์ฉํ ํธ์ํฐ ๊ณ์ (์ฌ๋ฌ ๊ณ์ ์ด ์๋ ๊ฒฝ์ฐ)์ ์ ํํด์ผ ํฉ๋๋ค. (์ ๊ฐ ๋ฐฉ๊ธ ๋ง๋ ์ค์ ์์
๋๋ค.)
@sprynmr ํผ๋๋ฐฑ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ๋น์ทํ์ง๋ง IMO๊ฐ ์ฝ๊ฐ ๋ ๊ฐ๋จํ ์๋ฃจ์ ์ ์ฌ์ฉํ์ต๋๋ค.
๋จ์ผ ์ธ์๋ฅผ ์ฌ์ฉํ๋ deleteWithConfirmation:
๋ผ๋ ๋ฉ์๋๋ก ์์ฑ์ ๋์ฒดํ์ต๋๋ค. RACSignal
๋ฅผ ๋ฐํํ๋ ๋ธ๋ก์ ๋จ์ผ ๊ฐ, @YES
๋๋ @NO
์ ์ ์กํ์ฌ ํ์ธ์ ๋ํ๋ด๋ ๋ธ๋ก์
๋๋ค
๋ช ๋ น ์์ฒด๋ ํ์ธ ์ ํธ์์ ์ฒซ ๋ฒ์งธ ๊ฐ์ ๊ฐ์ ธ์ ์ ์ ํ ์ ํธ์ ๋งคํํ๋ ์ ํธ์ ๋๋ค. ํ์ธ๋์ง ์์ผ๋ฉด ์ญ์ ์ ํธ๊ฐ ๋น์ด ์๋ ์ ํธ์ ๋๋ค.
- (RACCommand *)deleteWithConfirmation:(RACSignal*(^)(void))signalBlock
{
NSParameterAssert(signalBlock);
@weakify(self);
return [[RACCommand alloc] initWithEnabled:nil signalBlock:^RACSignal *(id input) {
@strongify(self);
RACSignal *confirmationSignal = signalBlock();
return [[confirmationSignal take:1] flattenMap:^RACStream *(id value) {
if ([value boolValue]) {
return [self doDeletion]; // for example
}
else {
return [RACSignal empty];
}
}];
}];
}
๋ทฐ ์ปจํธ๋กค๋ฌ์์ ๋ค์๊ณผ ๊ฐ์ด ๋ฒํผ์ ๋ช ๋ น์ ์ฐ๊ฒฐํฉ๋๋ค.
self.deleteButton.rac_command = [self.viewModel deleteWithConfirmation:^RACSignal *{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Delete Widget" message:@"Are you sure you want to delete this widget?" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"Delete", nil];
[alert show];
return [alert.rac_buttonClickedSignal map:^id(NSNumber *buttonIndex) {
return @([buttonIndex integerValue] == 1);
}];
}];
๋ณด์๋ค์ํผ, ๋ด๊ฐ ๋ฐํํ๋ ์ ํธ๋ ๋ฒํผ์ ํด๋ฆญํ ์ ํธ์์ YES/NO ๊ฐ์ผ๋ก์ ๋งต์ผ ๋ฟ์ ๋๋ค.
๋๋ฅผ ์ํด ์ถฉ๋ถํ ์ ์๋ํฉ๋๋ค! ํ์ธ์ ๊ฑด๋๋ฐ๊ณ ์ถ๋ค๋ฉด ๋จ์ผ YES ๊ฐ์ ๋ณด๋ด๋ ์ ํธ๋ฅผ ๋ฐํํ๋ ๋ธ๋ก์ ๋จ์ํ ์ ๋ฌํ ์ ์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ์ฌ์ ํ โโํฉ๋ฆฌ์ ์ผ๋ก ์ ์ฐํด ๋ณด์ ๋๋ค. ์ด๋ฅผ ๋ด ๋ทฐ ๋ชจ๋ธ์์ ๋ณ๋์ ๋ฉ์๋๋ก ์บก์ํํ ์๋ ์์ต๋๋ค. ์๋ฅผ ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- (RACCommand *)deleteWithoutConfirmationCommand
{
return [self deleteWithConfirmation:^RACSignal *{
return [RACSignal return:@YES];
}]
}
์ด๊ฒ๋ ๊ฝค ๊ด์ฐฎ์ ์๋ฃจ์ ์ธ ๊ฒ ๊ฐ์ต๋๋ค. ํ์ผ์ ์ญ์ ํ๊ฒ ์ต๋๋ค.
@sprynmr ๋๋ ๋น์ ์ ๋๋ต์ ์๋ํ์ต๋๋ค. ๊ทธ๋ฌ๋, ๋๋ฅผ ๋นํน์ค๋ฝ๊ฒ ํ๋ ๊ฒ์ด ์๋ค.
๋ธ๋ก์์ ๋ฐํ๋ ์ ํธ๋ ์๋ฃ๋์ง ์์ต๋๋ค( self.confirmationCommand.executionSignals.switchToLatest
). ์ด๋ ๋ช
๋ น์ด ํญ์ ์คํ ๋ชจ๋๋ฅผ ์ ์งํ๋ฏ๋ก ๋ค๋ฅธ ๋ช
๋ น์ ์คํํ ์ ์์์ ์๋ฏธํฉ๋๋ค.
๋ค์ ์ฝ๋๋ฅผ ์ค์ ๋ก ์ด๋ป๊ฒ ์๋์ํค๋์?
self.deleteCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id objectToDelete) {
[return self.confirmationCommand.executionSignals
switchToLatest]
flattenMap:^id(NSNumber *confirmed) {
if(confirmed) {
return [self deleteObject:objectToDelete];
} else {
return [RACSignal error:someErrorWithAMessageMaybe];
}
}];
}];
@haifengkao take:1
๋ค์ switchToLatest
take:1
์ ๊ฐ์ด ์๋ช
์ฃผ๊ธฐ๋ฅผ ์ ์ดํ ์ ์๋ ํญ๋ชฉ์ ์ถ๊ฐํฉ๋๋ค.
๋ํ ์ ์ง ์ฃผ๊ธฐ์ ์ฃผ์ํ์ญ์์ค. self
๋ํ ์ฌ๋ฌ ์ฐธ์กฐ๋ฅผ @strongify/weakify