views:

707

answers:

3

I am using NSURLConnection to make connections to a server, through a proxy that requires authentication this fails. The proxy settings are set under the WiFi, but the connection still fails. I believe there is a part of CFNetwork that can fix this, but this might be just for streams and I am unsure of how to implement it with NSURLConnection. How can I tell my application to use the proxy settings set under WiFi?

A: 

The solution is to use the delegate method

-(void)connection:(NSURLConnection *)connection
    didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
woody993
A: 

woody993, could you share some info on how to get proxy credentials from WiFi settings? I am experiencing the same problem.

I am trying to use NSURLCredentialsStorage in order to retrieve credentials, but it seems empty at all!

oradyvan
+1  A: 

oradyvan, Apple does not provide access to the credentials set under the WiFi settings therefore you are required to ask the user. This is the code I use to ask them.

The XIB contains a UITableView with dataSource and delegate connected to File's Owner. A UINavigationBar with two UIBarButtonItems, Cancel and Login with their Sent Actions connected to -CancelAction and -LoginAction respectively, are also in the view.

NSProxyView.xib:

alt text

NSProxyView.h:

#import <UIKit/UIKit.h>


@interface NSProxyView : UIViewController <UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate> {
    NSURLAuthenticationChallenge *_challenge;

    UITextField *usernameField;
    UITextField *passwordField;
}

- (id)initWithAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
- (IBAction)CancelAction;
- (IBAction)LoginAction;
- (void)ProcessAuth;

@property (nonatomic, retain) NSURLAuthenticationChallenge *_challenge;

@end

NSProxyView.m:

#import "NSProxyView.h"


@implementation NSProxyView

@synthesize _challenge;

- (id)initWithAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    if (self = [super initWithNibName:@"NSProxyView" bundle:[NSBundle mainBundle]]) {
        _challenge = challenge;
    }
    return self;
}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];

    usernameField = [[UITextField alloc] init];
    usernameField.delegate = self;
    usernameField.borderStyle = UITextBorderStyleNone;
    usernameField.frame = CGRectMake(100, 12, 200, 23);
    usernameField.backgroundColor = [UIColor clearColor];
    usernameField.autocorrectionType = UITextAutocorrectionTypeNo;
    usernameField.autocapitalizationType = UITextAutocapitalizationTypeNone;
    usernameField.returnKeyType = UIReturnKeyNext;

    passwordField = [[UITextField alloc] init];
    passwordField.delegate = self;
    passwordField.borderStyle = usernameField.borderStyle;
    passwordField.frame = usernameField.frame;
    passwordField.backgroundColor = usernameField.backgroundColor;
    passwordField.autocorrectionType = usernameField.autocorrectionType;
    passwordField.autocapitalizationType = usernameField.autocapitalizationType;
    passwordField.returnKeyType = UIReturnKeyDone;
    passwordField.secureTextEntry = YES;
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    if (textField == usernameField) {
        [passwordField becomeFirstResponder];
        return YES;
    }
    [self ProcessAuth];
    return YES;
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [usernameField becomeFirstResponder];
}

- (IBAction)CancelAction {
    [[self._challenge sender] cancelAuthenticationChallenge:self._challenge];
    [self dismissModalViewControllerAnimated:YES];
}

- (IBAction)LoginAction {
    [self ProcessAuth];
}

- (void)ProcessAuth {
    [[self._challenge sender] useCredential:[NSURLCredential credentialWithUser:[usernameField text] password:[passwordField text] persistence:NSURLCredentialPersistencePermanent] forAuthenticationChallenge:self._challenge];
    [self dismissModalViewControllerAnimated:YES];
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    tableView.tableHeaderView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 45)] autorelease];
    return 1;
}

// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 2;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    cell.textLabel.font = [UIFont boldSystemFontOfSize:14.0];
    switch (indexPath.row) {
        case 0:
            cell.textLabel.text = @"Username";
            [cell addSubview:usernameField];
            break;
        case 1:
            cell.textLabel.text = @"Password";
            [cell addSubview:passwordField];
            break;
    }

    // Configure the cell.
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
    switch (indexPath.row) {
        case 0:
            [usernameField becomeFirstResponder];
            break;
        case 1:
            [passwordField becomeFirstResponder];
            break;
    }
}

- (void)dealloc {
    [usernameField release];
    [passwordField release];
    [super dealloc];
}
woody993
don't you need a `[challenge retain]` inside `initWithAuthenticationChallenge:`?
WineSoaked