Skip to content
This repository has been archived by the owner on Aug 14, 2019. It is now read-only.

Commit

Permalink
documentation for JSQMessageAvatarImageDataSource and JSQMessagesAvat…
Browse files Browse the repository at this point in the history
…arImage. slight refactor of both, remove size property. update tests. #319
  • Loading branch information
jessesquires committed Sep 6, 2014
1 parent 9156843 commit 45ae209
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 40 deletions.
16 changes: 7 additions & 9 deletions JSQMessagesTests/ModelTests/JSQMessagesAvatarImageTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ - (void)tearDown
- (void)testInitInvalid
{
XCTAssertThrows([[JSQMessagesAvatarImage alloc] init], @"Invalid init should throw");
XCTAssertThrows([[JSQMessagesAvatarImage alloc] initWithPlaceholderImage:nil size:CGSizeMake(10, 10)], @"Invalid init should throw");
XCTAssertThrows([[JSQMessagesAvatarImage alloc] initWithPlaceholderImage:[UIImage imageNamed:@"demo_avatar_jobs"] size:CGSizeZero], @"Invalid init should throw");
XCTAssertThrows([JSQMessagesAvatarImage avatarImageWithPlaceholder:nil], @"Invalid init should throw");
XCTAssertThrows([[JSQMessagesAvatarImage alloc] initWithAvatarImage:nil highlightedImage:nil placeholderImage:nil], @"Invalid init should throw");
}

- (void)testInitValid
{
UIImage *mockImage = [UIImage imageNamed:@"demo_avatar_jobs"];
JSQMessagesAvatarImage *avatar = [[JSQMessagesAvatarImage alloc] initWithPlaceholderImage:mockImage size:CGSizeMake(30, 30)];
JSQMessagesAvatarImage *avatar = [JSQMessagesAvatarImage avatarImageWithPlaceholder:mockImage];
XCTAssertNotNil(avatar, @"Valid init should succeed");
}

Expand All @@ -48,8 +48,7 @@ - (void)testCopy
UIImage *mockImage = [UIImage imageNamed:@"demo_avatar_jobs"];
JSQMessagesAvatarImage *avatar = [[JSQMessagesAvatarImage alloc] initWithAvatarImage:mockImage
highlightedImage:mockImage
placeholderImage:mockImage
size:CGSizeMake(34, 34)];
placeholderImage:mockImage];

JSQMessagesAvatarImage *copy = [avatar copy];
XCTAssertNotNil(copy, @"Copy should succeed");
Expand All @@ -71,14 +70,13 @@ - (void)testCurrentDisplayImage
UIImage *mockImage = [UIImage imageNamed:@"demo_avatar_jobs"];
UIImage *mockPlaceholderImage = [UIImage imageNamed:@"demo_avatar_cook"];

JSQMessagesAvatarImage *avatar = [[JSQMessagesAvatarImage alloc] initWithPlaceholderImage:mockPlaceholderImage
size:CGSizeMake(34, 34)];
JSQMessagesAvatarImage *avatar = [JSQMessagesAvatarImage avatarImageWithPlaceholder:mockPlaceholderImage];

XCTAssertNil(avatar.avatarImage);
XCTAssertEqualObjects(mockPlaceholderImage, [avatar currentDisplayImage], @"Should display placeholder image if avatar image is nil");
XCTAssertEqualObjects(mockPlaceholderImage, avatar.currentDisplayImage, @"Should display placeholder image if avatar image is nil");

avatar.avatarImage = mockImage;
XCTAssertEqualObjects(mockImage, [avatar currentDisplayImage], @"Should display avatar image if available");
XCTAssertEqualObjects(mockImage, avatar.currentDisplayImage, @"Should display avatar image if available");
}

@end
33 changes: 29 additions & 4 deletions JSQMessagesViewController/Model/JSQMessageAvatarImageDataSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,43 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

// TODO: documentation

/**
* The `JSQMessageAvatarImageDataSource` protocol defines the common interface through which
* a `JSQMessagesViewController` and `JSQMessagesCollectionView` interact with avatar image model objects.
*
* It declares the required and optional methods that a class must implement so that instances
* of that class can be display properly within a `JSQMessagesCollectionViewCell`.
*
* A concrete class that conforms to this protocol is provided in the library. See `JSQMessagesAvatarImage`.
*
* @see JSQMessagesAvatarImage.
*/
@protocol JSQMessageAvatarImageDataSource <NSObject>

@required

/**
* @return The avatar image for a regular display state.
* You may return `nil` from this method while the image is being downloaded.
*/
- (UIImage *)avatarImage;

/**
* @return The avatar image for a highlighted display state.
* You may return `nil` from this method if this does not apply.
*/
- (UIImage *)avatarHighlightedImage;

/**
* @return A placeholder avatar image to be displayed if avatarImage is not yet available.
* For example, if avatarImage needs to be downloaded, this placeholder image
* will be used until avatarImage is not `nil`.
*
* @discussion If you do not need support for a placeholder image, that is, your images
* are stored locally on the device, then you may simply return the same value as avatarImage here.
*
* @warning You must not return `nil` from this method.
*/
- (UIImage *)avatarPlaceholderImage;

- (CGSize)avatarImageSize;

@end
50 changes: 41 additions & 9 deletions JSQMessagesViewController/Model/JSQMessagesAvatarImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,58 @@
#import <UIKit/UIKit.h>
#import "JSQMessageAvatarImageDataSource.h"

// TODO: documentation


/**
* A `JSQMessagesAvatarImage` model object represents an avatar image.
* This is a concrete class that implements the `JSQMessageAvatarImageDataSource` protocol.
* It contains a regular avatar image, a highlighted avatar image, and a placeholder avatar image.
*
* @see `JSQMessagesAvatarImageFactory`.
*/
@interface JSQMessagesAvatarImage : NSObject <JSQMessageAvatarImageDataSource, NSCopying>

/**
* The avatar image for a regular display state.
*/
@property (nonatomic, strong) UIImage *avatarImage;

/**
* The avatar image for a highlighted display state.
*/
@property (nonatomic, strong) UIImage *avatarHighlightedImage;

/**
* Returns the placeholder image for an avatar to display if avatarImage is `nil`.
*/
@property (nonatomic, strong, readonly) UIImage *avatarPlaceholderImage;

@property (nonatomic, assign, readonly) CGSize avatarImageSize;
/**
* Returns the current display image for the avatar image.
*
* @discussion This property returns the value of avatarImage if it is not `nil`,
* otherwise it returns the value of avatarPlaceholderImage.
*/
@property (nonatomic, readonly) UIImage *currentDisplayImage;

- (instancetype)initWithPlaceholderImage:(UIImage *)image size:(CGSize)size;
/**
* Initializes and returns an avatar image object having the specified placeholder image.
*
* @param placeholderImage The placeholder image for this avatar image. This value must not be `nil`.
*
* @return An initialized `JSQMessagesAvatarImage` object if successful, `nil` otherwise.
*/
+ (instancetype)avatarImageWithPlaceholder:(UIImage *)placeholderImage;

/**
* Initializes and returns an avatar image object having the specified regular, highlighed, and placeholder images.
*
* @param avatarImage The avatar image for a regular display state.
* @param highlightedImage The avatar image for a highlighted display state.
* @param placeholderImage The placeholder image for this avatar image. This value must not be `nil`.
*
* @return An initialized `JSQMessagesAvatarImage` object if successful, `nil` otherwise.
*/
- (instancetype)initWithAvatarImage:(UIImage *)avatarImage
highlightedImage:(UIImage *)highlightedImage
placeholderImage:(UIImage *)placeholderImage
size:(CGSize)size;

- (UIImage *)currentDisplayImage;
placeholderImage:(UIImage *)placeholderImage;

@end
28 changes: 10 additions & 18 deletions JSQMessagesViewController/Model/JSQMessagesAvatarImage.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,40 +22,36 @@ @implementation JSQMessagesAvatarImage

#pragma mark - Initialization

- (instancetype)initWithPlaceholderImage:(UIImage *)image size:(CGSize)size
+ (instancetype)avatarImageWithPlaceholder:(UIImage *)placeholderImage
{
return [self initWithAvatarImage:nil
highlightedImage:nil
placeholderImage:image
size:size];
return [[JSQMessagesAvatarImage alloc] initWithAvatarImage:nil
highlightedImage:nil
placeholderImage:placeholderImage];
}

- (instancetype)initWithAvatarImage:(UIImage *)avatarImage
highlightedImage:(UIImage *)highlightedImage
placeholderImage:(UIImage *)placeholderImage
size:(CGSize)size
{
NSParameterAssert(placeholderImage != nil);
NSParameterAssert(!CGSizeEqualToSize(size, CGSizeZero));

self = [super init];
if (self) {
_avatarImage = avatarImage;
_avatarHighlightedImage = highlightedImage;
_avatarPlaceholderImage = placeholderImage;
_avatarImageSize = size;
}
return self;
}

- (id)init
{
NSAssert(NO, @"%s is not a valid initializer for %@. Use %@ instead.",
__PRETTY_FUNCTION__, [self class], NSStringFromSelector(@selector(initWithAvatarImage:highlightedImage:placeholderImage:size:)));
__PRETTY_FUNCTION__, [self class], NSStringFromSelector(@selector(initWithAvatarImage:highlightedImage:placeholderImage:)));
return nil;
}

#pragma mark - Avatar image
#pragma mark - Getters

- (UIImage *)currentDisplayImage
{
Expand All @@ -66,16 +62,13 @@ - (UIImage *)currentDisplayImage

- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: avatarImage=%@, avatarImageSize=%@, avatarHighlightedImage=%@, avatarPlaceholderImage=%@>",
[self class], self.avatarImage, NSStringFromCGSize(self.avatarImageSize), self.avatarHighlightedImage, self.avatarPlaceholderImage];
return [NSString stringWithFormat:@"<%@: avatarImage=%@, avatarHighlightedImage=%@, avatarPlaceholderImage=%@>",
[self class], self.avatarImage, self.avatarHighlightedImage, self.avatarPlaceholderImage];
}

- (id)debugQuickLookObject
{
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.avatarImageSize.width, self.avatarImageSize.height)];
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.image = [self currentDisplayImage];
return imageView;
return [[UIImageView alloc] initWithImage:[self currentDisplayImage]];
}

#pragma mark - NSCopying
Expand All @@ -84,8 +77,7 @@ - (instancetype)copyWithZone:(NSZone *)zone
{
return [[[self class] allocWithZone:zone] initWithAvatarImage:[UIImage imageWithCGImage:self.avatarImage.CGImage]
highlightedImage:[UIImage imageWithCGImage:self.avatarHighlightedImage.CGImage]
placeholderImage:[UIImage imageWithCGImage:self.avatarPlaceholderImage.CGImage]
size:self.avatarImageSize];
placeholderImage:[UIImage imageWithCGImage:self.avatarPlaceholderImage.CGImage]];
}

@end

0 comments on commit 45ae209

Please sign in to comment.