- 將HTML中圖片的網址轉為本地端的路徑
- 使用UIWebView元件將上述轉換後的HTML顯示出內容
問題
- 轉換後的路徑為file://xxx/.../xxx.jpg,但發現圖片不能正常顯示出來(文字部份可以)
解決
- 使用API取出的路徑除了要加上"file://"外,還要加上"localhost";故完整的路徑應為"file://localhost/xxx/.../xxx.jpg",才能顯示出來
// Store用來管理Producer及Consumer一同存取的容器
// 故需要考慮到同步的問題,不可發生同時存取相同容器的問題
@interface Store : NSObject
{
NSMutableArray* mProducts; NSCondition* mLocker;
}
- (id) initStore;
- (void) add:(NSNumber*) product;
- (NSNumber*) get;
@end#import "Store.h"
@implementation Store
- (id) initStore
{
self = [super init];
if (self){
mProducts = [[NSMutableArray alloc] init];
mLocker = [[NSCondition alloc] init];
}
return self;
}
- (void) add:(NSNumber*) product
{
// 同步add product階段
[mLocker lock];
while ([mProducts count] >= 2)
{
[mLocker wait];
}
[mProducts addObject:product];
[mLocker signal];
// wake up one thread
[mLocker unlock];
}
- (NSNumber*) get
{
// 同步get product階段
[mLocker lock];
while ([mProducts count] <= 0)
{
[mLocker wait];
NSNumber* product = [mProducts objectAtIndex:0];
[mProducts removeObjectAtIndex:0];
[mLocker signal];
// wake up one thread
[mLocker unlock]; return product;
}
@end
// 將數字放入容器中 #import "Store.h"
@interface Producer : NSOperation
{
Store* mStore;
}
- (id) initProducer:(Store*) store;
- (void) main;
@endProducer.m #import "Producer.h"
@implementation Producer
- (id) initProducer:(Store*) store
{
self = [super init];
if (self) {
mStore = store;
}
return self;
}
- (void) main
{
for (int iProduct = 1; iProduct <= 10; iProduct++)
{
// 隨機睡眠 0~4秒
[NSThread sleepForTimeInterval:(arc4random() % 5)];
[mStore add:[NSNumber numberWithInt:iProduct]];
NSLog(@"Produce %d", iProduct);
}
}
@endConsumer.h // 將收字從容器中拿出 #import "Store.h"
@interface Consumer : NSOperation
{
Store* mSotre;
}
- (id) initConsumer:(Store*) store;
- (void) main;
@end#import "Consumer.h"
@implementation Consumer
- (id) initConsumer:(Store*) store
{
self = [super init];
if (self)
{
mSotre = store;
}
return self;
}
- (void) main
{
for (int iLoop = 0; iLoop <= 10; iLoop++)
{
[NSThread sleepForTimeInterval:(arc4random() % 5)];
NSLog(@"Consume %d", [[mSotre get] intValue]);
}
}
@end
#import "Producer.h"
#import "Consumer.h"
#import "Store.h"
@interface ViewController : UIViewController
{
NSOperationQueue* mQueue;
Producer* mProducer;
Consumer* mConsumer;
Store* mStore;
}
@end- (void)viewDidLoad
{
[super viewDidLoad];
mQueue = [[NSOperationQueue alloc] init];
mStore = [[Store alloc] initStore];
// 將Store放入Producer & Consumer裡
mProducer = [[Producer alloc] initProducer:mStore];
mConsumer = [[Consumer alloc] initConsumer:mStore];
// 將Producer & Consumer放入Operation queue中,
// 開始執行Producer & Consumer
[mQueue addOperation:mProducer];
[mQueue addOperation:mConsumer];
}![]() |
| 圖片來源 |
#import <UIKit/UIKit.h> #import "ASIHTTPRequest.h" #import "ASINetworkQueue.h" @interface ViewController : UIViewController <ASIHTTPRequestDelegate> { NSMutableData* mDataBuf; ASINetworkQueue* mQue; NSArray* mUrls } @end |
- (void)viewDidLoad { [super viewDidLoad]; // 下載的緩衝區 mDataBuf = [[NSMutableData alloc] init]; // 執行Request區域,類似NSOperationQueue, // 故在執行Request時是以執行緒方式進行,不影響原執行緒 mQue = [[ASINetworkQueue alloc] init]; [mQue reset]; [mQue setShowAccurateProgress:YES]; [mQue go]; // 設定下載位址 NSURL* url = [NSURL URLWithString:@"http://c.blog.xuite.net/c/b/6/5/20656505/blog_1172634/txt/23851923/10.jpg"]; ASIHTTPRequest* request = [[ASIHTTPRequest alloc] initWithURL:url]; // 設置ASIHTTPRequest delegate,用於回傳訊息並處理 request.delegate = self; // 開始處理Request [que addOperation:request]; } // ASIHTTPRequestDelegate 接收到資料後 - (void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data { [mDataBuf appendData:data]; NSLog(@"Recevie %d bytes...", [data length]); } // ASIHTTPRequestDelegate 資料接收完成 - (void)requestFinished:(ASIHTTPRequest *)request { // 取得存放位置 NSArray *pathList = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *path = [pathList objectAtIndex:0]; // 指定 資料夾 path = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"/tmp/test"]]; // 若指定資料夾不存在則創建 NSFileManager* fileM = [NSFileManager defaultManager]; NSError* error; if(![fileM fileExistsAtPath:path]) [fileM createDirectoryAtPath:path withIntermediateDirectories:true attributes:nil error:&error]; //加上檔名 path = [path stringByAppendingPathComponent: [NSString stringWithFormat: @"/00.jpg"]]; NSLog(@"儲存路徑:%@", path); //寫入檔案 [mDataBuf writeToFile:path atomically:NO]; mDataBuf = [[NSMutableData alloc] init]; NSLog(@"Download success"); } |
![]() |
| 上述錯誤需加入sqlite3的library |
![]() |
| 進入TARGETS |
NSError* error; // 取得Yahoo的HTML內容 NSString* tmp = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.yahoo.com.tw"] encoding:NSUTF8StringEncoding error:&error]; // 使用regular expression過濾內容 NSString* regEx = @"<title>(.*)</title>"; for(NSString* sub in [tmp componentsMatchedByRegex:regEx]) { NSLog(sub); } |
![]() |
| 點選紅框標示的地方 |
![]() | ||
點選紅框標示的地方,最後使用“+”把libxml2加入
|
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. NSError* error; // 取得yahoo首頁的HTML NSData* data = [[NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.yahoo.com.tw"] encoding:NSUTF8StringEncoding error:&error] dataUsingEncoding:NSUTF8StringEncoding]; // 取出title標籤中的值 TFHpple* parser = [[TFHpple alloc] initWithHTMLData:data]; NSArray* values = [parser searchWithXPathQuery:@"//title"]; // get the title TFHppleElement* value = [values objectAtIndex:0]; NSString* result = [value content]; NSLog(@"result = %@", result); mLabel.text = result; } |
// 設定Label元件在文字內容超過框架時的樣式 content.lineBreakMode = UILineBreakModeWordWrap; // 設定Label元件最多顯示的行數,0為不限 content.numberOfLines = 0; // 透過NSFileManager取得Document的路徑 NSURL* url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; // 在Document下新增DB檔案 NSString* dbPath = [[url path] stringByAppendingPathComponent:@"myDB.db"]; // 透過FMDatabase物件與DB溝通 db = [FMDatabase databaseWithPath:dbPath]; if(![db open]) { NSLog(@"Could not open database."); } if(![db executeUpdate:@"CREATE TABLE IF NOT EXISTS info (id INTEGER PRIMARY KEY, name TEXT, tel TEXT)"]) { NSLog(@"Could not creat table (%@)", [db lastErrorCode]); } |
// VALUES後的格式需使用範例這樣的方法,否則會出錯 if(![db executeUpdate:@"INSERT INTO info (name, tel) VALUES (?, ?)",@"Vince",@"9988765"]) { NSLog(@"Could not insert"); } |
FMResultSet* rs = [db executeQuery:@"SELECT * FROM info"]; // 印出所有Query到的資料 while([rs next]) { int _id = [rs intForColumn:@"id"]; NSString* name = [rs stringForColumn:@"name"]; NSString* tel = [rs stringForColumn:@"tel"]; NSMutableString* strTemp = [NSMutableString stringWithString:content.text]; if([strTemp compare:@"Label"]) { [strTemp appendFormat:@"%d-%@-%@\n", _id, name, tel]; content.text = strTemp; }else { content.text = [NSString stringWithFormat:@"%d-%@-%@\n", _id, name, tel]; } } |
@interface TEST: NSObject // 公開方法 - (void)publicMethod; // 靜態方法 + (void)staticMethod; @end |
TEST* test = [TEST alloc] init]; [test publicMethod]; [test release]; |
[TEST staticMethod] |
@interface TEST: NSObject { NSString* param; } @property (nonatomic, retain) NSString *param; @end |
@implementation TEST @synthesize param; - (id)init{} @end |
@interface TEST: NSObject { @public NSString* publicString; @protected NSString* protectedString; @private NSString* privateString; } @end |
#import "TEST.h" @interface TEST (private) - (void) privateMethod @end @implementation TEST - (id)init { ... } - (void)privateMethod { ... } @end |
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. myTable.dataSource = self; myTable.delegate = self; dataArray = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", @"four", @"five", nil]; } // 決定section的個數,return 1表示只有一個section - (NSInteger)numberOfSectionInTableView:(UITableView *)tableView { return 1; } // 因為只有一個section,故直接回傳dataArray count,若有多個section要加if-else - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [dataArray count]; } // 決定所要回傳的cell - (UITableView *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // 定義一個名稱,供reuse queue使用 static NSString* CellIdentifier = @"Cell"; UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; // 一開始還沒有queue時,會initial一個新的queue if(cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]; } cell.textLabel.text = [dataArray objectAtIndex:indexPath.row]; return cell; } // 取得使用者所按到的cell - (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"Selected %@", [dataArray objectAtIndex:indexPath.row]); } |
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. myTable.dataSource = self; myTable.delegate = self; dataArray = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", @"four", @"five", nil]; subArray = [[NSArray alloc] initWithObjects:@"1", @"2", @"3", @"4", @"5", nil]; } // 決定所要回傳的cell - (UITableView *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // 定義一個名稱,供reuse queue使用 static NSString* CellIdentifier = @"Cell"; UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; // 一開始還沒有queue時,會initial一個新的queue if(cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; } cell.textLabel.text = [dataArray objectAtIndex:indexPath.row]; cell.detailTextLabel.text = [subArray objectAtIndex:indexPath.row]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; return cell; } |
// 決定所要回傳的cell - (UITableView *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // 定義一個名稱,供reuse queue使用 static NSString* CellIdentifier = @"Cell"; UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; // 一開始還沒有queue時,會initial一個新的queue if(cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; } cell.textLabel.text = [dataArray objectAtIndex:indexPath.row]; cell.detailTextLabel.text = [subArray objectAtIndex:indexPath.row]; cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; return cell; } // 當按下藍色按鈕時,呼叫此方法 - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath { NSLog(@"Press %@ button", [dataArray objectAtIndex:indexPath.row]); } |