同时学iPhone和wp7开发(一)
去年看iPhone很火,心头痒痒就去买了本iPhone开发入门经典,那时候没现在这么多书(现在书城里都有一书架的iPhone开发书籍了),这本入门经典是网上很多人推荐的。兴冲冲买回来就看了第一章。可怜啊,加班经常半夜1,2点,回来倒头睡,电脑都不想摸一下。书就放在那里落满了灰尘。最近有了时间,心想不能让69块钱白花呀,于是把书皮上的灰尘擦去,又开始了iPhone开发的学习。我没有c/c++和obj-c的经验,就会点C#,还是不精通那种,mac也从没拥有过。算是从零开始。然后又突发奇想,在学习iPhone开发时,顺便也学习WP7的开发,虽然Silverlight,XNA,WPF之类的都一点不会,好赖还有C#的语言基础,至少不用学语法了。
准备环境:
wp7:下载vm_web2.exe,运行,网络顺畅的话,很快搞定。
iPhone:没有mac,只能在虚拟机上安装,怎么安装,网上教程一大把,照着做就行了。用的Vmware,安装时是雪豹10.6.0,可以通过软件更新升级到10.6.8,Xcode用的3.2.4,ios sdk是4.1,为什么不是最新版的sdk呢,这个后面讲。
三个Hello World:
环境准备完毕,我们来写三个Hello World,wp7一个,iPhone两个,为什么是两个呢,有一个是MonoTouch写的
wp7版:打开VS2010 Express For WP,New---Project
vm_web2下载的是wp7.1 sdk,所以能看到项目模板里有VB了,以前7.0是不能用VB来编写的。当然,我们还是用C#来写。
选择Window Phone Application,确定后会弹出选择wp7.0还是wp7.1,选择完毕后,VS会创建好工程目录。
我们是从零开始,不会SL,不会XNA,就当在做WinForm把,从ToolBox拖出来两个控件,按钮和文本标签
设置一下标签和按钮的属性,然后双击按钮,生成事件,在事件里写代码。。多么熟悉的操作步骤啊。跟WinForm一样。
生成的XAML代码:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <TextBlock Height="96" HorizontalAlignment="Left" Margin="73,81,0,0" Name="lbShow" Text="" VerticalAlignment="Top" Width="311" FontSize="56" TextAlignment="Center"/> <Button Content="Click" Height="72" HorizontalAlignment="Left" Margin="144,231,0,0" Name="btnClick" VerticalAlignment="Top" Width="160" Click="btnClick_Click" FontSize="28"/> </Grid>
C#代码:
publicpartialclass MainPage : PhoneApplicationPage { // Constructor public MainPage() { InitializeComponent(); } privatevoid btnClick_Click(object sender, RoutedEventArgs e) { lbShow.Text ="Hello World"; } }
分析:可以想想ASP.NET,用HTML做页面,用C#写逻辑。换成用XAML描述UI,还是用C#写逻辑。
总结:从第一个简单的HelloWorld Demo来看,没接触过SilverLight,只会WinForm或者WebForm完全没障碍。一行代码,两次拖拉,实现起来超级简单。
iPhone版:打开虚拟机,启动mac os,打开xcode,File----New Project----选iOS----Application---View-Based Application。
Xcode像VS2010一样创建好了工程目录结构。参考着我1年前买的入门经典,再加上斯坦福大学的iPhone开发公开课第一课,尝试倒腾了俩小时,才做出了和上面wp7一样效果的一个Hello World。个中曲折最后总结再说,这里直接列出正确的步骤
首先双击Resources目录里的Hello_WorldViewController.xib,会调用Interface Builder打开这个xib文件
同样拖拉出一个文本标签Label,一个按钮Round Rect Button,在iPhone中按钮是圆角按钮,拖到界面之后,就没那么容易了,按照思路,现在应该是给按钮写一个事件,当点击按钮时候,文本标签的字改变成Hello World,拆分开看,只要弄明白两件事,这活就成了。1,怎么设置标签的值,还是XXX.text = "xxx"吗? 2,怎么给按钮添加一个事件。双击现在是不成的啦。
首先,想通过代码读取或者设置控件的属性值,也就是想操作控件的话,不像wp7里那样,拖出控件来就可以用。必须在代码中先定义一个,然后和Interface Builder里拖出来的关联在一起,并设置它的get,set。要操作按钮,也要先定义。
在Xcode里选Hello_WorldViewController.h,在里面定义:
#import<UIKit/UIKit.h> @interface Hello_WorldViewController : UIViewController { IBOutlet UILabel *lbShow; } @property (retain nonatomic) UILabel *lbShow; -(IBAction)changeLabelText:(id)sender; @end
定义好了之后,在IB里关联。按住Ctrl从File's owner拖到label关联属性,右键点按钮,选Touch up Inside事件,点旁边的+号,拖到File's owner关联事件。
好了,到这里,才算是做完了和wp7拖出俩控件一样的工作。可以写逻辑了。
在Hello_WorldViewController.m里实现刚才定义的changeLabelText方法,看后面那个参数sender,想想wp7里事件的那个object sender参数,一样的东西。逻辑代码也就一行代码,和wp7一样。但为这一行代码要先做很多。。
@synthesize lbShow; - (void)changeLabelText:(id)sender { lbShow.text =@"Hello World"; }
点Build and Run,会在模拟器打开程序和wp7不同的是,wp7叫Emulator,ip叫Simulator
分析:抛开C#和Obj-C的语法差别,同样简单的功能,Xcode从UI自动生成代码的能力没有VS给力,属性,事件神马的都要自己定义再关联。但这样一来,貌似耦合就降低了,如同WebForm和MVC的区别。
总结:万变不离其宗,思路都是一样的,数据("Hello World"),逻辑("ChangeLabelText"),显示(XAML/XIB)。组织好数据,画好界面,然后用不同的逻辑来控制显示。同样写一个Hello World,wp7比iPhone做起来快很多,VS拖两下写一行搞定,Xcode+InterfaceBuilder拖四下写八行有木有。。
MonoTouch版:
obj-c初看很蛋疼,一个Hello World搞很久,所以也试着用MonoTouch来搞,看看有没有wp7写起来那么“效率”,Mono版本是2.10.5,MonoDevelop是2.6
关于MonoTouch,园子里知识库有文章,从安装到使用,老赵还写了怎么用VS2010来搞MonoTouch。先来New一个Solution,选iPhone and IPad---iPhone Window Based Application,创建之。注意,MonoDevelop还不支持输入中文,显示中文也会乱码,在设置中把语言改成英文。创建成功后如下图,好亲切的C#呀
双击xib文件,会调用Interface Builder打开,重复和Xcode开发时一样的工作,拖控件,这里不需要先在代码里定义,而是利用AppDelegate来添加关联。在IB里搞定后,保存,会发现已经在同名的xxx.xib.designer.cs中自动生成了添加的控件和相应的事件。
[MonoTouch.Foundation.Register("AppDelegate")] publicpartialclass AppDelegate { private MonoTouch.UIKit.UIWindow __mt_window; private MonoTouch.UIKit.UILabel __mt_lbShow; #pragma warning disable 0169 [MonoTouch.Foundation.Export("changeLabelText:")] partialvoid changeLabelText (MonoTouch.UIKit.UIButton sender); [MonoTouch.Foundation.Connect("window")] private MonoTouch.UIKit.UIWindow window { get { this.__mt_window = ((MonoTouch.UIKit.UIWindow)(this.GetNativeField("window"))); returnthis.__mt_window; } set { this.__mt_window = value; this.SetNativeField("window", value); } } [MonoTouch.Foundation.Connect("lbShow")] private MonoTouch.UIKit.UILabel lbShow { get { this.__mt_lbShow = ((MonoTouch.UIKit.UILabel)(this.GetNativeField("lbShow"))); returnthis.__mt_lbShow; } set { this.__mt_lbShow = value; this.SetNativeField("lbShow", value); } } }
嗯,分布类分布方法,只需要实现就行了。
// The name AppDelegate is referenced in the MainWindow.xib file. publicpartialclass AppDelegate : UIApplicationDelegate { // This method is invoked when the application has loaded its UI and its ready to run publicoverridebool FinishedLaunching (UIApplication app, NSDictionary options) { // If you have defined a view, add it here: // window.AddSubview (navigationController.View); window.MakeKeyAndVisible (); returntrue; } partialvoid changeLabelText (MonoTouch.UIKit.UIButton sender) { lbShow.Text ="Hello World"; } // This method is required in iPhoneOS 3.0 publicoverridevoid OnActivated (UIApplication application) { } }
保存后点小齿轮运行,模拟器顺利弹出
这里两个图标,第一个是Xcode开发的,后面的是MonoTouch
分析:看MonoTouch生成的代码,就是把Obj-C翻译成C#了,貌似是把ios的库都包装成了C#库,然后用C#来调用,MonoTouch就是一个代理者,负责把C#的东西转换成对ios sdk的调用。
总结:C#程序员用起来很爽快,不用学obj-c,工具也很顺手,开发效率上,写起来比wp7慢,比Xcode快(少了定义UI的代码,IB里拖拉之后自动生成了)
最后是设置Xcode免99刀真机调试程序的教程,我就是因为Xcode4+ios4.3没办法部署真机上,才用的3.2.4+ios4.1(我的3GS是4.1一直没升级过)