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;
}
Related
I want to write location tracking app like "find my iphone" that runs in foreground,background and even terminating ( not running). Location will be sent to my server periodically time. I have searched in google and read many many documents,tutorials comments, codes about this topic. Then I have found this tutorial. But in this tutorial, location is sent to ".txt" file in foreground and background not terminating... I mean, when the app is killed, it is not relaunched in the background to send location ".txt" file .. So I have added and updated some codes to send location when it is not running.. However, I didn't do it... I mean, when I kill(close) the app in multitasking (double tapping home button), it is not sending to location...
Can you help me, how can I fix this problem?
Thanks in advance
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
[self log:[NSString stringWithFormat:#"Background location %.06f %.06f %#" , newLocation.coordinate.latitude, newLocation.coordinate.longitude, newLocation.timestamp]];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
id locationValue = [launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey];
if (locationValue)
{
// create a new manager and start checking for sig changes
[self log:#"didFinishLaunchingWithOptions location key"];
m_locManager = [[CLLocationManager alloc] init];
[self log:#"didFinishLaunchingWithOptions created manager"];
m_locManager.delegate = self;
[self log:#"didFinishLaunchingWithOptions set delegate"];
[m_locManager startMonitoringSignificantLocationChanges];
[self log:#"didFinishLaunchingWithOptions monitoring sig changes"];
return YES;
}
[self log:#"didFinishLaunchingWithOptions"];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
[self log:#"applicationWillResignActive"];
NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setBool:viewController.m_significantSwitch.on forKey:#"significant"];
[userDefaults synchronize];
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
[self log:#"applicationDidEnterBackground"];
[m_locManager startMonitoringSignificantLocationChanges];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[self log:#"applicationWillEnterForeground"];
[m_locManager stopMonitoringSignificantLocationChanges];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[self log:#"applicationDidBecomeActive"];
if (![window.subviews count])
{
// Add the view controller's view to the window and display.
[window addSubview:viewController.view];
[window makeKeyAndVisible];
NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
viewController.m_significantSwitch.on = [userDefaults boolForKey:#"significant"];
if (viewController.m_significantSwitch.on)
[viewController actionSignificant:nil];
}
}
- (void)applicationWillTerminate:(UIApplication *)application {
[self log:#"applicationWillTerminate"];
[m_locManager startMonitoringSignificantLocationChanges];
}
That is not correct, when your app is terminated it can still monitor significant location updates.
My friend , you are on wrong way. Actually there is no any way to do a task after killing of app in iOS. You can read about this here in Apple documentation.
Find My iPhone - It is an Apple App and they are using private api's to make this possible. And these type of features not available for general purpose developer programming.
So please don't go on this path.All will go in vain.
Hope this Helps you !
You cannot run anything when the app is killed, except you can recieve push notifications or UILocalNotifications. You could try duplicating UILocalNotifications functionality and do your stuff even when your app is killed/in bg/. BTW this is a complex thing and you could do more digging about ios7 background tasks or something.
This may help you.
Getting the User’s Location
see the section Starting the Significant-Change Location Service. It says
If you leave the significant-change location service running and your iOS app is subsequently suspended or terminated, the service automatically wakes up your app when new location data arrives. At wake-up time, the app is put into the background and you are given a small amount of time (around 10 seconds) to manually restart location services and process the location data.
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.
I have an Iphone application in which i am recieving push notifications from the server.Now i am going to a view controller to show the message.Where that same message is loaded in a tableview .so thats not a problem.Now i am recieving two kinds of messages,one is a link and another is the message as earlier.if it is a link i want to open it in saffari,not need to go to tableview as usual.Can anybody help me to achieve this?
When You click on the push notification then you get a dictionary in the function - didReceiveRemoteNotification:
try this code:-
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(#"remote notification: %#",[userInfo description]);
if (userInfo)
{
if ([[userInfo allKeys] containsObject:#"aps"])
{
if([[[userInfo objectForKey:#"aps"] allKeys] containsObject:#"alert"])
{
if([[[userInfo objectForKey:#"aps"] allKeys] containsObject:#"alert"])
{
NSString *urlString = [[userInfo objectForKey:#"aps"] objectForKey:#"alert"];
NSURL *url = [NSURL URLWithString:urlString];
if(url)
{
[[UIApplication sharedApplication]openURL:url]; // open in the safari...
}
else
{
// use the message in table view
}
}
}
}
}
}
The push notification is tied to your application, so in short its not possible to have a push notification from you application open safari directly. However, one workaround might go something like this:
user responds to notification (ie swipes to open it on the lock screen)
your app opens, and the data from the notification is passed into your applications
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method. You could then interrogate the the data passed in as so
NSDictionary *dictionary = [launchOptions objectForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"];
// If dictionary is not nil, then your app is launched due to a push notification
if (dictionary != nil) {
NSDictionary *payload = [tmpDic objectForKey:#"aps"];
}
Once you've got your payload, look at the contents, and if it is a URL, call the safari URL scheme, passing in the URL. Like so
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: <URL from payload>]];
This will help you achieve what you want to do, but it may mean the user briefly sees your app first before the os will switch them into safari.
A side note, why would you want to do this? Your users should not be launching a random URL from a notification, and I don't think Apple would like that too much. Prehaps they should be seeing some information about the URL first in your app, and then choosing whether they would like to open it in safari?
Does Apple not allow developers to add an icon into a status bar?
I followed code from a book. The code is simple:
#interface UIApplication (extended)
- (void) addStatusBarImageNamed:(NSString *)aName;
- (void) removeStatusBarImageNamed:(NSString *)aName;
#end
- (void)performAction{
if (xxx) {
[[UIApplication sharedApplication]addStatusBarImageNamed:#"Default_EN.png"];
}
else {
[[UIApplication sharedApplication]addStatusBarImageNamed:#"Default_EC.png"];
}
}
But it gives the following feedback :
-addStatusBarImageNamed: is deprecated. Doing nothing.
What can I do?
To my best knowledge, this isn't permitted within the SDK, but there could be the possibilities that they could have some private API to do so but so far they haven't exposed those, I think you are'nt able to add icon in status bar. If someone know please correct me .
In Classes/YourViewController.m, the addStatusBarImageNamed:removeOnExit: method needs to be overwritten with this.
- (void) addStatusBarImageNamed:(NSString*)image removeOnExit: (BOOL) remove {
if(_statusbarimage!=nil && _responds) {
if ([[[NSUserDefaults standardUserDefaults] objectForKey:#"statusBarEnabled"] integerValue] == 1)
[self removeStatusBarImageNamed:_statusbarimage];
statusbarimage=image;
}
if (_responds) {
if ([[[NSUserDefaults standardUserDefaults] objectForKey:#"statusBarEnabled"] integerValue] == 1)
[super addStatusBarImageNamed:image removeOnExit: remove];
}
}
See if it works fine.
I'm writing an iPhone app that involves handling network events from a server over a VoIP socket in the background. I've successfully set up the socket, the background service info in the .plist, and the appropriate streams, but I'm having trouble figuring out how to do anything useful in my callback. I don't know how to access the rest of my application's state from within the callback function. Here is where I set up the connections in the AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(#"AppDelegate: didFinishLaunchingWithOptions");
// Override point for customization after application launch.
// Add the view controller's view to the window and display.
[self.window addSubview:viewController.view];
[self.window makeKeyAndVisible];
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFHostRef host = CFHostCreateWithName(kCFAllocatorDefault, (CFStringRef)#"irc.freenode.net");
CFStreamCreatePairWithSocketToCFHost(kCFAllocatorDefault, host, 6667, &readStream, &writeStream);
CFReadStreamSetProperty(readStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
CFWriteStreamSetProperty(writeStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
CFStreamClientContext myContext = {
0,
viewController,
(void *(*)(void *info))CFRetain,
(void (*)(void *info))CFRelease,
(CFStringRef (*)(void *info))CFCopyDescription
};
CFOptionFlags registeredEvents = kCFStreamEventHasBytesAvailable |
kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered;
if(CFReadStreamSetClient(readStream, registeredEvents, clientCB, &myContext)) {
CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
}
if (!CFReadStreamOpen(readStream)) {
NSLog(#"Read stream could not be opened");
}
else {
NSLog(#"Successfully opened read stream");
}
return YES;
}
And here is the callback function for CFStream events, where I'm having my issues:
void clientCB(CFReadStreamRef stream, CFStreamEventType event, void* myPtr) {
switch(event) {
case kCFStreamEventHasBytesAvailable:{
UInt8 buf[32];
CFIndex bytesRead = CFReadStreamRead(stream, buf, 32);
if (bytesRead > 0) {
NSLog(#"Readstream Not Empty %i", buf[0]);//dummy debug marker
}
//I WANT TO ACCESS CLASSES, PROPERTIES, FUNCTIONS, ETC. ABOUT THE REST OF MY PROGRAM HERE (E.G. GET A WORKING POINTER BACK TO THE MAIN APPDELEGATE).
break;
}
case kCFStreamEventErrorOccurred:
case kCFStreamEventEndEncountered:
default:
break;
}
}
These two functions are both defined in the same AppDelegate class. I've tried passing pointers via the CFStreamClientContext struct: VoIP_TestViewController* testViewController = context->info;, I've tried to access the main appDelegate via: [[UIApplication sharedApplication] delegate], and I've tried the usual Obj-C and C constructs ("this", "self", "super").
Any help would be greatly greatly appreciated!
Make sure you import your main app delegate header file into the view where you need to call it.
Use this to call it:
nameOfYourAppDelegate *appDelegate = (_nameOfYourAppDelegate *)[[UIApplication sharedApplication] delegate];
//than you can use appDelegate for whatever you want (ie. appDelegate.somView.someProperty )
Ah I'm an idiot. I forgot to import a class header for a member class (i.e. I forgot to import ClassB when I tried to access [ClassA.ClassB methodB]). Of course XCode only provided an unrecognized selector runtime error rather than a missing declaration compiler error, making debugging slightly harder than it should have been. Thanks for the catch!