getting operator details in iphone - iphone

How to get the currently using operator details (like Airtel or Idea or etc..)of iPhone.
Is it possible to get those details or is there any way to identify which operator currently we are using.I am developing an application which is based on the operator, if user changes his SIM(Operator) then the app shouldn't work, it has to work for that particular operator.

CTCarrier should have the info you need in it.
Edit: CTTelephonyNetworkInfo responds to a user switching SIMs mid-session, and provides an instance of CTCarrier for you.
Sample code (in your app delegate):
#import <CoreTelephony/CoreTelephony.h>
static NSString *requiredCarrier = #"Verizon"; // example carrier
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CTTelephonyNetworkInfo *myNetworkInfo = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier *myCarrier = [myNetworkInfo subscriberCellularProvider];
if(![[myCarrier carrierName] isEqualToString:requiredCarrier])
{
// lock the app, possibly terminate the app after displaying a UIAlertView
// informing the user of the network-lock.
}
// ...
return YES;
}
Note the following advisory on the properties of CTCarrier (I would recommend not doing a permanent one-way lock if a nil carrier is read):
"The value for this property is nil if any of the following apply:
The device is in Airplane mode.
There is no SIM card in the device.
The device is outside of cellular service range."
Of the properties of CTCarrier to validate on, I would recommend carrierName specifically as it doesn't change when the user is roaming so the app will still work as long as the SIM is tied to your desired operator.

Just a quick note in case someone is looking for this.
I have noticed from playing with the CTCarrier API that "nil" is returned to any of its properties only on the emulator. On the device it returns #"" (blank string) for some reason! Checking agains nil failed ont eh device but checking equality with #"" worked!

You can use the Core Telephony framework to achieve this. In particular CTCarrier and the carrierName property. View the documentation here: http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Reference/CTCarrier/Reference/Reference.html%23//apple_ref/doc/uid/TP40009596

Related

Checking if Bluetooth is Disabled on iOS 5 without BluetoothManager

I have seen that in iOS 5, CoreBluetooth provides the capability to check if Bluetooth is disabled. From what I have seen of the documentation, it is clearly aimed at bluetooth peripheral use. However, I am attempting to check if bluetooth is on because I am using GameKit (GKPeerPickerController) that will search endlessly for bluetooth connections if it is not enabled, which is an issue.
I tried to do this like so:
CBCentralManager * manager = [[CBCentralManager alloc] init];
if (manager.state == CBCentralManagerStatePoweredOn ) {
//go ahead with GameKit
}
This does not work, and manager.state is always equal to null. What am I doing wrong here? Or alternatively, are there better ways to check the status of bluetooth on the iPhone?
EDIT: I don't want to call any private APIs because I will be submitting this app to the app store. I have edited my question title to clarify this.
Ok, I discovered that by doing this:
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:FALSE], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
NSMutableArray * discoveredPeripherals = [NSMutableArray new];
CBCentralManager * manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
[manager scanForPeripheralsWithServices:discoveredPeripherals options:options];
[manager stopScan];
If bluetooth is off, the system will pop up an alert view which will offer the choice to turn bluetooth on. Otherwise, if it finds a peripheral it will call a corresponding delegate method, but if there is nothing in that implementation you don't need to worry about it.
You can find the answer of your question by this link. Check it out.
Edited
Have you checked out the Game Kit Framework reference?
According to Apple:
Game Kit offers your applications the ability to create Bluetooth
connections between two devices.
Edited
Then try this project. https://github.com/sergiomtzlosa/MultiContactsSelector-ios

How to check if iCloud is configured programmatically

Here is the sentence from Apple Docs:
"If iCloud is not configured, ask users if they want to configure it (and, preferably, transfer them to Launch Settings if they want to configure iCloud)."
How can I check if iCloud is configured or not and how to launch settings for iCloud?
Edit:
If you are targeting iOS6 or above you can use [[NSFileManager defaultManager] ubiquityIdentityToken];. For usage example please refer #Dj S' answer :).
It is faster and easier than the original solution which was meant for people targeting iOS5 and above
Original Answer
As documented in iOS App programming guide - iCloud Storage. That can be checked by asking the ubiquity container URL to the file manager :)
As long as you supply a valid ubiquity container identifier below method should return YES
- (BOOL) isICloudAvailable
{
// Make sure a correct Ubiquity Container Identifier is passed
NSURL *ubiquityURL = [[NSFileManager defaultManager]
URLForUbiquityContainerIdentifier:#"ABCDEFGHI0.com.acme.MyApp"];
return ubiquityURL ? YES : NO;
}
However, I've found that URLForUbiquityContainerIdentifier: might take several seconds the very first time within a session (I used it in iOS5 so things might be different now). I remember using something like this:
dispatch_queue_t backgroundQueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(backgroundQueue,^{
BOOL isAvailable = [self isICloudAvailable]
/* change to the main queue if you want to do something with the UI. For example: */
dispatch_async(dispatch_get_main_queue(),^{
if (!isAvailable){
/* inform the user */
UIAlertView *alert = [[UIAlertView alloc] init...]
[alert show];
[alert release];
}
});
});
Just to supplement the answer above,
if you only want to know if iCloud is available for your application,
e.g.
1. no iCloud account is setup, or
2. Documents and Data is disabled (for all apps), or
3. Documents and Data is disabled for your app only
then you can use NSFileManager's ubiquityIdentityToken for iOS 6 and above.
If value is nil, then iCloud account is not configured. Otherwise, iCloud account is configured.
id token = [[NSFileManager defaultManager] ubiquityIdentityToken];
if (token == nil)
{
// iCloud is not available for this app
}
else
{
// iCloud is available
}
Note that according to Apple docs, you can call it from the main thread.
Because this method returns relatively quickly, you can call it at launch time and you can call it from your app’s main thread.

MKStoreKit Implementation

I have spent the last 2 days fighting trying to get in app purchases working! The app has not been approved by Apple (its not ready yet), so I just did the Developer Pulled Binary method. I added a non-consumable (and I am pretty sure my contracts are cleared) and called it com.MYAPP.MYAPPNAME.levelone
I am using the MKStoreKit 3.1 relevant
I just want to see that the item will appear in the NSLog for the app, so I have this in my App Delagate
- (void) applicationDidFinishLaunching:(UIApplication*)application
{
[MKStoreManager sharedManager];
[[MKStoreManager sharedManager] purchasableObjectsDescription];
...
When I run this it just tells me
Problem in iTunes connect configuration for product: com.mycompany.myapp.005
Problem in iTunes connect configuration for product: com.mycompany.myapp.featureA
This is a Cocos2d based game if it makes any difference.
There are reasons why I didn't implement MKStoreManager to accept a set of products as parameters.
1) You should not litter your code with hard coded product ids. This is because you initiate a purchase request with a product id. The former happens on AppDelegate and the latter happens on one of your view controllers. So there should be some file where you put in all those product constants. Why not use MKStoreManager.h itself for that?
MKStoreKit 3.1 requires some configuration before you use it; it doesn't just work out of the box.
Specifically, you need to tell MKStoreKit the list of features/product identifiers that you have configured in iTunes Connect. Oddly, you do that by modifying the source code, instead of passing in an array of arguments.
Examine MKStoreManager.h lines 26-34:
// CONFIGURATION STARTS -- Change this in your app
define kConsumableBaseFeatureId #"com.mycompany.myapp."
#define kFeatureAId #"com.mycompany.myapp.featureA"
#define kConsumableFeatureBId #"com.mycompany.myapp.005"
// consumable features should have only number as the last part of the product name
// MKStoreKit automatically keeps track of the count of your consumable product
#define SERVER_PRODUCT_MODEL 0
// CONFIGURATION ENDS -- Change this in your app
You have to change that stuff. If you don't, you'll get errors like the one you posted.
But that's not the only place. You also have to update the requestProductData implementation function in MKStoreManager.m, where kFeatureAId and kConsumableFeatureBId are used.
-(void) requestProductData
{
SKProductsRequest *request= [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObjects:
kFeatureAId,
kConsumableFeatureBId,
nil]];
request.delegate = self;
[request start];
}
You have to specify the product identifier list yourself; MKStoreKit can't guess it for you.
Still, it's weird. It makes you wish MKStoreKit would just accept an array of product identifiers in its initializer!
Remove the unused products inside MKStoreManager.m as follows
-(void) requestProductData
{
SKProductsRequest *request= [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObjects:
kFeatureAId,
//kConsumableFeatureBId,
nil]];
request.delegate = self;
[request start];
}

GKSession - what if I have Bluetooth and Wi-Fi turned off?

I'm working on an iPhone app that will allow for peer-to-peer connections. From what I understand, I have the choice between using GKPeerPicker or the GKSession. I don't like the idea of using the PeerPicker because I want to show a custom interface, so I decided to go with GKSession, and hey, BONUS is that it also works over Wi-Fi, whereas the Peer Picker does not.
OK, so problem is... what if the user has both Bluetooth and Wi-Fi turned off? In the Peer Picker, there is a prompt to turn Bluetooth on w/o leaving the app. GKSession doesn't have it... but woah wait a second, it appears that I can't even check to see if Bluetooth is on or not programatically!
Carpe Cocoa claims no problem, just use the Delegate's session:didFailWithError: method. But, as it explains in the comments... that doesn't seem to work anymore! And in my experience, I concur.
Is there some other way to programmatically check if Bluetooth is on? Is this something that I should be leveraging Reachability for? Or is it just a bug that Apple has yet to fix?
To be more specific, I'm creating my session like this:
GKSession *aSession = [[GKSession alloc] initWithSessionID:nil
displayName:user.displayName
sessionMode:GKSessionModePeer];
self.gkSession = aSession;
[aSession release];
self.gkSession.delegate = self;
self.gkSession.available = YES;
[self.gkSession setDataReceiveHandler:self withContext:NULL];
The class implements the GKSessionDelegate, and I know that it's working because when I have bluetooth turned on, the delegate methods are called no problem. I've implemented them as such:
#pragma mark -
#pragma mark GKSessionDelegate methods
- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state {
if (GKPeerStateAvailable == state) {
[session connectToPeer:peerID withTimeout:10];
} else if (GKPeerStateConnected == state) {
// gets user
NSError *error = nil;
[session sendData:user.connectionData
toPeers:[NSArray arrayWithObjects:peerID,nil]
withDataMode:GKSendDataReliable error:&error];
if (error)
NSLog(#"%#",error);
}
}
- (void)session:(GKSession *)session didReceiveConnectionRequestFromPeer:(NSString *)peerID {
NSError *error = nil;
[session acceptConnectionFromPeer:peerID error:&error];
if (error)
NSLog(#"%#",error);
}
- (void)session:(GKSession *)session connectionWithPeerFailed:(NSString *)peerID withError:(NSError *)error {
NSLog(#"%#",error);
}
- (void)session:(GKSession *)session didFailWithError:(NSError *)error {
NSLog(#"%#",error);
}
None of the log statements are printed and I set breakpoints in each method, but none of them are hit when the user has both Bluetooth and Wi-Fi turned off. I was hoping that something would happen to trigger session:didFailWithError: so that I could prompt the user to turn on Bluetooth or connect to a Wi-Fi network.
Now in iOS 5, this can be achieved like so:
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:FALSE], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
NSMutableArray * discoveredPeripherals = [NSMutableArray new];
CBCentralManager * manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
[manager scanForPeripheralsWithServices:discoveredPeripherals options:options];
[manager stopScan];
This requires that you import the CoreBluetooth framework in iOS 5. If bluetooth is off, the system will pop up an alert view which will offer the choice to turn bluetooth on. Otherwise, if it finds a peripheral it will call a corresponding delegate method, but if there is nothing in that implementation you don't need to worry about it.
I agree with Martin Gordon, but a workaround might be to use Apple's reachability.
Interesting point, have you tried testing it with Bluetooth OFF and the WiFi ON? I found out recently that although my program was calling this 'Bluetooth Unavailable' message, it wasn't in fact using Bluetooth AT ALL but was connecting over my WiFi network. I don't know of a way to force GKSession into a Bluetooth connection without using Apple's PeerPicker object, but the PeerPicker object does allow for people to make their own interfaces. What it doesn't seem to allow is connection types other than Peer, so if you want a Client/Server arrangement it's not going to be much help.
-Ash
You can switch on Blutooth programmatically, by using Apple's private API (i think BluetoothManger.h), but be careful , it will cause rejection in the Apple App Store push.
I second the notion of using Apple's reachability. As a bonus it's listed as one of the Apple App Store submission guidelines.
It's not that hard to implement either as much of the code needed is already written for you.
Slf provided a link to some source code using the Reachability class, additionally here's a link to Apple Dev's official reachability example.
However, make sure you are checking for connectability asynchronously.
I'm using it in my app and although it isn't the best solution at least it notifies the user that he/she needs to adjust the connection settings or that no networks exist.
You should use the same sessionID.

Problem with applicationShouldTerminate on iPhone

I'm having a problem with applicationShouldTerminate.
What ever I do it seams that has no effect. Any help would be
appreciated.
I'm well versed in programing but this just gives me headache. Im going
over some basic tutorials for xcode , as I'm new to mac in general, and am currently looking at a simple flashlight app.
It exists but I would like to add a alert box here with option not to
quit.
(void)applicationWillTerminate:(UIApplication *)application
{
[application setIdleTimerDisabled:NO];
}
this has no effect, alert is closed even before its created.
(void)applicationWillTerminate:(UIApplication *)application
{
[application setIdleTimerDisabled:NO];
UIAlertView *alertTest = [[UIAlertView alloc]
initWithTitle:#"This is a Test"
message:#"This is the message contained
with a UIAlertView"
delegate:self
cancelButtonTitle:#"Button #1"
otherButtonTitles:nil];
[alertTest addButtonWithTitle:#"Button #2"];
[alertTest show];
[alertTest autorelease];
NSLog(#"Termination");
}
I did some reading online and found that it should be possible to do
this with
(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender
But no mater where I put that declaration I get error: syntax error
before NSApplicationTerminateReply.
There is no syntax error except that xcode seems not to recognize
NSApplicationTerminateReply as valid input.
Any sample code would be greatly appreciated.
I know this is a non-answer, but hopefully I can be helpful:
Displaying a "Really quit?"-type alert like this, even if you can pull it off technically (and I'm not sure you can), is a bad idea and is likely to either cause rejection from the App Store or, at best, an inconsistent user experience because no other apps do this.
The convention with iPhone apps is to save state if necessary, then yield control (for termination) as quickly as possible when the user hits the home button or switches apps.
To ensure a consistent experience, Apple probably has an aggressive timer in place to restrict what you can do in applicationWillTerminate. And even if they don't have a technical measure in place, they probably have an App Store approval policy to ensure that applications quit immediately when they're asked to.
applicationShouldTerminate and NSApplication do not exist on the iPhone. You have to use UIApplication.
The alert view is never shown because the 'show' method does not block, and therefore, the end of 'applicationWillTerminate' is reached immediately after you create the alert view and try to show it. I believe this is by design. You can't really begin asynchronous operations in 'applicationWillTerminate'.
With regards to the applicationShouldTerminate error, in case anyone's curious, NSApplicationTerminateReply and NSApplication seem to be deprecated...even though the OP's method is exactly how it appears in the docs!
Defining your method as the below should build with no errors:
-(BOOL)applicationShouldTerminate :(UIApplication *)application
I think I found the answer to what I wanted to do but will need to check it when I get back home.
Some directions were found here
http://blog.minus-zero.org/
The iPhone 2.0 software was recently released, and with it came the
ability for users to download native apps (i.e., not web sites)
directly to their phones from within the iPhone UI or via iTunes.
Developers (anyone who pays Apple 59GBP for the privilege) can then
write their own apps and have them available for purchase in the App
Store.
One limitation of the Apple-sanctioned SDK is that only one
application is allowed to be running at a time. This presents a
problem for apps such as IM clients, music players and other programs
whose functionality relies on being able to run in the background.
Another example (courtesy of James) would be an app that takes
advantage of the iPhone 3G's GPS chip to create a log of all the
places you visit.
However, there is a neat trick that I discovered: your app will only
get terminated if you switch away from it, and hitting the iPhone's
power button while your app is in the foreground doesn't count as
switching away. The upshot of this is you can create apps which
continue to run while the iPhone is in your pocket - perfect for the
GPS example.
Achieving this is as simple as implementing two methods in your
UIApplication delegate - applicationWillResignActive: and
applicationDidBecomeActive:. Here's a simple example to demonstrate
the effect.
In your UIApplication delegate header file, add a new ivar: BOOL
activeApp. Then, in your implementation, add the following three
methods:
- (void)applicationWillResignActive:(UIApplication *)application {
NSLog(#"resigning active status...");
activeApp = NO;
[self performSelector:#selector(sayHello) withObject:nil afterDelay:1.0];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSLog(#"becoming the active app...");
activeApp = YES;
}
- (void)sayHello {
NSLog(#"Hello!");
if (!activeApp)
[self performSelector:#selector(sayHello) withObject:nil afterDelay:1.0];
}