Can someone please help me what could the stated error be for?
[NSNull dataUsingEncoding:]: unrecognized selector sent to instance
I am stuck at printer plugin for an iOS application.
I have been struggling to get this app work for sometime now....the watched code may help find the error...
import "APPPrinter.h"
#interface APPPrinter (Private)
- (UIPrintInteractionController*) getPrintController;
- (UIPrintInteractionController*) adjustSettingsForPrintController:(UIPrintInteractionController*)controller;
- (void) loadContent:(NSString*)content intoPrintController:(UIPrintInteractionController*)controller;
- (void) informAboutResult:(int)code callbackId:(NSString*)callbackId;
- (BOOL) isPrintServiceAvailable;
#end
#implementation APPPrinter
// Is printing available.
- (void) isServiceAvailable:(CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult;
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsBool:[self isPrintServiceAvailable]];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
- (void) print:(CDVInvokedUrlCommand*)command
{
if (![self isPrintServiceAvailable])
{
return;
}
NSArray* arguments = [command arguments];
NSString* content = [arguments objectAtIndex:0];
UIPrintInteractionController* controller = [self getPrintController];
[self adjustSettingsForPrintController:controller];
[self loadContent:content intoPrintController:controller];
[self openPrintController:controller];
[self commandDelegate];
}
- (UIPrintInteractionController*) getPrintController
{
return [UIPrintInteractionController sharedPrintController];
}
- (UIPrintInteractionController*) adjustSettingsForPrintController:(UIPrintInteractionController*)controller
{
UIPrintInfo* printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral;
controller.printInfo = printInfo;
controller.showsPageRange = YES;
return controller;
}
- (void) loadContent:(NSString*)content intoPrintController:(UIPrintInteractionController*)controller
{
// Set the base URL to be the www directory.
NSURL *basEURL = [[NSBundle mainBundle] URLForResource:#"Login" withExtension:#"html"];
// Load page into a webview and use its formatter to print the page
UIWebView* webPage = [[UIWebView alloc] init];
[webPage loadHTMLString:content baseURL:basEURL];
UIViewPrintFormatter* formatter = [webPage viewPrintFormatter];
controller.printFormatter = formatter;
controller.showsPageRange = YES;
}
- (void) openPrintController:(UIPrintInteractionController*)controller
{
[self.commandDelegate runInBackground:^
{
[controller presentAnimated:YES completionHandler:NULL];
}];
[self performSelectorOnMainThread:#selector(openPrintController:) withObject:nil waitUntilDone:NO];
}
- (BOOL) isPrintServiceAvailable
{
Class printController = NSClassFromString(#"UIPrintInteractionController");
if (printController)
{
UIPrintInteractionController* controller = [UIPrintInteractionController sharedPrintController];
return (controller != nil) && [UIPrintInteractionController isPrintingAvailable];
}
return NO;
}
#end
Any help/links on creating and getting Print Plugin to run in my app will also be great.
It means that a message "dataUsingEncoding:" was sent to an instance of NSNull.
Somewhere in your program is an object where you apparently think it is an NSString*, but in reality it is an NSNull*. NSNull objects are used as placeholders in arrays and dictionaries to say "there is no value", because you can't store nil in arrays and dictionaries.
In Xcode, click on "Breakpoints", click on the "+", and add an "Exception breakpoint". Run your program again. This time it will stop in the debugger exactly on the code that tries to call dataUsingEncoding: Find out where the object comes from and fix it.
Related
when I launch App for first time (App is not installed perviously) on simulator, the instance of CBLQueryEnumerator count returns nil.
I found it by placing breakpoints and executing
po enumeratorResult
but the enumerator object seems to be allocated.
When I launch App for second time (in this case App is already installed on simulator) the instance of CBLQueryEnumerator count returns 5 (I have 5 documents in DB).
Am I making mistake in using CBLQuery or CBLQueryEnumerator please guide me correct.
viewContoller.m
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.progressView.progressViewStyle = UIProgressViewStyleBar;
[self.progressView setProgress:2.5 animated:YES];
self.cbObject = [CouchBaseObject sharedInstance];
self.syncURLLabel.text = [NSString stringWithFormat:#"%#",self.cbObject.syncURL];
self.documentList = [NSMutableArray array];
[self addDocumentToTicketModel:self.cbObject.database];
if(self.cbObject.pull.status == kCBLReplicationOffline || self.cbObject.pull.status != kCBLReplicationActive){
[self performSelector:#selector(pushTicketDetailViewController) withObject:self afterDelay:2.5];
}
}
-(void)addDocumentToTicketModel:(CBLDatabase*)database{
CBLView* view = [database viewNamed:#"_temp_view"];
if (!view.mapBlock) {
[view setMapBlock:MAPBLOCK({
if (doc) {
emit(doc,#"1");
}
})version:#"1.0"];
}
CBLQuery* query = [view createQuery];
[query runAsync:^(CBLQueryEnumerator * enumeratorResult, NSError * error) {
if(!error){
for (CBLQueryRow* row in enumeratorResult) {
CBLDocument* document = [database documentWithID:row.documentID];
Ticket* ticket = [Ticket modelForDocument:document];
NSLog(#"Ticket ; %#",ticket.propertiesToSave);
[self.documentList addObject:ticket];
}
}
}];
}
#end
CouchBaseObject.m
#implementation CouchBaseObject
-(instancetype)init{
self = [super init];
if(self){
NSError* error;
self.manager = [CBLManager sharedInstance];
if(!self.manager){
NSLog(#"manager fail");
return nil;
}
self.database = [self.manager databaseNamed:#"couch_sample_one" error:&error];
if(!self.database){
NSLog(#"database fail");
return nil;
}
[self initReplication];
}
return self;
}
+(CouchBaseObject*)sharedInstance{
static CouchBaseObject* sharedInstance = nil;
if(sharedInstance == nil){
sharedInstance = [[CouchBaseObject alloc]init];
}
return sharedInstance;
}
-(void)initReplication{
self.syncURL = [[NSURL alloc]initWithString:#"http://***.***.***.***:5984/couch_sample_one"];
self.pull = [self.database createPullReplication:self.syncURL];
self.push = [self.database createPushReplication:self.syncURL];
self.pull.continuous = NO;
self.push.continuous = NO;
[self startReplication];
}
-(void)startReplication{
[self.push start];
[self.pull start];
}
-(void)stopReplication{
[self.push stop];
[self.pull stop];
}
#end
For first time the control will not enter into for in loop
for (CBLQueryRow* row in result)
and for second time control will be in that loop.
This also happens when on just on launch.
Scenario.
Run App (Freshly installed app)
Navigate from initialViewController to viewController.
First time control does not enter into for loop, CBLQueryEnumerator Object.count returns nil.
pop to initialViewController
Push viewController, but this time controls enter into for in loop and CBLQueryEnumerator object.count returns 5
Hierarchy (Push).
initialViewContoller -> ViewContoller -> ListViewController
I'm using Phonegap's implementation to use the video capture and can't seem to get startVideoCapture to work. I'm a novice when it comes to Objective C, so I apologize if I'm off base here. Sounds like startVideoCapture is mainly for custom UI's. Is there something I can do to auto start the video recording (since I'm starting the video interface from another action). Here's a link to the full file:
https://github.com/apache/cordova-plugin-media-capture/blob/master/src/ios/CDVCapture.m
Thanks,
Steve
- (void)captureVideo:(CDVInvokedUrlCommand*)command
{
NSString* callbackId = command.callbackId;
NSDictionary* options = [command.arguments objectAtIndex:0];
NSLog(#"hereeeee");
if ([options isKindOfClass:[NSNull class]]) {
options = [NSDictionary dictionary];
}
// options could contain limit, duration and mode
// taking more than one video (limit) is only supported if provide own controls via cameraOverlayView property
NSNumber* duration = [options objectForKey:#"duration"];
NSString* mediaType = nil;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
// there is a camera, it is available, make sure it can do movies
pickerController = [[CDVImagePicker alloc] init];
NSArray* types = nil;
if ([UIImagePickerController respondsToSelector:#selector(availableMediaTypesForSourceType:)]) {
types = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
// NSLog(#"MediaTypes: %#", [types description]);
if ([types containsObject:(NSString*)kUTTypeMovie]) {
mediaType = (NSString*)kUTTypeMovie;
} else if ([types containsObject:(NSString*)kUTTypeVideo]) {
mediaType = (NSString*)kUTTypeVideo;
}
}
}
if (!mediaType) {
// don't have video camera return error
NSLog(#"Capture.captureVideo: video mode not available.");
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageToErrorObject:CAPTURE_NOT_SUPPORTED];
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
pickerController = nil;
} else {
pickerController.delegate = self;
pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
pickerController.cameraDevice = UIImagePickerControllerCameraDeviceFront;
pickerController.allowsEditing = NO;
// iOS 3.0
pickerController.mediaTypes = [NSArray arrayWithObjects:mediaType, nil];
if ([mediaType isEqualToString:(NSString*)kUTTypeMovie]) {
if (duration) {
pickerController.videoMaximumDuration = [duration doubleValue];
}
// NSLog(#"pickerController.videoMaximumDuration = %f", pickerController.videoMaximumDuration);
}
// iOS 4.0
if ([pickerController respondsToSelector:#selector(cameraCaptureMode)]) {
pickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
// pickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;
// pickerController.cameraDevice = UIImagePickerControllerCameraDeviceRear;
// pickerController.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
}
// CDVImagePicker specific property
pickerController.callbackId = callbackId;
SEL selector = NSSelectorFromString(#"presentViewController:animated:completion:");
if ([self.viewController respondsToSelector:selector]) {
[self.viewController presentViewController:pickerController animated:YES completion:nil];
} else {
// deprecated as of iOS >= 6.0
[self.viewController presentModalViewController:pickerController animated:YES];
}
// Auto start capture
[pickerController startVideoCapture];
}
}
My problem wasn't the use of startVideoRecording, it was when:
[self.viewController presentViewController:pickerController animated:YES completion:^(){
[pickerController startVideoCapture];
}];
Hope this helps someone else.
Thanks,
Steve
PhoneGap offers a plug-in for recording video, but this plug-in seems to force users to leave the app for the Camera app in order to record video.
Is it possible to initiate and stop video recording without leaving the app?
The two methods below are the primary methods we are using (rest of plug-in is viewable from the link above) to capture video. How should we modify this to allow recording from the front camera, without leaving the app, when the user taps a button?
Can anyone provide guidance please? Thanks.
Capture.m:
- (void)captureVideo:(CDVInvokedUrlCommand*)command
{
NSString* callbackId = command.callbackId;
NSDictionary* options = [command.arguments objectAtIndex:0];
if ([options isKindOfClass:[NSNull class]]) {
options = [NSDictionary dictionary];
}
// options could contain limit, duration and mode
// taking more than one video (limit) is only supported if provide own controls via cameraOverlayView property
NSNumber* duration = [options objectForKey:#"duration"];
NSString* mediaType = nil;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
// there is a camera, it is available, make sure it can do movies
pickerController = [[CDVImagePicker alloc] init];
NSArray* types = nil;
if ([UIImagePickerController respondsToSelector:#selector(availableMediaTypesForSourceType:)]) {
types = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
// NSLog(#"MediaTypes: %#", [types description]);
if ([types containsObject:(NSString*)kUTTypeMovie]) {
mediaType = (NSString*)kUTTypeMovie;
} else if ([types containsObject:(NSString*)kUTTypeVideo]) {
mediaType = (NSString*)kUTTypeVideo;
}
}
}
if (!mediaType) {
// don't have video camera return error
NSLog(#"Capture.captureVideo: video mode not available.");
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageToErrorObject:CAPTURE_NOT_SUPPORTED];
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
pickerController = nil;
} else {
pickerController.delegate = self;
pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
pickerController.allowsEditing = NO;
// iOS 3.0
pickerController.mediaTypes = [NSArray arrayWithObjects:mediaType, nil];
if ([mediaType isEqualToString:(NSString*)kUTTypeMovie]){
if (duration) {
pickerController.videoMaximumDuration = [duration doubleValue];
}
//NSLog(#"pickerController.videoMaximumDuration = %f", pickerController.videoMaximumDuration);
}
// iOS 4.0
if ([pickerController respondsToSelector:#selector(cameraCaptureMode)]) {
pickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
// pickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;
// pickerController.cameraDevice = UIImagePickerControllerCameraDeviceRear;
// pickerController.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
}
// CDVImagePicker specific property
pickerController.callbackId = callbackId;
SEL selector = NSSelectorFromString(#"presentViewController:animated:completion:");
if ([self.viewController respondsToSelector:selector]) {
[self.viewController presentViewController:pickerController animated:YES completion:nil];
} else {
// deprecated as of iOS >= 6.0
[self.viewController presentModalViewController:pickerController animated:YES];
}
}
}
- (CDVPluginResult*)processVideo:(NSString*)moviePath forCallbackId:(NSString*)callbackId
{
// save the movie to photo album (only avail as of iOS 3.1)
/* don't need, it should automatically get saved
NSLog(#"can save %#: %d ?", moviePath, UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(moviePath));
if (&UIVideoAtPathIsCompatibleWithSavedPhotosAlbum != NULL && UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(moviePath) == YES) {
NSLog(#"try to save movie");
UISaveVideoAtPathToSavedPhotosAlbum(moviePath, nil, nil, nil);
NSLog(#"finished saving movie");
}*/
// create MediaFile object
NSDictionary* fileDict = [self getMediaDictionaryFromPath:moviePath ofType:nil];
NSArray* fileArray = [NSArray arrayWithObject:fileDict];
return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:fileArray];
}
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;
}
In my application i have integrated Zbar SDK scanner, while scanning usually its working fine but my case is some times didfinishpickingmediawithInfo: delegate method firing twice. Here is my code which is in a singletone class.
-(void)scanProductBarCode
{
ZBarReaderViewController *reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
reader.supportedOrientationsMask = ZBarOrientationMaskLandscape;
else
reader.supportedOrientationsMask = ZBarOrientationMaskPortrait;
ZBarImageScanner *scanner = reader.scanner;
[scanner setSymbology: ZBAR_UPCA config: ZBAR_CFG_ENABLE to: 1];
[scanner setSymbology: ZBAR_CODE39 config: ZBAR_CFG_ADD_CHECK to: 0];
}
#pragma mark - Scanner delegate methods
- (void) imagePickerController: (UIImagePickerController*) reader didFinishPickingMediaWithInfo: (NSDictionary*) info
{
id<NSFastEnumeration> results = [info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
break;
barCodeString = [[NSString alloc] initWithString:symbol.data];
if(self.delegate)
[self.delegate getBarcodeString:barCodeString];
[reader dismissModalViewControllerAnimated:YES];
}
See this screen shot:
At background the scanner is still running like this in twice occuring case..
I ran into the same problem. I added a BOOL instance variable to my class named _processing. Then I did this:
- (void)imagePickerController:(UIImagePickerController*)reader didFinishPickingMediaWithInfo:(NSDictionary*)info
{
if (_processing) return;
id<NSFastEnumeration> results = [info objectForKey:ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results) {
_processing = YES;
barCodeString = symbol.data;
if(self.delegate) {
[self.delegate getBarcodeString:barCodeString];
}
break;
}
[reader dismissModalViewControllerAnimated:YES];
}
This ensures that only the first call is processed. You may need to reset _processing if you plan to reuse the view controller more than once.
Since the ZBarReaderViewController scans the image in continuous mode, it could be that the image is scanned twice before you dismiss the ZBarReaderViewController. You may try making the reader (ZBarReaderViewController *reader ) an instance variable of your class, and in the delegate method:
- (void)imagePickerController:(UIImagePickerController*)reader didFinishPickingMediaWithInfo:(NSDictionary*)info
{
// Stop further scanning
[reader.readerView stop];
...
//Continue with processing barcode data.
}