Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // ViewController.m
- // RenderTextDemo
- //
- // Created by Shubham Goyal on 10/3/12.
- // Copyright (c) 2012 [email protected]. All rights reserved.
- //
- #import "ArticleViewController.h"
- #import "CommentsWidgetViewController.h"
- #import "RatingWidgetViewController.h"
- #import "RelatedArticlesWidgetViewController.h"
- #import "SDURLCache.h"
- #define BAR_HEIGHT 60
- #define IPAD_HEIGHT 748
- #define IPAD_WIDTH 1024
- #define ANIMATION_DURATION 0.5
- #define PADDING 50
- #define articleURLFormat @"http://ec2-175-41-180-218.ap-southeast-1.compute.amazonaws.com/article/list_article_content/%u"
- #define themeURLFormat @"http://ec2-175-41-180-218.ap-southeast-1.compute.amazonaws.com/publisher/get_theme/%u"
- #define kJSONThemeKey @"data"
- #define kJSONSuccessKey @"success"
- #define kJSONErrorMessageKey @"error_msg"
- @interface ArticleViewController ()
- #pragma mark - Network
- @property (strong, nonatomic) NSMutableData *receivedThemeData;
- @property (strong, nonatomic) NSMutableData *receivedArticleData;
- @end
- @implementation ArticleViewController
- @synthesize publisherId;
- @synthesize articleId;
- @synthesize pages;
- @synthesize pageNumber = _pageNumber;
- - (void)setPageNumber: (NSUInteger) aPageNumber {
- _pageNumber = aPageNumber;
- [[NSNotificationCenter defaultCenter] postNotificationName:@"pageNumberSet" object:@"nil"];
- }
- @synthesize pageViews;
- @synthesize pageViewContainer;
- @synthesize comments;
- @synthesize rating;
- @synthesize relatedArticles;
- @synthesize images;
- @synthesize numberOfStars;
- @synthesize bar;
- @synthesize ratingButton;
- @synthesize isRatingButtonClicked;
- @synthesize commentsButton;
- @synthesize relatedArticlesButton;
- @synthesize curtain;
- @synthesize thumbnailContentView;
- @synthesize thumbnailScrollView;
- @synthesize headerView;
- @synthesize themeModel;
- @synthesize receivedThemeData;
- @synthesize receivedArticleData;
- #pragma mark - Custom initialization
- - (id) initWithCoder:(NSCoder *)aDecoder {
- if (self = [super initWithCoder: aDecoder]) {
- pages = [NSMutableArray array];
- pageViews = [NSMutableArray array];
- }
- return self;
- }
- #pragma mark - Page layout
- + (LayoutType) layoutTypeFromString: (NSString*) aLayoutTypeString {
- if ([aLayoutTypeString isEqualToString: @"TWO_COLUMN"]) {
- return TWO_COLUMN;
- } else if ([aLayoutTypeString isEqualToString: @"THREE_COLUMN"]) {
- return THREE_COLUMN;
- } else if ([aLayoutTypeString isEqualToString: @"TWO_COLUMN_IMAGE"]) {
- return TWO_COLUMN_IMAGE;
- } else if ([aLayoutTypeString isEqualToString: @"TWO_COLUMN_VIDEO"]) {
- return TWO_COLUMN_VIDEO;
- } else {
- // TODO: Should not crash like this
- // @throw [NSException exceptionWithName: NSGenericException reason: @"Unexpected LayoutType string" userInfo: nil];
- return DEFAULT_LAYOUT;
- }
- }
- - (void) applyLayout:(LayoutType)layoutType toView:(UIView*)view pageData: (NSDictionary*) aPage {
- switch (layoutType) {
- case TWO_COLUMN:
- case THREE_COLUMN:
- break;
- case TWO_COLUMN_IMAGE:
- [self putImageWidgetInView: view pageData: aPage];
- break;
- case TWO_COLUMN_VIDEO:
- [self putVideoInView: view pageData: aPage];
- break;
- default:
- DLog(@"/!\\ WARNING!!! Bad LayoutType input")
- break;
- }
- }
- #define kYouTubeVideoHTMLFormat @"<embed src=\"%@\" type=\"application/x-shockwave-flash\" width=\"%f\" height=\"%f\"></embed>"
- - (void) putVideoInView:(UIView*)view pageData: (NSDictionary*) aPage {
- UIWebView* video = [[UIWebView alloc] initWithFrame:CGRectMake(530, 155, 470, 345)];
- video.scrollView.scrollEnabled = NO;
- // TODO: Currently the server doesn't support video on other pages. Add support later.
- NSString* urlString = [aPage objectForKey: @"video"];
- NSString *html = [NSString stringWithFormat: kYouTubeVideoHTMLFormat, urlString, video.frame.size.width, video.frame.size.height];
- [video loadHTMLString:html baseURL:nil];
- [view addSubview:video];
- }
- #define serverBaseURL @"http://ec2-175-41-180-218.ap-southeast-1.compute.amazonaws.com/"
- - (void) putImageWidgetInView: (UIView*) view pageData: (NSDictionary*) aPage {
- // TODO: Currently the server doesn't support image on other pages. Add support later.
- NSArray *imageURLStrings = [aPage objectForKey: @"images"];
- DLog(@"imageURLStrings: %@", imageURLStrings);
- NSMutableArray *imageURLs = [NSMutableArray array];
- for (NSString *URLString in imageURLStrings) {
- DLog(@"%@", [serverBaseURL stringByAppendingPathComponent:URLString])
- NSString *imageURLString = [serverBaseURL stringByAppendingString: [URLString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
- NSURL *imageURL = [NSURL URLWithString: imageURLString];
- if (imageURL) {
- DLog(@"%@", imageURL);
- [imageURLs addObject: imageURL];
- } else {
- DLog(@"Failed to create URL for: %@", imageURLString);
- }
- }
- self.images = [ImageWidgetViewController createImageWidgetWithImageURLs: [NSArray arrayWithArray:imageURLs] frame: CGRectMake(530, 155, 470, 345) fullScreenSuperview: self.view];
- // TODO: When to remove the child view controller?
- // TODO: Check if we need to add as child VC
- [self addChildViewController: self.images];
- [view addSubview: self.images.view];
- }
- #pragma mark - Theme
- - (void) parseTheme: (NSData*) aData {
- NSError* jsonParsingError = nil;
- NSDictionary* responseJSON = [NSJSONSerialization JSONObjectWithData: aData options: kNilOptions error: &jsonParsingError];
- assert(responseJSON == nil ^ jsonParsingError == nil);
- if (jsonParsingError) {
- DLog(@"JSON parsing error: %@", jsonParsingError.debugDescription);
- DLog(@"Data dump: %@", [[NSString alloc] initWithData: aData encoding: NSUTF8StringEncoding]);
- return;
- }
- assert([responseJSON isKindOfClass: [NSDictionary class]]);
- BOOL isSuccess = [(NSNumber*) [responseJSON valueForKey: kJSONSuccessKey] boolValue];
- if (!isSuccess) {
- DLog(@"Error encountered on server: %@", [responseJSON valueForKey: kJSONErrorMessageKey]);
- DLog(@"Data dump: %@", [[NSString alloc] initWithData: aData encoding: NSUTF8StringEncoding]);
- return;
- }
- NSDictionary* themeImages = [responseJSON valueForKey: kJSONThemeKey];
- assert(themeImages && [themeImages isKindOfClass: [NSDictionary class]]);
- self.themeModel = [[ThemeModel alloc] initWithDictionary: themeImages];
- }
- - (void) loadTheme {
- NSURL* themeURL = [[NSURL alloc] initWithString: [NSString stringWithFormat: themeURLFormat, self.publisherId]];
- NSURLRequest *themeRequest = [[NSURLRequest alloc] initWithURL: themeURL cachePolicy:NSURLRequestReloadRevalidatingCacheData timeoutInterval: 60.];
- NSURLConnection *themeConnection = [[NSURLConnection alloc] initWithRequest:themeRequest delegate:self];
- if (themeConnection) {
- self.receivedThemeData = [NSMutableData data];
- }
- }
- - (void) updateHeader {
- self.headerView.image = self.themeModel.primaryHeader;
- }
- #pragma mark - Article
- #define kJSONContentKey @"content"
- #define kJSONLayoutTypeKey @"layoutType"
- #define kInsertCSSFormatString @"<style type=\"text/css\">h1,h2,h3,h4,h5 {color: %@;}</style>"
- - (void) parseArticle: (NSData*) aData {
- NSError* jsonParsingError = nil;
- NSDictionary* responseJSON = [NSJSONSerialization JSONObjectWithData: aData options: kNilOptions error: &jsonParsingError];
- assert(responseJSON == nil ^ jsonParsingError == nil);
- if (jsonParsingError) {
- DLog(@"JSON parsing error: %@", jsonParsingError.debugDescription);
- DLog(@"Data dump: %@", [[NSString alloc] initWithData: aData encoding: NSUTF8StringEncoding]);
- return;
- }
- assert([responseJSON isKindOfClass: [NSDictionary class]]);
- BOOL isSuccess = [(NSNumber*) [responseJSON valueForKey: kJSONSuccessKey] boolValue];
- if (!isSuccess) {
- DLog(@"Error encountered on server: %@", [responseJSON valueForKey: kJSONErrorMessageKey]);
- DLog(@"Data dump: %@", [[NSString alloc] initWithData: aData encoding: NSUTF8StringEncoding]);
- return;
- }
- NSArray *data_ = [responseJSON objectForKey: @"data"];
- NSDictionary *obj = [data_ objectAtIndex: 0];
- self.pages = [obj objectForKey: @"content"];
- NSString *colorString = [obj objectForKey: @"color"];
- int i = 0;
- for (i = 0; i < [self.pages count]; i++) {
- NSDictionary *page = [self.pages objectAtIndex: i];
- NSString *pageContent = [page objectForKey: kJSONContentKey];
- assert(pageContent);
- // TODO: Remove this hack!!!
- UIWebView* pageView = [[UIWebView alloc] initWithFrame:CGRectMake(i * IPAD_WIDTH, 30, IPAD_WIDTH, IPAD_HEIGHT - BAR_HEIGHT)];
- pageView.delegate = self;
- NSString* css = [NSString stringWithFormat: kInsertCSSFormatString, colorString];
- pageContent = [css stringByAppendingString: pageContent];
- [pageView loadHTMLString: pageContent baseURL:nil];
- pageView.scrollView.scrollEnabled = NO;
- [self.pageViews addObject:pageView];
- [self.pageViewContainer insertSubview: pageView atIndex:i];
- UISwipeGestureRecognizer *leftSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleLeftSwipeGesture:)];
- leftSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
- [pageView addGestureRecognizer:leftSwipeGestureRecognizer];
- UISwipeGestureRecognizer *rightSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleRightSwipeGesture:)];
- rightSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
- [pageView addGestureRecognizer:rightSwipeGestureRecognizer];
- NSString *layoutTypeString = [page objectForKey: kJSONLayoutTypeKey];
- assert(layoutTypeString);
- LayoutType layoutType = [ArticleViewController layoutTypeFromString: layoutTypeString];
- [self applyLayout:layoutType toView:pageView pageData: page];
- }
- self.pageNumber = 0;
- }
- - (void) loadArticleContent {
- NSURL* articleURL = [[NSURL alloc] initWithString: [NSString stringWithFormat: articleURLFormat, self.articleId]];
- NSURLRequest *articleRequest = [[NSURLRequest alloc] initWithURL: articleURL cachePolicy:NSURLRequestReloadRevalidatingCacheData timeoutInterval: 60.];
- NSURLConnection *articleConnection = [[NSURLConnection alloc] initWithRequest:articleRequest delegate:self];
- if (articleConnection) {
- self.receivedArticleData = [NSMutableData data];
- }
- }
- - (void) handleLeftSwipeGesture:(UISwipeGestureRecognizer*)swipeGestureRecognizer {
- if (self.pageNumber < self.pages.count - 1)
- self.pageNumber += 1;
- }
- - (void) handleRightSwipeGesture:(UISwipeGestureRecognizer*)swipeGestureRecognizer {
- if (self.pageNumber > 0)
- self.pageNumber -= 1;
- }
- - (void) updatePagesView {
- [UIView animateWithDuration:ANIMATION_DURATION animations:^{
- // For consistency
- int currentPage = self.pageNumber;
- int i = 0;
- for (UIView* page in self.pageViews) {
- page.center = CGPointMake((i - currentPage) * IPAD_WIDTH + IPAD_WIDTH / 2, page.center.y);
- i++;
- }
- }];
- }
- - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
- // TODO: Pop up a browser like Flipboard
- return navigationType != UIWebViewNavigationTypeLinkClicked;
- }
- #pragma mark - Overview
- // UIScrollViewDelegate function
- - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
- if (scrollView == self.thumbnailScrollView)
- return self.thumbnailContentView;
- else
- return nil;
- }
- - (void) handleSelectPage: (UITapGestureRecognizer*) sender {
- DLog(@"Detected tap gesture");
- DLog(@"%d", [self.thumbnailContentView.subviews indexOfObject: sender.view]);
- self.pageNumber = [self.thumbnailContentView.subviews indexOfObject: sender.view];
- [self closeOverview];
- }
- - (void) openOverview {
- for (UIView* thumbnailImageView in self.thumbnailContentView.subviews) {
- [thumbnailImageView removeFromSuperview];
- }
- int i = 0;
- for (UIView* page in self.pageViews) {
- UIGraphicsBeginImageContext(page.frame.size);
- [[page layer] renderInContext: UIGraphicsGetCurrentContext()];
- UIImage* webPageImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- UIView* thumbnailView = [[UIView alloc] initWithFrame: CGRectMake(i * (self.pageViewContainer.frame.size.width + PADDING), 0, self.pageViewContainer.frame.size.width, self.pageViewContainer.frame.size.height)];
- UIImageView *webPageImageView = [[UIImageView alloc] initWithImage: webPageImage];
- webPageImageView.frame = CGRectMake(0, 30, webPageImageView.frame.size.width, webPageImageView.frame.size.height);
- UIImageView *headerImageView = [[UIImageView alloc] initWithFrame: CGRectMake(0, 0, 1024, 130)];
- headerImageView.image = self.headerView.image;
- [thumbnailView addSubview: webPageImageView];
- [thumbnailView addSubview: headerImageView];
- [self.thumbnailContentView addSubview: thumbnailView];
- UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(handleSelectPage:)];
- tap.numberOfTapsRequired = 1;
- [thumbnailView addGestureRecognizer: tap];
- i++;
- }
- self.thumbnailContentView.frame = CGRectMake(0, 0, MAX(0, (IPAD_WIDTH + PADDING) * self.pages.count- PADDING), IPAD_HEIGHT - BAR_HEIGHT);
- self.thumbnailScrollView.contentSize = CGSizeMake(MAX(self.thumbnailContentView.frame.size.width * self.thumbnailScrollView.zoomScale, self.thumbnailScrollView.frame.size.width), self.thumbnailScrollView.frame.size.height);
- [UIView beginAnimations: @"ProtonReader.ArticleViewController.overviewButtonPressed.open" context: nil];
- [UIView setAnimationDuration: 0.3];
- self.curtain.hidden = NO;
- self.thumbnailScrollView.frame = CGRectMake(0, self.pageViewContainer.frame.size.height - self.thumbnailScrollView.frame.size.height, self.thumbnailScrollView.frame.size.width, self.thumbnailScrollView.frame.size.height);
- [UIView commitAnimations];
- DLog(@"%f %f %f %f", self.thumbnailScrollView.frame.origin.x, self.thumbnailScrollView.frame.origin.y, self.thumbnailScrollView.frame.size.width, self.thumbnailScrollView.frame.size.height);
- }
- - (void) closeOverview {
- [UIView beginAnimations: @"ProtonReader.ArticleViewController.overviewButtonPressed.close" context: nil];
- [UIView setAnimationDuration: 0.3];
- self.curtain.hidden = YES;
- self.thumbnailScrollView.frame = CGRectMake(0, 768, self.thumbnailScrollView.frame.size.width, self.thumbnailScrollView.frame.size.height);
- [UIView commitAnimations];
- DLog(@"%f %f %f %f", self.thumbnailScrollView.frame.origin.x, self.thumbnailScrollView.frame.origin.y, self.thumbnailScrollView.frame.size.width, self.thumbnailScrollView.frame.size.height);
- }
- #pragma mark - Article view
- - (void) loadArticle: (NSUInteger) anArticleId {
- for (UIView* view in self.pageViews) {
- [view removeFromSuperview];
- }
- [self.pageViews removeAllObjects];
- self.images = nil;
- // [self.comments.view removeFromSuperview];
- [self.comments.background removeFromSuperview];
- // [self.rating.view removeFromSuperview];
- [self.rating.rateView removeFromSuperview];
- [self.relatedArticles.view removeFromSuperview];
- [self closeOverview];
- self.articleId = anArticleId;
- [self loadArticleContent];
- self.comments = [[CommentsWidgetViewController alloc] initWithMainController:self];
- self.rating = [[RatingWidgetViewController alloc] initWithMainController:self];
- self.relatedArticles = [[RelatedArticlesWidgetViewController alloc] initWithMainController:self];
- }
- #pragma mark - View life cycle
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // TODO: Do we need to remove the observer?
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updatePagesView) name:@"pageNumberSet" object:nil];
- self.thumbnailScrollView.delegate = self;
- self.thumbnailScrollView.zoomScale =
- self.thumbnailScrollView.minimumZoomScale =
- self.thumbnailScrollView.maximumZoomScale = self.thumbnailScrollView.frame.size.height / self.pageViewContainer.frame.size.height;
- [self loadTheme];
- [self loadArticle: self.articleId];
- // [self.comments viewDidLoad];
- }
- - (void)viewDidUnload
- {
- [self setRating:nil];
- [self setComments:nil];
- [self setRelatedArticles:nil];
- [self setBar:nil];
- [self setRatingButton:nil];
- [self setCommentsButton:nil];
- [self setRelatedArticlesButton:nil];
- [self.pageViews removeAllObjects];
- [self setHeaderView:nil];
- [self setCurtain:nil];
- [self setThumbnailContentView:nil];
- [self setThumbnailScrollView:nil];
- [self setPageViewContainer:nil];
- [super viewDidUnload];
- }
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
- {
- return UIInterfaceOrientationIsLandscape(interfaceOrientation);
- }
- #pragma mark - Network
- - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
- {
- if ([[connection.originalRequest.URL.absoluteString stringByDeletingLastPathComponent]
- isEqual: [themeURLFormat stringByDeletingLastPathComponent]]) {
- [self.receivedThemeData setLength: 0];
- }
- else if ([[connection.originalRequest.URL.absoluteString stringByDeletingLastPathComponent]
- isEqual: [articleURLFormat stringByDeletingLastPathComponent]]) {
- [self.receivedArticleData setLength: 0];
- }
- else {
- assert(0);
- }
- }
- - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
- {
- if ([[connection.originalRequest.URL.absoluteString stringByDeletingLastPathComponent]
- isEqual: [themeURLFormat stringByDeletingLastPathComponent]]) {
- [self.receivedThemeData appendData: data];
- }
- else if ([[connection.originalRequest.URL.absoluteString stringByDeletingLastPathComponent]
- isEqual: [articleURLFormat stringByDeletingLastPathComponent]]) {
- [self.receivedArticleData appendData:data];
- }
- else {
- assert(0);
- }
- }
- - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
- {
- DLog(@"Connection failed - %@", error.debugDescription);
- NSCachedURLResponse* cachedResponse = [[SDURLCache sharedURLCache] cachedResponseForRequest:connection.originalRequest];
- if (cachedResponse) {
- DLog(@"Cached response for %@ found.", connection.originalRequest.URL);
- if ([[connection.originalRequest.URL.absoluteString stringByDeletingLastPathComponent]
- isEqual: [themeURLFormat stringByDeletingLastPathComponent]]) {
- DLog(@"Theme");
- self.receivedThemeData = nil;
- [self parseTheme: cachedResponse.data];
- [self updateHeader];
- }
- else if ([[connection.originalRequest.URL.absoluteString stringByDeletingLastPathComponent]
- isEqual: [articleURLFormat stringByDeletingLastPathComponent]]) {
- DLog(@"Article");
- self.receivedArticleData = nil;
- [self parseArticle: cachedResponse.data];
- }
- else {
- assert(0);
- }
- } else {
- DLog(@"Cached response not found for %@.", connection.originalRequest.URL);
- if ([[connection.originalRequest.URL.absoluteString stringByDeletingLastPathComponent]
- isEqual: [themeURLFormat stringByDeletingLastPathComponent]]) {
- DLog(@"Theme");
- self.receivedThemeData = nil;
- }
- else if ([[connection.originalRequest.URL.absoluteString stringByDeletingLastPathComponent]
- isEqual: [articleURLFormat stringByDeletingLastPathComponent]]) {
- DLog(@"Article");
- self.receivedArticleData = nil;
- }
- else {
- assert(0);
- }
- }
- }
- - (void)connectionDidFinishLoading:(NSURLConnection *)connection
- {
- if ([[connection.originalRequest.URL.absoluteString stringByDeletingLastPathComponent]
- isEqual: [themeURLFormat stringByDeletingLastPathComponent]]) {
- DLog(@"Theme");
- [self parseTheme: self.receivedThemeData];
- self.receivedThemeData = nil;
- [self updateHeader];
- }
- else if ([[connection.originalRequest.URL.absoluteString stringByDeletingLastPathComponent]
- isEqual: [articleURLFormat stringByDeletingLastPathComponent]]) {
- DLog(@"Article");
- [self parseArticle: self.receivedArticleData];
- self.receivedArticleData = nil;
- }
- else {
- assert(0);
- }
- }
- #pragma mark - Action handler
- - (IBAction)ratingButtonPressed:(id)sender {
- if (isRatingButtonClicked) {
- [self.rating viewDidUnload];
- }
- else {
- if (self.rating.rateView != nil) {
- [self.rating.rateView removeFromSuperview];
- self.rating.rateView = nil;
- }
- [self.rating viewDidLoad];
- }
- self.isRatingButtonClicked = !self.isRatingButtonClicked;
- }
- - (IBAction)commentsButtonPressed:(id)sender {
- [self.comments buttonPressed:sender];
- }
- - (IBAction)relatedArticlesButtonPressed:(UIButton *)sender {
- [self.relatedArticles buttonPressed:sender];
- }
- - (IBAction)homeButtonPressed:(id)sender {
- UINavigationController *navigationController = self.navigationController;
- [navigationController popToRootViewControllerAnimated: YES];
- }
- - (IBAction)tappedOnCurtain:(id)sender {
- [self closeOverview];
- }
- - (IBAction)overviewButtonPressed:(id)sender {
- if (self.curtain.hidden) {
- [self openOverview];
- } else {
- [self closeOverview];
- }
- }
- - (IBAction)backButtonPressed:(id)sender {
- [self.navigationController popViewControllerAnimated: YES];
- }
- @end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement