How to connect two iPhone using corebluetooth? - iphone

Can i connect two idevice using core bluetooth framework?I am using following code snippet:
cBCM = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
[cBCM scanForPeripheralsWithServices:nil options:nil];
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
}
but the delegates are not firing at all. any solution?

Instead of trying to fire didDiscoverCharacteristicsForService you should try the didDiscoverPeripheral which will fire on all periperals. The didDiscoverChar... will only trigger if you have found a specific characteristic within the peripherals properties.
When didDiscover... triggers you can try printing out it's name by
// Discovered peripheral
- (void) centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI
{
// Print out the name parameter of the discovered peripheral
#NSSlog ("Discovered peripheral: %#", [peripheral name];
}

Related

setDefaultCredential not working for UIWebView in iOS 7 but works fine in earlier iOS versions

I am currently using the following code to set default credentials for UIWebView. This works fine in iOS 6.1 and earlier. However, in iOS 7 Beta 6 it does not work at all.
The web pages that I am trying to load use Windows Authentication. I am able to open them in Safari in iOS 7. However, when I run the below code and then open the URL in a UIWebView, I get an empty white rectangle and nothing ever loads! Like I said, this works perfectly in iOS 6.1 and earlier.
I also tried a second approach that involves using NSURLConnectionDelegate to hand off the credentials. This second approach also works fine in iOS 6.1 and earlier, but is broken in iOS 7.
Does anyone know why this is happening? Similar experiences? Thoughts?
// Authenticate
NSURLCredential *credential = [NSURLCredential credentialWithUser:#"myusername"
password:#"mypassword"
persistence:NSURLCredentialPersistenceForSession];
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]
initWithHost:#"mysite.com"
port:80
protocol:#"http"
realm:nil
authenticationMethod:NSURLAuthenticationMethodDefault];
[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential forProtectionSpace:protectionSpace];
I had the same exact issue - an NSURLConnection to a Sharepoint site configured for Windows Authentication was working fine in iOS 6.1. In iOS 7 - regardless of whether I targeted and built the app for 6 or 7 - all authentications would seem to succeed (receiving the proper cookie) but still respond with a 401; all subsequent requests sent with the cookie would receive 401 as well.
I resolved the issue by dumping the didReceiveAuthenticationChallenge delegate protocol in favor of willSendRequestForAuthenticationChallenge. Implementing the 2nd delegate protocol means the first never gets called.
In your delegate, implement this delegate protocol:
- (void)connection:(NSURLConnection *)sender willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge previousFailureCount] > 0]) {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}else{
NSURLCredential *credential = [NSURLCredential credentialWithUser:#"username" password:#"password" persistence:NSURLPersistenceForSession];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
}
After I implemented this on a whim, my iOS 7 NTLM authentication issues disappeared.
Update: This issue appears to be fixed in iOS 7.0.3
I answered this in the Apple developer forum, but now that iOS7 is out of beta, I'll repost here. Currently Windows Authentication is broken in iOS7. I expect there will be a fix out shortly, but until then you can work around the problem by handling authentication challenges in your UIViewController that contains your UIWebView.
Essentially you
Make an NSURLRequest and NSURLConnection yourself
Handle the connection:didReceiveAuthenticationChallenge:
In the connection:didReceivedResponse manually load your data into the UIWebView
Below I'm loading a PDF, but the process works the same whatever your content type.
//Make sure you implement NSURLConnectionDelegate and NSURLConnectionDataDelegate in your header
#interface MyViewController ()
#property (weak, nonatomic) IBOutlet UIWebView *webView;
#property (strong, nonatomic) NSURLConnection *conn;
#property (strong, nonatomic) NSMutableData *pdfData;
#end
#implementation MyViewController
//... all of your init and other standard UIViewController methods here...
//Method that loads UIWebview. You'll probably call this in viewDidLoad or somewhere similar...
- (void) loadWebView {
//Make Request manually with an NSURLConnection...
NSString *url = //Get your url
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
self.conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
//#pragma mark - NSURLConnectionDelegate
//Handle authentication challenge (NSURLConnectionDelegate)
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
if([challenge previousFailureCount] == 0) {
NSString *username = //Get username
NSString *password = //Get password
//Use credentials to authenticate
NSURLCredential *cred = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistencePermanent];
[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
} else {
//Cancel authentication & connection
[[challenge sender] cancelAuthenticationChallenge:challenge];
[self.conn cancel];
self.conn = nil;
}
}
//#pragma mark - NSURLConnectionDataDelegate
//Received response (NSURLConnectionDataDelegate)
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
//Init data
self.pdfData = [NSMutableData data];
}
//Collect data as it comes in (NSURLConnectionDataDelegate)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.pdfData appendData:data];
}
//Handle connection failure (NSURLConnectionDataDelegate)
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
//Clean up...
[self.conn cancel];
self.conn = nil;
self.pdfData = nil;
//TODO: Notify user and offer next step...
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
//Finally, load data into UIWebview here (I'm loading a PDF)...
[self.webView loadData:self.pdfData MIMEType:#"application/pdf" textEncodingName:#"utf-8" baseURL:nil];
}
#end

Application Freezing when calling CocoaAsyncMethod scheduleDequeueRead

I'm using CocoaAsyncSocket library to create a TCP socket connection. The problem I'm having is after a few library methods are called, I'm getting an error.
appDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
socket = [[AsyncSocket alloc] initWithDelegate:self];
NSError *error = nil;
if (![socket connectToHost:#"199.5.83.63" onPort:11005 error:&error])
{
NSLog(#"Error connecting: %#", error);
}
[socket readDataWithTimeout:10 tag:1];
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
self.viewController = [[[tekMatrixViewController alloc] initWithNibName:#"tekMatrixViewController" bundle:nil] autorelease];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
And here are my methods from the CocoaAsyncSocket Library:
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
NSData *strData = [data subdataWithRange:NSMakeRange(0, [data length])];
NSString *msg = [[NSString alloc] initWithData:strData encoding:NSUTF8StringEncoding];
NSLog(#"RX length: %d", [data length]);
if(msg)
{
NSLog(#"RX:%#",msg);
}
else
{
NSLog(#"Fail");
}
}
- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
NSLog(#"error - disconnecting");
//start reconnecting procedure here...
}
- (void)onSocketDidDisconnect:(AsyncSocket *)sock
{
NSLog(#"disconnected");
}
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
NSLog(#"connected");
}
When I run my app in the simulator, this is what my output log spits out:
2012-06-08 13:17:30.808 tekMatrix[2793:f803] connected
2012-06-08 13:17:30.815 tekMatrix[2793:f803] RX length: 8
2012-06-08 13:17:30.816 tekMatrix[2793:f803] Fail
After that, I get an error in the AsyncSocket.m file (part of library) in this method:
- (void)scheduleDequeueRead
{
if((theFlags & kDequeueReadScheduled) == 0)
{
theFlags |= kDequeueReadScheduled;
[self performSelector:#selector(maybeDequeueRead) withObject:nil afterDelay:0 inModes:theRunLoopModes];
}
}
Specifically, the error is on line:
[self performSelector:#selector(maybeDequeueRead) withObject:nil afterDelay:0 inModes:theRunLoopModes];
And the exception is: Thread 1: BAD_EXC_ACCESS (code 1=0, address=0xd0688b8a)
After that, the app is completely frozen in the simulator. If anybody could offer some insight as to why this is causing the app to freeze, I would really appreciate it.
Here is the library I'm using: CocoaAsyncSocket
EDIT:
After Enabling Zombie Objects and running the app in the simulator, this is spit out in the output:
2012-06-08 14:53:15.416 tekMatrix[3217:f803] *** -[__NSArrayI count]: message sent to deallocated instance 0x6d10a70
I'll have to do a little digging on this and figure out what's happening.
EDIT 2:
After a little digging using instruments, I found out the following:
An Objective-C message was sent to a deallocated object (zombie) at address: 0x6b8bb10.
EDIT 3:
Now the error reads:
Thread 1: EXC_BREAKPOINT(code=EXC_I386_BPT, subcode=0x0)
Here is a screenshot from instruments. I'm not really following how to interpret this, though. It looks like I'm sending a message to an object that has been deallocated. Is this true? If so, how do I go about figuring out where this occurs?
If the image is hard to see, here's a direct link: Instruments Screenshot
You are trying to access a object, that doesnt exsits anymore. Probably you are under-retaining/over-releasing it.
see this answer for a tool to find such objects: How do I set up NSZombieEnabled in Xcode 4?
I know it's way after the fact, but I just had this same exact problem. The solution was adding the ARC flag to AsyncSocket.m, -fobjc-arc
:)

Delegate not working (Restkit related?)

I'm just getting started with Objective C and Restkit
I created a sample application and added the RKRequestDelegate in MyAppDelegate file
#interface MyAppDelegate : NSObject <UIApplicationDelegate, RKRequestDelegate> {…
and added
RKClient* client = [RKClient clientWithBaseURL:#"http://localhost:3000"];
NSLog(#"I am your RKClient singleton : %#", [RKClient sharedClient]);
[client get:#"/titles.json" delegate:self];
to MyAppDelegate.m in the
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method
I also added a method to MyAppDelegate.m
- (void) request: (RKRequest *) request didLoadResponse: (RKResponse *) response {
if ([request isGET]) {
NSLog (#"Retrieved : %#", [response bodyAsString]);
}
}
so far so good everything is working and I see the results from my Rails app in the output!!!
As those things don't belong into MyAppDelegate.m I'm moving that stuff into my models. In my Titles.h I added
#interface Titles : NSManagedObject <RKRequestDelegate> {
and in Titles.m I added
+ (void) update {
[[RKClient sharedClient] get:#"/titles.json" delegate:self];
}
and
- (void) request: (RKRequest *) request didLoadResponse: (RKResponse *) response {
if ([request isGET]) {
NSLog (#"Retrieved : %#", [response bodyAsString]);
}
}
In my MyAppDelegate.m I replaced :
RKClient* client = [RKClient clientWithBaseURL:#"http://localhost:3000"];
NSLog(#"I am your RKClient singleton : %#", [RKClient sharedClient]);
[client get:#"/titles.json" delegate:self];
with
RKClient* client = [RKClient clientWithBaseURL:#"http://localhost:3000"];
NSLog(#"I am your RKClient singleton : %#", [RKClient sharedClient]);
[Titles update];
when I run now I don't get any output.
I put several breakpoints, one in the - (void)didFinishLoad:(RKResponse*)response in the RKRequest file
and there the if test for :
if ([_delegate respondsToSelector:#selector(request:didLoadResponse:)]) {
[_delegate request:self didLoadResponse:finalResponse];
}
fails while it succeeds in my first attempt (when everything is in MyAppDelegate)
I checked the variable _delate in de debugger and it says: _delegate = MyAppDelegate in my first attempt and _delegate = Titles in my second attempt (both like it should)
Why does that respondsToSelector fail ? (the delegate is correct and the method exists in Titles)
Your problem is that your trying to set a class as the delegate:
+ (void) update {
[[RKClient sharedClient] get:#"/titles.json" delegate:self];
}
self here is the class Titles.
The callback is (as expected), an instance method:
- (void) request: (RKRequest *) request didLoadResponse: (RKResponse *) response {
if ([request isGET]) {
NSLog (#"Retrieved : %#", [response bodyAsString]);
}
}
You should have some kind of "DataModel" model class (perhaps "SongList" or whatever makes sense). This is often a singleton, so you have a +sharedModel instance. That instance is what is the delegate for RKClient.

iphone uiwebview authentication challenge keeps firing when signed in

i have recently implemented authentication challenge log in through the iPhones UIWebView. i've got it working to the point where i get challenged then i present an alert with text fields, then send the data to the site that needs authentication.
i have not yet tried to use this on anything else besides my netgear router. But my problem is when i navigate through the settings for the router, the authentication challenge gets called, thus presenting the alert even though the user is logged in.
below is the code i'm using, any advice would be grately appreciated
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(#"Did start loading: %# auth:%d", [[request URL] absoluteString], _authed);
myRequest=[request copy];
if (_authed) {
NSLog(#"_authed");
_authed = NO;
// pretty sure i'm leaking here, leave me alone... i just happen to leak sometimes
[[NSURLConnection alloc] initWithRequest:request delegate:self];
return YES;
}
[[NSURLConnection alloc] initWithRequest:request delegate:self];
return YES;}
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
NSLog(#"protection space %#", protectionSpace.authenticationMethod);
//if(![protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodDefault]){
return NO;
//}
//else{
// return YES;
//}
//[protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust] || [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic];}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;{NSLog(#"received response via nsurlconnection %#", connection);
NSLog(#"got auth challange %#", challenge);
UIApplication* app = [UIApplication sharedApplication];
app.networkActivityIndicatorVisible = NO;
/*NSString *aarrgghh=[NSString stringWithFormat:#"%#",connection];
NSString *searchForMe = #"login";
NSLog (#"arrgghhh %#",aarrgghh);
NSRange range = [aarrgghh rangeOfString:searchForMe];*/
if ([challenge previousFailureCount] <=1) {
//present alert with text fields for credentials
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}}
-(void)connection:(NSURLConnection *)connection didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{
NSLog(#"Challenge cancelled");}
//`-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
NSLog(#"received data");
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;{
NSLog(#"received response via nsurlconnection %#", response);
// THIS IS WHERE YOU SET MAKE THE NEW REQUEST TO UIWebView, which will use the new saved auth info
if(_authed){
//NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:self.webView.request.URL.absoluteString]];
[webView loadRequest:myRequest];
}
}
`
Might be a simpler way to do this, but this is what worked for me.
First off, when shouldStartLoadWithRequest returns YES, that tells UIWebView to create NSURLConnections and run them for you . Since you can't assign a delegate to this connection, that's not going to work. If you want to handle authentication via a NSURLConnectionDelegate, then shouldStartLoadWithRequest should always return NO for that UIWebView.
So you need to handle the connection yourself. Fire off an NSURLConnection with the request and use the rest of the NSURLConnection delegate methods to handle the loading (e.g. keep track of the MIME type and build up an NSMutableData)
Finally, when you get to connectionDidFinishLoading, you can call UIWebView's loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)textEncodingName baseURL:(NSURL *)baseURL with the NSData your connection downloaded.

Multiple NSURLConnection & NSRunLoop

I am trying to speed up my application download speed. I used Asynchronous NSURLConnection to download contents from the server, it was working fine with one connection.
I use the code from this post to implement multiple delegate objects. Multiple NSURLConnection delegates in Objective-C
When I created 2 NSURLConnection objects, each one is trying to download different files.
The callback didReceiveData routine was called but the it only received data of the first NSURLConnection object until the first connection was done then it started to receive the data from the second NSURLConnection. I want these two connections to receive data at the same time,what should I do? Here is my current code.
-(IBAction) startDownloadClicked :(id) sender
{
while (bDownloading)
{
int nCurrentCon = 0;
while (nCurrentCon < 2)
{
[self downloadAFile:[filenameArray objectAtIndex:nCurrentCon]];
nCurrentCon++;
}
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
}
}
- (void) downloadAFile: (NSString*) filename
{
NSString* urlstr = #"ftp://myftpusername:password#hostname";
NSURLRequest* myreq = [NSURLRequest requestWithURL:[NSURL URLWithString:urlstr]];
DownloadDelegate* dd = [[DownloadDelegate alloc] init]; //create delegate object
MyURLConnection* myConnection = [[MyURLConnection alloc] initWithRequest:myreq delegate:dd
startImmediately:YES];
}
Then in my Delegate Object, I implemented these routines
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[receiveBuffer setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(#"receiving data for %#", targetFileName); //the file name were set when this delegate object is initialized.
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"Download Failed with Error - %# %#",
[error localizedDescription],
[[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"File %# - downloaded.", targetFileName);
}
Your code looks okay. I have a similar setup that works successfully (although there seems to be a limit of four concurrent conections).
The main difference between your and my code is that you use FTP while I use HTTP. Why don't you try it with HTTP connections just to see whether you have run into a restriction of FTP connections on the iPhone?