2011/07/21

Django初體驗

Web開發技術真是越來越強大了,一段時間沒碰就跟不上了,此時我的技術力還停留在ASP.Net 2.0與純PHP的時代... 快速開發與MVC架構似乎是framework的最大訴求,最近碰到要寫網頁,在想要選擇什麼走什麼路好,雖然有些許PHP底子,但最後是擔心PHP framework performance的問題,選擇了Python Django,開啟新的學習旅程~

第一步:Quick Start 照著做一次

第二步:了解MTV概念與專案內的manage.py settings.py urls.py各是做什麼用的

第三步:



Oh no! 遇到一些麻煩...
django-nonrel是用來補足Django NoSQL這一塊,目前支援的NoSQL有 MongoDB, ElasticSearch, Cassandra,但Amazon SimpleDB還沒完成阿!只好被迫放棄. (雖然說有找到 boto - Python interface to Amazon Web Services 提供了SimpleDB的存取方式,但就用不到ORM的特性了)


沒想到初體驗這麼快就結束了...

2011/07/19

透過NSURLConnection和NSMutableURLRequest上傳/POST一個檔案

直接來看code
NSURLConnection *conn;
NSMutableData *tempData;  /* Store response */

- (void)uploadFile {
    NSString *boundary = @"0xKhTmLbOuNdArY";
    NSData *imgData = UIImageJPEGRepresentation(image.image, 90);  /* Image data come from UIImageView */
    NSString *urlString = @"http://my_server/upload.php";
    NSURL *url = [[NSURL alloc]initWithString:urlString];

    /* Set up request */
    NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
    [urlRequest setHTTPMethod:@"POST"];
    [urlRequest setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary] forHTTPHeaderField:@"Content-Type"];

    /* Prepare content part */
    NSMutableData *postData = [NSMutableData dataWithCapacity:[imgData length] + 512];
    [postData appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [postData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"file.bin\"\r\n\r\n", @"image"] dataUsingEncoding:NSUTF8StringEncoding]];
    [postData appendData:imgData];
    [postData appendData: [[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

    /* Assign content part */
    [urlRequest setHTTPBody:postData];

    tempData = [NSMutableData alloc];
    conn = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
}


Prepare 4 delegate
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    [conn release];
    NSLog(@"Error occur");
}

- (void)connection: (NSURLConnection *)connection didReceiveResponse: (NSURLResponse *)aResponse {
    NSInteger status = (NSInteger)[(NSHTTPURLResponse *)aResponse statusCode];
    NSLog(@"%d", status);
}

-(void) connection:(NSURLConnection *)connection didReceiveData: (NSData *) incomingData {
 [tempData appendData:incomingData];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSString *loadData = [[NSMutableString alloc] initWithData:tempData encoding:NSUTF8StringEncoding];    
    NSLog(@"%@", loadData);
}


Server - PHP sample code
<?php 
    if (isset($_FILES["image"]))
    {
        print_r($_FILES["image"]);
    }
?>

參考資料
CocoaDev: HTTPFileUploadSample

2011/07/12

在iPhone上建立HTTP連線(GET/POST)

HTTP Get
Create request
NSString *str = @"http://my_server/get.php?name=brian&gender=male";
NSString *str_enc = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [[NSURL URLWithString:str_enc] retain];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];

Prepare delegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;


HTTP Post
NSString *content = @"name=brian&gender=male";
NSData *postData = [content dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
 
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:@"http://my_server/post.php"]];
[request setHTTPMethod:@"POST"];

/* Header */
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];

/* Content */
[request setHTTPBody:postData];

connect = [[NSURLConnection alloc] initWithRequest:request delegate:self];
// 跟GET一樣設定4組delegate去接response

參考資料

2011/07/07

架設 Apple Push Notification Provider Server

參考下列兩篇教學


針對製作pem的地方我再加強解說(這邊我搞超久的)。
延續上一篇Apple Push Notification Service - 推播服務,此時你手上會有下列東西:

  • CertificateSigningRequest.certSigningRequest (憑證申請書)
  • aps_development.cer (憑證,從Apple下載的)


原文是請你到Keychain Assistant(鑰匙圈存取)去製作apns-dev-cert.p12的檔案,不過我就是沒辦法export出來。還好找到另一個手動解法:HowToCreatePKCS12Certificate

1. 打開"鑰匙圈存取",找到自己的Private Key(專用密鑰),按右建選擇匯出成private_key.p12

2. 將 aps_development.cer 轉換為 aps_development.pem
openssl x509 -in aps_development.cer -inform DER -out aps_development.pem -outform PEM}

3. 將 private_key.p12 轉換為 private_key.pem
openssl pkcs12 -nocerts -out private_key.pem -in private_key.p12

4. 去除轉發密碼
openssl rsa -out private_key_noenc.pem -in private_key.pem

5. 合併 aps_development.pemprivate_key_noenc.pem
cat aps_development.pem private_key_noenc.pem > apns_dev.pem

有了 apns_dev.pem 這個憑證就可以傳送推播了!



傳送時的 message payload 格式也可以參考上面兩篇文章。

最後提供幾個人家implement好的APNS


Production server
  • ssl://gateway.push.apple.com:2195
  • Development server
  • ssl://gateway.sandbox.push.apple.com:2195
  • 2011/07/06

    Facebook API with iPhone app

    最近在研究怎麼使用facebook API,看了蠻多的參考資料:
    Sorry 還蠻雜的,沒有太多時間做整理 ><


    簡單來說,有兩件事情要做
    • 學習使用 Facebook iOS SDK
    • API有哪些?要怎麼使用?
    Facebook API走HTTP協定,資料交換格式為JSON,採用OAuth方式來認證。
    Facebook iOS SDK其實就是幫你搞定這些事情,預設會開啓Safari或fb外掛來display login畫面,其中還包含了permission確認,如果上述兩項無法使用,則改用SDK裡面自己刻的dialog。使用者login後會拿到auth token,之後access API都要靠它。Request包成callback形式,接到response再做對應的事情。資料格式也幫你parse成NSData格式,存取相當方便。

    SDK下載按這裡

    稍微整理SDK使用方式 (不同時期的SDK使用方法不太一樣,下面敘述的是2011/7的版本)