Create universal search textfield (google and url) in iOS 7 - ios

How do we create a universal search textfield like in iOS 7 safari. I know how to create a Google search field, but how can I create one textfield which has both Google search and URL search.
Google Searchfield:
-(void)SearchButtonClicked {
NSString *query = [maintext.text stringByReplacingOccurrencesOfString:#" " withString:#"+"];
NSString *urlString = [NSString stringWithFormat:#"%#", query];
// remember to change the view controller class in storyboard
MyWebViewController *webViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"WebView"];
// urlString is a public property on MyWebViewController
webViewController.urlString = urlString;
[self presentViewController:webViewController animated:YES completion:nil];
}
- (IBAction)SearchButton:(id)sender {
NSString *query = [maintext.text stringByReplacingOccurrencesOfString:#" " withString:#"+"];
NSString *urlString = [NSString stringWithFormat:#"http://www.google.com/search?q=%#", query];
// remember to change the view controller class in storyboard
MyWebViewController *webViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"WebView"];
// urlString is a public property on MyWebViewController
webViewController.urlString = urlString;
[self presentViewController:webViewController animated:YES completion:nil];
}
My Webview controller:
#import "MyWebViewController.h"
#import "ViewController.h"
#import <Social/Social.h>
#import "SIAlertView.h"
#import "TTAlertView.h"
#import "ETActivityIndicatorView.h"
#implementation MyWebViewController {
}
#synthesize searchField;
#synthesize webView;
ETActivityIndicatorView * etActivity;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSURL *url = [NSURL URLWithString:self.urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
}
-(void)webView:(UIWebView *)webBlog didFailLoadWithError:(NSError *)error{
if ([error code] != -999) {
NSLog(#"Could not load the dumb webPage");
//show error alert, etc.
TTAlertView *alert = [[TTAlertView alloc] initWithTitle:#"Internet Error"
message:#"Searched cannot open the page because your iPhone is not connected to the internet."
delegate:self
cancelButtonTitle:#"Dismiss"
otherButtonTitles:nil];
[alert show];
[etActivity setHidden:YES];
}else{
NSLog(#"Could not load the dumb web page...just might blame user!");
}
}
//Called whenever the view starts loading something
- (void)webViewDidStartLoad:(UIWebView *)webView {
[etActivity startAnimating];
[etActivity setHidden:NO];
}
//Called whenever the view finished loading something
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[etActivity stopAnimating];
[etActivity setHidden:YES];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[webView setDelegate:self];
self.searchField.backgroundColor = [UIColor colorWithRed:255.0/255 green:255.0/255 blue:255.0/255 alpha:1.0f];
self.searchField.layer.cornerRadius = 3.0f;
self.searchField.placeholder = #"Search or enter address";
self.searchField.leftViewMode = UITextFieldViewModeAlways;
UIView* leftView1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
self.searchField.leftView = leftView1;
//Setup handling of LEFT and RIGHT swipes
UISwipeGestureRecognizer *recognizer;
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[[self view] addGestureRecognizer:recognizer];
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[[self view] addGestureRecognizer:recognizer];
self.searchField.delegate = self;
//ETActivityIndicatorView
etActivity = [[ETActivityIndicatorView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 60.0f, 60.0f)];
etActivity.center=self.view.center;
//you can set your custom color for ETActivityIndicatorView
etActivity.color = [UIColor colorWithRed:13.0/255 green:136.0/255 blue:236.0/255 alpha:1.0f];
[self.view addSubview:etActivity];
}
-(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
if (recognizer.direction == UISwipeGestureRecognizerDirectionRight) {
NSLog(#"Swipe Right");
[webView goBack];
}
if (recognizer.direction == UISwipeGestureRecognizerDirectionLeft) {
NSLog(#"Swipe Left");
[webView goForward];
}
}
#pragma mark - RNGridMenuDelegate
- (void)gridMenu:(RNGridMenu *)gridMenu willDismissWithSelectedItem:(RNGridMenuItem *)item atIndex:(NSInteger)itemIndex {
if (itemIndex == 0) {
NSLog(#"Reload");
[self.webView reload];
}
if (itemIndex == 1) {
NSLog(#"Facebook");
if([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) //check if Facebook Account is linked
{
mySLComposerSheet = [[SLComposeViewController alloc] init]; //initiate the Social Controller
mySLComposerSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook]; //Tell him with what social plattform to use it, e.g. facebook or twitter
[mySLComposerSheet setInitialText:[NSString stringWithFormat:#""]]; //the message you want to post
[self presentViewController:mySLComposerSheet animated:YES completion:nil];
}
[mySLComposerSheet setCompletionHandler:^(SLComposeViewControllerResult result) {
switch (result) {
case SLComposeViewControllerResultCancelled:
break;
case SLComposeViewControllerResultDone:
break;
default:
break;
} //check if everything worked properly. Give out a message on the state.
}];
}
if (itemIndex == 2) {
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter])
{
SLComposeViewController *tweetSheet = [SLComposeViewController
composeViewControllerForServiceType:SLServiceTypeTwitter];
[tweetSheet setInitialText:#""];
[self presentViewController:tweetSheet animated:YES completion:nil];
}
}
if (itemIndex == 3) {
NSLog(#"Home");
MyWebViewController *MainView = [self.storyboard instantiateViewControllerWithIdentifier:#"MainView"];
[self presentViewController:MainView animated:NO completion:nil];
}
}
- (void)showList {
NSInteger numberOfOptions = 4;
NSArray *options = #[
#"Reload",
#"Facebook",
#"Twitter",
#"Home",
];
RNGridMenu *av = [[RNGridMenu alloc] initWithTitles:[options subarrayWithRange:NSMakeRange(0, numberOfOptions)]];
av.delegate = self;
av.itemFont = [UIFont boldSystemFontOfSize:18];
av.itemSize = CGSizeMake(150, 55);
[av showInViewController:self center:CGPointMake(self.view.bounds.size.width/2.f, self.view.bounds.size.height/2.f)];
}
- (IBAction)onShowButton:(id)sender {
[self showList];
}
![enter image description here][1]

Google Chrome assumes the typed text is a URL in these cases:
Text contains no whitespaces (One word):
Starts with a valid and accepted URI scheme (Like http, https, and ftp).
Starts with a forward slash (/).
Ends with a valid TLD (See 1, 2, 3).
Ends with a forward slash (/).
Known hostnames (Like localhost).
Valid IP addresses.
Text contains whitespaces (Multiple words):
Starts with a forward slash (/).
Text contains a question mark (?) and the part before it can be assumed a URL.
In all other cases you can safely assume the typed text is a search term.
This isn't a complete list of rules, but I think it's more than enough for regular usage.
Main reference: Chromium - Omnibox design principles.
Update:
Here are some hints to help you convert the previous rules to a working code (the order is important):
(Rule 3) Replace the part of text that matches this regular expression:
\?.*$
with empty string #"", and then apply other rules.
(Rules 1.1, 1.2, 1.4, 1.5, and 2.1) Match against this regular expression:
^((\/)|((https?|ftp):\S+$)|(\S+\/$)|(localhost$))
(Rule 1.3) You can collect some popular TLDs from the links above and form a one regular expression from them like this:
\S+\.(com|net|org|....)$
(Rule 1.6) Match against this regular expression:
^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9‌​]{2}|2[0-4][0-9]|25[0-5])$

Use this code. This basically checks the text entered into the textfield. If it's a complete url, then it redirects directly to it else the text entered is searched on google.
- (IBAction)SearchButton:(id)sender
{
MyWebViewController *webViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"WebView"];
NSString *urlString = maintext.text;
if([urlString rangeOfString:#"//"].location == NSNotFound)
{
// to resolve a url according to rfc 1808 (the most common form of URL), it must contain '//' in it.
// appending '//' in the url string to check for valid url
urlString = [NSString stringWithFormat:#"//%#", urlString];
}
NSURL *url = [NSURL URLWithString:urlString];
if(url && (url.scheme || url.host) && ([urlString rangeOfString:#"."].location != NSNotFound))
{
// url is valid, it contains domain and host
webViewController.urlString = maintext.text;
}
else
{
NSString *query = [maintext.text stringByReplacingOccurrencesOfString:#" " withString:#"+"];
NSString *urlString = [NSString stringWithFormat:#"http://www.google.com/search?q=%#", query];
// urlString is a public property on MyWebViewController
webViewController.urlString = urlString;
}
[self presentViewController:webViewController animated:YES completion:nil];
}
For, extra checks, you can also check that the url is valid or not like pinging to it and checking for it whether it responds or not.

You can create a category:
#interface NSString (NSStringValidator)
- (BOOL)isValidEmail;
- (BOOL)isValidURL;
#end
#implementation NSString (NSStringValidator)
- (BOOL)isValidEmail {
NSString *regExpPattern = #"\\b([a-zA-Z0-9%_.+\\-]+)#([a-zA-Z0-9.\\-]+?\\.[a-zA-Z]{2,6})\\b";
NSError *errorNext = NULL;
NSRegularExpression *regexNext = [NSRegularExpression regularExpressionWithPattern:regExpPattern
options:NSRegularExpressionCaseInsensitive
error:&errorNext];
NSRange range = [regexNext rangeOfFirstMatchInString:self
options:NSRegularExpressionCaseInsensitive
range:NSMakeRange(0, self.length)];
return NSEqualRanges(range, NSMakeRange(0, self.length));
}
- (BOOL)isValidURL {
NSString *regExpPattern = #"(?i)(?:(?:https?):\\/\\/)?(?:\\S+(?::\\S*)?#)?(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))(?::\\d{2,5})?(?:\\/[^\\s]*)?";
NSError *errorNext = NULL;
NSRegularExpression *regexNext = [NSRegularExpression regularExpressionWithPattern:regExpPattern
options:NSRegularExpressionCaseInsensitive
error:&errorNext];
NSRange range = [regexNext rangeOfFirstMatchInString:self
options:NSRegularExpressionCaseInsensitive
range:NSMakeRange(0, self.length)];
return NSEqualRanges(range, NSMakeRange(0, self.length));
}
#end
Then call category method:
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField
{
[theTextField resignFirstResponder];
if (theTextField.text.isValidURL) {
//open site
} else {
//search text
}
return YES;
}

Related

Can't Revert Back to Original Image After Using UIImagePickerController

I am having an interesting little problem using the uiimagepickercontroller and was wondering if anyone has any insight as to what might be happening. Users can take pictures with the camera or pick from the photo library until the cows come home as many times in a row as they like. My issue lies in allowing users to revert back to the original image that shipped with the app. Here is the flow:
Users go the the tableview which shows a thumbnail of the image.
Users navigate to the detail view which shows a larger view of the image.
Users can tap on the image in the detail view to bring up a custom alertcontroller with options to a) use the camera to take a picture, b) use a picture from their library, or c) revert back to the original image.
Users choose either option 'a' or option 'b' to either take a picture or use a picture from the photo library. IF they IMMEDIATELY change their mind about using one of those choices and want to just go back to using the original image, nothing happens! They can snap another picture or choose another image right away, but cannot revert back to the original image right away.
Reverting back to the original image DOES work perfectly when the app has been closed and then opened again. Sometimes it will work if you navigate around to other views within the app and then come back to the detail view where they just added their own image. By why the delay? I've searched around for two weeks but have not found anything resembling my problem or any solutions that help in any way (like reloading the headerview where image is sitting). Any thoughts?
Also I have figured out how to save the image to iCloud by using the documentation but cannot figure out how to retrieve them so there is no code for that. That is entirely different question. The same thing seems to occur even without that code.
Thanks for taking the time to look at this!
Here is some code:
-(void)bookImageTapped:(UIGestureRecognizer *)gesture
{
URBAlertView *changeImageAlertView = [[URBAlertView alloc] initWithTitle:#"Add A New Book Cover Image" message:nil cancelButtonTitle:#"Cancel" otherButtonTitles:#"Use Camera", #"Open Gallery", #"Use Original Photo", nil];
[changeImageAlertView setHandlerBlock:^(NSInteger buttonIndex, URBAlertView *alertView) {
[self checkPermission];
if (PHAuthorizationStatusAuthorized)
{
if(buttonIndex == 0)
{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
UIImagePickerController *pickerController = [[UIImagePickerController alloc] init];
pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
pickerController.delegate = self;
pickerController.allowsEditing = NO;
pickerController.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
[self presentViewController:pickerController animated:YES completion:nil];
}];
[alertView hide];
}
else
{
NSLog(#"Camera not available");
[alertView hide];
}
}
else if (buttonIndex == 1)
{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
UIImagePickerController *pickerController = [[UIImagePickerController alloc] init];
pickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
pickerController.delegate = self;
pickerController.allowsEditing = NO;
pickerController.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
[self presentViewController:pickerController animated:YES completion:nil];
}];
[alertView hide];
}
else if (buttonIndex == 2)
{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self restoreOriginalPhoto];
}];
[alertView hide];
}
else
{
NSLog(#"button 2 cancel");
[alertView hide];
}
}
}];
[changeImageAlertView show];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(nonnull NSDictionary<NSString *,id> *)info
{
[picker dismissViewControllerAnimated:YES completion:nil];
_book.largeBookImage = [info objectForKey:UIImagePickerControllerOriginalImage];
_book.largeBookImage = [self scaleImage:_book.largeBookImage toSize:CGSizeMake(120, 168)];
_bookImageView.image = _book.largeBookImage;
_book.wasNewImageAdded = YES;
_book.originalImageUsed = NO;
NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
[self saveImage:_book.largeBookImage withFileName:_book.bookImageID ofType:#"jpg" inDirectory:documentsDirectory];
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissViewControllerAnimated:YES completion:nil];
}
-(void)saveImage:(UIImage *)image withFileName:(NSString *)imageName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath
{
if ([[extension lowercaseString] isEqualToString:#"png"])
{
[UIImagePNGRepresentation(image) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.%#", imageName, #"png"]] options:NSAtomicWrite error:nil];
//Create a URL to the local file
NSURL *resourceURL = [NSURL fileURLWithPath:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.%#", imageName, #"png"]]];
if (resourceURL)
{
CKAsset *asset = [[CKAsset alloc] initWithFileURL:resourceURL];
//create a record object
CKRecord *bookCover = [[CKRecord alloc] initWithRecordType:#"Bookcover"];
//set the record's fields
bookCover[#"title"] = _book.title;
bookCover[#"bookImage"] = asset;
/* TO SAVE A RECORD */
//get the public database
CKContainer *appContainer = [CKContainer defaultContainer];
CKDatabase *publicDatabase = [appContainer publicCloudDatabase];
[publicDatabase saveRecord:bookCover completionHandler:^(CKRecord *bookCover, NSError *error) {
if (error)
{
//insert error handling
return;
}
//insert succesfully saved record code
NSLog(#"png record saved after using picker!");
}];
}
}
else if ([[extension lowercaseString] isEqualToString:#"jpg"] || [[extension lowercaseString] isEqualToString:#"jpeg"])
{
[UIImageJPEGRepresentation(image, 1.0) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.%#", imageName, #"jpg"]] options:NSAtomicWrite error:nil];
//Create a URL to the local file
NSURL *resourceURL = [NSURL fileURLWithPath:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.%#", imageName, #"jpg"]]];
if (resourceURL)
{
CKAsset *asset = [[CKAsset alloc] initWithFileURL:resourceURL];
//create a record object
CKRecord *bookCover = [[CKRecord alloc] initWithRecordType:#"Bookcover"];
//set the record's fields
bookCover[#"title"] = _book.title;
bookCover[#"bookImage"] = asset;
/* TO SAVE A RECORD */
//get the public database
CKContainer *appContainer = [CKContainer defaultContainer];
CKDatabase *publicDatabase = [appContainer publicCloudDatabase];
[publicDatabase saveRecord:bookCover completionHandler:^(CKRecord *bookCover, NSError *error) {
if (error)
{
//insert error handling
return;
}
//insert succesfully saved record code
NSLog(#"jpg record saved after using picker!");
}];
}
}
else
{
NSLog(#"Image Save Failed\nExtension: (%#) is not recognized, use (PNG/JPG)", extension);
}
}
- (UIImage *) scaleImage:(UIImage*)image toSize:(CGSize)newSize
{
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
-(void)restoreOriginalPhoto
{
NSLog(#"restore photo called");
_book.originalImageUsed = YES;
_book.wasNewImageAdded = NO;
_bookImageView.image = _book.largeBookImage;
NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
[self saveImage:_book.largeBookImage withFileName:_book.bookImageID ofType:#"jpg" inDirectory:documentsDirectory];
}
Here is the headerview with the imageview:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
_headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 26)];
_headerView.backgroundColor = [UIColor colorWithRed:8/255.0 green:46/255.0 blue:46/255.0 alpha:0.8];
if (section == 0)
{
_headerView.backgroundColor = [UIColor whiteColor];
_bookImageView = [[UIImageView alloc] initWithFrame:CGRectMake((tableView.frame.size.width - 120)/2, 6, 120, 168)];
_bookImageView.contentMode = UIViewContentModeScaleAspectFit;
if (_book.wasNewImageAdded)
{
NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
UIImage * image = [self loadImageWithFileName:_book.bookImageID ofType:#"jpg" inDirectory:documentsDirectory];
_bookImageView.image = image;
}
else
{
_bookImageView.image = _book.largeBookImage;
}
if(_book.originalImageUsed)
{
NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
UIImage * image = [self loadImageWithFileName:_book.bookImageID ofType:#"jpg" inDirectory:documentsDirectory];
_bookImageView.image = image;
}
UITapGestureRecognizer *bookImageTouched = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(bookImageTapped:)];
bookImageTouched.numberOfTapsRequired = 1;
[_bookImageView addGestureRecognizer:bookImageTouched];
_bookImageView.userInteractionEnabled = YES;
[_headerView addSubview:_bookImageView];
}
I finally figured it out! It seems that I was confusing xcode with my property names. The code ended up much simpler in the end.
In didFinishPickingMediaWithInfo I created a UIImage and then set it to the bookImageView.image. Later, when I wanted to be able to update the image back to the original image, then I could call the bundle asset, _book.largeBookImage. Voila! The image was able to update immediately.
The most pertinent code is posted below.
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(nonnull NSDictionary<NSString *,id> *)info
{
[picker dismissViewControllerAnimated:YES completion:nil];
_chosenImage = [[UIImage alloc] init];
_chosenImage = [info objectForKey:UIImagePickerControllerOriginalImage];
_bookImageView.image = _chosenImage;
_book.wasNewImageAdded = YES;
_book.originalImageUsed = NO;
NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
[self saveImage:_chosenImage withFileName:_book.bookImageID ofType:#"jpg" inDirectory:documentsDirectory];
}
-(void)saveImage:(UIImage *)image withFileName:(NSString *)imageName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath
{
if ([[extension lowercaseString] isEqualToString:#"png"])
{
[UIImagePNGRepresentation(image) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.%#", imageName, #"png"]] options:NSAtomicWrite error:nil];
[self.tableView reloadData];
}
else if ([[extension lowercaseString] isEqualToString:#"jpg"] || [[extension lowercaseString] isEqualToString:#"jpeg"])
{
[UIImageJPEGRepresentation(image, 1.0) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.%#", imageName, #"jpg"]] options:NSAtomicWrite error:nil];
[self.tableView reloadData];
}
else
{
//NSLog(#"Image Save Failed\nExtension: (%#) is not recognized, use (PNG/JPG)", extension);
}
}
-(void)restoreOriginalPhoto
{
_book.originalImageUsed = YES;
_book.wasNewImageAdded = NO;
_bookImageView.image = _book.largeBookImage;
_backgroundImage.image = _book.largeBookImage;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
if (section == 0)
{
_bookImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 120, 168)];
_bookImageView.contentMode = UIViewContentModeScaleAspectFit;
_bookImageView.clipsToBounds = YES;
_bookImageView.layer.cornerRadius = 10.0f;
if (_book.wasNewImageAdded)
{
NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
UIImage * image = [self loadImageWithFileName:_book.bookImageID ofType:#"jpg" inDirectory:documentsDirectory];
_bookImageView.image = image;
}
else
{
_bookImageView.image = _book.largeBookImage;
}
if(_book.originalImageUsed)
{
_bookImageView.image = _book.largeBookImage;
}
}
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if(_book.originalImageUsed)
{
_bookImageView.image = _book.largeBookImage;
}
[self.tableView reloadData];
[self.tableView setContentOffset:CGPointZero animated:NO];
}

Bounds does not work for GMSAutocompleteFetcher in Google Place API in iOS Objective C

I made this autocomplete code for searching places. And search correctly but bounds and region not set. show places out of my bounds.
#import "SearchViewController.h"
#import <GooglePlaces/GooglePlaces.h>
#import <GoogleMaps/GoogleMaps.h>
#import GooglePlaces;
#interface SearchViewController () <GMSAutocompleteViewControllerDelegate,GMSAutocompleteFetcherDelegate>
#end
#implementation SearchViewController{
UITextField *_textField;
UITextView *_resultText;
GMSAutocompleteFetcher* _fetcher;
GMSPlacesClient *_placesClient;
GMSCoordinateBounds *_bounds;
GMSAutocompleteFilter *_filter;
}
- (void)viewDidLoad {
[super viewDidLoad];
//APIkEy
[GMSPlacesClient provideAPIKey:#"AIzaSyBYA7KlOZ3VqjQTG4x0R1jaCt9I1-1EVBc"];
_placesClient = [GMSPlacesClient sharedClient];
self.view.backgroundColor = [UIColor whiteColor];
self.edgesForExtendedLayout = UIRectEdgeNone;
// Set bounds
CLLocationCoordinate2D neBoundsCorner = CLLocationCoordinate2DMake(35.818074, 51.586990);
CLLocationCoordinate2D swBoundsCorner = CLLocationCoordinate2DMake(35.557071, 51.098099);
_bounds = [[GMSCoordinateBounds alloc] initWithCoordinate:neBoundsCorner coordinate:swBoundsCorner];
// Set up the autocomplete filter.
_filter = [[GMSAutocompleteFilter alloc] init];
_filter.type = kGMSPlacesAutocompleteTypeFilterNoFilter;
// Create the fetcher.
_fetcher = [[GMSAutocompleteFetcher alloc] initWithBounds:_bounds filter:_filter];
_fetcher.delegate = self;
// Set up the UITextField and UITextView.
_textField = [[UITextField alloc] initWithFrame:CGRectMake(5.0f, 0, self.view.bounds.size.width - 5.0f, 44.0f)];
_textField.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[_textField addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
_resultText =[[UITextView alloc] initWithFrame:CGRectMake(0, 45.0f, self.view.bounds.size.width, self.view.bounds.size.height - 1.0f)];
_resultText.backgroundColor = [UIColor colorWithWhite:0.95f alpha:1.0f];
_resultText.text = #"No Results";
_resultText.editable = NO;
[self.view addSubview:_textField];
[self.view addSubview:_resultText];
}
- (void)textFieldDidChange:(UITextField *)textField {
NSLog(#"%#", textField.text);
[_fetcher sourceTextHasChanged:textField.text];
}
#pragma mark - GMSAutocompleteFetcherDelegate
- (void)didAutocompleteWithPredictions:(NSArray *)predictions {
NSMutableString *resultsStr = [NSMutableString string];
for (GMSAutocompletePrediction *prediction in predictions) {
[resultsStr appendFormat:#"%#\n", [prediction.attributedPrimaryText string]];
NSLog(#"sec is: %#",[prediction.attributedSecondaryText string]);
NSLog(#"placeID is: %#", prediction.placeID );
[_placesClient lookUpPlaceID:prediction.placeID callback:^(GMSPlace *place, NSError *error) {
if (error != nil) {
NSLog(#"Place Details error %#", [error localizedDescription]);
return;
}
if (place != nil) {
NSLog(#"Place name %#", place.name);
NSLog(#"Place address %#", place.formattedAddress);
NSLog(#"Place placeID %#", place.placeID);
NSLog(#"Place attributions %#", place.attributions);
NSLog(#"Place latitude %f", place.coordinate.latitude);
NSLog(#"Place longitude %f", place.coordinate.longitude);
} else {
NSLog(#"No place details for %#", prediction.placeID);
}
}];
}
_resultText.text = resultsStr;
}
Setting the bounds only biases results to that rectangle, it isn't a strict restrict.

Cancel button action in zbar shows blank view

I am using tab bar in my iOS app. When I tap on the scan tab, i invoked the delegate method to start the camera immediately on scan tab. When I start the camera to scan the QR Code and tap on cancel button before scanning, I get the blank view. How to display the view when camera is dismissed
- (void) openCameraScanner
{
ZBarReaderViewController *reader = [[ZBarReaderViewController alloc] init];
reader.readerDelegate = self;
reader.supportedOrientationsMask = ZBarOrientationMaskAll;
reader.showsZBarControls = YES;
ZBarImageScanner *scanner = reader.scanner;
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
[self presentViewController:reader animated:YES completion:nil];
reader.showsZBarControls = YES;
//reader.cameraOverlayView = [self commonOverlay];
}
- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
// ADD: get the decode results
id<NSFastEnumeration> results =
[info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
// EXAMPLE: just grab the first barcode
break;
// EXAMPLE: do something useful with the barcode data
//resultsView.text = symbol.data;
NSString *urlString = symbol.data;
NSURL *url = [NSURL URLWithString:urlString];
NSLog(#"Query after scan = %#", [url query]);
//Extract id from URL which is there in QR Code --- start
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
for(NSString *param in [urlString componentsSeparatedByString:#"&"])
{
NSArray *elements = [param componentsSeparatedByString:#"="];
if([elements count]<2)
continue;
[dictionary setObject:[elements objectAtIndex:1] forKey:[elements objectAtIndex:0]];
NSLog(#"value is == %#", [elements objectAtIndex:1]);
//Extract id from URL which is there in QR Code --- end
if([[elements objectAtIndex:1] intValue])
{
NSUserDefaults *defaultsForAsk = [NSUserDefaults standardUserDefaults];
idToAsk = [NSString stringWithFormat:#"%d",[[elements objectAtIndex:1] intValue]];
[defaultsForAsk setObject:idToAsk forKey:#"IDTOASKVIEW"];
flagToShowView = YES;
listViewCntrl.getFlag = flagToShowView;
[self viewDidLoadForDynamicFields];
}
else if([elements objectAtIndex:1] == [NSNull null])
{
[reader dismissViewControllerAnimated:YES completion:Nil];
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Invalid QR Code scanned" message:#"Please scan Collaborator's QR Code" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[message show];
}
}
image.image =
[info objectForKey: UIImagePickerControllerOriginalImage];
// ADD: dismiss the controller (NB dismiss from the *reader*!)
//[reader dismissViewControllerAnimated:YES completion:nil];
[reader dismissViewControllerAnimated:YES completion:Nil];
}
You can re display the view using -(void)viewWillAppear:(BOOL)animated method of your ViewController class.

I am getting an unauthorized error quickblox

I have the following code using quickblox.
Unfortunately, when I accessthe view controller, I get an "unAuthorized" error from quickblox API.
What am I doing wrong?
#import "QChatViewController.h"
#include "ChatMessageTableViewCell.h"
#interface QChatViewController ()
#end
#implementation QChatViewController
#synthesize opponent;
#synthesize currentRoom;
#synthesize messages;
#synthesize toolBar;
#synthesize sendMessageField;
#synthesize sendMessageButton;
#synthesize tableView;
#pragma mark -
#pragma mark View controller's lifecycle
- (id) initWithStartup: (NSDictionary *) _startup investor: (NSDictionary *) _investor chat_id: (NSInteger) _chat_id chat_name: (NSString *) _name
{
self = [self initWithNibName: #"QChatViewController" bundle: nil];
if(self)
{
startup = _startup;
investor = _investor;
startup_id = 0;
investor_id = 0;
if ([startup objectForKey: #"id"] &&
[startup objectForKey: #"id"] != (id)[NSNull null])
{
startup_id = [[startup objectForKey: #"id"] intValue];
}
if ([investor objectForKey: #"id"] &&
[investor objectForKey: #"id"] != (id)[NSNull null])
{
investor_id = [[investor objectForKey: #"id"] intValue];
}
past = 0;
chat_id = _chat_id;
self.title = _name;
self.title = #"Chat";
UIButton * button4 = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage * btnImage = [UIImage imageNamed: #"chatrightbtn.png"];
[button4 setFrame:CGRectMake(-90.0f, 0.0f, btnImage.size.width, btnImage.size.height)];
[button4 addTarget:self action:#selector(showSheet:) forControlEvents:UIControlEventTouchUpInside];
[button4 setImage: btnImage forState:UIControlStateNormal];
UIBarButtonItem *random1 = [[UIBarButtonItem alloc] initWithCustomView:button4];
self.navigationItem.rightBarButtonItem = random1;
self.navigationItem.leftBarButtonItem.title = #"";
}
return self;
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear: animated];
QBASessionCreationRequest *extendedAuthRequest = [QBASessionCreationRequest request];
extendedAuthRequest.userLogin = #"testjk";
extendedAuthRequest.userPassword = #"jerry";
[QBAuth createSessionWithExtendedRequest:extendedAuthRequest delegate:self];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBarHidden = NO;
if(chat_id >= 1) {
NSString * roomName = [NSString stringWithFormat: #"%d", chat_id];
[[QBChat instance] createOrJoinRoomWithName: roomName membersOnly:YES persistent:NO];
}
messages = [[NSMutableArray alloc] init];
}
-(void) chatDidLogin{
// You have successfully signed in to QuickBlox Chat
}
- (void)completedWithResult:(Result *)result{
// Create session result
if(result.success && [result isKindOfClass:QBAAuthSessionCreationResult.class]){
// You have successfully created the session
QBAAuthSessionCreationResult *res = (QBAAuthSessionCreationResult *)result;
// Sign In to QuickBlox Chat
QBUUser *currentUser = [QBUUser user];
currentUser.ID = res.session.userID; // your current user's ID
currentUser.password = #"jerry"; // your current user's password
// set Chat delegate
[QBChat instance].delegate = self;
// login to Chat
[[QBChat instance] loginWithUser:currentUser];
}
}
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
// leave room
if(self.currentRoom){
if ([self.navigationController.viewControllers indexOfObject:self] == NSNotFound) {
// back button was pressed.
[[QBChat instance] leaveRoom:self.currentRoom];
[[DataManager shared].rooms removeObject:self.currentRoom];
}
}
}
- (void)viewDidUnload{
[self setToolBar:nil];
[self setSendMessageField:nil];
[self setSendMessageButton:nil];
[self setTableView:nil];
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)dealloc {
}
- (IBAction)sendMessage:(id)sender {
if(self.sendMessageField.text.length == 0){
return;
}
if(chat_id == 0)
{
NSString * sid = [NSString stringWithFormat: #"%d", startup_id];
NSString * iid = [NSString stringWithFormat: #"%d", investor_id];
NSString * pasts = [NSString stringWithFormat: #"%d", past];
NSString * chat_ids = [NSString stringWithFormat: #"%d", chat_id];
NSString * path_str = [NSString stringWithFormat: #"chats/?format=json"];
NSMutableDictionary* params =[NSMutableDictionary dictionaryWithObjectsAndKeys:
sid, #"startup",
iid, #"investor",
pasts, #"past",
chat_ids, #"conversation_id",
#"avv7ejtaegxxk2wzgnymsj8xtm2tk9s4xgp6854r6dqn8bk6jjwux4g9dh9b", #"apikey",
nil];
[[API sharedInstance] postcommandWithParams:params
path: path_str
onCompletion:^(NSDictionary *json)
{
if(chat_id == 0)
{
if ([json objectForKey: #"id"] &&
[json objectForKey: #"id"] != (id)[NSNull null])
{
chat_id = [[json objectForKey: #"id"] intValue];
if(chat_id >= 1) {
NSString * roomName = [NSString stringWithFormat: #"%d", chat_id];
[[QBChat instance] createOrJoinRoomWithName: roomName membersOnly:YES persistent:NO];
}
[[QBChat instance] sendMessage:self.sendMessageField.text toRoom:self.currentRoom];
// reload table
[self.tableView reloadData];
// hide keyboard & clean text field
[self.sendMessageField resignFirstResponder];
[self.sendMessageField setText:nil];
}
}
}];
}
else
{
[[QBChat instance] sendMessage:self.sendMessageField.text toRoom:self.currentRoom];
// reload table
[self.tableView reloadData];
// hide keyboard & clean text field
[self.sendMessageField resignFirstResponder];
[self.sendMessageField setText:nil];
}
}
-(void)keyboardShow{
CGRect rectFild = self.sendMessageField.frame;
rectFild.origin.y -= 215;
CGRect rectButton = self.sendMessageButton.frame;
rectButton.origin.y -= 215;
[UIView animateWithDuration:0.25f
animations:^{
[self.sendMessageField setFrame:rectFild];
[self.sendMessageButton setFrame:rectButton];
}
];
}
-(void)keyboardHide{
CGRect rectFild = self.sendMessageField.frame;
rectFild.origin.y += 215;
CGRect rectButton = self.sendMessageButton.frame;
rectButton.origin.y += 215;
[UIView animateWithDuration:0.25f
animations:^{
[self.sendMessageField setFrame:rectFild];
[self.sendMessageButton setFrame:rectButton];
}
];
}
#pragma mark -
#pragma mark TextFieldDelegate
- (void)textFieldDidBeginEditing:(UITextField *)textField{
[self keyboardShow];
}
- (void)textFieldDidEndEditing:(UITextField *)textField{
[self keyboardHide];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField setText:nil];
[textField resignFirstResponder];
return YES;
}
#pragma mark -
#pragma mark TableViewDataSource & TableViewDelegate
static CGFloat padding = 20.0;
- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"MessageCellIdentifier";
// Create cell
ChatMessageTableViewCell *cell = (ChatMessageTableViewCell *)[_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[ChatMessageTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
cell.accessoryType = UITableViewCellAccessoryNone;
cell.userInteractionEnabled = NO;
// Message
QBChatMessage *messageBody = [messages objectAtIndex:[indexPath row]];
// set message's text
NSString *message = [messageBody text];
cell.message.text = message;
// message's datetime
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat: #"yyyy-mm-dd HH:mm:ss"];
[formatter setTimeZone:[NSTimeZone timeZoneWithName:#"..."]];
NSString *time = [formatter stringFromDate:messageBody.datetime];
CGSize textSize = { 260.0, 10000.0 };
CGSize size = [message sizeWithFont:[UIFont boldSystemFontOfSize:13]
constrainedToSize:textSize
lineBreakMode:UILineBreakModeWordWrap];
size.width += (padding/2);
// Left/Right bubble
UIImage *bgImage = nil;
if ([[[DataManager shared] currentUser] ID] == messageBody.senderID || self.currentRoom) {
bgImage = [[UIImage imageNamed:#"orange.png"] stretchableImageWithLeftCapWidth:24 topCapHeight:15];
[cell.message setFrame:CGRectMake(padding, padding*2, size.width+padding, size.height+padding)];
[cell.backgroundImageView setFrame:CGRectMake( cell.message.frame.origin.x - padding/2,
cell.message.frame.origin.y - padding/2,
size.width+padding,
size.height+padding)];
cell.date.textAlignment = UITextAlignmentLeft;
cell.backgroundImageView.image = bgImage;
if(self.currentRoom){
cell.date.text = [NSString stringWithFormat:#"%d %#", messageBody.senderID, time];
}else{
cell.date.text = [NSString stringWithFormat:#"%# %#", [[[DataManager shared] currentUser] login], time];
}
} else {
bgImage = [[UIImage imageNamed:#"aqua.png"] stretchableImageWithLeftCapWidth:24 topCapHeight:15];
[cell.message setFrame:CGRectMake(320 - size.width - padding,
padding*2,
size.width+padding,
size.height+padding)];
[cell.backgroundImageView setFrame:CGRectMake(cell.message.frame.origin.x - padding/2,
cell.message.frame.origin.y - padding/2,
size.width+padding,
size.height+padding)];
cell.date.textAlignment = UITextAlignmentRight;
cell.backgroundImageView.image = bgImage;
cell.date.text = [NSString stringWithFormat:#"%# %#", self.opponent.login, time];
}
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.messages count];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
QBChatMessage *chatMessage = (QBChatMessage *)[messages objectAtIndex:indexPath.row];
NSString *text = chatMessage.text;
CGSize textSize = { 260.0, 10000.0 };
CGSize size = [text sizeWithFont:[UIFont boldSystemFontOfSize:13]
constrainedToSize:textSize
lineBreakMode:UILineBreakModeWordWrap];
size.height += padding;
return size.height+padding+5;
}
#pragma mark -
#pragma mark QBChatDelegate
// Did receive 1-1 message
- (void)chatDidReceiveMessage:(QBChatMessage *)message{
[self.messages addObject:message];
// save message to cache if this 1-1 chat
if (self.opponent) {
[[DataManager shared] saveMessage:[NSKeyedArchiver archivedDataWithRootObject:messages]
toHistoryWithOpponentID:self.opponent.ID];
}
// reload table
[self.tableView reloadData];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[messages count]-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
// Did receive message in room
- (void)chatRoomDidReceiveMessage:(QBChatMessage *)message fromRoom:(NSString *)roomName{
// save message
[self.messages addObject:message];
// reload table
[self.tableView reloadData];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[messages count]-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
// Fired when you did leave room
- (void)chatRoomDidLeave:(NSString *)roomName{
NSLog(#"Chat Controller chatRoomDidLeave");
}
// Called in case changing occupant
- (void)chatRoomDidChangeOnlineUsers:(NSArray *)onlineUsers room:(NSString *)roomName{
NSLog(#"chatRoomDidChangeOnlineUsers %#, %#",roomName, onlineUsers);
}
- (void)chatRoomDidEnter:(QBChatRoom *)room{
NSLog(#"Private room %# was created", room.name);
// You have to retain created room if this is temporary room. In other cases room will be destroyed and all occupants will be disconnected from room
self.currentRoom = room;
// Add users to this room
NSInteger user_id = [[[[API sharedInstance] user] objectForKey: #"id"] intValue];
NSNumber *me = [NSNumber numberWithInt: user_id];
NSArray *users = [NSArray arrayWithObjects: me, nil];
[[QBChat instance] addUsers:users toRoom:room];
}
#end
I'm not sure that you have user with these credentials
extendedAuthRequest.userLogin = #"testjk";
extendedAuthRequest.userPassword = #"jerry";
I first check user exist or not modified your code like this...
//your code
.....
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear: animated];
//Create extended session request with user authorization
QBASessionCreationRequest *extendedAuthRequest = [QBASessionCreationRequest request];
//Check user exist or not
if(self.currentQBUser){
extendedAuthRequest.userLogin = #"testjk";
extendedAuthRequest.userPassword = #"testjk";
}
[QBAuth createSessionWithExtendedRequest:extendedAuthRequest delegate:self];
}
........
- (void)completedWithResult:(Result *)result{
// Create session result
if(result.success && [result isKindOfClass:QBAAuthSessionCreationResult.class]){
// Register new user
self.currentQBUser = [[QBUUser alloc] init];
user.fullName = #"Your Name";
user.login = #"testjk";
user.password = #"testjk";
user.tags = [NSMutableArray arrayWithObject:#"Chat"];
// Create user
[QBUsers signUp:user delegate:self];
// You have successfully created the session
QBAAuthSessionCreationResult *res = (QBAAuthSessionCreationResult *)result;
} else if([result isKindOfClass:[QBUUserLogInResult class]]){
if(result.success){
QBUUserLogInResult *res = (QBUUserLogInResult *)result;
//Now login to chat
// Sign In to QuickBlox Chat
QBUUser *currentUser = res.user;
currentUser.ID = #"testjk; // your current user's ID
currentUser.password = #"testjk"; // same as user id
// set Chat delegate
[QBChat instance].delegate = self;
// login to Chat
[[QBChat instance] loginWithUser:currentUser];
}
}
if (result.errors.count && (401 != result.status))
{
NSLog(#"QBErrors: %#",result.errors);
}
}
I met the same problem here. And i gave the way i made it.
error unauthorized is the user.login or user.password.
user.login can not be email address but your login username. these i do not know why.
user.password is the email address/username password.
check these informations in your User list at QuickBlox Dashboard
Hope these instructions will help.
use quickblox.min.js
var QBApp = {
appId: 123,
authKey: 'dfdgfd44444',
authSecret: 'dffdgfdg455445'
};
$(document).ready(function () {
QB.init(QBApp.appId, QBApp.authKey, QBApp.authSecret);
QB.createSession(function (err, result) {
console.log('Session create callback', err, result);
});
})
function addUser() {
var pwd, ctr, data;
ctr = document.getElementById(myForm.password);
pwd = ctr.value;
var params = { 'login': 'Rajesh', 'password': 'Pass#123' };
alert(params)
QB.users.create(params, function (err, user) {
debugger;
if (user) {
alert('Done')
//$('#output_place').val(JSON.stringify(user));
} else {
alert('Error')
//$('#output_place').val(JSON.stringify(err));
}
})}

Trouble hiding iAd banner and displaying UIWebView in its place

When there is no iAd banner to display, we would like to display a UIWebView of the same dimensions pointed to a specific URL.
However, hiding the iAd banner and showing the UIWebView doesn't work. We embed the show/hide code inside bannerViewDidLoadAd and didFailToReceiveAdWithError. All that appears is the white, blank rectangle when there is no iAd inventory instead of our UIWebView.
If a user clicks on a link inside the UIWebView, we would like the link to open in Safari. Do we need to add a delegate to the UIWebView?
Code:
//
// SAiOSAdPlugin.m
// Ad Plugin for PhoneGap
//
// Created by shazron on 10-07-12.
// Copyright 2010 Shazron Abdullah. All rights reserved.
// Cordova v1.5.0 Support added 2012 #RandyMcMillan
//
#import "SAiOSAdPlugin.h"
//#ifdef CORDOVA_FRAMEWORK
#import <Cordova/CDVDebug.h>
//#else
//#import "CDVDebug.h"
//#endif
#interface SAiOSAdPlugin(PrivateMethods)
- (void) __prepare:(BOOL)atBottom;
- (void) __showAd:(BOOL)show;
#end
#implementation SAiOSAdPlugin
#synthesize adView;
#synthesize bannerIsVisible, bannerIsInitialized, bannerIsAtBottom, isLandscape;
#pragma mark -
#pragma mark Public Methods
- (void) resizeViews
{
Class adBannerViewClass = NSClassFromString(#"ADBannerView");
if (adBannerViewClass && self.adView)
{
CGRect webViewFrame = [super webView].frame;
CGRect superViewFrame = [[super webView] superview].frame;
CGRect adViewFrame = self.adView.frame;
BOOL adIsShowing = [[[super webView] superview].subviews containsObject:self.adView];
if (adIsShowing)
{
if (self.bannerIsAtBottom) {
webViewFrame.origin.y = 0;
CGRect adViewFrame = self.adView.frame;
CGRect superViewFrame = [[super webView] superview].frame;
adViewFrame.origin.y = (self.isLandscape ? superViewFrame.size.width : superViewFrame.size.height) - adViewFrame.size.height;
self.adView.frame = adViewFrame;
} else {
webViewFrame.origin.y = adViewFrame.size.height;
}
webViewFrame.size.height = self.isLandscape? (superViewFrame.size.width - adViewFrame.size.height) : (superViewFrame.size.height - adViewFrame.size.height);
}
else
{
webViewFrame.size = self.isLandscape? CGSizeMake(superViewFrame.size.height, superViewFrame.size.width) : superViewFrame.size;
webViewFrame.origin = CGPointZero;
}
[UIView beginAnimations:#"blah" context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[super webView].frame = webViewFrame;
[UIView commitAnimations];
}
}
- (void) orientationChanged:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
{
NSInteger orientation = [[arguments objectAtIndex:0] integerValue];
switch (orientation) {
// landscape
case 90:
case -90:
self.isLandscape = YES;
break;
// portrait
case 0:
case 180:
self.isLandscape = NO;
break;
default:
break;
}
Class adBannerViewClass = NSClassFromString(#"ADBannerView");
if (adBannerViewClass && self.adView)
{
self.adView.currentContentSizeIdentifier = self.isLandscape ? ADBannerContentSizeIdentifierLandscape : ADBannerContentSizeIdentifierPortrait;
[self resizeViews];
}
}
- (void) prepare:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
{
NSUInteger argc = [arguments count];
if (argc > 1) {
return;
}
NSString* atBottomValue = [arguments objectAtIndex:0];
[self __prepare:[atBottomValue boolValue]];
}
- (void) showAd:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
{
NSUInteger argc = [arguments count];
if (argc > 1) {
return;
}
NSString* showValue = [arguments objectAtIndex:0];
[self __showAd:[showValue boolValue]];
}
#pragma mark -
#pragma mark Private Methods
- (void) __prepare:(BOOL)atBottom
{
NSLog(#"SAiOSAdPlugin Prepare Ad At Bottom: %d", atBottom);
Class adBannerViewClass = NSClassFromString(#"ADBannerView");
if (adBannerViewClass && !self.adView)
{
self.adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
// we are still using these constants even though they are deprecated - if it is changed, iOS 4 devices < 4.3 will crash.
// will need to do a run-time iOS version check
self.adView.requiredContentSizeIdentifiers = [NSSet setWithObjects: ADBannerContentSizeIdentifierPortrait, ADBannerContentSizeIdentifierLandscape, nil];
self.adView.delegate = self;
NSString* contentSizeId = (self.isLandscape ? ADBannerContentSizeIdentifierLandscape : ADBannerContentSizeIdentifierPortrait);
self.adView.currentContentSizeIdentifier = contentSizeId;
if (atBottom) {
self.bannerIsAtBottom = YES;
}
self.bannerIsVisible = NO;
self.bannerIsInitialized = YES;
self.houseAdView = [[UIWebView alloc] initWithFrame: CGRectMake(0.0, 0.0, 1.0, 1.0)];
self.houseAdView.frame = self.adView.frame;
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: [NSURL URLWithString: #"http://www.panabee.com"]];
[self.houseAdView loadRequest: request];
}
}
- (void) __showAd:(BOOL)show
{
NSLog(#"SAiOSAdPlugin Show Ad: %d", show);
if (!self.bannerIsInitialized){
[self __prepare:NO];
}
if (!(NSClassFromString(#"ADBannerView") && self.adView)) { // ad classes not available
return;
}
if (show == self.bannerIsVisible) { // same state, nothing to do
return;
}
if (show)
{
[UIView beginAnimations:#"blah" context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[[[super webView] superview] addSubview:self.adView];
[[[super webView] superview] bringSubviewToFront:self.houseAdView];
[[[super webView] superview] bringSubviewToFront:self.adView];
[self resizeViews];
[UIView commitAnimations];
self.bannerIsVisible = YES;
}
else
{
[UIView beginAnimations:#"blah" context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[self.adView removeFromSuperview];
[self resizeViews];
[UIView commitAnimations];
self.bannerIsVisible = NO;
}
}
#pragma mark -
#pragma ADBannerViewDelegate
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
Class adBannerViewClass = NSClassFromString(#"ADBannerView");
if (adBannerViewClass)
{
NSString* jsString =
#"(function(){"
"var e = document.createEvent('Events');"
"e.initEvent('iAdBannerViewDidLoadAdEvent');"
"document.dispatchEvent(e);"
"})();";
[banner setHidden:YES];
[self.houseAdView setHidden:NO];
[super writeJavascript:[NSString stringWithFormat:jsString]];
}
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError*)error
{
Class adBannerViewClass = NSClassFromString(#"ADBannerView");
if (adBannerViewClass)
{
NSString* jsString =
#"(function(){"
"var e = document.createEvent('Events');"
"e.initEvent('iAdBannerViewDidFailToReceiveAdWithErrorEvent');"
"e.error = '%#';"
"document.dispatchEvent(e);"
"})();";
[banner setHidden:YES];
[self.houseAdView setHidden:NO];
[super writeJavascript:[NSString stringWithFormat:jsString, [error description]]];
}
}
#end
It's me again :)
You're not adding it to the sub view tree.
From your __prepare method
self.houseAdView = [[UIWebView alloc] initWithFrame: CGRectMake(0.0, 0.0, 1.0, 1.0)];
self.houseAdView.frame = self.adView.frame;
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: [NSURL URLWithString: #"http://www.panabee.com"]];
[self.houseAdView loadRequest: request];
That's great. But it doesn't work - you are missing one line of code - a critical, vital line that gets every developer some time or another.
[self addSubview:self.houseAdView];
I'm making a few assumptions, like that self is a UIView. Test before shipping.
So, that part of your __prepare method should look like this:
self.houseAdView = [[UIWebView alloc] initWithFrame: CGRectMake(0.0, 0.0, 1.0, 1.0)];
self.houseAdView.frame = self.adView.frame;
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: [NSURL URLWithString: #"http://www.panabee.com"]];
[self.houseAdView loadRequest: request];
[self addSubview:self.houseAdView];

Resources