Skip to content
This repository has been archived by the owner on Feb 19, 2020. It is now read-only.

Commit

Permalink
Merge branch 'release/3.5.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
DerAndereAndi committed Oct 30, 2013
2 parents 18a3e93 + f6ab185 commit c41a1dc
Show file tree
Hide file tree
Showing 247 changed files with 39,500 additions and 2,059 deletions.
20 changes: 20 additions & 0 deletions Classes/BITAppStoreHeader.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,30 @@

#import <UIKit/UIKit.h>

#ifndef __IPHONE_6_1
#define __IPHONE_6_1 60100
#endif


/**
* Header style depending on the iOS version
*/
typedef NS_ENUM(NSUInteger, BITAppStoreHeaderStyle) {
/**
* Default is iOS 6 style
*/
BITAppStoreHeaderStyleDefault = 0,
/**
* Draw header in the iOS 7 style
*/
BITAppStoreHeaderStyleOS7 = 1
};

@interface BITAppStoreHeader : UIView

@property (nonatomic, copy) NSString *headerText;
@property (nonatomic, copy) NSString *subHeaderText;
@property (nonatomic, strong) UIImage *iconImage;
@property (nonatomic, assign) BITAppStoreHeaderStyle style;

@end
41 changes: 31 additions & 10 deletions Classes/BITAppStoreHeader.m
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@

#define kLightGrayColor BIT_RGBCOLOR(235, 235, 235)
#define kDarkGrayColor BIT_RGBCOLOR(186, 186, 186)
#define kWhiteBackgroundColor BIT_RGBCOLOR(245, 245, 245)
#define kWhiteBackgroundColorDefault BIT_RGBCOLOR(245, 245, 245)
#define kWhiteBackgroundColorOS7 BIT_RGBCOLOR(255, 255, 255)
#define kImageHeight 72
#define kImageBorderRadius 12
#define kImageBorderRadiusiOS7 16.5
#define kImageLeftMargin 14
#define kImageTopMargin 12
#define kTextRow kImageTopMargin*2 + kImageHeight
Expand All @@ -54,7 +56,8 @@ @implementation BITAppStoreHeader {
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
self.backgroundColor = kWhiteBackgroundColor;
self.backgroundColor = kWhiteBackgroundColorDefault;
self.style = BITAppStoreHeaderStyleDefault;
}
return self;
}
Expand All @@ -66,20 +69,35 @@ - (void)drawRect:(CGRect)rect {
CGRect bounds = self.bounds;
CGContextRef context = UIGraphicsGetCurrentContext();

// draw the gradient
NSArray *colors = [NSArray arrayWithObjects:(id)kDarkGrayColor.CGColor, (id)kLightGrayColor.CGColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(CGColorGetColorSpace((__bridge CGColorRef)[colors objectAtIndex:0]), (__bridge CFArrayRef)colors, (CGFloat[2]){0, 1});
CGPoint top = CGPointMake(CGRectGetMidX(bounds), bounds.size.height - 3);
CGPoint bottom = CGPointMake(CGRectGetMidX(bounds), CGRectGetMaxY(bounds));
CGContextDrawLinearGradient(context, gradient, top, bottom, 0);
CGGradientRelease(gradient);
if (self.style == BITAppStoreHeaderStyleDefault) {
// draw the gradient
NSArray *colors = [NSArray arrayWithObjects:(id)kDarkGrayColor.CGColor, (id)kLightGrayColor.CGColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(CGColorGetColorSpace((__bridge CGColorRef)[colors objectAtIndex:0]), (__bridge CFArrayRef)colors, (CGFloat[2]){0, 1});
CGPoint top = CGPointMake(CGRectGetMidX(bounds), bounds.size.height - 3);
CGPoint bottom = CGPointMake(CGRectGetMidX(bounds), CGRectGetMaxY(bounds));
CGContextDrawLinearGradient(context, gradient, top, bottom, 0);
CGGradientRelease(gradient);
} else {
// draw the line
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(ctx, 1.0);
CGContextSetStrokeColorWithColor(ctx, kDarkGrayColor.CGColor);
CGContextMoveToPoint(ctx, 0, CGRectGetMaxY(bounds));
CGContextAddLineToPoint( ctx, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds));
CGContextStrokePath(ctx);
}

// icon
[_iconImage drawAtPoint:CGPointMake(kImageLeftMargin, kImageTopMargin)];

[super drawRect:rect];
}


- (void)layoutSubviews {
if (self.style == BITAppStoreHeaderStyleOS7)
self.backgroundColor = kWhiteBackgroundColorOS7;

[super layoutSubviews];

CGFloat globalWidth = self.frame.size.width;
Expand Down Expand Up @@ -130,7 +148,10 @@ - (void)setIconImage:(UIImage *)anIconImage {

// scale, make borders and reflection
_iconImage = bit_imageToFitSize(anIconImage, CGSizeMake(kImageHeight, kImageHeight), YES);
_iconImage = bit_roundedCornerImage(_iconImage, kImageBorderRadius, 0.0);
CGFloat radius = kImageBorderRadius;
if (self.style == BITAppStoreHeaderStyleOS7)
radius = kImageBorderRadiusiOS7;
_iconImage = bit_roundedCornerImage(_iconImage, radius, 0.0);

[self setNeedsDisplay];
}
Expand Down
2 changes: 2 additions & 0 deletions Classes/BITAppVersionMetaInfo.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Author: Peter Steinberger
* Andreas Linde
*
* Copyright (c) 2012-2013 HockeyApp, Bit Stadium GmbH.
* Copyright (c) 2011 Andreas Linde, Peter Steinberger.
Expand Down Expand Up @@ -34,6 +35,7 @@
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *version;
@property (nonatomic, copy) NSString *shortVersion;
@property (nonatomic, copy) NSString *minOSVersion;
@property (nonatomic, copy) NSString *notes;
@property (nonatomic, copy) NSDate *date;
@property (nonatomic, copy) NSNumber *size;
Expand Down
60 changes: 49 additions & 11 deletions Classes/BITAppVersionMetaInfo.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Author: Peter Steinberger
* Andreas Linde
*
* Copyright (c) 2012-2013 HockeyApp, Bit Stadium GmbH.
* Copyright (c) 2011 Andreas Linde, Peter Steinberger.
Expand Down Expand Up @@ -43,6 +44,7 @@ + (BITAppVersionMetaInfo *)appVersionMetaInfoFromDict:(NSDictionary *)dict {
appVersionMetaInfo.name = [dict objectForKey:@"title"];
appVersionMetaInfo.version = [dict objectForKey:@"version"];
appVersionMetaInfo.shortVersion = [dict objectForKey:@"shortversion"];
appVersionMetaInfo.minOSVersion = [dict objectForKey:@"minimum_os_version"];
[appVersionMetaInfo setDateWithTimestamp:[[dict objectForKey:@"timestamp"] doubleValue]];
appVersionMetaInfo.size = [dict objectForKey:@"appsize"];
appVersionMetaInfo.notes = [dict objectForKey:@"notes"];
Expand All @@ -57,7 +59,6 @@ + (BITAppVersionMetaInfo *)appVersionMetaInfoFromDict:(NSDictionary *)dict {

#pragma mark - NSObject


- (BOOL)isEqual:(id)other {
if (other == self)
return YES;
Expand All @@ -66,24 +67,58 @@ - (BOOL)isEqual:(id)other {
return [self isEqualToAppVersionMetaInfo:other];
}

- (BOOL)isEqualComparingString:(NSString *)stringA withString:(NSString *)stringB {
if ([stringA isKindOfClass:[NSString class]] && [stringB isKindOfClass:[NSString class]]) {
return [stringA isEqualToString:stringB];
}

return NO;
}

- (BOOL)isEqualComparingNumber:(NSNumber *)numberA withNumber:(NSNumber *)numberB {
if ([numberA isKindOfClass:[NSNumber class]] && [numberB isKindOfClass:[NSNumber class]]) {
return [numberA isEqualToNumber:numberB];
}

return NO;
}

- (BOOL)isEqualComparingDate:(NSDate *)dateA withDate:(NSDate *)dateB {
if ([dateA isKindOfClass:[NSDate class]] && [dateB isKindOfClass:[NSDate class]]) {
return [dateA isEqualToDate:dateB];
}

return NO;
}

- (BOOL)isEqualComparingDictionary:(NSDictionary *)dictA withDate:(NSDictionary *)dictB {
if ([dictA isKindOfClass:[NSDictionary class]] && [dictB isKindOfClass:[NSDictionary class]]) {
return [dictA isEqualToDictionary:dictB];
}

return NO;
}

- (BOOL)isEqualToAppVersionMetaInfo:(BITAppVersionMetaInfo *)anAppVersionMetaInfo {
if (self == anAppVersionMetaInfo)
return YES;
if (self.name != anAppVersionMetaInfo.name && ![self.name isEqualToString:anAppVersionMetaInfo.name])
if (![self isEqualComparingString:self.name withString:anAppVersionMetaInfo.name])
return NO;
if (self.version != anAppVersionMetaInfo.version && ![self.version isEqualToString:anAppVersionMetaInfo.version])
if (![self isEqualComparingString:self.version withString:anAppVersionMetaInfo.version])
return NO;
if (self.shortVersion != anAppVersionMetaInfo.shortVersion && ![self.shortVersion isEqualToString:anAppVersionMetaInfo.shortVersion])
if (![self isEqualComparingString:self.shortVersion withString:anAppVersionMetaInfo.shortVersion])
return NO;
if (self.notes != anAppVersionMetaInfo.notes && ![self.notes isEqualToString:anAppVersionMetaInfo.notes])
if (![self isEqualComparingString:self.minOSVersion withString:anAppVersionMetaInfo.minOSVersion])
return NO;
if (self.date != anAppVersionMetaInfo.date && ![self.date isEqualToDate:anAppVersionMetaInfo.date])
if (![self isEqualComparingString:self.notes withString:anAppVersionMetaInfo.notes])
return NO;
if (self.size != anAppVersionMetaInfo.size && ![self.size isEqualToNumber:anAppVersionMetaInfo.size])
if (![self isEqualComparingDate:self.date withDate:anAppVersionMetaInfo.date])
return NO;
if (self.mandatory != anAppVersionMetaInfo.mandatory && ![self.mandatory isEqualToNumber:anAppVersionMetaInfo.mandatory])
if (![self isEqualComparingNumber:self.size withNumber:anAppVersionMetaInfo.size])
return NO;
if (![self.uuids isEqualToDictionary:anAppVersionMetaInfo.uuids])
if (![self isEqualComparingNumber:self.mandatory withNumber:anAppVersionMetaInfo.mandatory])
return NO;
if (![self isEqualComparingDictionary:self.uuids withDate:anAppVersionMetaInfo.uuids])
return NO;
return YES;
}
Expand All @@ -95,6 +130,7 @@ - (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:self.name forKey:@"name"];
[encoder encodeObject:self.version forKey:@"version"];
[encoder encodeObject:self.shortVersion forKey:@"shortVersion"];
[encoder encodeObject:self.minOSVersion forKey:@"minOSVersion"];
[encoder encodeObject:self.notes forKey:@"notes"];
[encoder encodeObject:self.date forKey:@"date"];
[encoder encodeObject:self.size forKey:@"size"];
Expand All @@ -108,6 +144,7 @@ - (id)initWithCoder:(NSCoder *)decoder {
self.name = [decoder decodeObjectForKey:@"name"];
self.version = [decoder decodeObjectForKey:@"version"];
self.shortVersion = [decoder decodeObjectForKey:@"shortVersion"];
self.minOSVersion = [decoder decodeObjectForKey:@"minOSVersion"];
self.notes = [decoder decodeObjectForKey:@"notes"];
self.date = [decoder decodeObjectForKey:@"date"];
self.size = [decoder decodeObjectForKey:@"size"];
Expand Down Expand Up @@ -166,9 +203,10 @@ - (NSString *)notesOrEmptyString {
}
}

// a valid app needs at least following properties: name, version, date

// A valid app needs at least following properties: name, version, date
- (BOOL)isValid {
BOOL valid = [self.name length] && [self.version length] && self.date;
BOOL valid = [self.name length] && [self.version length] && self.date;
return valid;
}

Expand Down
27 changes: 18 additions & 9 deletions Classes/BITAttributedLabel.m
Original file line number Diff line number Diff line change
Expand Up @@ -271,11 +271,16 @@ - (void)setNeedsFramesetter {
- (CTFramesetterRef)framesetter {
if (_needsFramesetter) {
@synchronized(self) {
if (_framesetter) CFRelease(_framesetter);
if (_highlightFramesetter) CFRelease(_highlightFramesetter);
if (_framesetter) {
CFRelease(_framesetter);
_framesetter = nil;
}
if (_highlightFramesetter) {
CFRelease(_highlightFramesetter);
_highlightFramesetter = nil;
}

self.framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)self.renderedAttributedText);
self.highlightFramesetter = nil;
_framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)self.renderedAttributedText);
_needsFramesetter = NO;
}
}
Expand Down Expand Up @@ -666,6 +671,7 @@ - (void)drawStrike:(CTFrameRef)frame inRect:(CGRect)rect context:(CGContextRef)c

CTFontRef font = CTFontCreateWithName((__bridge CFStringRef)self.font.fontName, self.font.pointSize, NULL);
CGContextSetLineWidth(c, CTFontGetUnderlineThickness(font));
CFRelease(font);
CGFloat y = roundf(runBounds.origin.y + runBounds.size.height / 2.0f);
CGContextMoveToPoint(c, runBounds.origin.x, y);
CGContextAddLineToPoint(c, runBounds.origin.x + runBounds.size.width, y);
Expand All @@ -685,12 +691,15 @@ - (void)setText:(id)text {
[self setText:text afterInheritingLabelAttributesAndConfiguringWithBlock:nil];
return;
}

self.attributedText = text;
NSAssert([text isKindOfClass:[NSAttributedString class]], @"TTTAttributedLabel accepts either NSStrings or NSAttributedStrings");
NSAttributedString *attributedString = text;
self.attributedText = attributedString;

self.links = [NSArray array];
if (self.dataDetectorTypes != UIDataDetectorTypeNone) {
for (NSTextCheckingResult *result in [self detectedLinksInString:[self.attributedText string] range:NSMakeRange(0, [text length]) error:nil]) {
for (NSTextCheckingResult *result in [self detectedLinksInString:[self.attributedText string]
range:NSMakeRange(0, [attributedString length])
error:nil]) {
[self addLinkWithTextCheckingResult:result];
}
}
Expand Down Expand Up @@ -822,8 +831,8 @@ - (void)drawTextInRect:(CGRect)rect {
NSMutableAttributedString *highlightAttributedString = [self.renderedAttributedText mutableCopy];
[highlightAttributedString addAttribute:(NSString *)kCTForegroundColorAttributeName value:(id)[self.highlightedTextColor CGColor] range:NSMakeRange(0, highlightAttributedString.length)];

if (!self.highlightFramesetter) {
self.highlightFramesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)highlightAttributedString);
if (!_highlightFramesetter) {
_highlightFramesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)highlightAttributedString);
}

[self drawFramesetter:self.highlightFramesetter attributedString:highlightAttributedString textRange:textRange inRect:textRect context:c];
Expand Down
94 changes: 94 additions & 0 deletions Classes/BITAuthenticationViewController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Author: Stephan Diederich
*
* Copyright (c) 2013 HockeyApp, Bit Stadium GmbH.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

#import <UIKit/UIKit.h>
@protocol BITAuthenticationViewControllerDelegate;
@class BITAuthenticator;
@class BITHockeyAppClient;

/**
* View controller handling user interaction for `BITAuthenticator`
*/
@interface BITAuthenticationViewController : UITableViewController

- (instancetype) initWithDelegate:(id<BITAuthenticationViewControllerDelegate>) delegate;

/**
* can be set to YES to show an additional button + description text
* and allowing to login via external website/UDID.
* if this is set to yes, no further email/password options are shown
*
* defaults to NO
*/
@property (nonatomic, assign) BOOL showsLoginViaWebButton;

/**
* Description shown on top of view. Should tell why this view
* was presented and what's next.
*/
@property (nonatomic, copy) NSString* tableViewTitle;

/**
* can be set to YES to also require the users password
*
* defaults to NO
*/
@property (nonatomic, assign) BOOL requirePassword;

@property (nonatomic, weak) id<BITAuthenticationViewControllerDelegate> delegate;

/**
* allows to pre-fill the email-addy
*/
@property (nonatomic, copy) NSString* email;
@end

/**
* BITAuthenticationViewController protocol
*/
@protocol BITAuthenticationViewControllerDelegate<NSObject>

- (void) authenticationViewControllerDidTapWebButton:(UIViewController*) viewController;

/**
* called when the user wants to login
*
* @param viewController the delegating viewcontroller
* @param email the content of the email-field
* @param password the content of the password-field (if existent)
* @param completion Must be called by the delegate once the auth-task completed
* This viewcontroller shows an activity-indicator in between and blocks
* the UI. if succeeded is NO, it shows an alertView presenting the error
* given by the completion block
*/
- (void) authenticationViewController:(UIViewController*) viewController
handleAuthenticationWithEmail:(NSString*) email
password:(NSString*) password
completion:(void(^)(BOOL succeeded, NSError *error)) completion;

@end
Loading

0 comments on commit c41a1dc

Please sign in to comment.