blob: 611dc3a17ca2adb720d593dfd4fb9570b28eedef [file] [log] [blame]
//
// Created by Jesse Squires
// http://www.jessesquires.com
//
//
// Documentation
// http://cocoadocs.org/docsets/JSQMessagesViewController
//
//
// GitHub
// https://github.com/jessesquires/JSQMessagesViewController
//
//
// License
// Copyright (c) 2014 Jesse Squires
// Released under an MIT license: http://opensource.org/licenses/MIT
//
#import "JSQLocationMediaItem.h"
#import "JSQMessagesMediaPlaceholderView.h"
#import "JSQMessagesMediaViewBubbleImageMasker.h"
@interface JSQLocationMediaItem ()
@property (strong, nonatomic) UIImage *cachedMapSnapshotImage;
@property (strong, nonatomic) UIImageView *cachedMapImageView;
@end
@implementation JSQLocationMediaItem
#pragma mark - Initialization
- (instancetype)initWithLocation:(CLLocation *)location
{
self = [super init];
if (self) {
[self setLocation:location withCompletionHandler:nil];
}
return self;
}
- (void)clearCachedMediaViews
{
[super clearCachedMediaViews];
_cachedMapImageView = nil;
}
#pragma mark - Setters
- (void)setLocation:(CLLocation *)location
{
[self setLocation:location withCompletionHandler:nil];
}
- (void)setAppliesMediaViewMaskAsOutgoing:(BOOL)appliesMediaViewMaskAsOutgoing
{
[super setAppliesMediaViewMaskAsOutgoing:appliesMediaViewMaskAsOutgoing];
_cachedMapSnapshotImage = nil;
_cachedMapImageView = nil;
}
#pragma mark - Map snapshot
- (void)setLocation:(CLLocation *)location withCompletionHandler:(JSQLocationMediaItemCompletionBlock)completion
{
[self setLocation:location region:MKCoordinateRegionMakeWithDistance(location.coordinate, 500.0, 500.0) withCompletionHandler:completion];
}
- (void)setLocation:(CLLocation *)location region:(MKCoordinateRegion)region withCompletionHandler:(JSQLocationMediaItemCompletionBlock)completion
{
_location = [location copy];
_cachedMapSnapshotImage = nil;
_cachedMapImageView = nil;
if (_location == nil) {
return;
}
[self createMapViewSnapshotForLocation:_location
coordinateRegion:region
withCompletionHandler:completion];
}
- (void)createMapViewSnapshotForLocation:(CLLocation *)location
coordinateRegion:(MKCoordinateRegion)region
withCompletionHandler:(JSQLocationMediaItemCompletionBlock)completion
{
NSParameterAssert(location != nil);
MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc] init];
options.region = region;
options.size = [self mediaViewDisplaySize];
options.scale = [UIScreen mainScreen].scale;
MKMapSnapshotter *snapShotter = [[MKMapSnapshotter alloc] initWithOptions:options];
[snapShotter startWithQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
completionHandler:^(MKMapSnapshot *snapshot, NSError *error) {
if (snapshot == nil) {
NSLog(@"%s Error creating map snapshot: %@", __PRETTY_FUNCTION__, error);
return;
}
MKAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:nil];
CGPoint coordinatePoint = [snapshot pointForCoordinate:location.coordinate];
UIImage *image = snapshot.image;
coordinatePoint.x += pin.centerOffset.x - (CGRectGetWidth(pin.bounds) / 2.0);
coordinatePoint.y += pin.centerOffset.y - (CGRectGetHeight(pin.bounds) / 2.0);
UIGraphicsBeginImageContextWithOptions(image.size, YES, image.scale);
{
[image drawAtPoint:CGPointZero];
[pin.image drawAtPoint:coordinatePoint];
self.cachedMapSnapshotImage = UIGraphicsGetImageFromCurrentImageContext();
}
UIGraphicsEndImageContext();
if (completion) {
dispatch_async(dispatch_get_main_queue(), completion);
}
}];
}
#pragma mark - MKAnnotation
- (CLLocationCoordinate2D)coordinate
{
return self.location.coordinate;
}
#pragma mark - JSQMessageMediaData protocol
- (UIView *)mediaView
{
if (self.location == nil || self.cachedMapSnapshotImage == nil) {
return nil;
}
if (self.cachedMapImageView == nil) {
UIImageView *imageView = [[UIImageView alloc] initWithImage:self.cachedMapSnapshotImage];
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES;
[JSQMessagesMediaViewBubbleImageMasker applyBubbleImageMaskToMediaView:imageView isOutgoing:self.appliesMediaViewMaskAsOutgoing];
self.cachedMapImageView = imageView;
}
return self.cachedMapImageView;
}
- (NSUInteger)mediaHash
{
return self.hash;
}
#pragma mark - NSObject
- (BOOL)isEqual:(id)object
{
if (![super isEqual:object]) {
return NO;
}
JSQLocationMediaItem *locationItem = (JSQLocationMediaItem *)object;
return [self.location isEqual:locationItem.location];
}
- (NSUInteger)hash
{
return super.hash ^ self.location.hash;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: location=%@, appliesMediaViewMaskAsOutgoing=%@>",
[self class], self.location, @(self.appliesMediaViewMaskAsOutgoing)];
}
#pragma mark - NSCoding
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
CLLocation *location = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(location))];
[self setLocation:location withCompletionHandler:nil];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:self.location forKey:NSStringFromSelector(@selector(location))];
}
#pragma mark - NSCopying
- (instancetype)copyWithZone:(NSZone *)zone
{
JSQLocationMediaItem *copy = [[[self class] allocWithZone:zone] initWithLocation:self.location];
copy.appliesMediaViewMaskAsOutgoing = self.appliesMediaViewMaskAsOutgoing;
return copy;
}
@end