在OS X 10.9配置WebDAV服務器聯合NSURLSessionUploadTask實現文件上傳

iOS7推出的NSURLSession簡化了NSURLConnection的文件上傳和下載的工做,本文記錄如何配置WebDAV服務以支持PUT方式的文件上傳。web

一. 配置WebDAV服務器

1. 修改httpd.conf

1> 打開終端,依次輸入:apache

cd /etc/apache2/
sudo vi httpd.conf

2> 在vi中輸入服務器

/httpd-dav.conf

查找httpd-dav.confsession

3> 將該行最前面的 # 註釋刪除ide

4> 保存並退出測試

輸入ui

:wq

2. 修改httpd-dav.conf

1> 在終端中依次輸入:編碼

cd /etc/apache2/extra
sudo vi httpd-dav.conf

2> 按照如下內容修改httpd-dav.conf中的內容url

提示:僅修改了受權類型和用戶密碼文件兩個位置spa

DavLockDB "/usr/var/DavLock"

Alias /uploads "/usr/uploads"

<Directory "/usr/uploads">
    Dav On

    Order Allow,Deny
    Allow from all

    #用戶的受權類型
    AuthType Basic
    AuthName DAV-upload

    # You can use the htdigest program to create the password database:
    #   htdigest -c "/usr/user.passwd" DAV-upload admin
    # 用戶密碼文件
    AuthUserFile "/usr/webdav.passwd"
    AuthDigestProvider file

    # Allow universal read-access, but writes are restricted
    <LimitExcept GET OPTIONS>
        require user admin
    </LimitExcept>
</Directory>

說明:

按照上述配置文件,能夠經過URL->http://localhost/uploads,將文件上傳至/usr/uploads目錄

上傳文件所使用的用戶名是:admin

3> 保存並退出

輸入

:wq

3. 創建文件夾並配置文件

1> 建立admin的密碼,在終端中輸入:

sudo htpasswd -c /usr/webdav.passwd admin

而後輸入admin的密碼,密碼文件會保存在/usr/webdav.passwd中

2> 設置webdav.passwd權限

sudo chgrp www /usr/webdav.passwd

3> 創建var文件夾,以保存DavLockDB相關文件

sudo mkdir -p /usr/var
sudo chown -R www:www /usr/var

 4> 創建上傳文件夾:uploads

sudo mkdir -p /usr/uploads
sudo chown -R www:www /usr/uploads

5> 從新啓動Apache

sudo apachectl -k restart

4. 測試

打開Finder,在菜單中選擇「前往」「鏈接服務器」,在地址欄中輸入:http://localhost/uploads

而後用戶名admin及在終端設置的密碼,鏈接至服務器,並測試更新文件。

 

二. 使用NSURLSessionUploadTask實現文件上傳

- (IBAction)uploadFile
{
    // 要上傳的文件
    UIImage *image = [UIImage imageNamed:@"123.jpg"];
    NSData *imageData = UIImageJPEGRepresentation(image, 1.0f);
    
    // 上傳的文件名
    NSString *urlString = @"http://localhost/uploads/demo.jpg";
    urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
    NSURL *url = [NSURL URLWithString:urlString];
    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url];
    // 使用PUT方法
    [request setHTTPMethod: @"PUT"];
    
    // 用戶受權
    NSString *basicAuthCredentials = [NSString stringWithFormat:@"%@:%@", @"admin", @"123"];
    NSString *authValue = [NSString stringWithFormat:@"Basic %@", AFBase64EncodedStringFromString(basicAuthCredentials)];
    [request setValue:authValue forHTTPHeaderField:@"Authorization"];

    [request setHTTPBody: imageData];
    [request setValue:@"image/jpg" forHTTPHeaderField:@"Content-Type"];
    [request setValue:[NSString stringWithFormat:@"%d", [imageData length]] forHTTPHeaderField:@"Content-Length"];
    
    // URLSession
    NSURLSession *session = [NSURLSession sharedSession];
    // 上傳任務
    NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromData:imageData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        
        if (!data) {
            NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"%@ %@", result, response);
        } else {
            NSLog(@"upload ok!");
        }
    }];
    
    [task resume];
}

另外,還須要一個對字符串進行Base64編碼的方法,代碼以下:

static NSString *AFBase64EncodedStringFromString(NSString *string)
{
    NSData *data = [NSData dataWithBytes:[string UTF8String] length:[string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
    NSUInteger length = [data length];
    NSMutableData *mutableData = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
    
    uint8_t *input = (uint8_t *)[data bytes];
    uint8_t *output = (uint8_t *)[mutableData mutableBytes];
    
    for (NSUInteger i = 0; i < length; i += 3) {
        NSUInteger value = 0;
        for (NSUInteger j = i; j < (i + 3); j++) {
            value <<= 8;
            if (j < length) {
                value |= (0xFF & input[j]);
            }
        }
        
        static uint8_t const kAFBase64EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        
        NSUInteger idx = (i / 3) * 4;
        output[idx + 0] = kAFBase64EncodingTable[(value >> 18) & 0x3F];
        output[idx + 1] = kAFBase64EncodingTable[(value >> 12) & 0x3F];
        output[idx + 2] = (i + 1) < length ? kAFBase64EncodingTable[(value >> 6)  & 0x3F] : '=';
        output[idx + 3] = (i + 2) < length ? kAFBase64EncodingTable[(value >> 0)  & 0x3F] : '=';
    }
    
    return [[NSString alloc] initWithData:mutableData encoding:NSASCIIStringEncoding];
}
相關文章
相關標籤/搜索