Xây dựng một ứng dụng trình chiếu iOS cho iPad

Sử dụng các API của XML, XCode và iOS

Tìm hiểu cách xây dựng một ứng dụng trình chiếu (slideshow) của iOS khi bạn đi qua từng bước tiến trình trong bài này. Ứng dụng ví dụ sẽ giao tiếp với một máy chủ web để lấy ra một định nghĩa trình chiếu XML và hiển thị các hình ảnh có trong trình chiếu.

Jack Herrington, Tổng biên tập, Code Generation Network

Jack D. Herrington là kỹ sư phần mềm cao cấp với hơn 20 năm kinh nghiệm. Ông là tác giả của ba cuốn sách: Code Generation in Action, Podcasting Hacks và PHP Hacks. Ông cũng đã viết hơn 30 bài báo.



09 07 2012

Giới thiệu

Các từ viết tắt thông dụng

  • IDE: Môi trường phát triển tích hợp
  • iOS: Hệ điều hành di động của Apple
  • OS X: Hệ điều hành của Apple cho các máy tính Macintosh

Không có gì bí ẩn vì sao viết các ứng dụng cho một thiết bị iOS, như iPad hoặc iPhone, là một hoạt động rất phổ biến: Các thiết bị tuyệt đẹp và dễ sử dụng. Với hàng triệu người dùng, các thiết bị này đem lại rất nhiều lợi nhuận cho việc phát triển ứng dụng. Mọi người thích thú xem các bức ảnh của họ trên màn hình đẹp của các máy iPad và iPhone.

Trong bài này, hãy tìm hiểu cách xây dựng một ứng dụng trình chiếu bức ảnh iOS từ đầu. Bạn sẽ đặt một số mã XML và các bức ảnh trên máy chủ, xây dựng ứng dụng iOS, thêm một khung nhìn hình ảnh, lấy ra XML và tạo hình ảnh động của trình chiếu.

Xây dựng tầng sau

Tầng sau của ứng dụng trình chiếu ví dụ thực sự chỉ là một tệp XML mà bạn có thể nhập vào máy chủ của bạn. Liệt kê 1 cho thấy XML ví dụ, với một số hình ảnh mẫu.

Liệt kê 1. photos.xml
<photos> 
   <photo url="http://localhost/photos/CRW_0675.jpg" /> 
   <photo url="http://localhost/photos/CRW_1488.jpg" /> 
   <photo url="http://localhost/photos/CRW_3273.jpg" /> 
   <photo url="http://localhost/photos/CRW_3296.jpg" /> 
   <photo url="http://localhost/photos/CRW_3303.jpg" /> 
   <photo url="http://localhost/photos/CRW_3359.jpg" /> 
   <photo url="http://localhost/photos/CRW_3445.jpg" /> 
   <photo url="http://localhost/photos/CRW_3752.jpg" /> 
   <photo url="http://localhost/photos/CRW_3754.jpg" /> 
   <photo url="http://localhost/photos/CRW_4525.jpg" /> 
   <photo url="http://localhost/photos/CRW_4547.jpg" /> 
   <photo url="http://localhost/photos/CRW_4700.jpg" /> 
   <photo url="http://localhost/photos/CRW_4860.jpg" /> 
</photos>

XML rất đơn giản. Thẻ <photos> (các bức ảnh) có chứa nhiều thẻ <photo> (bức ảnh). Mỗi thẻ <photo> có URL của hình ảnh mà bạn muốn hiển thị. URL cần có đủ điều kiện và bất biến; ứng dụng khách sẽ tải URL trực tiếp — không thông qua bất kỳ loại trình duyệt nào có xử lý các URL tương đối.

Để hoàn thành tầng sau, hãy sửa đổi XML để đưa các tài liệu tham khảo vào các bức ảnh của bạn và tải XML đó tới một vị trí đã biết trên máy chủ của bạn. Nếu tất cả mọi thứ diễn ra đúng kế hoạch, bạn sẽ có thể duyệt XML bằng cách sử dụng Safari (hay bất cứ trình duyệt nào mà bạn chọn) và thấy một cái gì đó như Hình 1.

Hình 1. XML trên máy chủ
Ảnh chụp màn hình tệp XML (Liệt kê 1) trong trình duyệt

Hình 1 cho thấy XML của Liệt kê 1 được định dạng như văn bản. Kết quả sẽ khác nhau giữa các trình duyệt, vì đây chỉ là XML đơn giản (và không có tiêu chuẩn nào giữa các trình duyệt).

Để kiểm tra xem các URL có đúng không:

  1. Chọn một trong số các URL.
  2. Sao chép và dán nó vào vùng URL của trình duyệt.
  3. Nhấn phím Return.

Bạn sẽ thấy một hình tương tự như Hình 2.

Hình 2. Một trong các bức ảnh trên máy chủ
Ảnh chụp màn hình bức ảnh mẫu CRW_1488.jpg, hiển thị khuôn mặt của một bé gái

Một bức ảnh, đặt trên máy chủ, có liên quan đến một trong các URL trong XML. Nếu bạn không thấy XML, hoặc không nhìn thấy các bức ảnh đó, thì bạn cần kiểm tra cấu hình máy chủ web và các URL của bạn. Nếu bạn không thể nhìn thấy một bức ảnh trong trình duyệt, thì ứng dụng iOS mới của bạn cũng không thể thấy nó.


Xây dựng ứng dụng trình chiếu khách

Sau khi máy chủ được cấu hình và các bức ảnh được tải lên, bạn có thể bắt đầu xây dựng ứng dụng iOS. Bước đầu tiên là cài đặt Các công cụ phát triển của Apple - Apple Developer Tools (xem Tài nguyên để có một liên kết). Nếu bạn có:

  • Pre-Lion, bạn cần tải về các công cụ phát triển từ trang web của nhà phát triển Apple - Apple Developer Site (xem Tài nguyên để có một liên kết).
  • Chạy Lion, bạn có thể sử dụng Kho ứng dụng Mac (Mac App Store) để tải về các công cụ này (xem Tài nguyên để có một liên kết).

Sau khi bạn cài đặt các công cụ của nhà phát triển, hãy chạy môi trường XCode, là IDE của Apple cho cả việc phát triển iOS và Mac OS X. Từ môi trường XCode, hãy chọn tùy chọn trình đơn cho một New Project (Dự án mới). Bạn sẽ thấy trang đầu tiên của trình hướng dẫn ứng dụng mà bạn sẽ sử dụng để xây dựng các ứng dụng iOS hoặc Mac OS X, như trong Hình 3.

Hình 3. Trình hướng dẫn ứng dụng
Ảnh chụp màn hình trang web nơi bạn chọn một khuôn mẫu cho một dự án mới

Bạn có thể chọn từ một vài khuôn mẫu ứng dụng khác nhau. Với ví dụ này, hãy chọn View-based Application (Ứng dụng dựa trên Khung nhìn) và nhấn Next. Bạn sẽ thấy trang cuối cùng của trình hướng dẫn, như trong Hình 4.

Hình 4. Các tùy chọn dự án
Ảnh chụp màn hình trang web nơi bạn chọn các tùy chọn cho một dự án mới

Trên trang thứ hai của trình hướng dẫn này, hãy đặt tên ứng dụng của bạn và chọn họ thiết bị mặc định (iPad hoặc iPhone). Tên sản phẩm (Product Name) của ứng dụng ví dụ là slideshow. Giá trị trong trường Company Identifier (Mã định danh công ty) cho biết ứng dụng ở trong vùng tên com.jherrington. (Tất nhiên, bạn có thể chọn bất cứ tên và mã định danh công ty nào bạn muốn). Chọn iPad cho Device Family (Họ thiết bị) và nhấn Next.

Dự án được tạo ra. Tại thời điểm này, tốt nhất là chọn nút Play to ở phía trên bên trái của giao diện để chạy ứng dụng của bạn lần đầu tiên. Bước này biên dịch mọi thứ và đưa ra bộ mô phỏng iPad.


Thêm khung nhìn hình ảnh

Bước tiếp theo là thêm khung nhìn hình ảnh để hiển thị các hình ảnh. Khung công tác iOS đi kèm với một tập các nút điều khiển dựng sẵn, phong phú mà bạn có thể dùng để xây dựng ứng dụng của bạn. Ví dụ, bạn sẽ sử dụng nút điều khiển UIImageView. Với UIImageView bạn có thể hiển thị các hình ảnh được biên dịch vào ứng dụng, được lưu trữ cục bộ trên thiết bị hoặc như trong ví dụ này, được tải về từ một trang web.

Để thêm UIImageView, mở các tệp slideshowControllerView.XIB, là tệp định nghĩa giao diện người dùng cho slideshowControllerView. Với XIB đã mở, chuyển đến bảng đối tượng và chọn Image View (Khung nhìn hình ảnh), như trong Hình 5.

Hình 5. Thêm một đối tượng UIImageView tới XIB của trình điều khiển khung nhìn
Ảnh chụp màn hình tùy chọn Image View được chọn

Với Image View đã chọn, hãy kéo và thả nó vào trong slideshowControllerView. Thông thường IDE tự động thay đổi nút điều khiển cho phù hợp với không gian có sẵn. Nếu không, chỉ cần kéo nút điều khiển để điều chỉnh kích thước của nó cho đến khi nó lấp đầy toàn bộ vùng hiển thị.

Sau khi có nút điều khiển trên khung nhìn này, hãy thiết lập một số tham số để có được dáng vẻ và cảm nhận tối ưu cho ứng dụng. Hình 6 cho thấy các giá trị thiết lập trên màn hình các thuộc tính với nút điều khiển Image View.

Hình 6. Cấu hình UIImageView
Ảnh chụp màn hình các thuộc tính cho nút điều khiển Image View

Hai sửa đổi mà bạn cần thực hiện là Mode (Chế độ) and Background (Nền). Thiết lập Mode là Aspect Fit để hình ảnh có thể co dãn được nhưng vẫn duy trì tỷ lệ tương quan của ảnh gốc. Nếu bạn không sử dụng Aspect Fit, các hình ảnh của bạn sẽ kéo dài và co dãn cho vừa với vùng hiển thị của khung nhìn hình ảnh — và cuối cùng có thể trông rất lạ.

Vì hình ảnh có thể không phải lúc nào cũng vừa với vùng hiển thị có sẵn, bạn cũng cần thiết lập thuộc tính Background là Dark Text Color (Màu chữ đen) hoặc sử dụng bộ chọn màu để chọn một màu đen sẫm. Theo mặc định, giá trị này là màu trắng. Hầu hết các bức ảnh không nhìn rõ khi được đặt trong một màu trắng sáng chói.

Lưu tệp XIB và di chuyển sang tới tệp slideshowViewController.h. Hãy thực hiện một thay đổi nhỏ trong Liệt kê 2.

Liệt kê 2. Tệp slideshowViewController.h
#import <UIKit/UIKit.h> 
   @interface slideshowViewController : 
       UIViewController { IBOutlet UIImageView *imgView; } 
   @end

Bạn cần thêm một Outlet (Ổ cắm) tới slideshowViewController để cho phép nút điều khiển được đinh nghĩa trong XIB nối tới lớp trình điều khiển khung nhìn.

Sau khi thêm outlet, hãy quay trở lại tệp XIB, chọn UIImageView và sử dụng trình kiểm tra các kết nối để móc nối đối tượng UIImageView với biến imgView trong lớp slideshowViewController.

Sau khi tạo được kết nối đó, thực hiện các sửa đổi mã cho chính lớp của trình điều khiển khung nhìn trình chiếu để tải một hình ảnh. Liệt kê 3 cho thấy phiên bản hoàn chỉnh đầu tiên của lớp này.

Liệt kê 3. Tệp slideshowViewController.m
#import "slideshowViewController.h" 
@implementation slideshowViewController - (void)didReceiveMemoryWarning 
   { [super didReceiveMemoryWarning]; } 
   #pragma mark 
   - View lifecycle - (void)viewDidLoad {
     [super viewDidLoad]; 
     NSURL *imageURL = [NSURL
                URLWithString:@"http://localhost/photos/CRW_0675.jpg"]; 
     NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; 
     UIImage *image = [UIImage imageWithData:imageData];
     [imgView setImage:image]; 
   } 
   - (void)viewDidUnload { 
     [super viewDidUnload]; 
   } 
   - (BOOL)shouldAutorotateToInterfaceOrientation:
                (UIInterfaceOrientation)interfaceOrientation { 
     return YES; 
   } 
@end

Công việc quan trọng trong lớp slideshowViewController được thực hiện trong phương thức viewDidLoad, bây giờ phương thức này:

  • Tải dữ liệu từ một URL.
  • Chuyển dữ liệu đó thành một hình ảnh.
  • Sử dụng phương thức setImage trên khung nhìn hình ảnh để hiển thị hình ảnh đó.

Tại thời điểm này, bạn nên chạy ứng dụng để kiểm tra xem có một hình ảnh đi kèm không. Bạn sẽ thấy một hình tương tự như Hình 7, hiển thị một hình ảnh đã hiển thị trong bộ mô phỏng iPad.

Hình 7. Hình ảnh đầu tiên từ máy chủ
Ảnh chụp màn hình hình ảnh (khuôn mặt của bé gái) như được hiển thị trong trình duyệt

Nếu bạn không thấy hình ảnh đó, có khả năng vấn đề là ở cuộc gọi phương thức setImage tới imgView. Kiểm tra xem đối tượng UIImageView được kết nối đúng với biến imgView chưa. Nếu trước đó ứng dụng không kết nối được, thì có lẽ bạn không có URL đúng hoặc một cái gì đó không đúng trên máy chủ.


Phân tích cú pháp XML

Bây giờ bạn có một cách để hiển thị các hình ảnh trên một iPad, bước tiếp theo là tải XML để lấy một danh sách tất cả các hình ảnh cần hiển thị. Khung công tác iOS có trình phân tích cú pháp XML dựng sẵn, vì vậy bạn chỉ cần tạo ra đối tượng của trình phân tích cú pháp và lắng nghe các các cuộc gọi lại cho các thẻ khác nhau.

Mở rộng chính lớp đó bằng giao diện NSXMLParserDelegate, để cho khung công tác iOS biết lớp này có khả năng nhận được các cuộc gọi lại từ trình phân tích cú pháp XML. Bạn cũng cần thêm một mảng có tên là photos để lưu giữ danh sách các URL được trích ra từ XML. Liệt kê 4 cho thấy các bản cập nhật này.

Liệt kê 4. Tệp slideshowViewController.h với các bức ảnh
#import <UIKit/UIKit.h> 
@interface slideshowViewController :
                UIViewController<NSXMLParserDelegate> { 
   IBOutlet UIImageView *imgView;
   NSMutableArray *photos; 
   } 
@end

Khi bạn viết nhiều ứng dụng iOS hơn nữa, bạn sẽ thấy rằng bạn sử dụng ngày càng nhiều các ủy quyền để kết nối với các API khác nhau. Có các cuộc gọi lại dữ liệu cho các bảng, các phần tử giao diện người dùng, các cuộc gọi lại GPS và nhiều hơn nữa. Bạn thậm chí có thể tạo ra các giao diện tuỳ chỉnh của mình cho các thư viện riêng của bạn.

Để sử dụng trình phân tích cú pháp XML, hãy mở rộng lớp của trình điều khiển khung nhìn, như trong Liệt kê 5.

Liệt kê 5. Tệp slideshowViewController.m với các bức ảnh
- (void)viewDidLoad { 
   [super viewDidLoad]; 
   photos = [[NSMutableArray alloc] init]; 
   NSXMLParser *photoParser = [[[NSXMLParser alloc] initWithContentsOfURL: 
     [NSURL URLWithString:@"http://localhost/photos/index.xml"]] autorelease]; 
   [photoParser setDelegate:self]; 
   [photoParser parse]; 
   NSURL *imageURL = [NSURL URLWithString:[photos objectAtIndex:0]]; 
   NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; 
   UIImage *image = [UIImage imageWithData:imageData];
   [imgView setImage:image]; 
} 
- (void)parser:(NSXMLParser *)parser didStartElement:
     (NSString *)elementName namespaceURI:(NSString *)namespaceURI
     qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { 
    if ([elementName isEqualToString:@"photo"]) { 
      [photos addObject:[attributeDict objectForKey:@"url"]]; 
    } 
}

Bây giờ lớp này tạo ra một trình phân tích cú pháp theo phương thức viewDidLoad và đặt yêu cầu cho nó và phân tích cú pháp XML từ máy chủ. Nó cũng thiết lập ủy quyền cho trình phân tích cú pháp quay lại chính lớp đó để nó nhận được các cuộc gọi lại.

Trong ví dụ này, bạn muốn nghe cuộc gọi lại didStartElement được kích hoạt bất cứ khi nào gặp một thẻ. Sau đó chức năng didStartElement xem xét tên thẻ để xem liệu nó có là một thẻ bức ảnh không. Nếu đúng, didStartElement thêm giá trị của thuộc tính url tới mảng các bức ảnh.

Sau khi hoàn thành mảng các bức ảnh, phương thức viewDidLoad tiếp tục và thiết lập hình ảnh cho hình ảnh đầu tiên trong mảng đó.

Chạy ứng dụng để kiểm tra tiến trình của bạn. Bạn sẽ thấy hình ảnh đầu tiên được chỉ rõ trong XML xuất hiện trong bộ mô phỏng. Nếu bạn không thấy hình ảnh đầu tiên này, bạn có thể có một vấn đề với XML trên máy chủ. Hãy thiết lập một điểm ngắt trong phương thức didStartElement để xem liệu nó có đang được gọi không. Nếu nó không được gọi, thì bạn không nhận được bất kỳ XML hợp lệ nào trả về từ máy chủ của bạn.


Tạo hiệu ứng trình chiếu

Bước cuối cùng là sử dụng mảng các bức ảnh để tạo hiệu ứng cho một trình chiếu. Bạn sẽ cần hai thứ:

  • Một timer (đồng hồ hẹn giờ).
  • Một biến để lưu giữ vị trí hiện tại của bạn trong trình chiếu.

Thêm cả hai mục này vào định nghĩa lớp, như trong Liệt kê 6.

Liệt kê 6. Tệp slideshowViewController.h đã hoàn thành
#import <UIKit/UIKit.h> 
@interface slideshowViewController
      : UIViewController<NSXMLParserDelegate> { 
   IBOutlet UIImageView *imgView;
   NSMutableArray *photos; 
   NSTimer *timer; 
   int currentImage; 
} 
@end

Timer là một đối tượng sẽ phát ra các sự kiện với khoảng thời gian mà bạn quy định. CurrentImage chỉ là một chỉ mục trong mảng các bức ảnh mà bạn sẽ sử dụng để lặp qua tất cả các hình ảnh.

Liệt kê 7 cho thấy phiên bản cuối cùng của mã ứng dụng của trình chiếu.

Liệt kê 7. Tệp slideshowViewController.m đã hoàn thành
#import "slideshowViewController.h" 
@implementation slideshowViewController 
- (void)didReceiveMemoryWarning { 
   [super didReceiveMemoryWarning]; 
} 
#pragma mark 
- View lifecycle 
- (void)viewDidLoad {
  [super viewDidLoad]; 
  photos = [[NSMutableArray alloc] init]; 
  NSXMLParser *photoParser = [[[NSXMLParser alloc] 
  initWithContentsOfURL:[NSURL URLWithString:
     @"http://localhost/photos/index.xml"]] autorelease]; 
  [photoParser setDelegate:self];
  [photoParser parse]; 
  currentImage = 0; 
  NSURL *imageURL = [NSURL URLWithString:[photos objectAtIndex:0]]; 
  NSData *imageData = [NSData
                dataWithContentsOfURL:imageURL]; 
  [imgView setImage:[UIImage
                imageWithData:imageData]]; 
  timer = [NSTimer scheduledTimerWithTimeInterval: 5.0
     target: self selector: @selector(handleTimer:) userInfo: nil repeats: YES]; 
} 
-(void) handleTimer: (NSTimer *) timer { 
  currentImage++; 
  if ( currentImage >= photos.count ) currentImage = 0; 
  NSURL *imageURL = [NSURL URLWithString:[photos objectAtIndex:currentImage]]; 
  NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; 
  [imgView setImage:[UIImage imageWithData:imageData]]; 
} 
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
     namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
     attributes:(NSDictionary *)attributeDict { 
  if ([elementName isEqualToString:@"photo"]) { 
    [photos addObject:[attributeDict objectForKey:@"url"]]; 
  } 
} 
- (void)viewDidUnload { [super viewDidUnload]; } 
- (BOOL)shouldAutorotateToInterfaceOrientation:
                (UIInterfaceOrientation)interfaceOrientation { 
  return YES; 
} 
@end

Hai phần tử mới trong Liệt kê 7 là tạo đồng hồ hẹn giờ trong phương thức viewDidLoad và bổ sung phương thức handleTimer được gọi khi timer bắt đầu chạy. Phương thức handleTimer chỉ tăng thêm currentImage, sau đó quay vòng tròn chỉ mục nếu nó chạm đến cuối mảng. Nó cũng sử dụng logic tìm nạp hình ảnh tiêu chuẩn để lấy ra hình ảnh đó tại chỉ mục cụ thể và hiển thị nó.

Các timer có hai chế độ: chúng có thể chạy một lần hoặc chúng có thể chạy liên tục. Trong phương thức viewDidLoad, ví dụ này chỉ rõ YES để lặp lại sao cho phương thức handleTimer được gọi lặp lại trong vòng đời của ứng dụng.


Kết luận

Trong bài này, bạn đã tạo ra một ứng dụng iOS cơ bản. Bây giờ bạn có thể thực hiện ứng dụng theo nhiều hướng khác nhau. Khung công tác iOS CoreGraphics cung cấp một bộ các quá trình chuyển tiếp phong phú mà bạn có thể sử dụng để tạo hiệu ứng thay đổi giữa các hình ảnh. Bạn có thể sử dụng PHP ở tầng sau để tạo XML động. Hoặc thậm chí bạn có thể sử dụng API CoreAudio để đặt một số bản nhạc bên dưới toàn bộ trình chiếu.

Tài nguyên

Học tập

Lấy sản phẩm và công nghệ

Thảo luận

Bình luận

developerWorks: Đăng nhập

Các trường được đánh dấu hoa thị là bắt buộc (*).


Bạn cần một ID của IBM?
Bạn quên định danh?


Bạn quên mật khẩu?
Đổi mật khẩu

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Ở lần bạn đăng nhập đầu tiên vào trang developerWorks, một hồ sơ cá nhân của bạn được tạo ra. Thông tin trong bản hồ sơ này (tên bạn, nước/vùng lãnh thổ, và tên cơ quan) sẽ được trưng ra cho mọi người và sẽ đi cùng các nội dung mà bạn đăng, trừ khi bạn chọn việc ẩn tên cơ quan của bạn. Bạn có thể cập nhật tài khoản trên trang IBM bất cứ khi nào.

Thông tin gửi đi được đảm bảo an toàn.

Chọn tên hiển thị của bạn



Lần đầu tiên bạn đăng nhập vào trang developerWorks, một bản trích ngang được tạo ra cho bạn, bạn cần phải chọn một tên để hiển thị. Tên hiển thị của bạn sẽ đi kèm theo các nội dung mà bạn đăng tải trên developerWorks.

Tên hiển thị cần có từ 3 đến 30 ký tự. Tên xuất hiện của bạn phải là duy nhất trên trang Cộng đồng developerWorks và vì lí do an ninh nó không phải là địa chỉ email của bạn.

Các trường được đánh dấu hoa thị là bắt buộc (*).

(Tên hiển thị cần có từ 3 đến 30 ký tự)

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Thông tin gửi đi được đảm bảo an toàn.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=70
Zone=Nguồn mở
ArticleID=823472
ArticleTitle=Xây dựng một ứng dụng trình chiếu iOS cho iPad
publish-date=07092012