Dose CoreBluetooth work on IOS6.0,IOS6.1,IOS6.1.2? - core-bluetooth

i am working on bluetooth4.0 , but i found that CoreblueTooth cannot run on iOS 6+,my iphone4s is IOS 6.1.2.
it cannot find any device(i am sure the device is power on), the Log as below every time:
CoreBluetooth[WARNING] is not powered on
Dose anyone have encounter this issue?

The status CBCentralManagerStatePoweredOn means not only that Bluetooth is turned on, but also that your instance of CBCentralManager or CBPeripheralManager is ready to use. You must initialize your manager, then wait for its state to change before using it. For example, if you are acting as a Central, you would initialize it with the following:
centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
And implement the delegate method centralManagerDidUpdateState:
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
if (central.state == CBCentralManagerPoweredOn)
{
//do your stuff, it's ready
}
}

I'm testing on a iPhone 4S running 6.0.1. The iPhone is in central role and I don't see your warning.
Can you please be more specific about what you're doing?
- Are you in peripheral or central role?
Have you initialized the CBCentralManager (if you're a central) as follows?
centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()];
I hope I could help you

Related

NSNetService says it is published, but it isn't visible on the network

I'm working on a little iOS app for my own use (initially, at least) and I thought I would use Bonjour to configure networking between two iOS devices.
My server's interface defines
NSNetService *netService;
and the implementation uses the following code to advertise its existence:
const NSString *kSEBonjourServiceDomain = #""; //use defaults
const NSString *kSEBonjourServiceName = #"_test._tcp.";
//...
netService = [[NSNetService alloc] initWithDomain:(NSString *)kSEBonjourServiceDomain type:(NSString *)kSEBonjourServiceName name:#"" port:sin.sin_port];
if (netService)
{
netService.delegate = self;
netService.includesPeerToPeer = YES;
[netService publish];
}
else NSLog(#"Failed to create NSNetService");
When I start the server, my NSNetService object does call the -netServiceDidPublish: delegate method, but when I use Discovery to browse the bonjour services on my network, my service doesn't appear. Apart from the const strings, this code is the same as some code in one of my Mac apps (which works as expected) and also very similar to Apple's sample code.
I've gone through all the options in Xcode's capabilities tab in case I needed to add something there, but I can't see anything relevant. I've also read a bunch of documents and tutorials that don't mention having to do anything more than that, but it wouldn't surprise me to learn that this only works on iOS if you set an obscure build setting to a string that you had to learn about by reading the Human Interface Guidelines for watchOS last September.
So, can anyone enlighten me? What am I missing?
Thanks in advance!
It turned out that due to a silly error elsewhere in my code, sin.sin_port was set to 0 by the time I was registering my NSNetService. Although NSNetService doesn't see this as a problem, it was causing the service to be ignored by service browsers.
So the answer is, a service with a port of 0 will register without error, but won't work.
Thanks to gaige for the assistance.

sessionWithConfiguration: delegate: delegateQueue: working in simulator but not in device

I am downloading multiple audio files using background transfer service, everything was working as expected till yesterday. Now when I run the project it stuck on the second line of following lines -
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:#"com.example.myapp"];
session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil]; //Did not return anything
I have downloaded multiple demo apps but they also stuck on the same line, although they are working as expected in simulator as well as for "defaultSessionConfiguration" in device.
What could be the problem then?
Thanks for any help

didDiscoverPeripheral is not called after upgrading from iOS 7 to iOS 8

I am calling scanForPeripheralsWithServices from didFinishLaunchingWithOptions callback of AppDelegate. The code looks like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSLog(#"didFinishLaunchingWithOptions");
// Override point for customization after application launch.
cm = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
[cm scanForPeripheralsWithServices:nil
options:nil];
}
- (void) centralManager:(CBCentralManager*)central didDiscoverPeripheral:(CBPeripheral*)peripheral advertisementData:(NSDictionary*)advertisementData RSSI:(NSNumber*)RSSI{
NSLog(#"Did discover peripheral %#", peripheral.name);
[cm stopScan];
}
Before upgrading to iOS 8 everything was working well, however after the upgrade (exactly the same code, no single line was changed) I am not getting any error, but also didDiscoverPeripheral is not being called.
I appears that the major change which has occurred with Core Bluetooth in iOS 8 is that the BLE stack isn't powered on until you try to connect (or possible issue some other command).
CBCentralManager *cbCentralManager;
[cbCentralManager scanForPeripheralsWithServices:...];
This call used to issue a warning visible in the Xcode debug log saying that the central manager needed to be powered-up before it could be used. However, this warning was always a catch-22 — the only way to power-on the central manager was to send it a message, and the only way for it to process a message was for it to be powered-on.
Apple seems to have resolved this problem by handling power-on a bit differently. Now, after issuing the above command the central manager tells its delegate that its state changed via centralManagerDidUpdateState:.
We resolved the problem you describe by responding to centralManagerDidUpdateState: by re-issuing the scanForPeripherals... message.

Game Center not authenticating using Swift

I'm trying to authenticate the local player using swift, but every time I get a false value for the .authenticated property. Here is the code I'm using, it is called by the main view controller when the app starts.
func authenticateLocalPlayer(){
var localPlayer = GKLocalPlayer()
localPlayer.authenticateHandler = {(viewController, error) -> Void in
if viewController {
self.presentViewController(viewController, animated: true, completion: nil)
}else{
println((GKLocalPlayer().authenticated))
}
}
}
It brings up the log in view just fine, but when I enter a test account login, it just returns the GKLocalPlayer().authenticatedas false. The bundle identifier in iTunes Connect and the info.plist are exactly the same, as is the version and the app name. Everything is enabled for Game Center on iTunes Connect and in Xcode, but I have a feeling it's not a coding error, it's a setup error in the app record somewhere but I can't for the life of me find where.
After further tinkering, I'm getting this error:
Error Domain=GKErrorDomain Code=15 "The requested operation could not be completed because this application is not recognized by Game Center." UserInfo=0x17006b300 {NSLocalizedDescription=The requested operation could not be completed because this application is not recognized by Game Center.}
I have no idea why this is the case, the bundle ID, name and versions all match...
Any help would be greatly appreciated.
This issue has been resolved by Apple - just call:
GKLocalPlayer.localPlayer()
Previously, the issue was that GKLocalPlayer() does not return the GKLocalPlayer singleton, but instead returns a new GKLocalPlayer instance.
If you were on the Xcode 6 BETA, you could add a C function or Objective-C method that returns the real GKLocalPlayer singleton, then use this in Swift. This is the gist of my workaround (with bad naming conventions):
In an Objective-C header:
GKLocalPlayer *getLocalPlayer(void);
In an Objective-C implementation:
GKLocalPlayer *getLocalPlayer(void) {
return [GKLocalPlayer localPlayer];
}
In your bridging header:
#import "ThatHeader.h"
Then whenever you need to access the GKLocalPlayer singleton in Swift, you can just use getLocalPlayer() instead of GKLocalPlayer(). It's probably a better idea to stick that in an method of a GKLocalPlayer category.
However, this is no longer necessary as detailed above.
Even with Xcode 6 Beta 6, on a device using iOS 8 beta 5, making GKLocalPlayer.localPlayer() available, I was still getting the error:
"NSLocalizedDescription=The requested operation could not be completed
because this application is not recognized by Game Centre"
The solution (discovered through Apple's Dev forum) was to go to "Settings" on the device, and then into "Game Centre" and enable "Sandbox" under the developer section.
You can use that, I create a simple class for iOS game center in GitHub
Easy Class Game Center Swift
https://github.com/DaRkD0G/Easy-Game-Center-Swift

GameKit Match - invite friends between iOS5 and iOS6

I'm trying to implement Game Center invites in a 2-person realtime game. Since invites are not supported in the simulator, I'm testing this on one device running iOS5 and a second one running iOS6 (this is done on purpose).
If I'm using the old-fashioned built-in GKMatchmakerViewController UI on either device to initiate the invite, it works fine both ways - when the iOS5 device initiates the invite as well as when the iOS6 device initiates it.
However, in iOS6 I want to use my own UI to select the player to invite, so I'm using GKMatchRequest to programmatically issue the invite, setting the playersToInvite attribute.
The problem is, the other (iOS5) device gets the push notification, launches the application, runs the [GKMatchmaker sharedMatchmaker].inviteHandler, shows the Game Center UI with the invite details, but even when the iOS6 device sends a finishMatchmakingForMatch request - the iOS5 device doesn't proceed any further. No other handler / delegate is called on the iOS5 machine, no GKMatch object is returned, and it continues to show the Game Center UI with both players marked as "Ready" and with a message saying "Waiting for [iOS6 player] to start the game". The only button on this UI is a Cancel button.
Here's the code snippet that sends the invitation on the iOS6 machine:
GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease];
request.minPlayers = 2;
request.maxPlayers = 2;
request.playersToInvite = [NSArray arrayWithObject:playerID];
request.inviteMessage = message;
request.inviteeResponseHandler = ^(NSString *playerID, GKInviteeResponse response)
{
if (response == GKInviteeResponseAccepted)
[[GKMatchmaker sharedMatchmaker] finishMatchmakingForMatch:self.match];
};
[[GKMatchmaker sharedMatchmaker] findMatchForRequest:request withCompletionHandler:^(GKMatch *match, NSError *error)
{
... [whatever]
}];
And here's the code snippet for the invite handler on the iOS5 machine:
[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite)
{
if (acceptedInvite)
{
GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:acceptedInvite] autorelease];
mmvc.matchmakerDelegate = self;
[navController presentModalViewController:mmvc animated:YES];
});
else if (playersToInvite)
{
... [whatever]
}
}
The sequence is as follows:
iOS6 sends a findMatchForRequest request with the iOS5 player id.
A push notification is shown on the iOS5 machine.
The application is launched on the iOS5 machine and the inviteHandler is called.
The GKMatchmakerViewController is shown on the iOS5 machine with the invite details, and the iOS6 user has a spinning "Connecting" status.
The inviteeResponseHandler on the iOS6 machine is called and sends a finishMatchmakingForMatch request.
The status of the iOS6 user in the iOS5 Game Center screen changes from spinning "Connecting" to "Ready", and at this point both players are marked as "Ready".
The iOS6 machine gets a match: player: didChangeState: callback, showing the iOS5 player as GKPlayerStateConnected, so as far as the iOS6 machine is concerned the match process is finished and the game can begin.
Nothing whatsoever happens from now on on the iOS5 machine. It is stuck with "Waiting for [iOS6 user] to start the game" until it is cancelled by a timeout. It never receives any GKMatch object at any point, so it cannot start the game.
Since things work fine if I use the standard Game Center UI on the iOS6 machine rather than a programmable invite, it means that the standard UI must do something more to tell the other machine that the game has to start. However, I browsed through all the relevant Game Center objects and couldn't find anything else to send.
I should mention again that the reverse configuration (iOS5 initiating the invite using the standard UI) works fine on both machines.
Help, anyone?
I am having a similar problem. One of the things I did to partially solve is to use programmatic for ios6 users, and viewController for ios5 users. I think you are doing that too but your inviteHandler code only seems to have viewController code. Were you able to fully solve your issue?

Resources