How to get available SSID list for iOS6 - iphone

in iOS 4.x, there were APIs about my requirement, But it seems changed into private in 5.x, And It seems to removed in 6.x. (Actually it seems can't be called in sandbox)
Getting SSID list for 802.11 is very essential idea for our new project.

This code work well in order to get SSID.
#import <SystemConfiguration/CaptiveNetwork.h>
#implementation IODAppDelegate
#synthesize window = _window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
CFArrayRef myArray = CNCopySupportedInterfaces();
CFDictionaryRef myDict = CNCopyCurrentNetworkInfo(CFArrayGetValueAtIndex(myArray, 0));
NSLog(#"Connected at:%#",myDict);
NSDictionary *myDictionary = (__bridge_transfer NSDictionary*)myDict;
NSString * BSSID = [myDictionary objectForKey:#"BSSID"];
NSLog(#"bssid is %#",BSSID);
// Override point for customization after application launch.
return YES;
}
And this is the results :
Connected at:{
BSSID = 0;
SSID = "Eqra'aOrange";
SSIDDATA = <45717261 27614f72 616e6765>;
}

I believe that there is no solution for this. the reason is:
Even user disabled location service, an App which accesses SSID list(actually BSSID) can infer location of user by using skyhook or something similar solution.
This information is not confirmed by Apple, But I'm pretty sure about it.

Related

Usage of captive network

sorry for my english.
I want to do an app that use captive network. My idea is that when an user try to connect to a captive portal network the app will open instead od the relative web sheet.
I know that i have to use the function CNSetSupportedSSIDs(), but i don't understand how to implement it.
thanks in advance!
This is the code that i have already wrote.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSArray *array = [NSArray arrayWithObjects:#"SSID of my network",nil];
bool ok = CNSetSupportedSSIDs((__bridge CFArrayRef) array);
if(ok)
{
NSLog(#"completed %lu",(unsigned long)[array count]);
}
else
{
NSLog(#"failed");
}
// Override point for customization after application launch.
return YES;
}

Run Internet Connection Check Throughout Entire App

The method below works very well for checking to see if a user has an internet connection. I would like to check for an internet connection throughout my entire app, and am wondering if there is somewhere I can put it within my App Delegate where it will get called from every view controller.
Is there a way to do this? Doesn't seem to work properly if I put it in my applicationDidFinishLaunching. Any recommendations would be great! Thank you!
NSURL *scriptUrl = [NSURL URLWithString:#"http://www.google.com/m"];
NSData *data = [NSData dataWithContentsOfURL:scriptUrl];
if (data) {
NSLog(#"Device is connected to the internet");
}
else {
NSLog(#"Device is not connected to the internet");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No Internet Connectivity"
message:#"You must have an internet connection" delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
[alert show];
return;
}
If you're looking to place this particular method in a location that can be accessed and called from the entirety of your application then this is simply a design decision. There are a number of ways to achieve this.
I like to make use of the singleton paradigm when implementing global methods. John Wordsworth covers this in a nice succinct blog post here:
http://www.johnwordsworth.com/2010/04/iphone-code-snippet-the-singleton-pattern/
Here's a quick chunk of code:
InternetConnectionChecker.h
#import <Foundation/Foundation.h>
#interface InternetConnectionChecker : NSObject
// Accessor for singelton instance of internet connection checker.
+ (InternetConnectionChecker *)sharedInternetConnectionChecker;
// Check to see whether we have a connection to the internet. Returns YES or NO.
- (BOOL)connected;
#end
InternetConnectionChecker.m
#import "InternetConnectionChecker.h"
#implementation InternetConnectionChecker
// Accessor for singelton instance of internet connection checker.
+ (InternetConnectionChecker *)sharedInternetConnectionChecker
{
static InternetConnectionChecker *sharedInternetConnectionChecker;
#synchronized(self)
{
if (!sharedInternetConnectionChecker) {
sharedInternetConnectionChecker = [[InternetConnectionChecker alloc] init];
}
}
return sharedInternetConnectionChecker;
}
// Check to see whether we have a connection to the internet. Returns YES or NO.
- (BOOL)connected
{
NSURL *scriptUrl = [NSURL URLWithString:#"http://www.google.com/m"];
NSData *data = [NSData dataWithContentsOfURL:scriptUrl];
if (data) {
NSLog(#"Device is connected to the internet");
return TRUE;
}
else {
NSLog(#"Device is not connected to the internet");
return FALSE;
}
}
#end
In my example I've amended your method to return a true/false so you can handle the result within the UI calling the method appropriately but you could continue to show a UIAlertView if you pleased.
You would then use the singleton in the following way:
InternetConnectionChecker *checker = [InternetConnectionChecker sharedInternetConnectionChecker];
BOOL connected = [checker connected];
There are of course more complex ways of doing it, but the easiest way, (and the way I use) is to simply create a "CheckNetwork" class with your method as a class method which returns a bool, i.e:
+ (BOOL) checkConnection{
yourMethodDetails;
}
then simply #import "CheckNetwork.h" into any file in your project and call
if([CheckNetwork checkConnection]){
whatever you want to do here;
}
While Singleton class and Static methods are a way, you could also implement static inline methods in a .h file which as no .m file
Also, as a sidetalk, checking internet connectivity using using NSURL along with google.com is not a good practice.
Because,
It is not a simple ping operation
It downloads the whole page which may consume time
OS provided ways are more radical and appropriate.
It you are working with a specific web site, then using that web site for connectivity is the best practice, i think. See this Answer by Jon Skeet
I would suggest using the Reachability framework by Apple.
Or if you need more compact single function version, you could also use this function excerpted from Reachabilty myself
+ (BOOL) reachabilityForInternetConnection;
{
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)&zeroAddress);
SCNetworkReachabilityFlags flags;
if (SCNetworkReachabilityGetFlags(reachability, &flags))
{
return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
}
return NO;
}

Programmatically show soft keyboard on iPhone in a PhoneGap application?

I've been searching far and long, and to this moment, I did not come across a working solution for PhoneGap / Cordova applications that would show soft keyboard programmatically.
Scenario:
We have a PhoneGap application - a website created in jQuery Mobile - that at one point shows a dialog to the user. This dialog is also a web page and has one single INPUT text box where user should enter a code.
Problem:
When the code dialog is shown, the input box is focused using JavaScript. However, due to restrictions placed on iPhone's internal browser, the soft keyboard does not come up until the user actually really clicks inside the input text box.
What we tried:
creating a hidden text box and making it first responder
making the actual webview a first responder once the input receives focus via JavaScript
using sendActionsForControlEvents to try and delive Touch events to the webview (although if anyone has a working code for a PhoneGap application, I would appreciate if they could share it, since I'm no professional in iOS coding)
Any ideas?
EDIT: The restriction mentioned in this question is for built-in browsers only... if you're aiming Opera, you will be successful by using the following code:
var e = jQuery.Event("keydown", { keyCode: 37 });
$('#element').focus().trigger(e);
EDIT2: This is a final working PhoneGap code that can be used in a plugin:
keyboardhelper.h
//
// keyboardHelper.h
// soft keyboard displaying plugin for PhoneGap
//
// Copyright 2012 Martin Ambrus.
//
#import <Foundation/Foundation.h>
#ifdef CORDOVA_FRAMEWORK
#import <Cordova/CDVPlugin.h>
#else
#import "CDVPlugin.h"
#endif
#interface keyboardHelper : CDVPlugin {
NSString *callbackID;
}
#property (nonatomic, copy) NSString *callbackID;
- (void)showKeyboard:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
#end
keyboardhelper.m
//
// keyboardHelper.m
// soft keyboard displaying plugin for PhoneGap
//
// Copyright 2012 Martin Ambrus.
//
#import "keyboardHelper.h"
#import "AppDelegate.h"
#implementation keyboardHelper
#synthesize callbackID;
-(void)showKeyboard:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options {
self.callbackID = [arguments pop];
//Get text field coordinate from webview. - You should do this after the webview gets loaded
//myCustomDiv is a div in the html that contains the textField.
int textFieldContainerHeightOutput = [[((AppDelegate *)[[UIApplication sharedApplication] delegate]).viewController.webView stringByEvaluatingJavaScriptFromString:#"document.getElementById(\"myCustomDiv\").offsetHeight;"] intValue];
int textFieldContainerWidthOutput = [[((AppDelegate *)[[UIApplication sharedApplication] delegate]).viewController.webView stringByEvaluatingJavaScriptFromString:#"document.getElementById(\"myCustomDiv\").offsetWidth;"] intValue];
int textFieldContainerYOffset = [[((AppDelegate *)[[UIApplication sharedApplication] delegate]).viewController.webView stringByEvaluatingJavaScriptFromString:#"document.getElementById(\"myCustomDiv\").offsetTop;"] intValue];
int textFieldContainerXOffset = [[((AppDelegate *)[[UIApplication sharedApplication] delegate]).viewController.webView stringByEvaluatingJavaScriptFromString:#"document.getElementById(\"myCustomDiv\").offsetLeft;"] intValue];
UITextField *myTextField = [[UITextField alloc] initWithFrame: CGRectMake(textFieldContainerXOffset, textFieldContainerYOffset, textFieldContainerWidthOutput, textFieldContainerHeightOutput)];
[((AppDelegate *)[[UIApplication sharedApplication] delegate]).viewController.webView addSubview:myTextField];
myTextField.delegate = self;
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: #"ok"];
[self writeJavascript:[pluginResult toSuccessCallbackString:self.callbackID]];
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
//here you create your request to the server
return NO;
}
-(BOOL)textFieldDidEndEditing:(UITextField *)textField
{
//here you create your request to the server
return NO;
}
#end
javascript
var keyboardHelper = {
showKeyboard: function(types, success, fail) {
return Cordova.exec(success, fail, "keyboardHelper", "showKeyboard", types);
}
};
You can solve the issue with a config.xml entry these days, add:
<preference name="keyboardDisplayRequiresUserAction" value="false" />
You can get the coordinates for the input field using javascript on the webView. Then, place your own textField right on top of it and in it's delegate method textFieldShouldReturn send a request to the server with the code the user typed in.
//Get text field coordinate from webview. - You should do this after the webview gets loaded
//myCustomDiv is a div in the html that contains the textField.
int textFieldContainerHeightOutput = [[webView stringByEvaluatingJavaScriptFromString:#"document.getElementById(\"myCustomDiv\").offsetHeight;"] intValue];
int textFieldContainerWidthOutput = [[webView stringByEvaluatingJavaScriptFromString:#"document.getElementById(\"myCustomDiv\").offsetWidth;"] intValue];
int textFieldContainerYOffset = [[webView stringByEvaluatingJavaScriptFromString:#"document.getElementById(\"myCustomDiv\").offsetTop;"] intValue];
int textFieldContainerXOffset = [[webView stringByEvaluatingJavaScriptFromString:#"document.getElementById(\"myCustomDiv\").offsetLeft;"] intValue];
myTextField.frame = CGRectMake(textFieldContainerXOffset, textFieldContainerYOffset, textFieldContainerWidthOutput, textFieldContainerHeightOutput);
[webView addSubview:myTextField];
myTextField.delegate = self;
Then you implement textFieldShouldReturn and create your request to the server there.
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
//here you create your request to the server
return NO;
}
This is done in existing project, however without using PhoneGap. I hope you can adapt it to suit your needs.
To remove the text field, you can hide it
myTextField.hidden = YES;
or
myTextField = nil;
or
[myTextField removeFromSuperView];
Prior to iOS 6, Apple only allowed the keyboard to be brought up following a user interaction. In iOS 6 they've introduced the following property for UIWebView which you merely need to set to NO.
"yourWebView".keyboardDisplayRequiresUserAction = NO;
Apple sets this by default to "Yes". Now you can call focus() in your JS and the keyboard will appear.
Have you tried using Native Controls and calling them from Javascript?
Here you have some code that shows the usage of Native Controls on a Phonegap Cordova application (Phonegap 1.5)
https://gist.github.com/1384250
Hope it helps to solve the problem :)
I admit this is private, but it might help you out:
#class UIKeyboard;
void showKeyboard()
{
static UIKeyboard *kb = nil;
if ([[UIKeyboard class] respondsToSelector:#selector(automaticKeyboard)])
kb = [UIKeyboard automaticKeyboard];
else
kb = [UIKeyboard activeKeyboard];
if (kb == nil) {
kb = [[[UIKeyboard alloc] initWithDefaultSize] autorelease];
[[[UIApplication sharedApplication] keyWindow] addSubview:kb];
}
if ([kb respondsToSelector:#selector(orderInWithAnimation:)]) {
[kb orderInWithAnimation:YES];
} else {
[kb activate];
[kb minimize];
[kb maximize];
}
}
And call it like this:
showKeyboard();
I actually just found a solution to this.
Like horak says and as described in this article, with or without soft keyboard, it's now possible to achieve this with iOS 6.0 by using: KeyboardDisplayRequiresUserAction = NO;
As of Cordova 2.2, the iOS property mentioned above can simply be added to the Cordova.plist file:
KeyboardDisplayRequiresUserAction, boolean, NO
This solves it all for everyone using Cordova 2.2. Now just call input.focus() as previously discussed, and the keyboard will automatically appear. For those of us who haven't yet updated our Cordova to the current latest version (2.2), it's fortunately still possible.
Programmatically show keyboard on iPhone using cordova v. < 2.2
Step 1:
Adding property to Cordova.plist
Go to your project > Resources > Cordova.plist. Add: KeyboardDisplayRequiresUserAction, boolean, NO
Step 2:
Adding below code snippet to CDVViewController.m
Search for "#interface CDVViewController" (or similar to locate above file). For Cordova 2.1, go to line 240 (everyone else go to a line after a "IsAtLeastiOSVersion" if statement, sorry can't be more precise than that.) Add this code snippet to your CDVViewController.m on the above mentioned line:
if (IsAtLeastiOSVersion(#"6.0")) {
BOOL keyboardDisplayRequiresUserAction = YES; // KeyboardDisplayRequiresUserAction - defaults to YES
if ([self.settings objectForKey:#"KeyboardDisplayRequiresUserAction"] != nil) {
if ([self.settings objectForKey:#"KeyboardDisplayRequiresUserAction"]) {
keyboardDisplayRequiresUserAction = [(NSNumber*)[self.settings objectForKey:#"KeyboardDisplayRequiresUserAction"] boolValue]; //JB-VAL121212
}
}
// property check for compiling under iOS < 6
if ([self.webView respondsToSelector:#selector(setKeyboardDisplayRequiresUserAction:)]) {
[self.webView setValue:[NSNumber numberWithBool:keyboardDisplayRequiresUserAction] forKey:#"keyboardDisplayRequiresUserAction"];
}
}
Disclaimer: This has been tested on Cordova 2.1 only, it is, however, very likely that it still works with 2.0 or any other earlier version that comes with the CDVViewController.m file)
You can use the FocusOut event on the input field and this will be fired when the Done key is pressed. I could use this on IOS 6 and above. I believe it will also work on previous versions.

ipad UIImagePickerController problem?

My app is an iphone app not an universal app.I am implementing uiimagepickercontroller it's working fine in iphone .But our client test my app on ipad the app will crash.I find out the issue 'On iPad, UIImagePickerController must be presented via UIPopoverController'
I am checking device by
NSString *deviceType = [UIDevice currentDevice].model;
(This code work in universal app)
implementing UIPopoverController for iPad only. But deviceType always displays 'iPhone' even if i change to iPad simulator.Is it possible to solve this issue in iphone Build?
You should use UI_USER_INTERFACE_IDIOM macro to check for device.
if (UIUserInterfaceIdiomPad == UI_USER_INTERFACE_IDIOM())
{
// your code
}
UIDevice is not the right choice here.
Refer to userInterfaceIdiom property of UIDevice
I did iPad for separately to solve this issue.because i can't get a device type iPad in iPhone app.
Like Erica Sadun said you can access device string with:
- (NSString *) getSysInfoByName:(char *)typeSpecifier
{
size_t size;
sysctlbyname(typeSpecifier, NULL, &size, NULL, 0);
char *answer = malloc(size);
sysctlbyname(typeSpecifier, answer, &size, NULL, 0);
NSString *results = [NSString stringWithCString:answer encoding: NSUTF8StringEncoding];
free(answer);
return results;
}

Is there any way to switch on/off bluetooth in iPhone programmatically?

In my application I want to switch on/off iPhone Bluetooth.i m using sdk 4.3..I got some idea regarding Bluetooth manager framework, but it's not working in 4.3..any ideas? or can we programmatically determine whether Bluetooth is ON/OFF?
Please note that you wouldn't be able to publish the app on the App Store because doing that must use private API.
If you still want to do that you should read this link:
Is there a way to toggle bluetooth and/or wifi on and off programmatically in iOS?
Pay attention for adding GameKit framework for it to work and not using all the other thing written like adding .h files etc. unless gameKit doesn't sole all the problems.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
#if TARGET_IPHONE_SIMULATOR
exit( EXIT_SUCCESS ) ;
#else
/* this works in iOS 4.2.3 */
Class BluetoothManager = objc_getClass( "BluetoothManager" ) ;
id btCont = [BluetoothManager sharedInstance] ;
[self performSelector:#selector(toggle:) withObject:btCont afterDelay:1.0f] ;
#endif
return YES ;
}
#if TARGET_IPHONE_SIMULATOR
#else
- (void)toggle:(id)btCont
{
BOOL currentState = [btCont enabled] ;
[btCont setEnabled:!currentState] ;
[btCont setPowered:!currentState] ;
}
#endif
the above lines of code i got from here