Created
March 2, 2015 14:48
-
-
Save nhindman/c11271809fd8f8880613 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Copyright (c) 2014 URX. All rights reserved. | |
| #import "URXListenButtonSearchViewController.h" | |
| #import <URXSearch/URXTerm.h> | |
| #import <URXSearch/URXSearchResult.h> | |
| #import <URXSearch/NSDictionary+JSONLD.h> | |
| #import <URXSearch/URXActionFilter.h> | |
| #import <URXSearch/URXAnd.h> | |
| #define REUSE_IDENTIFIER @"URXSearchResultGenericTableViewCell" | |
| @interface URXSearchResultGenericTableViewCell : UITableViewCell | |
| @property (strong,nonatomic) URXSearchResult *searchResult; | |
| @property (strong, nonatomic) IBOutlet UIImageView *resultImageView; | |
| @property (strong, nonatomic) IBOutlet UILabel *resultName; | |
| @property (strong, nonatomic) IBOutlet UILabel *appName; | |
| - (IBAction)buttonPressed:(id)sender; | |
| @end | |
| @implementation URXSearchResultGenericTableViewCell | |
| -(void)prepareForReuse { | |
| NSString* mainBundlePath = [[NSBundle mainBundle] resourcePath]; | |
| NSString* frameworkBundlePath = [mainBundlePath stringByAppendingPathComponent:@"URXWidgetsResources.bundle"]; | |
| self.resultImageView.image = [UIImage imageWithContentsOfFile:[[NSBundle bundleWithPath:frameworkBundlePath] pathForResource:@"search-result-main-image@2x" ofType:@"png"]]; | |
| [self.resultImageView clipsToBounds]; | |
| } | |
| - (IBAction)buttonPressed:(id)sender { | |
| [self.searchResult resolveAsynchronouslyWithAppStoreFallbackAndFailureHandler:^(URXAPIError *error) { | |
| NSLog(@"URX API ERROR: %@", error.errorMessage); | |
| [[[UIAlertView alloc] initWithTitle:@"There was a problem launching your content." message:@"The content could not be resolved, please try again." delegate:nil cancelButtonTitle:@"Back" otherButtonTitles:nil] show]; | |
| }]; | |
| } | |
| @end | |
| @interface URXListenButtonSearchViewController () | |
| @property (strong, nonatomic) NSArray *searchResults; | |
| -(void) backButtonPressed; | |
| -(void) runQuery:(NSString *)keywords; | |
| @end | |
| @implementation URXListenButtonSearchViewController { | |
| __block BOOL _queryInProgress; | |
| } | |
| -(instancetype)init { | |
| if (self = [super init]) { | |
| _queryInProgress = NO; | |
| } | |
| return self; | |
| } | |
| - (void)viewDidLoad { | |
| [super viewDidLoad]; | |
| // Change search bar color if set | |
| if (self.searchBarTextColor != nil) { | |
| for (UIView *subView in self.searchBar.subviews) { | |
| for (UIView *secondLevelSubview in subView.subviews) { | |
| if ([secondLevelSubview isKindOfClass:[UITextField class]]) { | |
| UITextField *searchBarTextField = (UITextField *)secondLevelSubview; | |
| searchBarTextField.textColor = self.searchBarTextColor; | |
| } | |
| } | |
| } | |
| } | |
| // Prevent tableView from appearing underneath navigationBar: | |
| self.navigationController.navigationBar.translucent = NO; | |
| if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) | |
| self.edgesForExtendedLayout = UIRectEdgeNone; // iOS 7 specific | |
| // self.navigationController.navigationBar.translatesAutoresizingMaskIntoConstraints = NO; | |
| // Add a backButton to the navigationController.navigationBar: | |
| self.navigationController.navigationBar.titleTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys:self.modalBarTextColor, NSForegroundColorAttributeName, nil]; | |
| self.navigationController.navigationBar.barTintColor = self.modalBarColor; | |
| if (self.backButtonColor) { | |
| self.navigationController.navigationBar.tintColor = self.backButtonColor; | |
| } | |
| UIBarButtonItemStyle barButtonItemStyle; | |
| if (self.backButtonBoldText) { | |
| barButtonItemStyle = UIBarButtonItemStyleDone; | |
| } else { | |
| barButtonItemStyle = UIBarButtonItemStylePlain; | |
| } | |
| self.navigationItem.title = self.modalBarTitle; | |
| self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:self.backButtonText style:barButtonItemStyle target:self action:@selector(backButtonPressed)]; | |
| // Set the searchBar properties: | |
| self.searchBar.showsCancelButton = YES; | |
| [self.searchBar setText:self.lastQuery]; | |
| // Set the UIActivityIndicatorView: | |
| self.activityIndicatorView.hidden = YES; | |
| self.activityIndicatorView.translatesAutoresizingMaskIntoConstraints = NO; | |
| // Set the resultsLabel: | |
| self.resultsLabel.translatesAutoresizingMaskIntoConstraints = NO; | |
| self.resultsLabel.text = @"Search for music to listen to!"; | |
| // Run the query: | |
| if (self.lastQuery != nil) { | |
| [self runQuery:self.lastQuery]; | |
| } | |
| // Register the tableViewCell nib: | |
| NSString* mainBundlePath = [[NSBundle mainBundle] resourcePath]; | |
| NSString* frameworkBundlePath = [mainBundlePath stringByAppendingPathComponent:@"URXWidgetsResources.bundle"]; | |
| [self.tableView registerNib:[UINib nibWithNibName:@"URXSearchResultGenericTableViewCell" bundle:[NSBundle bundleWithPath:frameworkBundlePath]] forCellReuseIdentifier:REUSE_IDENTIFIER]; | |
| } | |
| -(void)runQuery:(NSString *)keywords { | |
| _queryInProgress = YES; | |
| self.resultsLabel.hidden = YES; | |
| self.activityIndicatorView.hidden = NO; | |
| [self.activityIndicatorView startAnimating]; | |
| self.lastQuery = keywords; | |
| [[[[[URXTerm termWithKeywords:keywords] and:[URXActionFilter listenAction]] and: [[URXTerm termWithKeywords:@"fitocracy"] not]] withTagCategory:@"widget" AndValue:@"listen button"] searchAsynchronouslyWithSuccessHandler:^(URXSearchResponse *response) { | |
| [self.activityIndicatorView stopAnimating]; | |
| self.activityIndicatorView.hidden = YES; | |
| _queryInProgress = NO; | |
| [self updateTableViewWithSearchResults:response.results]; | |
| // Handle results | |
| } andFailureHandler:^(URXAPIError *error) { | |
| // There was an error | |
| NSLog(@"%@", error.errorMessage); | |
| [self.activityIndicatorView stopAnimating]; | |
| self.activityIndicatorView.hidden = YES; | |
| _queryInProgress = NO; | |
| [self updateTableViewWithSearchResults:@[]]; | |
| if (error.errorType == URXNoSearchResultsError) { | |
| self.resultsLabel.text = @"No results found."; | |
| } else { | |
| self.resultsLabel.text = @"There was an error, please try again."; | |
| } | |
| self.resultsLabel.hidden = NO; | |
| }]; | |
| } | |
| -(void)updateTableViewWithSearchResults:(NSArray *)searchResults { | |
| [self.tableView beginUpdates]; | |
| NSMutableArray *updateIndexPaths = [NSMutableArray array]; | |
| NSMutableArray *insertIndexPaths = [NSMutableArray array]; | |
| NSMutableArray *deleteIndexPaths = [NSMutableArray array]; | |
| for (int i = 0; i < self.searchResults.count || i < searchResults.count; i++) { | |
| NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0]; | |
| if (i < self.searchResults.count && i < searchResults.count) { | |
| [updateIndexPaths addObject:indexPath]; | |
| } else if (i < self.searchResults.count) { | |
| [deleteIndexPaths addObject:indexPath]; | |
| } else { | |
| [insertIndexPaths addObject:indexPath]; | |
| } | |
| } | |
| self.searchResults = searchResults; | |
| [self.tableView reloadRowsAtIndexPaths:updateIndexPaths withRowAnimation:UITableViewRowAnimationAutomatic]; | |
| [self.tableView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationAutomatic]; | |
| [self.tableView deleteRowsAtIndexPaths:deleteIndexPaths withRowAnimation:UITableViewRowAnimationAutomatic]; | |
| [self.tableView endUpdates]; | |
| } | |
| -(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar { | |
| return !_queryInProgress; | |
| } | |
| -(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar { | |
| [searchBar resignFirstResponder]; | |
| } | |
| -(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { | |
| if (_queryInProgress) { | |
| searchBar.text = self.lastQuery; | |
| } | |
| } | |
| -(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { | |
| if ([searchBar.text isEqualToString:@""]) { | |
| if (self.lastQuery != nil) { | |
| searchBar.text = self.lastQuery; | |
| } | |
| } else { | |
| [self runQuery:searchBar.text]; | |
| } | |
| [searchBar resignFirstResponder]; | |
| } | |
| -(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar { | |
| if ([searchBar.text isEqualToString:@""] && self.lastQuery != nil) { | |
| searchBar.text = self.lastQuery; | |
| } | |
| } | |
| -(void) backButtonPressed { | |
| [self.callingViewController dismissViewControllerAnimated:YES completion:nil]; | |
| } | |
| - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { | |
| return 1; | |
| } | |
| - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { | |
| URXSearchResultGenericTableViewCell *cell = (URXSearchResultGenericTableViewCell *)[self.tableView dequeueReusableCellWithIdentifier:REUSE_IDENTIFIER]; | |
| URXSearchResult *searchResult = [self.searchResults objectAtIndex:indexPath.row]; | |
| cell.searchResult = searchResult; | |
| cell.resultName.text = searchResult.name; | |
| // Increase line-height of cell.resultName to make it more aesthetically pleasing: | |
| NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; | |
| paragraphStyle.lineHeightMultiple = 1.3f; | |
| UIFont *font = [UIFont fontWithName:@"Helvetica Neue" size:13.f]; | |
| cell.resultName.attributedText = [[NSAttributedString alloc] initWithString: | |
| searchResult.name attributes: | |
| @{NSParagraphStyleAttributeName : paragraphStyle, NSFontAttributeName : font}]; | |
| NSString *appName = [[[searchResult.entityData getSingle:@"potentialAction"] getSingle:@"name"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; | |
| NSString *actionDescription = [[[searchResult.entityData getSingle:@"potentialAction"] getSingle:@"description"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; | |
| cell.appName.text = [NSString stringWithFormat:@"%@ in %@", actionDescription, appName]; | |
| NSURLRequest *imageRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:searchResult.imageUrl] cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:10000]; | |
| [NSURLConnection sendAsynchronousRequest:imageRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { | |
| // If the data for this table hasn't changed | |
| if (data != nil && connectionError == nil && [[tableView indexPathsForVisibleRows] indexOfObject:indexPath] != NSNotFound) { | |
| cell.resultImageView.image = [UIImage imageWithData:data]; | |
| [cell.resultImageView clipsToBounds]; | |
| } | |
| }]; | |
| return cell; | |
| } | |
| - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { | |
| return 88; | |
| } | |
| - (NSArray *)searchResults { | |
| if (_searchResults == nil) { | |
| _searchResults = @[]; | |
| } | |
| return _searchResults; | |
| } | |
| - (UIColor *)modalBarColor { | |
| if (_modalBarColor == nil) { | |
| _modalBarColor = [UIColor colorWithRed:0.974 green:0.974 blue:0.974 alpha:1]; | |
| } | |
| return _modalBarColor; | |
| } | |
| - (NSString *)modalBarTitle { | |
| if (_modalBarTitle == nil) { | |
| _modalBarTitle = @"Listen to Music"; | |
| } | |
| return _modalBarTitle; | |
| } | |
| - (UIColor *)modalBarTextColor { | |
| if (_modalBarTextColor == nil) { | |
| _modalBarTextColor = [UIColor blackColor]; | |
| } | |
| return _modalBarTextColor; | |
| } | |
| - (NSString *)backButtonText { | |
| if (_backButtonText == nil) { | |
| _backButtonText = @"Back"; | |
| } | |
| return _backButtonText; | |
| } | |
| - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { | |
| return [self.searchResults count]; | |
| } | |
| - (void)didReceiveMemoryWarning { | |
| [super didReceiveMemoryWarning]; | |
| // Dispose of any resources that can be recreated. | |
| } | |
| @end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment