1

内部APIを使用してサーバーからデータを取得しています。これを実現するために基本認証を使用しています。APIの性質上、サーバーコードにセッションなどを実装していないため、すべてのリクエストでユーザー名とパスワードを送信しています。

このため、使用しているすべてのビューコントローラにNSURLConnectionデリゲートを実装したくありません。そこで、NSObjectを拡張するヘルパークラスを作成し、NSURLConnectionDelegateとして設定しました。

@interface HandlerClass : NSObject <NSURLConnectionDelegate>

私は必要なすべてのメソッドを実装しました、そして私はそれを次のように呼んでいます:

NSURL *URL = [NSURL URLWithString:@"https://url/ifuser/"];
NSLog(@"Connection ");

NSURLRequest *request = [NSURLRequest requestWithURL:URL
                                         cachePolicy:NSURLRequestReloadIgnoringCacheData
                                     timeoutInterval:30.0];

NSHTTPURLResponse *response;

HandlerClass *cc = [[HandlerClass alloc] init];

cc.username = self.username.text;
cc.password = self.password.text;

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:cc];

しかし、何をしようとしても、そのデリゲートからのデータ応答データに到達できません。

私は文字通り、stackoverflowと他のサイトの両方を含め、インターネットで書かれたすべての文章を読み込もうとしました。これのすべてのソリューションは認証を必要としません。

しかし、私は認証付きのソリューションのみが必要です。

ありがとう。

~~~~~~~~~~~~~~~~~~~~~~~~~

編集:私はいくつかの冗長なエラーをしたことを知っています。しかし、私は何が悪かったのかを理解することができました。目標を達成するには、NSRunLoopを使用する必要がありました。皆さんありがとう。

4

2 に答える 2

1

これが私がしたことです。記事を参照しました: Cocoa Touch で NSURLRequest を使用した基本認証 、同期要求を使用します。ここでは、リクエストに非同期が使用されます。

ConnectionHandler.h

#import <Foundation/Foundation.h>

@interface ConnectionHandler : NSObject<NSURLConnectionDataDelegate>

@property(nonatomic, retain) NSString *username;
@property(nonatomic, retain) NSString *password;

- (void)start;

@end

ConnectionHandler.m で

#import "ConnectionHandler.h"
#import "Base64.h"
@interface ConnectionHandler()
{
    NSMutableData *receivedData;
    NSURLConnection *connection;
}
@end
@implementation ConnectionHandler

- (id)init
{
    self = [super init];
    if (self) {
        receivedData = [[NSMutableData alloc] init];
    }
    return self;
}

- (void)start
{
    NSURL *url = [NSURL URLWithString:@"http://192.168.1.103/~will/"];

    NSError *myError = nil;

    // create a plaintext string in the format username:password
    NSMutableString *loginString = (NSMutableString*)[@"" stringByAppendingFormat:@"%@:%@", self.username, self.password];

    // employ the Base64 encoding above to encode the authentication tokens
    NSString *encodedLoginData = [Base64 encode:[loginString dataUsingEncoding:NSUTF8StringEncoding]];

    // create the contents of the header
    NSString *authHeader = [@"Basic " stringByAppendingFormat:@"%@", encodedLoginData];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: url
                                                       cachePolicy: NSURLRequestReloadIgnoringCacheData
                                                   timeoutInterval: 3];

    // add the header to the request.  Here's the $$$!!!
    [request addValue:authHeader forHTTPHeaderField:@"Authorization"];

    // perform the reqeust
    NSURLResponse *response;

    connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [connection start];

}

//a simple request may receive several response, when a new response receive, the previous received should be reset.
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [receivedData setLength:0];
}
//a connection may receive data several time, append the received data to existing data
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [receivedData appendData:data];
}


- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    connection = nil;
    receivedData = nil;

    NSLog(@"Connection failed! Error - %@ %@",
      [error localizedDescription],
      [[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
}


- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{

    NSLog(@"succeeded  %d byte received",[receivedData length]);
    receivedData = nil;
    connection = nil;
}
@end

Base64.m

#import "Base64.h"

static char *alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

@implementation Base64

+(NSString *)encode:(NSData *)plainText {
    int encodedLength = (4 * (([plainText length] / 3) + (1 - (3 - ([plainText length] % 3)) / 3))) + 1;
    unsigned char *outputBuffer = malloc(encodedLength);
    unsigned char *inputBuffer = (unsigned char *)[plainText bytes];

    NSInteger i;
    NSInteger j = 0;
    int remain;

    for(i = 0; i < [plainText length]; i += 3) {
        remain = [plainText length] - i;

        outputBuffer[j++] = alphabet[(inputBuffer[i] & 0xFC) >> 2];
        outputBuffer[j++] = alphabet[((inputBuffer[i] & 0x03) << 4) |
                                 ((remain > 1) ? ((inputBuffer[i + 1] & 0xF0) >> 4): 0)];

        if(remain > 1)
            outputBuffer[j++] = alphabet[((inputBuffer[i + 1] & 0x0F) << 2)
                                     | ((remain > 2) ? ((inputBuffer[i + 2] & 0xC0) >> 6) : 0)];
        else
            outputBuffer[j++] = '=';

        if(remain > 2)
            outputBuffer[j++] = alphabet[inputBuffer[i + 2] & 0x3F];
        else
            outputBuffer[j++] = '=';
    }

    outputBuffer[j] = 0;

    NSString *result = [NSString stringWithCString:outputBuffer length:strlen(outputBuffer)];
    free(outputBuffer);

    return result;
}

@end

ビューコントローラーで

- (void)viewDidLoad
{
    [super viewDidLoad];
    ConnectionHandler *connectionHandler = [[ConnectionHandler alloc] init];
    connectionHandler.username = @"username";
    connectionHandler.password = @"password";
    [connectionHandler start];

}
于 2013-02-10T16:21:36.123 に答える