使用Ruby on Rails和Eclipse开发iPhone应用程序,第1部分

为iPhone提供内容

通过 Ruby on Rails 应用程序检测 Mobile Safari

iPhone 和 iPod touch 使 Mobile Safari 成为风靡美国的手机浏览器。虽然使用 Mobile Safari 呈 现普通 Web 页面绰绰有余,但是许多 Web 开发人员都创建了针对 iPhone 的应用程序版本。“使用 Ruby on Rails 和 Eclipse 开发 iPhone 应用程序” 系列文章将说明如何在服务器端使用 Ruby On Rails 识别并为 Mobile Safari 提供自定义内容。

在 Apple 发布 iPhone 和 iPod touch 后的几个月内,Mobile Safari 就已成为风靡美国的手机 Web 浏览器,并且其市场占有率不断攀升。由于 iPhone 的物理参数和用户界面 (UI) 模型与其他手机浏览器 截然不同,因此许多开发人员都选择重新设计他们的 Web 站点以支持 Mobile Safari 的特殊 UI 模型。

决定为 iPhone 创建自定义内容是对两种较为极端的选择的折中。其中一个极端选择是什么都不做。 Mobile Safari 灵活的界面设计允许用户轻松地浏览 Web 站点,即使这些站点不是专为移动设备设计的 。Apple 遵循这样一个理念:iPhone 用户期望访问完全和完整的 Web。在另一个极端上,您可以使用新 发布的 iPhone 软件开发包 (SDK) 把应用程序放在 iPhone 中。这将为您提供极大的 UI 灵活性,并且 允许访问那些不可能在 Web 应用程序中使用的 iPhone 功能 — 例如加速计或摄像头。缺点在于:创建 一个原生 SDK 应用程序的开销高于创建一个 Web 应用程序,而且如果已经有 Web 应用程序,则创建一 个自定义 iPhone Web 版本是为用户提供干净 iPhone UI 的最快方法。

本文将说明如何构建可以动态识别 iPhone 或 iPod touch 浏览器(在本文中,我指的是 iPhone — 记住,此处的所有内容也适用于 iPod touch)的 Ruby on Rails 应用程序,同时允许 Mobile Safari 用户根据需要选择查看完整的 Web 内容。本文还将重点介绍为 iPhone 用户提供单独内容所需的服务器 端结构以及如何开始为 iPhone 提供内容服务。本系列的第 2 部分将重点介绍如何给内容提供 iPhone 界面外观。

设置环境

本文使用带有 Aptana 插件的 Eclipse 来提供 Ruby on Rails 和 iPhone 支持。Ruby on Rails 插 件将提供 Ruby 和 Rails 专有的语法突出显示、快捷键、执行环境等。iPhone 插件将提供在 iPhone 大 小的视窗中显示 Web 应用程序的预览环境。

获得 Eclipse/Aptana 组合有两种选择:可以把 Aptana 插件添加到现有的 Eclipse 环境中,也可以 下载 Aptana Studio(派生自 Eclipse),然后通过 Aptana 所提供的启动屏幕添加插件。如果已经设置 了 Eclipse 环境,请执行典型的 Eclipse 插件搜索。选择 Help > Software Updates > Find and Install 并添加 参考资料 部分中提供的插件 URL。您需要有两个 Eclipse 插件才能继续。如果进 行 Rails 开发时使用的是 Eclipse,则可能已经有 RadRails 插件。您还将使用 iPhone 开发插件,该 插件将为您提供一个模拟的 iPhone 屏幕以在 iPhone 大小的视窗中预览开发。虽然此插件专门用于预览 静态 HTML 页面,但是也可以将它配置为指向 Rails 应用程序。图 1 显示了使用中的插件。

图 1. iPhone 插件

您首先会注意到,插件显示界面比实际的 iPhone 大。这是为了维护像素到像素(pixel-for-pixel) 兼容性 — 插件显示界面与 iPhone 显示界面的像素尺寸相同,但是 iPhone 拥有的像素密度更大。如果 是在 Macintosh 中,则有两个其他 iPhone 模拟器可供选择:iPhoney 或者 iPhone SDK 中附带的官方 iPhone 模拟器。

iPhoney 是一个专用应用程序,用于提供类似于 Aptana 插件的仿 iPhone 显示界面。当站点比 iPhone 视窗大时,这两个显示界面在显示内容时会有所不同。如您所见,Aptana 插件显示内容的完整尺 寸并且提供滚动条。在 iPhoney 中,Web 页面将被压缩成视窗的尺寸(让页面更符合实际的 iPhone 显 示界面)。两个应用程序都不支持 Mobile Safari 的双击放大和缩小功能,因此无法完全替代在真正的 iPhone 中的测试。

如果您已注册并下载官方 iPhone SDK,那么也可以使用该包中的官方 iPhone 模拟器。它将发送正确 的用户代理并且模拟 Mobile Safari 的所有行为,包括双击缩放。惟一的小缺点是您必须运行 Mac OS X V10.5,并且由于它将模拟整个 iPhone 操作系统,因此需要在启动时显式启动 Mobile Safari。您也不 能像在桌面浏览器那样获取 HTML 源代码清单。如果您可以使用它,那么它将是可以使用的最可靠的 Mobile Safari 模拟器。

为 iPhone 提供内容

假定您是 Soups OnLine 的经营者,所有汤品的在线资料看上去热气腾腾且美味多汁。您的站点在台 式机中看上去很不错,但是您开始意识到越来越多的用户需要在回家的路上查看这些信息,并通过 iPhone 访问站点。目前,您的 iPhone 用户看到的内容如下所示:

图 2. iPhone 中的桌面视图

不太糟糕,而且感谢 Mobile Safari 提供的优秀缩放 UI,用户可以浏览站点。尽管如此,它的界面 可以更整洁并且更直接地满足手机用户的需求。

在这里应当说明的是,Soups OnLine 是在我的 Professional Ruby On Rails 一书中创建的站点。我 在这里使用它很大程度上是因为它是已经存在的完整站点,我可以随意改动,并且不会侵犯其他人的版权 。有关本文中使用的 Soups OnLine 版本的代码和初始版本所基于的模板的链接,请参阅 参考资料。

要服务手机用户,您的 Rails 应用程序需要管理以下所有工作:

当用户使用 iPhone 或 iPod touch 访问站点时进行检测。

允许用户在站点的手机版与常规版之间随意切换。

针对 Mobile Safari 用户使用不同的布局,包括独立的层叠样式表(Cascading Style Sheet,CSS) 文件和(可能包括)JavaScript 库。

为手机用户提供不同的内容。

在本文中执行这些任务的代码可以按原样使用。这段代码还被收集到名为 rails_iui 的 Rails 插件 中,您可以将该插件添加到项目中,这样就可以在一个包中获得所有相同功能。

检测 Mobile Safari 用户

要为 iPhone 提供自定义内容,您的 Rails 应用程序必须能够识别 iPhone。在服务器端,主要的识 别方法是由浏览器向服务器发送用户代理字符串。iPhone 用户代理字符串类似以下内容(版本号将随时 间改变):

  Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML,
  like Gecko) Version/3.0 Mobile/1A543 Safari/419.3

iPod touch 用户字符串的不同之处在于括号表达式的开头为 iPod,而不是 iPhone。Apple 建议您有 必要使用 WebKit 版本号(在本例中为 AppleWebKit/420+)以确定新标记或 CSS 设置是否可用(如果是 在客户端而不是在服务器端进行测试,Apple 建议根本不要使用用户代理字符串,但是要测试是否具有特 定功能)。

在 Rails 内部,您需要能够在 ApplicationController 中识别 iPhone 用户代理以便最终在 before 过滤器中使用。您不能在字符串中直接搜索 “iPhone”,因为这将漏掉 iPod touch。此时,最不会过时 的识别 iPhone 用户的方法是匹配 “Mobile” 与 “Safari”,如:

  def is_iphone_request?
   request.user_agent =~ /(Mobile\/.+Safari)/
  end

现在,目标是把 iPhone 集成到 Rails V2.0 respond_to 框架中,以便 iPhone 被自动视为伪 MIME 类型,并且可以增强控制器,如下所示:

清单 1. 处理 iPhone 的样例控制器方法

  def index
   @recipes = Recipe.find_for_index(params[:format])
   respond_to do |format|
    format.html # index.html.erb
    format.xml { render :xml => @recipes }
    format.iphone # index.iphone.erb
   end
  end

这将需要若干个步骤。首先,把下面一行添加到 config/initializers/mime_types.rb 文件中:

  Mime::Type.register_alias "text/html", :iphone

最新版本的 Rails 实际上将这一行作为一条注释,因此取消注释即可。对于没有 config/initializers 目录的早期版本的 Rails,您可以把这行放到 config/environment.rb 中。

这将创建一个自定义 iphone MIME 类型,可以在您的应用程序内使用。从外部看,iphone 类型被视 为 text/html,但是在内部,您可以分别响应两种类型。

返回到 ApplicationController 中,添加另一个私有方法作为 before 过滤器。

清单 2. 添加 iPhone 格式作为 before 过滤器

  before_filter :set_iphone_format
  
  def set_iphone_format
   if is_iphone_request?
    request.format = :iphone
   end
  end

此时,来自 iPhone 或 iPod touch 的所有请求将被标记为 :iPhone 的请求格式。注意,到目前为止 这段代码中没有任何内容是特定于我正在使用的站点示例的,因此您应当可以把这段代码片段随意添加到 要使用的任意站点中。

如果使用的是 rails_iui 插件,您只需把以下行插入 ApplicationController 或者需要响应 iPhone 请求的任意控制器中:

  acts_as_iphone_controller

如述,Aptana 插件不发送上面所列的用户代理字符串。但是,Rails 的命名约定有利于实现一种简单 的解决方案。在任意 URL 中使用 iphone 扩展名(如在 http://localhost:3000/recipies.iphone 中) 将把请求格式自动设为 :iphone 并为 iPhone 提供内容。这将使您可以在 Aptana 模拟器中测试 iPhone 代码。如果使用的是 rails_iui 插件,则把以上命令更改为 acts_as_iphone_controller(true) 将把应 用程序设置成测试模式,所有请求在这种模式中将被视为 iPhone 请求,从而使您可以轻松地在模拟器或 者其他浏览器中进行测试。

在开发期间查看 iPhone 内容

我已经提到过在开发过程中查看针对 iPhone 优化过的 Web 站点有四种方法:

Aptana 的 iPhone Eclipse 插件

iPhoney

iPhone SKD 模拟器

iPhone 或 iPod touch

Aptana 的 iPhone Eclipse 插件

Aptana 插件有很多优点。它是一个跨平台工具,可以在运行 Eclipse 的任意位置运行。它将允许您 同时查看手机版和传统版站点,并且它可以与其他 Eclipse 开发工具完美地集成。该插件允许您一次性 在多个浏览器中查看应用程序,如果您的目标是手机用户和传统用户,这会十分有帮助。此外,如果在 iPhone 中使用的是客户端 JavaScript 代码,Aptana 有一个优秀的控制台功能,它允许记录来自连接的 iPhone 的事件,甚至还允许把 JavaScript 命令从应用程序发送到手机中。由于本文的重点是服务器端 开发,因此我在这里不会讨论这些功能。

Aptana 的缺点是,如果不使用 Eclipse 作为其他开发环境,那么 Aptana 插件将变为重量级的插件 ,很难将它指定为在特定页面中启动,并且它不能在比 iPhone 显示界面宽的站点中完全模拟实际的 iPhone 行为。另一个缺点是 Aptana 插件不能识别自己是在使用 iPhone 还是在使用 iPod touch 用户 代理字符串。如前所述,这意味着您需要有一种在 Aptana 中查看 iPhone 内容的解决方法。

安装 Aptana 插件后,启动一个 iPhone 项目类型的新项目,然后给项目命名。Aptana 插件将默认测 试项目中的静态 index.html 页面。在这里,您实际上不希望这样做。您需要它转到应用程序的索引页面 。在 iPhone 项目的 Properties 窗口中执行以下操作:

转到 HTML Preview 选项卡并单击 Override workspace settings。

在 Preview Type 面板中,单击 Use absolute URL。

输入在本地运行的 Rails 服务器的 URL(Rails 项目不必运行在 Eclipse 中。它只需运行在您提供 给插件的 URL 中)。

完成后,所得到的内容应当类似图 3。

图 3. iPhone 项目的属性

568x406

iPhoney

使用 iPhoney 是预览 iPhone 内容的另一种选择。它是轻量级的,允许您在地址栏中输入任意的 URL 并且准确地压缩宽页面。主要缺点是它是仅适用于 Macintosh 的应用程序。如果一定要使用 iPhoney, 请确保将 iPhoney 菜单中的首选项设为使用 iPhone 用户代理字符串(这不是默认行为)。

iPhone SDK 模拟器

iPhone SDK 模拟器的工作方式也是类似的。启动程序并单击 Safari 按钮以进入浏览器。您可以通过 键盘在地址栏中直接进入 Web 站点,但是如果有必要的话,也可以显示 iPhone 软键盘。此模拟器的一 个优秀功能是既支持 Mobile Safari 的书签也支持 “place on home screen” 功能。在缺点方面,由 于它不是真正的 Safari 模拟器,因此不能轻松地显示正在呈现的 HTML 源代码,但是所有其他模拟器都 可以轻松完成这个功能。

iPhone 或 iPod touch

最后,您可以直接使用真正的 iPhone 或 iPod touch。在这里,联网问题是主要障碍。如果是在服务 器位于路由器之后并且其 IP 地址处于私有范围内(10.*.*.*、172.16-31.*.* 或 192.168.*.*)的常见 情况下进行开发,则仅当 iPhone 通过服务器所在的 Wi-Fi 局域网连接到 Internet 时才能看到开发服 务器(如果直接使用 IP 地址,则会更加轻松)。如果无法设置环境(例如,如果没有有权访问服务器的 Wi-Fi 网络可用),则需要把应用程序部署到可以公开访问的 staging 服务器中进行测试。

尝试查看站点

无论您使用哪种方法查看 iPhone,尝试并单击站点中的一个页面。在本例中,页面已被设为 http://localhost:3000/recipes(那应当是 Aptana 浏览器中的 recipes.iphone,如果使用 rails_iui 插件,则是测试模式)。如果做出前述代码更改,则会看到空白屏幕。这是预期行为(您可以在所选的桌 面浏览器中查看站点以进行验证 — 它运行正常)。before 过滤器已经识别出 Mobile Safari,更改了 响应格式,并且现在正在尝试以符合 Rails 约定的方式服务响应。在这种情况下,Rails 约定将尝试查 找 iphone 的 respond_to 代码块。如果找到,Rails 将查找布局的 layout.iphone.erb 文件,然后在 页面内部填充 app/views/recipes/index.iphone 的内容。由于该部分内容尚不存在,因此 Rails 将服 务一个空白页面。具体地说,它将服务一个空白页面,因为您尚未告诉它 recipe 控制器的 index 方法 应当响应 iphone 格式的请求。

创建 iPhone 布局

当您知道用户要使用 iPhone 浏览站点时,您可以对其环境作出一些典型的假设。此时,Mobile Safari 生态系统只有两个设备拥有相同尺寸的屏幕和浏览器软件。iPhone 中页面顶部的可视查看区为 320 像素(宽)X 356 像素(高)。页面顶部的 URL 栏是您的用户在向下滚动时将获得的额外 60 个像 素。Mobile Safari 页面将伸展到屏幕的各个边缘而不会留有空白。

Mobile Safari 的默认行为将假定 Web 站点的宽度为 980 像素,并且把它收缩三分之一以适应 iPhone 的可视区域。这样做对于许多站点都是有效的,但是下列情况除外:站点异乎寻常的窄;您正在 尝试让站点精确地满足 iPhone 的大小。幸运的是,Mobile Safari 为您准备了一种机制来精确指定显示 站点所需的宽度。

您可以使用特殊的 meta 标记来指定 Mobile Safari 视窗的属性。清单 3 显示了放在新 app/views/layouts/recipes.iphone.erb 布局文件中的标记。

清单 3. Mobile Safari 视窗标记的头文件

  
  
   
   
   
   <%= stylesheet_link_tag 'iphone' %>
  
  
   

<%= "Soups OnLine" %>

   <%= yield %>      

视窗 meta 标记将设置视窗的两个属性。第一个属性 width = device-width 将告诉 Mobile Safari 您需要使用设备的当前宽度呈现站点。也可以将该值设为 200 到 10,000 之间的任何常数值。第二个属 性 user-scalable = no 将关闭 Mobile Safari 双击缩放行为,对站点进行专门设置以符合 iPhone 查 看屏幕。除了这些属性之外,您还可以设置页面的 height。如果需要更精确地控制用户缩放行为,则可 以设置 initial-scale、minimum-scale 和 maximum-scale。三者全都使用 1.0 作为默认值并且范围可 以在 0.0 和 10.0 之间。

该局部布局文件中的另一个特定于 iPhone 的行是 CSS 样式表标记,该标记将指定新的特定于 iPhone 的 CSS 文件。您可能看到有些参考资料建议对 iPhone 内容使用条件 CSS。您可以这样做,但是 我发现语法有些不透明。由于您知道要呈现到服务器端的哪个浏览器中,因此实在没有必要这样做 — 您 可以为该浏览器指定所需的文件。

清单 4 是我为处理 Soups OnLine 的 iPhone 版本的初始页眉而创建的 CSS 文件。

清单 4. Mobile Safari 的 CSS 文件

  h1, h2, h3 {
    font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
    color: #000000;
  }
  h1 {
    font-weight: bold;
    font-size: 175%;
    margin: 0;
  }
  body {
    margin: 0;
    padding: 0;
  }
  #header {
    width: 320px;
    height: 40px;
    margin: 0 auto;
    background: url(/images/img02_iphone.gif) no-repeat;
  }

此文件与初始 CSS 文件中的匹配条目之间只有少许差异。h1 元素的字体大小较小(实际上,我通过一些尝试和错误偶然发现了所需的大小)。h1 标记现在是粗体并且将空白设置明确设为零。粗体可以增强显示,而零空白使它与视窗的左上部分衔接得十分紧密。#header ID 类的尺寸现在符合 iPhone 视窗的大小,并且我手动更改了背景图片以适应空间大小。

您还需要创建 app/views/recipes/index.iphone.erb 文件,但是目前,您可以把它留空。执行这些更改后,站点的 iPhone 版本已经成型。页眉将类似图 4。

图 4. Soups OnLine 页眉

321x227

在大多数模拟器中,您将注意到旋转视窗后将向外扩展图像以匹配设备的 480 像素的新宽度。这是因为您曾指定设备宽度应当用作缩放尺寸。

选择进入和选择退出

最后要添加的是 Mobile Safari 用户选择退出手机视图然后选择重新进入的机制。这将允许手机用户能够查看完整界面,界面可能有更多功能(不过可能很难进行导航),然后根据需要切回 iPhone 界面。您不需要为桌面用户设置类似链接以选择进入 iPhone 界面,因为最终(指在第 2 部分中)将在桌面使用 Mobile Safari 专用的 CSS 和 JavaScript 代码,而与站点没有关系。

机制非常简单:在设置指定用户浏览器类型首选项的 cookie 的 iPhone 界面的页脚中添加链接。然后允许该首选项在决定要发送哪种格式时覆盖用户代理字符串。

首先,添加链接。更改 app/views/layouts/recipes.iphone.erb 文件中的 body 标记,如下所示:

清单 5. 选择退出链接的布局主体

<%= "Soups OnLine" %>

<%= yield %> <%= link_to "Switch To Desktop View", {:controller => "browsers", :action => :desktop}, :class => "mobile_link" %>

该链接有一个新 CSS 类,该类是在 iPhone CSS 文件中定义的。

清单 6. 选择退出链接的 CSS 代码

.mobile_link {
      font-size: 14px;
    	font-weight: bold;
    	font-family: Helvetica;
    	color: #00f;
    	text-decoration: none;
    	text-align: center;
      display: block;
    	width: 320px;
    }

Helvetica 是为 iPhone 系统链接选择的字体。该字体比正文的推荐字体小一些,但是这里不应该是正文。其他条目将在视窗中居中显示该链接。结果将类似图 5。

图 5. 切换到桌面链接

323x78

下一步是设置 cookie。正如您可以从清单 5 中的链接定义看到的那样,我创建了一个新 BrowsersController 控制器类来管理这段代码。清单 7 提供设置 cookie 的代码。

清单 7. 选择进入和选择退出的 BrowsersController 代码

class BrowsersController < ApplicationController
      def desktop
        cookies["browser"] = "desktop"
        redirect_to recipes_path
      end
      def mobile
        cookies["browser"] = "mobile"
        redirect_to recipes_path
      end
    end

您可以看到它十分简单。它将只设置 cookie 并且重定向回被用作索引页面的页面。

然后,您需要更改 set_iphone_format 方法以考虑浏览器首选项。更新后的方法类似清单 8。

清单 8. 设置选择退出的 iPhone 格式

def set_iphone_format
      if is_iphone_request? or request.format.to_sym == :iphone
        request.format = if cookies["browser"] == "desktop"
                         then :html
                         else :iphone
                         end
      end
    end

这里实际上有两处更改。初始的 if 语句将添加子句 request.format.to_sym == :iphone。这将允许 iPhone 请求的 URL 通过 .iphone 扩展名也可以使用 cookie 覆盖它们的格式。主要是允许这段代码可以在 Aptana 模拟器中进行测试。然后,根据用户 cookie 中是否有 desktop 值(在 BrowserController 方法中设置)来设置 request.format。

剩下的惟一一项任务是把选择退出链接添加到桌面视图中。您只希望 iPhone 用户看到此链接,因此先把以下代码行添加到 ApplicationController 中:

helper_method :is_iphone_request?

这行代码将使 is_iphone_request? 方法成为助手方法,您可以从任何一个视图中调用它。尤其是,您可以使用它把清单 9 的内容添加到 app/views/layouts/recipes.html.erb 文件中的初始桌面布局的末尾。

清单 9. 如果 iPhone 存在则有条件的放置标记

<% if is_iphone_request? %>
      <%= link_to "Switch To Mobile Safari View",
          {:controller => "browsers", :action => :mobile},
          :class => "big_link"  %>
    <% end %>

添加的这段代码将把类似的链接设置到桌面浏览器中。它还将把 CSS 类添加到桌面 CSS 文件中(在本例为 public/scaffold.css),如下所示:

清单 10. 桌面选择进入链接的 CSS 清单

.big_link {
      font-size: 40px;
    	font-weight: bold;
    	font-family: Helvetica;
    	color: #00f;
    	text-decoration: none;
    	text-align: center;
    	display: block;
    	width: 980px;
    }

该 CSS 类将在桌面窗格的底部添加一个漂亮的、很难忽略的较大的链接。它必须非常显眼,因为 Mobile Safari 将把它缩小,但是您仍然希望用户能够看到并单击它,即使用户不缩放显示界面。您可以让它变大而且引人注目,因为桌面用户将不会查看此链接。在 iPhone 显示界面中,该链接类似图 6。

图 6. 切换回手机链接

320x78

该链接将把用户 cookie 设为 mobile 并且重定向回索引页面,在这里,链接将被重新解析为用于手机浏览器。

结束语

本文重点介绍了支持为 iPhone 和 iPod touch 用户分离内容所需的结构,还介绍了如何管理视窗以按照正确的大小和比例显示 Mobile Safari 内容,并且开始讨论在手机站点的基础布局中放置哪些内容。

第 2 部分将介绍如何在 Mobile Safari 浏览器中显示内容,还将查看管理 iPhone 内容的 UI 指导原则并研究如何在 Rails 应用程序中实际应用这些指导原则。

转载于:https://my.oschina.net/shuqi888/blog/148852

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值