使用控制器类来管理一个使用 iPhone SDK 工具包的客户端应用程序的视图部分是将 IBM WebSphere CloudBurst Appliance 与 Apple iPhone 设备集成在一起的 Web 2.0 应用程序开发的下一步。该应用程序使用工具包来实现模型-视图-控制器框架(Model-View-Controller Framework)。在 第 2 部分 中,您创建了视图部件及其对象(如按钮、文本框和表示视图)。在控制器类中,您创建了对象来管理协作。在本文中,您将在视图控制器类和 iPhone 应用程序相应的视图之间创建连接来管理应用程序内部的流控制器。
同上两期一样,本系列文章假定您对 Web 2.0 技术,包括 Rest、ATOM、JSON 和 Objective-C 有一个大致了解。这些文章中描述的示例应用程序是通过 Objective-C 中的模型-视图-控制器 (MVC) 模式,使用 Apple iPhone SDK 3.x 实现的,并将在一台安装了 3.x 固件的 iPhone(或 iPod Touch)设备上运行。因此,这个开发假设您基本了解 C 编程语言(Object-C 继承了所有 C 的特性)。而且,理解基本的面向对象概念(如继承、类、接口等)也很重要。
此外,这个练习使用了 Cocoa 框架,它是由一组 API、程序库和组成 iPhone SDK 开发层的运行时代码所构成的。Cocoa 是用 Object-C 实现的,并使用 MVC 模式来封装视图、应用程序数据、控制器和实现管理逻辑的类。
最后,要完成本文所介绍的步骤和运行例子,您需要在计算机上安装 Apple SDK 3.0 或以上版本,运行一个 Mac OS 兼容版本。您还需要运行在您环境中的 WebSphere CloudBurst Appliance 的访问权限。
每次在您开始创建 Cocoa 项目时,您都需要选择一个模板。对于本练习,您将选择 Tab Bar Application 模板。此模板会生成两个窗口(见图 1)和一个让您在这两个窗口之间进行切换的选项卡栏。
- First View: MainWindow.xib
- Second View: SecondView.xib
图 1. 应用程序视图
如果您打开 MainWindows.xib 的 View Component 窗口,您将看到如图 2 所示的结构。它是由以下内容组成:
- File's Owner(委托给 Test App Delegate)
- First Responder
- Test App Delegate
- Windows (不使用的通用窗口)
- Tab Bar Controller(管理两个 View Controller(First View 和 Second View)的选项卡栏控制器。)
- Tab Bar
- First View controller(适用于 First View)
- View(由 FirstViewController 管理的视图)
- Tab Bar Item(First View 的 Bar Controller 中的项)
- Second View controller(适用于 Second View)
- View(由 FirstViewController 管理的视图)
- Tab Bar Item(Second View 的 Bar Controller 中的项)
图 2. MainWindow 结构
TNavigation Controller 管理应用程序窗口流中视图之间的导航。正如在 第 2 部分 中所讨论的,您将使用三个界面之间的简单导航来设计应用程序。要做到这一点,您需要在 MainWindows 中定义 Navigation Controller。
Navigation Controller 具有以下部件:
- Navigation Controller:这是控制器对象,处理导航事件并将其所有捆绑在一起。
- Navigation Bar:这是位于顶部的工具栏,使用户可以看到他们正在遍历的一个导航层次结构,并使他们能够向后导航。
- View Controller:这是与 hold 视图相关的 View Controller 类。
- Navigation Item:导航项位于 Navigation Bar 中且具有用于导航的按钮。
在 MainWindow.xib 组件窗口中,请更改在 Tab Bar Controller 组件中定义的第一个视图控制器。
- 在 MainWindow 组件窗口中选择 Tab bar controller。
- 选择 Attribute View 并将名为 First 的 View Controller 类从
View Controller更改到Navigation Controller,如图 3 所示。
图 3. Navigation Controller 类定义
凭借 Navigation Controller 类,管理应用程序视图之间的导航成为可能。在此项目中,您将在 OneView.xib 文件(具有 OneViewController 类)中创建第一个视图。您需要用 OneView 替换 MainWindow。
- 通过单击顶部窗口选择包含 First 视图的窗口。
- 在视图内选择 First View 面板并删除它们。注意:请不要 选择标签。在图 4 中,在删除之后,您可以看到该视图。
图 4. 主视图
- 在视图窗口中,通过单击 View 的灰框部分来确保选择空视图。
- 在 View Controller 属性中,使用下拉菜单插入 NIB 文件:OneView。
图 5. OneView
- 单击左侧面板中部的 One View 蓝色链接以便打开 One View 视图。
- 在 View Component 视图中选择 File's Owner。
- 使用 Class 下拉菜单为选中的 One View 视图分配 OneViewController 视图控制器类。这意味着 OneViewController 类是 OneView 视图(图 6)的控制器。
图 6. OneView 控制器类
- 保存所有更改。
- 通过单击 Build > Build and Run 可以测试应用程序。
现在您可以看到 OneView 作为应用程序中的第一个打开窗口。
在您创建 OneViewController 类时,您定义了实例变量来管理视图组件。这些变量是:
- field1:适用于第一个输入字段
- field2:适用于第二个输入字段
- description:适用于测试文本字段
您需要分配这些变量到每一个视图组件。现在,让我们看看如何连接 field1。(您将使用相应的实例变量对所有视图组件重复此操作。)
- 在 Interface Builder 中打开 OneView。
- 选择 File's Owner。它应该是 OneViewController 类。
- 使用鼠标右键,将 File's Owner 行拖到第一个文本字段上,如图 7 所示。
图 7. 分配实例变量
- 从拖动操作结束时出现已分配给此组件的变量的菜单中选择。
图 8. 变量表
- 对所有视图组件重复相同的操作。为每个视图组件选择相应的实例变量。
最后,将所有实例变量都分配给视图组件。
在 OneView 中,有以下三个按钮:
- test:分配给
(IBAction) buttonPressedTest - load:分配给
(IBAction) buttonDownload - next:分配给
(IBAction) buttonNext
您需要将每一个操作分配给相应的按钮视图组件。现在将连接测试按钮。(使用相应的方法对所有按钮重复相同的操作。)
- 在 OneView 组件窗口中选择 Test 按钮。
- 在 Button Connection 中,您可以看到所有按钮事件。
- 使用鼠标左键,拖动您想要管理的操作(如 Touch Down)到 File's Owner 行。
- 从在拖动操作(例如,buttonPressedtest)结束时出现的列表中选择。
- 对所有的按钮重复相同的操作。为每个按钮组件选择相应的方法。
图 9. OneViewController 连接
现在您可以在类中插入所有需要的代码来管理 buttonPressedTest 和 buttonNext。ButtonPressedTest 方法会在 responseString 变量(参见清单 1)中加载测试文件 (example.sql)。
清单 1. (IBAction) buttonPressedTest
<![CDATA[
(IBAction) buttonPressedTest
{
[field1 resignFirstResponder];
[field2 resignFirstResponder];
NSString *filePath = [[NSBundle mainBundle]
pathForResource:@"example"
ofType:@"sql"];
NSString *responseString = [NSString stringWithContentsOfFile:filePath];
NSLog(@"responseString:%@",responseString);
description.text = responseString;
}]]> |
Example.sql 文件包含如清单 2 中所示的项。
清单 2. example.sql
[
{
"desiredstatus_text": null,
"currentstatus_text": "Stopped",
"created": 1260941860895,
"name": "Single Server",
"currentstatus": "RM01011",
"desiredstatus": null,
"currentmessage": "RM07153",
"pattern": "/resources/patterns/1",
"owner": "/resources/users/6",
"updated": 1260943821497,
"id": 51,
"currentmessage_text": "Stopped"
},
{
"desiredstatus_text": null,
"currentstatus_text": "Running",
"created": 1263868560454,
"name": "05WASadmin Cloned Lab Virtual System",
"currentstatus": "RM01005",
"desiredstatus": "",
"currentmessage": "RM07054(\"05WASAdmin+Lab+Application\",\"05WASadmin+Cloned+Lab+
Virtual+System+vm-001-016+dmgr\")",
"pattern": "/resources/patterns/43",
"owner": "/resources/users/15",
"updated": 1263869039755,
"id": 59,
"currentmessage_text": "script package of 05WASAdmin Lab Application
on VM 05WASadmin Cloned Lab Virtual System vm-001-016 dmgr"
},
{
"desiredstatus_text": null,
"currentstatus_text": "Stopped",
"created": 1263857152896,
"name": "Financial Application Test Group Sys 05",
"currentstatus": "RM01011",
"desiredstatus": null,
"currentmessage": "RM07153",
"pattern": "/resources/patterns/1",
"owner": "/resources/users/15",
"updated": 1263863898994,
"id": 54,
"currentmessage_text": "Stopped"
},
{
"desiredstatus_text": null,
"currentstatus_text": "Run",
"created": 1263857159858,
"name": "John",
"currentstatus": "RM01006",
"desiredstatus": "",
"currentmessage": "RM07045",
"pattern": "/resources/patterns/1",
"owner": "/resources/users/14",
"updated": 1263857536925,
"id": 55,
"currentmessage_text": "The VM is available"
},
{
"desiredstatus_text": null,
"currentstatus_text": "Run",
"created": 1263862881511,
"name": "LucaV",
"currentstatus": "RM01006",
"desiredstatus": "",
"currentmessage": "RM07045",
"pattern": "/resources/patterns/1",
"owner": "/resources/users/4",
"updated": 1263863256864,
"id": 56,
"currentmessage_text": "The VM is available"
}
] |
ButtonNext 方法将调用 ListElement 视图并实例化 ListElementViewController,如清单 3 所示。
Listing 3. (IBAction) buttonNext
<![CDATA[
-(IBAction) buttonNext
{
[field1 resignFirstResponder];
NSString *server = field1.text;
ListElementViewController *listElementController =
[[ListElementViewController alloc]
initWithNibName:@"ListElementView"
bundle:nil];
NSLog(@"func UnoViewController.buttonNext ");
[listElementController setDescpText:server];
[self.navigationController pushViewController:listElementController
animated:YES];
]]>
[listElementController loadJsonText:description.text];
<![CDATA[
}
]]> |
LoadJsonText 方法将接收的数据从 WCA 注入到 ListElementViewController。该接收的数据用于显示视图上的列表。
ListElement 视图由惟一的视图组件(Table View 组件)组成。虽然此组件在视图控制器类内不具有已分配的实例变量,但是您需要定义类 delegate 。这是必要的,因为您需要定义许多方法来管理所有必要的表视图操作。有必要时该框架都会调用类 delegate,且该类必须执行所有需要的方法。这些方法是:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
在 delegate 类中创建这些方法。定义 ListElement 视图的 delegate 类。为了简化,您将对视图控制器和表视图 delegate 这两种方法使用相同的类(如 ListElementViewController)。
- 打开 ListElementView.xib 文件并在 Identity 视图中插入 ListElementViewController 类。
- 在视图组件窗口中选择 Table View 组件。
- 选择 Table View connection。
- 使用鼠标左键,在视图组件窗口中从 dataSource 标签拖动到 File's Owner。
- 对 delegate 标签使用相同的操作。
图 10 显示了最终的 Table View connections。
图 10. 表视图 dataSource 和 delegate
此视图从调用方视图控制器接收 JSON 数据文件。在此解决方案中,先前的视图管理网络连接协议。虽然此视图将代替管理数据(不知道数据会到哪里),但是它必须将文本字符串(类 JSON 格式)转换为 Objective-C 数据对象。要获取字典,您就要使用 VirtualSystems 类。正如 第 2 部分 讨论的,您将包括在此 JSON 分析程序类中。要在类声明的顶部执行此操作,您需要包括:
- #import "JSON/JSON.h":根据 JSON 分析程序选择而不同。
- #import "VirtualSystems.h":包括用于获取 JSON 数据对象的类。在 JSON 文本文件中发现的每个元素都将转换为 VirtualSystems 对象。
调用方类 (OneViewController) 之间的连接和 ListElementViewController 都用以下代码方法执行,如清单 4 所示。
清单 4. IBAction) loadJsonText:(NSString *)jsonString.h
<![CDATA[
- (IBAction) loadJsonText:(NSString *)jsonString{
NSLog(@"func UnoViewController.loadJsonText :%@ ",jsonString);
NSError *error;]]><![CDATA[
SBJSON *json = [[SBJSON new] autorelease];
NSArray *luckyNumbers = [json objectWithString:jsonString
error:&error];
]]>
<![CDATA[for (int i = 0; i < [luckyNumbers count]; i++)
{
NSLog(@"number:%@",[luckyNumbers objectAtIndex:i]);
NSDictionary *tmpDict= [luckyNumbers objectAtIndex:i];
VirtualSystems *elem = [[VirtualSystems alloc]
initWithJSON:tmpDict name:@"test"];
[listElement addObject:elem];
[elem release];
}
}
]]> |
您会看到粗体的代码,这取决于您对 JSON 解析器的选择。根据解析器操作说明更改这几行代码。在这个示例中,该方法使用 SBJSON 对象来解析和获取数据对象数组。对于此数组中发现的每一个元素,您将创建一个 VirtualSystems 对象并在实例变量 (listElement) 中加载它。
正如您所看到的,我们使用了 NSDictionary 对象。Objective-C 中的字典是一个具有两组信息(惟一的密钥和相关的值)的对象,且使您能够使用该密钥来检索条目。如果您需要方便快捷的方式来检索与任意密钥相关的数据,那么您应该使用此种类型的对象。该密钥通常是整型或字符串的,条目是任何类型的。因为您使用了 NSDictionary,所以您创建了静态字典。由密钥和相关数据组成的每一行被称为一个条目。在字典内,密钥是惟一的。密钥或值可能是 null(如果需要字典中的 null 值,请使用 NSNull 替代)。您从 JSON 文件中提取数据并在被称为 tmpDict 的 Dictionary 对象中映射信息。根据已使用的 JSON 结构,Dictionary 对象会具有以下字段:
- desiredstatus_text
- currentstatus_text
- created
- name
- currentstatus
- desiredstatus
- currentmessage
- pattern
- owner
- updated
- id
- currentmessage_text
这些字段将包含从每项的 JSON 文件中提取的值。JSON 结构的每个节点都将有一个条目。在这种情况下,您将有 5 个条目。
在 ListElement 视图中,您将插入一个简单的 Table 视图。您将在单一的行表中创建一个具有更多标签的复杂列表和一个图标。有很多方法可以做到这一点。这里所用的方法不使用任何图形化界面,因此使用代码您将在表视图内部插入每个视图组件。
可以用 cellForRowAtIndexPath 方法来实现此功能。每次调用此方法,系统都需要了解何如构建表视图的任何单行。这样,您可以创建彼此之间不同的行。要减少使用这种方法,您将要在两种不同的块中构建方法,这两种块是:
- cell==nil:只有在第一次时此测试才为 true。您将为行创建单元格。
- cell!=nil:这意味着已经创建了单元格行。您需要将惟一的值分配给该单元格标签。在这种情况下,请跳过创建视图单元格表。
使用此方法,您需要在屏幕布局中使用正确的组件位置来设置编码(在单元格创建期间)。要做到这一点,您需要逐点地定义正确的 Frame 矩形点(rectangle point)(清单 5)。
清单 5. cellForRowAtIndexPath 方法
<![CDATA[
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"ImageOnRightCell";
UILabel *mainLabel, *secondLabel;
UIImageView *photo;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
mainLabel = [[[UILabel alloc]
initWithFrame:CGRectMake(0.0, 0.0, 290.0, 18.0)] autorelease];
mainLabel.tag = MAINLABEL_TAG;
mainLabel.font = [UIFont systemFontOfSize:14.0];
mainLabel.textAlignment = UITextAlignmentRight;
mainLabel.textColor = [UIColor blackColor];
mainLabel.autoresizingMask =
UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
[cell.contentView addSubview:mainLabel];
secondLabel = [[[UILabel alloc]
initWithFrame:CGRectMake(0.0, 20.0, 265.0, 25.0)] autorelease];
secondLabel.tag = SECONDLABEL_TAG;
secondLabel.font = [UIFont systemFontOfSize:12.0];
secondLabel.textAlignment = UITextAlignmentRight;
secondLabel.textColor = [UIColor darkGrayColor];
secondLabel.autoresizingMask =
UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
[cell.contentView addSubview:secondLabel];
photo = [[[UIImageView alloc]
initWithFrame:CGRectMake(270.0, 18.0, 25.0, 25.0)] autorelease];
photo.tag = PHOTO_TAG;
photo.autoresizingMask =
UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
[cell.contentView addSubview:photo];
} else {
mainLabel = (UILabel *)[cell.contentView viewWithTag:MAINLABEL_TAG];
secondLabel = (UILabel *)[cell.contentView viewWithTag:SECONDLABEL_TAG];
photo = (UIImageView *)[cell.contentView viewWithTag:PHOTO_TAG];
}
VirtualSystems *vs = (VirtualSystems *) [listElement
objectAtIndex:indexPath.row];
mainLabel.text = [vs getName];
secondLabel.text = [NSString stringWithFormat:@"%i",[vs getId]];
NSString *status=[vs getCurrentstatus];
NSString *imagePath = [[NSBundle mainBundle] pathForResource:status
ofType:@"png"];
UIImage *theImage = [UIImage imageWithContentsOfFile:imagePath];
photo.image = theImage;
return cell;
}
]]> |
当用户在表中选择特定行时,您需要识别选定行中所示的虚拟系统、从 listElement 阵列检索其数据以及调用 ListElementView 和其视图控制器。
在执行选择操作时将通过视图调用方法 didSelectRowAtIndexPath。该方法接收列表中选定元素的索引,且您将使用此索引来识别 listElement 元素、提取它并使用 setVirtualSystem 行为将其推入 DetailSystemViewController,如清单 6 所示。在退出该视图以前,请取消选定行。
清单 6. didSelectRowAtIndexPath 方法
<![CDATA[
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
VirtualSystems *elem = (VirtualSystems *)[listElement
objectAtIndex:indexPath.row];
DetailSystemViewController *dettaglioController =
[[DetailSystemViewController alloc]
initWithNibName:@"DetailSystemView" bundle:nil];
NSLog(@"func didSelectRowAtIndexPath elem.keyID:%i",indexPath.row);
[dettaglioController setVirtulaSystem: elem];
[self.navigationController pushViewController:dettaglioController
animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
]]> |
此视图已经接收了单一系统的信息作为 VirtualSystems 对象的实例。此对象是由 ListElement 视图中的用户选择的元素。使用 -(void)setVirtualSystems: 行为可将该对象存储在 aSystem 实例变量中。对象中的值用于将信息分配给视图元素并将其显示给用户。您将使用图标来描述系统状态(虽然您可以在下载 部分中发现图标示例,但是您已可以使用其他图标):
- RM01011:系统停止
- RM01006:系统正在运行
- RM01005:未知系统状态
将选定图标加载到项目中:
- 在 Mac 文件系统内加载图标。
- 将这些图标分别重命名为
RM01005.png、RM01006.png和RM01011.png。 - 选择如本系列 第 1 部分 所描述的 Add > Existing Files。
要简化代码,请分配通过 REST 联合检索的相同状态代码的图标。
您将从 aSystem 实例变量设置分配值到 -(void)viewDidLoad 方法中的视图组件。在清单 7 和清单 8 中,您可以看到 DetailSystemsViewController 代码。
清单 7. DetailSystemsViewController.h
<![CDATA[
//
// DetailSystemViewController.h
// WCA000
//
// Created by luca amato on 9/27/10.
//
#import <UIKit/UIKit.h>
#import "VirtualSystems.h"
@interface DetailSystemViewController : UIViewController {
IBOutlet UILabel *name;
IBOutlet UILabel *currentStatusText;
IBOutlet UILabel *created;
IBOutlet UILabel *owner;
IBOutlet UIImageView *statusImg;
IBOutlet UITextView *currentMessageText;
VirtualSystems *aSystem;
}
@property (nonatomic, retain) VirtualSystems *aSystem;
- (void)setVirtulaSystem:(VirtualSystems *)system;
@end]]> |
清单 8. DetailSystemsViewController.m
<![CDATA[
//
// DetailSystemViewController.m
// WCA000
//
// Created by luca amato on 9/27/10.
//
#import "DetailSystemViewController.h"
@implementation DetailSystemViewController
// Implement viewDidLoad to do additional setup
// after loading the view, typically from a nib.
- (void)viewDidLoad {
NSString *status=[aSystem getCurrentstatus];
NSString *imagePath = [[NSBundle mainBundle]
pathForResource:status ofType:@"png"];
statusImg.image = [UIImage imageWithContentsOfFile:imagePath];
self.title=[NSString stringWithFormat:@"%i",[aSystem getId]];
name.text=[aSystem getName];
created.text=[aSystem getCreated];
currentStatusText.text = [aSystem getCurrentstatusText];
currentMessageText.text = [aSystem getCurrentmessage];
NSObject *tmp=[aSystem getCreated];
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
}
- (void)dealloc {
[super dealloc];
}
- (void)setVirtulaSystem:(VirtualSystems *)system {
aSystem = system;
}
@end]]> |
现在您可以保存该文件。从选项菜单中选择 File > Save。
在很多用户应用程序中,保存应用程序状态很有用。在下一次启动应用程序时将检索已保存的信息,且在合适的字段中,是最近在应用程序中使用的值。
有很多方法可以做到这一点。在这里,使用一个简单文件就可以实现此功能。SDK 框架提供了一种方式以便将对象(包括标量值)编码成与体系结构无关的格式。您可以使用此类在文件中存储对象。这种键控存档文件(keyed archive)是使用 NSKeyedArchiver 实现的。要获得更多详细信息,请参见 Cocoa 库参考文档。在实例化第一个应用程序类(OneViewController)时,您将检索数据。第一次,您必须检查是否存在存档文件。如果不存在,您就必须创建一个空文件。在部署最后一个类时,将状态信息写进该文件。
对于一个良好的面向对象的方法来说,您将创建一个特定的类来管理所有必要的状态键值。您应该有 4 个值存储在状态文件中。因此,请创建 FourLines 类。此类管理 4 个值,每一个值都有特定的字段密钥。您将在 h 文件中定义该字段密钥值为常数:Field1,Field2,Field3,Field4。
保存 Field1 FourLine 密钥中的服务器名(来自 field1)以及 Field2 FourLines 密钥中的 User ID(来自 field2)(清单 9 和 10)。出于安全原因,密码不会存储在应用程序状态中。
清单 9. FourLines.h
<![CDATA[
//
// FourLines.h
// WCA000
//
// Created by luca amato on 9/27/10.
//
#import <Foundation/Foundation.h>
#define FIELD1KEY @"Field1"
#define FIELD2KEY @"Field2"
#define FIELD3KEY @"Field3"
#define FIELD4KEY @"Field4"
@interface FourLines : NSObject <NSCoding, NSCopying> {
NSString *field1 ;
NSString *field2 ;
NSString *field3 ;
NSString *field4 ;
}
@property (nonatomic, retain) NSString *field1;
@property (nonatomic, retain) NSString *field2;
@property (nonatomic, retain) NSString *field3;
@property (nonatomic, retain) NSString *field4;
@end
]]>
|
清单 10. FourLines.m
<![CDATA[
//
// FourLines.m
// Persistence
//
// Created by luca amato on 9/11/10.
//
#import "FourLines.h"
@implementation FourLines
@synthesize field1;
@synthesize field2;
@synthesize field3;
@synthesize field4;
#pragma mark NSCoding
-(void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:field1 forKey:FIELD1KEY];
[encoder encodeObject:field2 forKey:FIELD2KEY];
[encoder encodeObject:field3 forKey:FIELD3KEY];
[encoder encodeObject:field4 forKey:FIELD4KEY];
}
-(id)initWithCoder:(NSCoder *)decoder
{
if (self = [super init])
{
self.field1 = [decoder decodeObjectForKey:FIELD1KEY];
self.field2 = [decoder decodeObjectForKey:FIELD2KEY];
self.field3 = [decoder decodeObjectForKey:FIELD3KEY];
self.field4 = [decoder decodeObjectForKey:FIELD4KEY];
}
return self;
}
#pragma mark -
#pragma mark NSCopying
-(id)copyWithZone:(NSZone *)zone
{
FourLines *copy = [[[self class] allocWithZone:zone] init];
field1 = [self.field1 copy];
field2 = [self.field2 copy];
field3 = [self.field3 copy];
field4 = [self.field4 copy];
return copy;
}
@end
]]>
|
清单 11 所显示的代码部分可检索已保存的文件并从 FourLines 类提取特定字段值。
清单 11. 检索 FourLines
<![CDATA[ . . NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePathPersistence]]; NSKeyedUnarchiver *unarch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; FourLines *fourLines = [unarch decodeObjectForKey:DATAKEY]; [unarch finishDecoding]; field1.text = fourLines.field1; field2.text = fourLines.field2; [unarch release]; [data release]; . .]]> |
清单 12 中的代码部分可保存 FourLines 类。
清单 12. 保存 FourLines
<![CDATA[ . . FourLines *fourLines = [[FourLines alloc] init]; fourLines.field1 = field1.text; fourLines.field2 = field2.text; fourLines.field3 = @"uno"; fourLines.field4 = @"due"; NSMutableData *data = [[NSMutableData alloc] init]; NSKeyedArchiver *arch = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; [arch encodeObject:fourLines forKey:DATAKEY]; [arch finishEncoding]; [data writeToFile:[self dataFilePathPersistence] atomically:YES]; . .]]> |
您将在 OneViewController 类中插入这些代码,并在 -(void)DidLoad 方法插入检索方法代码。这将在加载 OneView 以后调用。
在删除 OneView 时调用 -(void)applicationWillTerminate 方法中保存的代码。在清单 13 中,您可以看到在 Unplugged 模式下运行的 OneViewController 类的完整代码。正如您看到的,从名为 example.sql 的静态文件中检索 JSON 数据。
清单 13. OneViewController.m
<![CDATA[
//
// UnoViewController.m
// WCA000
//
// Created by luca amato on 9/25/10.
//
#import "UnoViewController.h"
#import "ListElementViewController.h"
#import "FourLines.h"
#import "AlertPrompt.h"
@implementation UnoViewController
@synthesize inputString;
@synthesize field1 ;
@synthesize field2 ;
@synthesize description;
// Implement viewDidLoad to do additional setup
// after loading the view, typically from a nib.
- (void)viewDidLoad {
self.title = @"WCA Server";
NSString *filePath = [self dataFilePathPersistence];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
NSData *data = [[NSMutableData alloc]
initWithContentsOfFile:[self dataFilePathPersistence]];
NSKeyedUnarchiver *unarch = [[NSKeyedUnarchiver alloc]
initForReadingWithData:data];
FourLines *fourLines = [unarch decodeObjectForKey:DATAKEY];
[unarch finishDecoding];
field1.text = fourLines.field1;
field2.text = fourLines.field2;
[unarch release];
[data release];
}
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(applicationWillTerminate:)
name:UIApplicationWillTerminateNotification object:app
];
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
[super dealloc];
}
-(NSString *)dataFilePath
{
NSArray *path = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [path objectAtIndex:0];
return [documentDirectory stringByAppendingPathComponent: FILENAMEARCH];
}
-(IBAction) buttonDownloadImage
{
}
-(IBAction) buttonPressedTest
{
[field1 resignFirstResponder];
[field2 resignFirstResponder];
NSString *filePath = [[NSBundle mainBundle]
pathForResource:@"example" ofType:@"sql"];
NSString *responseString = [NSString stringWithContentsOfFile:filePath];
NSLog(@"responseString:%@",responseString);
description.text = responseString;
}
-(IBAction) buttonNext
{
[field1 resignFirstResponder];
NSString *server = field1.text;
ListElementViewController *listElementController =
[[ListElementViewController alloc]
initWithNibName:@"ListElementView" bundle:nil];
NSLog(@"func UnoViewController.buttonNext ");
[listElementController setDescpText:server];
[self.navigationController pushViewController:listElementController
animated:YES];
[listElementController loadJsonText:description.text];
}
-(NSString *)dataFilePathPersistence
{
NSArray *path = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [path objectAtIndex:0];
return [documentDirectory stringByAppendingPathComponent: FILENAMEARCH];
}
-(void)applicationWillTerminate:(NSNotification *)notification
{
FourLines *fourLines = [[FourLines alloc] init];
fourLines.field1 = field1.text;
fourLines.field2 = field2.text;
fourLines.field3 = @"uno";
fourLines.field4 = @"due";
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *arch = [[NSKeyedArchiver alloc]
initForWritingWithMutableData:data];
[arch encodeObject:fourLines forKey:DATAKEY];
[arch finishEncoding];
[data writeToFile:[self dataFilePathPersistence] atomically:YES];
[fourLines release];
[arch release];
[data release];
}
@end
]]>
|
确保保存所有文件。现在您可以通过从 Go 菜单选择 Build > Build 来测试应用程序。如果您发现一些错误,请删除它们并重新编译该项目。
要在主屏幕中测试应用程序,请单击 Test 按钮。在底部,您可以看到测试文件。单击 Next 按钮。该窗口显示了一系列在示例 JSON 文件中定义的服务器。您可以选择在行中存在的系统。在下一个视图 (DetailSystemView) 中,应用程序将显示选中系统的详细信息。在每一个视图中,使用视图顶部的导航工具栏中的按钮,您可以返回。使用向后按钮,您会看到前面视图的标题。
在本文中,使用 Cocoa 框架您可以创建 MVC 框架的控制器部件。该控制器类管理 GUI、实现 Navigation Controller、连接视图组件并分配操作给 GUI 的每一个按钮。然而,应用程序不管理 HTTPS 协议。要与 WebSphere Cloudburst Appliance 进行通信,您将需要实现网络元素,包括安全管理,这在 本系列结束语 中进行了描述。
| 描述 | 名字 | 大小 | 下载方法 |
|---|---|---|---|
| Sample code | 1105_amato1_WCAsample.zip | 1.5MB | HTTP |
学习
-
IBM WebSphere Cloudburst Appliance 产品信息
-
developerWorks 云计算专区
- 系列:管理您的私有云
- 系列:企业云计算
-
使用 XML-RPC 为 Web 服务启用 C++ 应用程序
-
Apple 开发者资源
-
Mac OS X Cocoa Frameworks
-
iOS 开发中心
-
JSON
-
Objective-C 教程
-
developerWorks WebSphere Application Server 专区
-
IBM developerWorks 中国 WebSphere 专区:为使用 WebSphere 产品的开发人员准备的技术信息和资料。这里提供产品下载、how-to 信息、支持资源以及免费技术库,包含 2000 多份技术文章、教程、最佳实践、IBM Redbook 和在线产品手册。
获得产品和技术
- 最受欢迎的 WebSphere 试用软件下载:下载关键 WebSphere 产品的免费试用版。
- IBM developerWorks 软件下载资源中心:IBM deveperWorks 最新的软件下载。
- IBM developerWorks 工具包:下载关键 WebSphere 最新的产品工具包。
讨论
- 加入 developerWorks 中文社区,developerWorks 社区是一个面向全球 IT 专业人员,可以提供博客、书签、wiki、群组、联系、共享和协作等社区功能的专业社交网络社区。
- 加入 IBM 软件下载与技术交流群组,参与在线交流。