From cd238a498c0eb35b44319064895a8351bdd5818a Mon Sep 17 00:00:00 2001 From: Ash Furrow Date: Tue, 22 Oct 2013 19:07:21 -0400 Subject: [PATCH] Added FRPPhotoViewModel. --- FRP.xcodeproj/project.pbxproj | 18 +++++++++++-- FRP/FRPPhotoViewController.h | 7 ++--- FRP/FRPPhotoViewController.m | 40 ++++++++++++++-------------- FRP/FRPPhotoViewModel.h | 20 ++++++++++++++ FRP/FRPPhotoViewModel.m | 50 +++++++++++++++++++++++++++++++++++ 5 files changed, 110 insertions(+), 25 deletions(-) create mode 100644 FRP/FRPPhotoViewModel.h create mode 100644 FRP/FRPPhotoViewModel.m diff --git a/FRP.xcodeproj/project.pbxproj b/FRP.xcodeproj/project.pbxproj index c26176d..bd1df47 100644 --- a/FRP.xcodeproj/project.pbxproj +++ b/FRP.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 5E730B0E1815F3E4003FCB43 /* FRPGalleryViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E730B0D1815F3E4003FCB43 /* FRPGalleryViewModel.m */; }; 5E730B101815F78B003FCB43 /* FRPGalleryViewModelTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E730B0F1815F78B003FCB43 /* FRPGalleryViewModelTests.m */; }; 5E730B141815FE97003FCB43 /* FRPFullSizePhotoViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E730B131815FE97003FCB43 /* FRPFullSizePhotoViewModel.m */; }; + 5EAD1F5818173A3200C67860 /* FRPPhotoViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EAD1F5718173A3200C67860 /* FRPPhotoViewModel.m */; }; 5EBC599E180B247500B683A7 /* FRPCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EBC599D180B247500B683A7 /* FRPCell.m */; }; 5EBC59A6180B2AA200B683A7 /* FRPPhotoImporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EBC59A5180B2AA200B683A7 /* FRPPhotoImporter.m */; }; 5EBC59A9180B2C4F00B683A7 /* FRPGalleryFlowLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EBC59A8180B2C4F00B683A7 /* FRPGalleryFlowLayout.m */; }; @@ -60,6 +61,8 @@ 5E730B0F1815F78B003FCB43 /* FRPGalleryViewModelTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FRPGalleryViewModelTests.m; sourceTree = ""; }; 5E730B121815FE97003FCB43 /* FRPFullSizePhotoViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FRPFullSizePhotoViewModel.h; sourceTree = ""; }; 5E730B131815FE97003FCB43 /* FRPFullSizePhotoViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FRPFullSizePhotoViewModel.m; sourceTree = ""; }; + 5EAD1F5618173A3200C67860 /* FRPPhotoViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FRPPhotoViewModel.h; sourceTree = ""; }; + 5EAD1F5718173A3200C67860 /* FRPPhotoViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FRPPhotoViewModel.m; sourceTree = ""; }; 5EBC599C180B247500B683A7 /* FRPCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FRPCell.h; sourceTree = ""; }; 5EBC599D180B247500B683A7 /* FRPCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FRPCell.m; sourceTree = ""; }; 5EBC59A0180B268600B683A7 /* FRPPhotoModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FRPPhotoModel.h; sourceTree = ""; }; @@ -124,8 +127,7 @@ children = ( 5E730B0B1815F39D003FCB43 /* Gallery */, 5E730B111815FE81003FCB43 /* Full Size Photo */, - 5E595115180E0C33002F44FA /* FRPPhotoViewController.h */, - 5E595116180E0C33002F44FA /* FRPPhotoViewController.m */, + 5EAD1F5518173A1E00C67860 /* Photo View Controller */, 5E595118180E21E0002F44FA /* FRPPhotoDetailViewController.h */, 5E595119180E21E0002F44FA /* FRPPhotoDetailViewController.m */, 5E59511B181219AC002F44FA /* FRPLoginViewController.h */, @@ -157,6 +159,17 @@ name = "Full Size Photo"; sourceTree = ""; }; + 5EAD1F5518173A1E00C67860 /* Photo View Controller */ = { + isa = PBXGroup; + children = ( + 5E595115180E0C33002F44FA /* FRPPhotoViewController.h */, + 5E595116180E0C33002F44FA /* FRPPhotoViewController.m */, + 5EAD1F5618173A3200C67860 /* FRPPhotoViewModel.h */, + 5EAD1F5718173A3200C67860 /* FRPPhotoViewModel.m */, + ); + name = "Photo View Controller"; + sourceTree = ""; + }; 5EBC599F180B267400B683A7 /* UICollectionView Extensions */ = { isa = PBXGroup; children = ( @@ -432,6 +445,7 @@ 5EBC59A6180B2AA200B683A7 /* FRPPhotoImporter.m in Sources */, 5EBE2B2B180B0AF1007B6BF3 /* FRPGalleryViewController.m in Sources */, 5E730B141815FE97003FCB43 /* FRPFullSizePhotoViewModel.m in Sources */, + 5EAD1F5818173A3200C67860 /* FRPPhotoViewModel.m in Sources */, 5EBE2B07180B07D0007B6BF3 /* FRPAppDelegate.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/FRP/FRPPhotoViewController.h b/FRP/FRPPhotoViewController.h index 848eff7..e36ebb9 100644 --- a/FRP/FRPPhotoViewController.h +++ b/FRP/FRPPhotoViewController.h @@ -8,13 +8,14 @@ #import -@class FRPPhotoModel; +@class FRPPhotoViewModel; @interface FRPPhotoViewController : UIViewController --(instancetype)initWithPhotoModel:(FRPPhotoModel *)photoModel index:(NSInteger)photoIndex; +-(instancetype)initWithViewModel:(FRPPhotoViewModel *)viewModel index:(NSInteger)photoIndex; @property (nonatomic, readonly) NSInteger photoIndex; -@property (nonatomic, readonly) FRPPhotoModel *photoModel; + +@property (nonatomic, readonly) FRPPhotoViewModel *viewModel; @end diff --git a/FRP/FRPPhotoViewController.m b/FRP/FRPPhotoViewController.m index 5a955b7..7c1bcc3 100644 --- a/FRP/FRPPhotoViewController.m +++ b/FRP/FRPPhotoViewController.m @@ -10,6 +10,7 @@ // Model #import "FRPPhotoModel.h" +#import "FRPPhotoViewModel.h" // Utilities #import "FRPPhotoImporter.h" @@ -19,7 +20,7 @@ // Private assignment @property (nonatomic, assign) NSInteger photoIndex; -@property (nonatomic, strong) FRPPhotoModel *photoModel; +@property (nonatomic, strong) FRPPhotoViewModel *viewModel; // Private properties @property (nonatomic, weak) UIImageView *imageView; @@ -28,12 +29,12 @@ @implementation FRPPhotoViewController --(instancetype)initWithPhotoModel:(FRPPhotoModel *)photoModel index:(NSInteger)photoIndex +-(instancetype)initWithViewModel:(FRPPhotoViewModel *)viewModel index:(NSInteger)photoIndex { self = [self init]; if (!self) return nil; - self.photoModel = photoModel; + self.viewModel = viewModel; self.photoIndex = photoIndex; return self; @@ -48,27 +49,26 @@ // Configure subviews UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.bounds]; - RAC(imageView, image) = [RACObserve(self.photoModel, fullsizedData) map:^id(id value) { - return [UIImage imageWithData:value]; - }]; + RAC(imageView, image) = self.viewModel.photoImageSignal; imageView.contentMode = UIViewContentModeScaleAspectFit; [self.view addSubview:imageView]; self.imageView = imageView; -} - --(void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - if (!self.presentedViewController) { - [SVProgressHUD show]; - - // Fetch data - [[FRPPhotoImporter fetchPhotoDetails:self.photoModel] subscribeError:^(NSError *error) { - [SVProgressHUD showErrorWithStatus:@"Error"]; - } completed:^{ - [SVProgressHUD dismiss]; - }]; - } + @weakify(self); + [[self rac_signalForSelector:@selector(viewDidAppear:)] subscribeNext:^(id x) { + @strongify(self); + if (!self.presentedViewController) { + [SVProgressHUD show]; + + [self.viewModel.viewDidAppearCommand execute:nil]; + } + }]; + [self.viewModel.viewDidAppearCommand.executionSignals subscribeCompleted:^{ + [SVProgressHUD dismiss]; + }]; + [self.viewModel.viewDidAppearCommand.errors subscribeNext:^(id x) { + [SVProgressHUD showErrorWithStatus:@"Error"]; + }]; } @end diff --git a/FRP/FRPPhotoViewModel.h b/FRP/FRPPhotoViewModel.h new file mode 100644 index 0000000..a5a9255 --- /dev/null +++ b/FRP/FRPPhotoViewModel.h @@ -0,0 +1,20 @@ +// +// FRPPhotoViewModel.h +// FRP +// +// Created by Ash Furrow on 10/22/2013. +// Copyright (c) 2013 Ash Furrow. All rights reserved. +// + +#import + +@class FRPPhotoModel; + +@interface FRPPhotoViewModel : NSObject + +-(instancetype)initWithPhotoModel:(FRPPhotoModel *)photoModel; + +@property (nonatomic, readonly) RACCommand *viewDidAppearCommand; +@property (nonatomic, readonly) RACSignal *photoImageSignal; + +@end diff --git a/FRP/FRPPhotoViewModel.m b/FRP/FRPPhotoViewModel.m new file mode 100644 index 0000000..27fd82e --- /dev/null +++ b/FRP/FRPPhotoViewModel.m @@ -0,0 +1,50 @@ +// +// FRPPhotoViewModel.m +// FRP +// +// Created by Ash Furrow on 10/22/2013. +// Copyright (c) 2013 Ash Furrow. All rights reserved. +// + +#import "FRPPhotoViewModel.h" + +//Utilities +#import "FRPPhotoImporter.h" + +@interface FRPPhotoViewModel () + +@property (nonatomic, strong) RACCommand *viewDidAppearCommand; +@property (nonatomic, strong) FRPPhotoModel *photoModel; +@property (nonatomic, strong) RACSignal *photoImageSignal; + +@end + +@implementation FRPPhotoViewModel + +-(instancetype)initWithPhotoModel:(FRPPhotoModel *)photoModel { + self = [self init]; + if (!self) return nil; + + self.photoModel = photoModel; + + @weakify(self); + self.viewDidAppearCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) { + return [RACSignal createSignal:^RACDisposable *(id subscriber) { + @strongify(self); + // Fetch data + [[FRPPhotoImporter fetchPhotoDetails:self.photoModel] subscribeError:^(NSError *error) { + [subscriber sendError:nil]; + } completed:^{ + [subscriber sendCompleted]; + }]; + }]; + }]; + + self.photoImageSignal = [RACObserve(self.photoModel, fullsizedData) map:^id(id value) { + return [UIImage imageWithData:value]; + }]; + + return self; +} + +@end