Using Protocol to Refactor
Preview:
Citation preview
- 1. Using Protocol to Refactor , Green Chiu, iOS Developer.
- 2. iOS Protocol ?
- 3. ?
- 4. Delegation ?
- 5. ?
- 6. Delegation Pattern Apple CocoaTouch SDK UITableView,
UICollectionView, UIGestureRecognizer and so on. NSURLSession,
StoreKit
- 7. NS-Protocols archive, copy, enumerate NSCopying NSCoding
NSFastEnumeration
- 8. Objective-C/Swift Protocols method
- 9. Protocol in Objective-C @protocol SampleProtocol -
(void)sampleMethodA; - (void)sampleMethodB; @optional -
(void)sampleOptionalMethod; @end
- 10. Protocol class method
- 11. The End
- 12. /
- 13. Class LocalPlaylistInfo -
(void)fetchPlaylistCoverImageWithSize { if () { UIImage *image =
nil; DBMetaReference *ref = ; if (ref.sourceType == ) { DBMetaItem
*item = ; } else if (ref.sourceType == ) { MPMediaItem *item = ;
image = [item.artwork imageWith ]; } else if (ref.sourceType ==
LocalDBContextSongSourceTypeStore) { DBMetaItem *item = ; if
(!item) { return; } NSString *imageFileURLString = ; void
(^imageCallback)(NSString *fileURLString, UIImage *image) =
^(NSString *fileURLString, UIImage *image) { if (image ) { } else
if ([NSURL URLWithString:item.photoURL]) { [[KKRadioImageManager
sharedImageManager] fetchImageWithURL: requester:nil
callback:^(UIImage *receiveImage, NSError *error) { if
(receiveImage) { } }]; } };
- 14. Class SongInfoViewModel - (void)loadSongInfo:(LocalSongInfo
*)inSongInfo { if (inSongInfo.type ==
LocalDBContextSongSourceTypeStore || ...) { DBMetaItem *item =
inSongInfo.rawItem; if (inSongInfo.type ==
LocalDBContextSongSourceTypeStore) { } else { }
self.imageFileURLString = ; void (^imageCallback)(NSString
*fileURLString, UIImage *image) = ^void(NSString *fileURLString,
UIImage *image){ if (image) { weakSelf.albumCoverImage = cropImage;
} else if ([NSURL URLWithString:item.photoURL]) {
[[KKRadioImageManager sharedImageManager] fetchImageWithURL:
requester:nil callback:^(UIImage *receiveImage, NSError *error) {
if (receiveImage) { weakSelf.albumCoverImage = } }]; } }; return; }
if (inSongInfo.image) { }
- 15. Issues View or Model classes/framework
- 16. Design Protocol typedef NS_ENUM(NSInteger, ProvideImageWay)
{ ProvideImageWayNone = NSNotFound,
ProvideImageWayFetchWithURLString = 0, ProvideImageWayGetWithSize,
ProvideImageWayGenerateWithCallback }; @protocol
LocalItemImageProvider - (ProvideImageWay)getCoverImageWay; -
(NSString *)coverURLString; - (UIImage
*)coverImageWithSize:(CGSize)inSize; -
(void)generateImageWithCallback:(void(^)(UIImage *))inCallback;
@end
- 17. After implemented - (void)loadSongInfo:(LocalSongInfo
*)inSongInfo { switch ([inSongInfo getCoverImageWay]) { case
UPProvideImageWayGetWithSize: self.albumCoverImageView.image =
[inSongInfo coverImageWithSize:CGSizeMake()]; break; case
UPProvideImageWayGenerateWithCallback: { __weak typeof(self)
weakSelf = self; [inSongInfo generateImageWithCallback:^(UIImage
*image) { weakSelf.albumCoverImageView.image = image; }]; break; }
case UPProvideImageWayFetchWithURLString: break; case
UPProvideImageWayNone: break; } }
- 18. Optimized // UIImageView+LocalItemImageProvider.m -
(void)loadImageWithImageProvider:(id)inImageProvider { if
(![inImageProvider
conformsToProtocol:@protocol(LocalItemImageProvider)]) { return; }
switch ([inImageProvider getCoverImageWay]) { case
ProvideImageWayGetWithSize: self.image = [inImageProvider
coverImageWithSize:CGSizeMake(44, 44)]; break; case
ProvideImageWayGenerateWithCallback: { __weak typeof(self) weakSelf
= self; [inImageProvider generateImageWithCallback:^(UIImage
*image) { weakSelf.image = image; }]; break; } case
ProvideImageWayFetchWithURLString: [self
fetchImageWithURLString:[inImageProvider coverURLString]]; break;
case ProvideImageWayNone: default: break; } }
- 19. Finally - (void)loadSongInfo:(UPLocalSongInfo *)inSongInfo
{ [self.albumCoverImageView loadImageWithImageProvider:inSongInfo];
}
- 20. Besides Protocol Mock
- 21. Testing // UIImageView+LocalItemImageProvider.m -
(void)loadImageWithImageProvider:(id)inImageProvider { if
(![inImageProvider
conformsToProtocol:@protocol(LocalItemImageProvider)]) { return; }
switch ([inImageProvider getCoverImageWay]) { case
ProvideImageWayGetWithSize: self.image = [inImageProvider
coverImageWithSize:CGSizeMake(44, 44)]; break; case
ProvideImageWayGenerateWithCallback: { __weak typeof(self) weakSelf
= self; [inImageProvider generateImageWithCallback:^(UIImage
*image) { weakSelf.image = image; }]; break; } case
ProvideImageWayFetchWithURLString: [self
fetchImageWithURLString:[inImageProvider coverURLString]]; break;
case ProvideImageWayNone: default: break; } }
- 22. Testing @interface TCDummyLocalImageProvider: NSObject -
(instancetype)initWithType:(ProvideImageWay)inWay; @end
@implementation TCDummyLocalImageProvider { ProvideImageWay way; }
- (instancetype)initWithType:(ProvideImageWay)inWay { self = [super
init]; if (self) { way = inWay; } return self; } -
(ProvideImageWay)getCoverImageWay { return way; } ... @end
- 23. Testing - (void)testUIImageLoadImageWithImageProvider {
UIImageView *imageView = [[UIImageView alloc] init]; [imageView
loadImageWithImageProvider:[NSObject new]]; [imageView
loadImageWithImageProvider:[[TCDummyLocalImageProvider alloc]
initWithWay:-1000]]; [imageView
loadImageWithImageProvider:[[TCDummyLocalImageProvider alloc]
initWithWay:ProvideImageWayGetWithSize]]; [imageView
loadImageWithImageProvider:[[TCDummyLocalImageProvider alloc]
initWithWay:...]]; }
- 24. This is Protocol-Oriented Programming
- 25. One more thing
- 26. We are hiring iOS Developer and others
- 27. Thanks