[iOS教學] 使用 PromiseKit 來管理你的 callback!

請參考 PromiseKit 的文件:

Promise 基本概念

在非同步執行的流程處理上,傳統作法一直是個麻煩點,
而 Promise 透過一些函式可以很直覺的管理非同步的流程。

傳統的做法

以 iOS 而言,你可能要透過 NSOperationQueue 或者
GCD (Grand Central Dispatch) 這些方法來做非同步的流程。

如果要接續觸發( A 事情做完做 B )的情境,A 事情的 callback 做完之後緊接著 B 事情,你可能會得到一個很深的縮排。
如果是互相等待完成( A 跟 B 事情 )的情境,你可能要透過一些 boolean 來把狀態記住,然後 A 事情跟 B 事情的 callback 同時要檢查對方是否做完,才接續另外一個 callback 。 以上並不是說這樣寫不能用,只是你會有更好的解法,讓程式碼變得更乾淨好閱讀。

Promise 的做法

主要關鍵字有 firstly then catch 還有 always
要字面上來看就是 「首先」、「然後」最後是有錯誤時用 catch 抓取錯誤。

這個範例還用了一個很實用的 when() 來綜合二件非同步的事情,當二件事情都結束時才會回傳到下一個 Callback。

這是一個綜合各種基本關鍵字的範例

firstly {
    // Show Loading status bar
    return when(myAsnycTaskA(), myAsnycTaskB())
}.then { (resultA:MyObjectA, resultB:MyObjectB) -> Void in
    // Show results
}.always {
    // Hide Loading status bar
}.catch { error in
    print(error)
}

最簡單的範例

這是一個最基本的範例
基本句型有 thencatch 就可以了

myAsnycTaskA().then { 
    (resultA:MyObjectA) -> Void in
    // Show results

}.catch { error in
    print(error)
}

宣告

至於你想要宣告一個事情也不難

func myAsnycTaskA()-> Promise<MyObjectA> {
    return Promise { fulfill, reject in
        // Done
        fulfill(result)

        // Fail
        reject(error)
    }
}

回傳一個 Promise,裡面有 fulfill()reject() 二個 method。
當資料回來的時候呼叫 fulfill()
當出現錯誤的時候呼叫 reject() 並帶入一個 Error 物件。

複雜一點的範例

這時回過頭來看第一個範例,我又把它改複雜了一點,是不是比較不難了呢?

firstly {
    // Show Loading status bar
    return when(myAsnycTaskA(), myAsnycTaskB())
}.then { (resultA:MyObjectA, resultB:MyObjectB) -> Promise<MyObjectC> in
    // So some processing
    return myProcessingTaskC()
}.then { (resultC:MyObjectC) -> Void in
    // Show results
}.always {
    // Hide Loading status bar
}.catch { error in
    print(error)
}

首先,同時做 myAsnycTaskA()myAsnycTaskB()
等二者結果回傳了之後,做 myProcessingTaskC() 最後回傳結果。

在 callback 的處理上是不是變得比較開心愉快了一點呢?
以上就是 Promise 的快速介紹。

有興趣的話,可以查看官方文件裡面有更進階的寫法。
這個概念不只在 iOS (Swift) 可以用,在 JavaScript (ES6) 也有類似的語法,有機會再專文介紹。

[iOS] Apple iOS Developer Program 開發者帳號 申請實錄

Screen Shot 2013-07-08 at 1.24.24 AM  

話說 iOS開發者帳號已經想申請想很久了

最近心一橫,拿出信用卡
就給它刷下去了

 

但是...申請過程沒有那麼順利(我申請了二次)

所以就把一些東西記錄下來,給大家參考

------

敗家 阿不是,是學習大門的網址都幫你準備好了:

https://developer.apple.com/programs/ios/

看到 iOS Developer Program

的藍色Enroll Now的按鈕,就用力的給他點下去吧!

Screen Shot 2013-07-08 at 1.26.26 AM  

這裡有大概跟你說整個申請流程
簡單來說選擇1. 申請身份 2. 填資料 3. 線上刷卡及人工審核
直接按Continue繼續

 

Screen Shot 2013-07-08 at 1.29.05 AM  

 

 

申請新的Apple ID

 

這裡說要登入Apple ID,或是新創一個Apple ID帳號去綁開發者帳號

我是選Create Apple ID去新創一個Apple ID

到這裡都還算簡單

Screen Shot 2013-07-08 at 1.32.16 AM  

 

然後就是填Apple ID的資料...資料都要真實的
因為到時候Apple那邊會查

Screen Shot 2013-07-08 at 1.33.40 AM  

這裡請特別注意...Middle Name請不要雞婆的去填寫它,乾脆說請直接忽視Middle Name的欄位

台灣人不需要這個欄位

只要依照指示填寫First Name姓氏,Last Name名字,就好

Screen Shot 2013-07-08 at 1.38.29 AM  

至於地址的部份,我當時是寫英文啦

只是Preferred Language是填Chinese就是了

送出之後呢...就創立一個 Apple ID了

------

但還沒完,還沒有填到重點的部份

 

 

開發者帳號申請

Screen Shot 2013-07-08 at 1.43.12 AM  

它會問你,你要申請哪種開發者帳號

Individual (個人) 還是Company/Organization (公司)

Company的部分我個人沒申請過...

我是選擇 Individual

------

Screen Shot 2013-07-08 at 1.48.46 AM  

看到很多黃色區塊了吧?這幾步非常的重要

它說,這個名字一定要是你信用卡申請人的名字

所以像圖上的範例就是

意思就是說....不能用他人的信用卡代刷這筆費用

而且這名字一定要是你的真名

而且還有一個重點,

申請送出了之後(包含錢),資料就無法做修改

所以要特別特別的填清楚

當然,Middle Name的欄位請略過...台灣人不需要這個欄位

至於填中文還是英文,Apple客服說都可以

 

但一定要讓他們對得到資料

Screen Shot 2013-07-08 at 1.57.01 AM  

地址欄位欄位也是,送出後無法修改
我就不贅述了

Screen Shot 2013-07-08 at 2.02.45 AM  

資料確認頁,確定無誤就按下一步
再次提醒你,這裡的Name打上的是Johnny Sung是

你必須要打上你的真名

Screen Shot 2013-07-08 at 2.04.17 AM  

Apple授權協議頁,他很貼心的給你PDF的版本
按 I Agree繼續

Screen Shot 2013-07-08 at 2.06.34 AM  

頁面會幫你轉到Apple Store的商店

加入iOS Developer Program這個項目到你的購物車裡

 

Screen Shot 2013-07-08 at 2.06.56 AM  

這邊有沒有覺得很神奇,突然什麼都變成中文了

我想可能是Preferred Language是填Chinese的關係

按下「結帳」繼續

 

Screen Shot 2013-07-08 at 2.07.50 AM  

直接按下「繼續」

Screen Shot 2013-07-08 at 2.08.09 AM

這邊很神奇,它又要你填一次地址

這次沒得選,只能填中文(它的表單有設計過,你填英文會不夠長)

我想這個欄位應該是沒有使用到

Screen Shot 2013-07-08 at 2.09.18 AM  

這裡就很重要了,要你填入信用卡的卡號 安全碼等等的資料

請容許我在重述一次

這個名字一定要跟你剛剛填的申請人名字一樣

所以....不能用他人的信用卡代刷這筆費用

而且這名字一定要是你的真名

申請送出了之後(包含錢),資料就無法做修改

按下「繼續」之後

按下同意授權條款就結束了

-------

你的信箱會收到一封類似這樣的信

Screen Shot 2013-07-08 at 2.23.04 AM  

能幹嘛呢?只有等...還是等...

 

Screen Shot 2013-07-08 at 2.28.27 AM  

大概在24小時之內,會收到一封啓動序號的信

Screen Shot 2013-07-08 at 2.30.57 AM  

順著啓動序號的連結會來到這個網頁

按下Activate鍵就會啓動...

------------

你認為這麼簡單嗎?別高興太早

那個按鈕,就算你是用合法的序號也是會被擋下來的

因為他有人工驗證的部份,人工驗證沒過
一切都白搭

 

如果你有看我文章(?),很細心的注意每個步驟和表單

你就會收到這個成功信件

Screen Shot 2013-07-08 at 2.39.02 AM  

這封信的大意是說,我們已經對過你提供的資料,並移除了擋板

你只要在重新到啓動碼頁面  點一下就會啓用開發者帳號了

 

=========================================

 

 

 

退換貨處理

如果你像我一樣,資料沒有打對的話
要怎麼辦?

 

首先,你會收到類似這樣的信件

Screen Shot 2013-07-08 at 2.37.54 AM  

這段文字很讓人飆髒話,所以貼出來

In order for us to verify your identity, you need to upload a notarized or solicitor certified copy of your government issued photo identification.

就是說,你提供的資料不符,他要求你要上傳一個經過公證單位或律師(solicitor) 公證過的有照片的文件

 

這時候有FAQs 跟 Contact us可以選

Screen Shot 2013-07-08 at 3.11.30 AM  

 

我當下直接選了Call us

https://developer.apple.com/contact/phone.php

Screen Shot 2013-07-08 at 3.18.00 AM   

直接找台灣的電話打就行了,還好是0800免付費電話

跟客服講你現在的情況,還有跟他說你的Apple ID

他就會把原因告訴你

 

打電話了之後,你現在只有二個選項:

  1. 乖乖的去把你的證件拿去公證單位公證然後上傳我是沒有去公證過啦,據網路上查詢的結果 

    根據外交部領事事務局的網頁
    http://www.boca.gov.tw/content?mp=1&CuItem=4990
    倘國、內外要證機關無特別規定要求護照影本須先經國內地方法院公證處或民間公證人證明,申請人可直接向本局或本部中部、南部、東部、雲嘉南四辦事處申辦出具中華民國護照影本與正本相符之證明。 

    蓋個章,規費 $400

    若真的要公證,需要到 台北地院公證處
    http://lawtw.com/article.php?template=article_content&area=free_browse&parent_path=,1,655,7,&job_id=82850&article_category_id=1965&article_id=36859
    中文 $500元,英文 $750元

    根據Apple客服的說法,雙證件也不行
    送出的資料也不能讓使用者或是客服修改資料後重新驗證

    比郵局開戶還難,這點真的會讓人家氣炸

  2. 把這筆申請(包含錢),通通退掉,再重來一次

我是選擇這個選項,他們會照著你的要求做,寄送紙本發票和
折讓單(SAS FORM)到你府上

 

 

你要填一些資料然後簽字寄回去給Apple

Screen Shot 2013-07-08 at 9.27.47 AM  

 

-------

過了幾天之後就會收到這個

LastScan2-2  

統一發票

LastScan-2  

所謂的折讓單(SAS FORM)....上面有個又愛又恨的蘋果

 

這裡我就不重述了,簽一簽,寄回去

然後又是等....

-------

你可以當下拿出信用卡,再刷一次

再走一次這樣的流程

有這麻煩到家的流程,所以一再的提醒你

別打錯字

 

 

折騰了老半天,最後還是申請出來了

大概花了4天吧

這種麻煩事,要走過才會知道有多麻煩
貼出來讓大家更瞭解這機車的流程

有很多地方要注意的點

 

之後我來筆記帳號開通之後能做的事情

謝謝收看。

[iOS筆記] 關於Protocol和物件導向 (Java下的介面(Interface) )

有關於iOS底下的Protocol

 

請參照至其版大的文章

Protocol in Objective-C

http://blog.eddie.com.tw/2010/12/11/protocol-in-objective-c/

這版大實在寫的思路很清晰,推薦一下摟

(看來我還是要多多拜讀別人的文章才是)

------------------------------------------------------------------------------------------------

為了響應不全文引用,以下採用節錄的,完整內容請移至版大的文章

 

Objective-C是單一繼承的,如果想要做到一個類別同時擁有多種型別的能力,可以透過實作其它型別的interface來達成這個目的。在Java/AS3是用”interface”這個關鍵字,在Objective-C則是用”@protocol”。

(有寫過Java/AS3的要特別注意不要把interface跟protocol搞混了
,在Objective-C的interface等於Java/AS3的class,而protocol則是相當於interface)

Johnny: 關於protocol這點,我也常常搞混.....= =||


如果你要新增一個自定的protocol的話,可以直接在你的專案裡新增一個protocol檔:

image

新增完成之後(它是一個header檔),就可以開始來寫了,

---------------------------------------------------------------------------------------------------

程式碼如下:

@protocol Drawable

@required
-(void) draw;
-(void) changeColor;

@optional
-(void) whateverMethod;

@end

在上面這段程式碼裡,我放了三個方法,但沒有寫內容。接下來如果我要實作自這個protocol的話,所有定義在@protocol裡的方法都得實作出來。

如果沒特別標明的,預設是@required。如果你要實作這個protocol的話,照英文字面來看,@required的部份是規定要實作的,@optional的話就隨你高興了。要注意的是@required跟@optional這兩個語法的影響範圍,是從它以下所有的method都會被影響,直到另一個directive或是@end為止


-------------------------------------------------------------------------------------------------------------------------

實作protocol的方法就是用”<>”標記,裡面放protocol的名稱。並不限定只能實作一個protocol,如果要實作多個protocol的話,則是用逗點分開

因為在protocol的地方已經有定義好了方法,所以在@interface的地方就不用再特別寫一次,只要在@implementation裡補上該實作的方法就行了。

// --------------

// interface
// --------------
#import <Cocoa/Cocoa.h>
#import "Drawable.h"

@interface Book : NSObject <Drawable>
{
int price;
}
@property int price;

@end

// --------------
// implementation
// --------------
#import "Book.h"
@implementation Book

@synthesize price;

// 實作方法draw
-(void) draw
{
NSLog(@"draw me!");
}

// 實作方法changeColor
-(void) changeColor
{
NSLog(@"change color!");
}

@end

 

-------------------------------------------------------------------------------------------------------------------------

Johnny: 簡單來講,protocol就是Java裡的介面(Interface),上面開出來的方法(method)
且有@required字樣的都要被實作(implementation)

protocol名稱加綴在類別(class)後面
只是為了要讓Complier,確實的去檢查,開出來的方法

是有都通通有實作完畢

實驗發現,某些Class對於protocol要求沒那麼嚴苛

只要實作出它要的方法,而不用加掛這個綴字

而且避免混淆,我現在習慣通通都加上去

(包含放在Class名稱之後的 < > ,和其protocol要的方法一起宣告在header檔)

 

 

我還是覺得還是要學Java一樣,嚴謹一點比較好,較不會出錯

[iOS] 從檔案載入NSMutableArray和NSMutableDictionary 的筆記

在iOS開發上

若是從檔案讀取一些資料,想必會用到

  • NSMutableArray
  • NSMutableDictionary

這二個類別

Mutable是可變動的意思,所以建立之後還可以變動

NSMutableArray的話存取方式採用序號來存取值

而NSMutableDictionary採用自訂的鍵值(key)來存取值(value)

 

二者可以互相混用,NSMutableDictionary裡面有NSMutableArray

或是NSMutableArray裡面包含NSMutableDictionary (就像本次範例)

 

使用initWithContentsOfFile: 方法來載入plist

https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/Reference/Reference.html#//apple_ref/occ/instm/NSData/initWithContentsOfFile:

NSMutableArray要取得值使用objectAtIndex 方法

https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html#//apple_ref/occ/instm/NSArray/objectAtIndex:

NSMutableDictionary要取得值使用objectForKey方法

https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDictionary/objectForKey:

-----------------------------------------------------------------------------------------------------------

提外話一下

如果有寫過php的話

他的概念和php的array有一點點類似

http://php.net/manual/en/language.types.array.php

而NSMutableArray類似於

<?php

$array = array("foo", "bar");
var_dump($array);
?>

螢幕輸出:

array(4) { [0]=> string(3) "foo" [1]=> string(3) "bar" }


NSMutableDictionary類似於

<?php
$array = array(
    "foo" => "bar",
    "bar" => "foo"
);
var_dump($array);
?>

螢幕輸出:

array(4) { ["foo"]=> string(3) "bar" ["bar"]=> string(3) "foo" }

 

-----------------------------------------------------------------------------------------------------------

 

建立一個專案,在專案上按右鍵New File:

Screen Shot 2012-03-25 at 上午10.51.49  

新增一個Property List,名叫article.plist

 

article.plist原始碼如下

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN""http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">

    <array>

        <dict>

            <key>title</key>

            <string>title 01</string>

            <key>content</key>

            <string>content 01</string>

        </dict>

        <dict>

            <key>title</key>

            <string>title 02</string>

            <key>content</key>

            <string>content 02</string>

        </dict>

        <dict>

            <key>title</key>

            <string>title 03</string>

            <key>content</key>

            <string>content 03</string>

        </dict>

    </array>

</plist>

 

 做一個Button出來,綁定TestpList_btn_onClick方法,該方法如下

 

- (IBAction)TestpList_btn_onClick:(id)sender {

   

    // 取得專案中內建的pList路徑

    NSString *path = [[NSBundlemainBundle] pathForResource:@"article"ofType:@"plist"];

    NSLog(@"pList Path: %@\n", path);

    // pList中的資料從檔案載入

     NSMutableArray *data_pList = [[NSMutableArrayalloc] initWithContentsOfFile:path];

   

    for(NSInteger i=0;i<[data_pList count]; i++)

    {

        NSIndexPath *indexPath=[NSIndexPathindexPathForRow:i inSection:0];

        NSString *title = [[data_pList objectAtIndex:indexPath.row] objectForKey:@"title"];

        NSString *content = [[data_pList objectAtIndex:indexPath.row] objectForKey:@"content"];

        NSLog(@"Index: %i Title: %@ Content: %@\n", i, title, content);

    }

}

 

 然後運行程式,按下按鈕之後,在Log這邊得到以下結果:

Screen Shot 2012-03-25 at 上午10.55.55  

-----------------------------------------------------------------------------------------------------------

順便補充在iOS上的printf裡的格式跟一般的C語言不同 

https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html#//apple_ref/doc/uid/TP40004265-SW1

string 要使用 %@

integer 要使用 %i 而不是 %d

 

[iOS] 利用NSURLConnection建立HTTP連線 (GET篇)

最近在研究iOS開發,對於Http連線的好處
在這裡就不再贅述

之前寫過Android版本的,請見:

http://j796160836.pixnet.net/blog/post/28994669

 

雖然我也在學習中,我盡量解釋其方法
如果有誤,還煩請大大們指正

-------------------------------------------------------------------------------------------------------------------

 

開一個新的專案

在Interface Builder版面設計中,拉出一個Button和一個Label

-------------------------------------------------------------------------------------------------------------------

其中 Button Touch Up Instide 中綁定  - (IBAction)request_btn_onclick:(id)sender   方法

LabelReferencing Outlets 綁定  @property (retain, nonatomic) IBOutletUILabel *label;     變數

-------------------------------------------------------------------------------------------------------------------

 

ViewController.h 放入以下宣告

@interface ViewController : UIViewController

{

    NSMutableData *responseData;

}

 

// 開始接收資料,會呼叫此方法

- (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;

-------------------------------------------------------------------------------------------------------------------

ViewController.m 加入以下程式片段

 

#pragma mark - Connection delegate

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

{

    // 開始下載,重置responseData資料

    NSLog(@"didReceiveResponse");

    [responseDatasetLength:0];

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

{

    // 下載中,附加資料

    [responseDataappendData:data];

}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

{

    // 下載完成,釋放responseData

    [connection release];

    NSLog (@"succeeded  %d byte received", [responseDatalength]);

    // 轉譯編碼文字

    NSString *responseString = [[NSStringalloc] initWithData:responseDataencoding:NSUTF8StringEncoding];

   

    [responseDatarelease];

   

    label.text =  responseString;

    [responseString release];

}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

{

    // 下載錯誤

    label.text = [NSStringstringWithFormat:@"Connection failed: %@",[error description]];

    NSLog(@"Connection failed! Error - %@ %@",

          [error localizedDescription],

          [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);

}

-------------------------------------------------------------------------------------------------------------------

這段就是按鈕按下去會執行的語法

#pragma mark – Button onClick

 

- (IBAction)request_btn_onclick:(id)sender {

   

    responseData = [[NSMutableDatadata] retain];

    NSString *url = [NSString stringWithFormat:@"http://127.0.0.1/httptest/t.php"];

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURLURLWithString:url ]];

    [[NSURLConnection alloc] initWithRequest:request delegate:self];

   

}

-------------------------------------------------------------------------------------------------------------------

我簡單解釋一下

剛剛在ViewController之中新增一個 NSMutableDatadata 變數 (Mutable代表可變動的)

然後在 - (IBAction)request_btn_onclick:(id)sender 這裡

指定一個 url 就是我們要瀏覽的位置,GET要上傳的內容就串在後面

再來建立一個 NSURLRequest 和 NSURLConnection 把連線建立起來

回應的部分傳進delegate (委派)之中

 

而delegate (委派)有四個

 

// 開始接收資料,會呼叫此方法

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;

當系統開始要接收資料的時候這個方法會被呼叫到
要把這 responseData 給清空,如果UI上有ProgressBar的話要將之歸零

// 接收新的資料時,會呼叫此方法

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;

每次資料在下載的時候,會不停的呼叫這個方法
可以看到這個data傳入的參數,就是每一小塊一小塊的資料
我們只要把它累加起來即可,如果UI上有ProgressBar的話就可以慢慢累加1

// 下載完畢時,會呼叫此方法

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

最後跑完會呼叫這個方法,就是你需要做處理的部分
例如顯示到畫面上,存入SQLite....等等


// 連線錯誤時,會呼叫此方法

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;

最後就是這個,中間若有網路錯誤等因素就會呼叫這個方法
你可以跳一個提示框或是印Log

 

這個範例的url是指到本機的Apache Server的其中的一隻php網頁
你也可以換成yahoo等網站,只是會跑出一堆網頁原始碼而已

可以玩看看 

-------------------------------------------------------------------------------------------------------------------

以下是我不負責任的把語法翻成大家熟悉的Java
對於像我一樣,對Objective-C有閱讀障礙的

可以看一下(當然,底下的程式完全不能跑,就不用複製了....XD)

 

public  class  ViewController  implements  NSURLConnectionDelegate  {

 

   public  static  UILabel  label;

 

   private  NSMutableData  responseData;

 

   public  void  viewDidLoad()  {

 

      responseData  =  new  NSMutableData();

 

      NSString  url  =  "http://127.0.0.1/httptest/t.php";

 

      NSURLRequest  request  =  new  NSURLRequest(url);

 

      new  NSURLConnection(request,  this);

 

   }

 

 

 

   @Override

 

   public  void  didReceiveResponse(NSURLConnection  connection, NSURLResponse  response)  {

 

      //  開始下載,重置responseData資料

 

      NSLog("didReceiveResponse");

 

      responseData.setLength(0);

 

   }

 

 

 

   @Override

 

   public  void  didReceiveData(NSURLConnection  connection,  NSData  data)  {

 

      //  下載中,附加資料

 

      responseData.appendData(data);

 

   }

 

 

 

   @Override

 

   public  void  connectionDidFinishLoading(NSURLConnection  connection)  {

 

      //  下載完成,釋放responseData

 

      connection  =  null;

 

      NSLog(NSString.format("succeeded    %d  byte  received"responseData.length));

 

      //  轉譯編碼文字

 

      NSString  responseNSString  =  responseData.toNSStringWithEncoding(NSUTF8NSStringEncoding);

 

      responseData  =  null;

 

 

 

      label.text  =  responseNSString;

 

      responseNSString  =  null;

 

   }

 

 

 

   @Override

 

   public  void  didFailWithError(NSURLConnection  connection,  NSError  error)  {

 

      //  下載錯誤

 

      label.text  =  NSString.format("Connection  failed:  %s",  error.description());

 

      NSLog(NSString.format("Connection  failed!  Error  -  %s",

 

             error.localizedDescription()));

 

   }

 

}

-------------------------------------------------------------------------------------------------------------------

參考資料

http://www.01-labor.com/2011/07/nsurlconnectionhttp.html

http://stm237.iteye.com/blog/1005752

NSURLConnection官方文件

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html

[iOS開發] 讓JB後的iPhone/iPad能夠從xcode安裝發佈自己開發的程式 (免付費開發者帳號)

注意:這只是拿來做程式開發測試用途,越獄(Jailbreak)後所產生的後果和問題要自行負責

 

首先,先感謝綠毒團隊 讓A5晶片(iPhone 4s / iPad2) 在iOS 5.01也成功越獄了
這下能夠釋放iDevices的全功能,讓iDevices更強大

--------------------------------------------------------------------------------------------------

好吧,這次的重點
是要讓自己寫的iOS程式能夠在實機底下執行做測試
畢竟有些功能模擬器還是無法達到的

若程式的規模不及到要上架的程度
可以使用這個方法來做測試

 

當然,有付費版的開發者帳號最佳 (USD$99/年),就別看此篇了
在開始之前,你需要先JB你的裝置
這可能需要你自行去Google,假設你已經完成越獄了
會有個Cydia的程式安裝在你的裝置上 

 

筆者的環境

Mac OSX 10.7.2 (Lion)

Xcode 4.2.1

iPad2 16G Wifi (iOS 5.01 Jailbreaken)

 

 

等下將會以iOS 5.01 做示範

--------------------------------------------------------------------------------------------------

Step1  到cydia安裝AppSync

 

打開Cydia,使用底下的搜尋框尋找Appsync

100APPLE_IMG_0049.PNG  

就會有很多的名稱叫AppSync for iOS5.0+,擇一安裝即可 (這需符合你裝置的iOS版本)

這裡只是以此為範例 

--------------------------------------------------------------------------------------------------

Step2  編輯SDKSettings.plist

 

打開Finder,找到左側欄的應用程式 > 工具程式 > 終端機

 

鍵入指令

#sudo vi /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/SDKSettings.plist

 

若是xcode 4.3版請修改

vi /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/SDKSettings.plist

(感謝Chiakie大大的幫忙)

Screen Shot 2012-01-23 at 下午1.52.00.png

輸入自己帳戶的密碼之後

會打開vim的介面
(vim共有三種模式 一般介面,編輯模式,指令列模式)

詳細vim操作可參照 鳥哥的文章
http://linux.vbird.org/linux_basic/0310vi.php

按下鍵盤的 i 可以編輯,編輯完畢按下鍵盤的 Esc

Screen Shot 2012-01-23 at 下午1.54.04.png

尋找CODE_SIGNING_REQUIRED,這個Key
將其底下的String從YES改成NO

 

編輯完畢按下鍵盤的Esc鍵,直接鍵入 :wq  在按鍵盤的 Enter (或return鍵)

Screen Shot 2012-01-23 at 下午2.39.06.png  

即可退出

--------------------------------------------------------------------------------------------------

Step3  修改Xcode專案的設定

 

打開你的Xcode,開啟你需要編輯的專案

Screen Shot 2012-01-21 at 下午5.14.25.png

依照圖片按到專案名稱,按下Info頁籤

找到Deployment Target,確認iOS Deployment Target是否是為 5.0  (這需符合你裝置的iOS版本)

 

再來相同的地方,找到Build Settings的頁籤

Screen Shot 2012-01-21 at 下午5.13.29.png

找到Code Signing

將以下全部改成Don't Code Sign

(預設值是Debug > Any iOS SDK和Release >  Any iOS SDK的值為iPhone Developer)

 

 

--------------------------------------------------------------------------------------------------

Step4  連接你的iDevice (iPhone/iPad)

 

連接你的iPhone或iPad

按下專案視窗的右邊Organizer,找到Devices頁籤

Screen Shot 2012-01-23 at 下午12.39.36.png

可以找到你的裝置並且是亮綠燈的,且符合專案使用的iOS版本

 

 

回到專案視窗

  

按Scheme下拉框選擇你剛剛連接的裝置,按下Run

複製 -Screen Shot 2012-01-23 at 下午12.53.46.png  

就會開始編譯

 Screen Shot 2012-01-23 at 下午12.52.47.png

 

--------------------------------------------------------------------------------------------------

Step5  實機測試

 

編譯成功後

Screen Shot 2012-01-23 at 下午12.53.46.png  

會出現這樣

Error launching remote program: fail to get the task for process ......

的錯誤沒有關係

 

查看一下iPhone或iPad

100APPLE_IMG_0048.PNG  

你會發現他已經成功裝到你的機器上摟

 

 

--------------------------------------------------------------------------------------------------

參考資料

http://www.minwt.com/?p=2825

http://happyjc1106.blogspot.com/2011/12/xcode43.html

http://linux.vbird.org/linux_basic/0310vi.php