LDAP 与 iPhone,第 1 部分: 使用 UNIX 库进行 iOS 开发

有许多为 UNIX® 系统编写的库。其中许多是使用开放源码许可协议发布的,允许在新的项目中重用库的源代码。通过把现有的库迁移到新的平台,开发人员可以节省在新平台上实现相同功能所花的开发时间。这个分两部分的文章系列讨论如何把 OpenLDAP 客户端库迁移到 iOS 上,本文是本系列的第一篇。第 1 部分介绍把 OpenLDAP 源代码导入 Xcode 并为 iOS 构建两个静态库的步骤。通过使用第 1 部分中创建的 Xcode 项目,第 2 部分将带领读者创建一个简单 iOS 应用程序,这个程序使用 OpenLDAP 库对 LDAP 服务器执行基本的查询。

David M. Syzdek, 软件工程师, Bindle Binaries

http://www.ibm.com/developerworks/i/p-dsyzdek.jpgDavid M. Syzdek 在为电信公司开发 UNIX 软件方面有 10 年经验。当 iPhone SDK 于 2007 年发布时,他开始为移动设备开发应用程序,是最早在 iTunes App Store 上发布应用程序的开发人员之一。David 当前是独立的开发人员,发布属于 Bindle Binaries 的应用程序。



2011 年 5 月 17 日

简介

iPhone 在手机市场上的出现导致 iTunes 中移动应用程序的数量急剧增加。由于大量应用程序的核心功能是相同的,新的应用程序很难在竞争者中脱颖而出。为了让应用程序能够吸引消费者,越来越有必要添加同类应用程序不支持的特性;但是,从头编写新功能的开发时间很长,工作量很大。迁移原来为 UNIX® 系统编写的库能够帮助开发人员降低成本,让应用程序更快地投入市场。

iPhone 使用的操作系统 iOS 是在 UNIX 核心之上构建的,iOS 应用程序是使用 GCC 编译的,而 GCC 也是大多数 UNIX 系统使用的编译器。这意味着,只需花些时间和精力,就可以把为 UNIX 系统编写的大多数库迁移到 iPhone 上。

本文带领您把一个库迁移到 iPhone 上,这个库一般情况下是在包含 Autoconf 和 Make 的环境中构建的。尽管本文并不详细解释如何迁移用 GNU 工具构建的包,但是了解 GNU 工具的开发人员应该能够根据这里提供的信息把包导入 Xcode 并迁移到 iOS 平台上。


开始

本文中使用的示例已经用 Mac OS X 10.6.4 上的 iOS SDK 4.1 和 OpenLDAP 2.4.22 测试过。尽管示例使用 iOS SDK 4.1,但是应该也适用于以后的 iOS SDK 版本(可能需要稍加修改)。可以在 “下载” 部分中的 zip 文件中找到示例的源代码文件和项目文件。

iPhone SDK 用于编译针对 iPhone OS 平台的移动应用程序。SDK 提供文档、IDE 和用于测试移动应用程序的模拟器(下载信息见 参考资料)。

OpenLDAP 是 Lightweight Directory Access Protocol 的一种免费开放源码实现。这个实现包含的库可以使用 LDAP over TCP 访问 X.500 目录服务(下载信息见 参考资料)。


准备 OpenLDAP 源代码

Xcode 是 iPhone SDK 包含的 IDE。它包含用于为 iOS 平台构建应用程序和库的模板和文档。为了更方便地在 OpenLDAP 源代码树中移动,我们先把源代码导入到一个 Xcode 项目中。为 iOS 平台创建新的 Xcode 项目的方法是,打开 Xcode 并从菜单栏上的 File 菜单中选择 New Project。这应该会打开一个新的对话框,其中有三个面板(见 图 1)。因为将使用这个项目编译 OpenLDAP 客户端库,所以应该用静态库模板创建它。在左面板上,在标题 iPhone OS 下面选择 Library。在右上方的面板中,选择 Cocoa Touch Static Library。单击 Choose 继续。

图 1. Xcode 中的 New Project 对话框
Xcode 中的 New Project 对话框

图 2 中的对话框用于设置 Xcode 项目的名称。

图 2. 用于在 Xcode 项目中添加现有文件的对话框
用于在 Xcode 项目中添加现有文件的对话框

Xcode 通过在项目名称前面加上 lib 并在后面加上 .a 构成库名称。因此,要想创建名为 libldap.a 的库,项目名称必须设置为 ldap。在 Save As 框中输入名称并单击 Save。这会创建一个目录,其中包含项目最初的文件。

既然已经创建了项目,就可以导入 OpenLDAP 的源代码了。从 OpenLDAP 项目页面下载源代码并在 Xcode 项目文件夹中展开 tar 文件。从菜单栏上的 Project 菜单中选择 Add to Project。在打开的文件选择对话框中,选择 Xcode 项目中的文件夹(其中包含 OpenLDAP 的源代码)并单击 Add 按钮。应该会出现另一个对话框。一定要选择 "Recursively create groups for any added folders" 选项并从目标列表中取消 ldap。单击 Add 按钮完成把源代码添加到项目中的步骤。现在,在 Xcode 主项目窗口的 Groups & Files 面板中应该会出现一个名为 OpenLDAP directory 的新组。

OpenLDAP 源代码树包含的一个目录中有头文件,库使用的源代码文件要包含这些头文件。需要通过配置 Xcode 让预处理器在处理 #include 指令时搜索这个目录。在 Xcode 主项目窗口的 Groups & Files 面板中双击项目名称。这应该会打开项目信息窗口(见 图 3)。在 "Search in Build Settings" 搜索框中单击并输入 Header Search Paths。在 Value 框中双击,添加新的搜索路径 openldap-2.4.22/include

图 3. 项目信息对话框
项目信息对话框

准备头文件

OpenLDAP 已经迁移到了许多平台上。OpenLDAP 开发人员使用 C 头文件在编译时定义系统信息。一般情况下,通过用 AutoConf 生成的脚本修改模板文件来创建这些头文件。因为 Xcode 不使用 Autoconf,所以必须手工修改这些文件。必须修改的文件是 lber_types.hin、ldap_config.hin、ldap_features.hin 和 portable.hin。这些文件在 OpenLDAP 源代码树中的 include 目录中。

lber_types.hin

lber_types.hin 文件包含用于定义变量类型的模板。这个模板文件需要改名为 lber_types.h。改名的方法是在 Xcode 中右键单击文件名并从菜单中选择 rename。这会更新文件的 Xcode 元数据,把它作为 C 头文件处理。打开文件,寻找 清单 1 所示的代码行。

清单 1. lber_types.h
27 /* LBER boolean, enum, integers (32 bits or larger) */
28 #undef LBER_INT_T
29 
30 /* LBER tags (32 bits or larger) */
31 #undef LBER_TAG_T
32
33 /* LBER socket descriptor */
34 #undef LBER_SOCKET_T
35 
36 /* LBER lengths (32 bits or larger) */
37 #undef LBER_LEN_T

这些行声明库使用的变量类型。因为 iPhone 是 32 位平台,类型 int 是合适的值。把 #undef 宏改为 #define,把变量类型设置为 int(见 清单 2)。

清单 2. 针对 32 位平台进行调整
27 /* LBER boolean, enum, integers (32 bits or larger) */
28 #define LBER_INT_T int
29 
30 /* LBER tags (32 bits or larger) */
31 #define LBER_TAG_T int
32
33 /* LBER socket descriptor */
34 #define LBER_SOCKET_T int
35 
36 /* LBER lengths (32 bits or larger) */
37 #define LBER_LEN_T int

文件的其他部分声明库使用的定制变量类型,不需要修改。

ldap_config.hin

ldap_config.hin 文件包含的模板定义库应该在哪里搜索 LDAP 客户端配置文件。因为 iOS 不允许用户在设备的文件系统中创建任意文件,所以不需要修改这个文件的内容。需要把这个文件改名为 ldap_config.h,从而避免在编译源代码文件时由于 include 指令失败而生成错误。按照把 lber_types.hin 改名为 lber_types.h 的方法在 Xcode 界面中修改这个文件名。

ldap_features.hin

ldap_features.hin 包含 iOS 平台必需的特性和当前 OpenLDAP 版本的相关信息。把 ldap_features.hin 改名为 ldap_features.h 并寻找 清单 3 所示的代码行。

清单 3. ldap_features.h
23 /* OpenLDAP API version macros */
24 #undef LDAP_VENDOR_VERSION
24 #undef LDAP_VENDOR_VERSION_MAJOR
24 #undef LDAP_VENDOR_VERSION_MINOR
24 #undef LDAP_VENDOR_VERSION_PATCH

OpenLDAP 的每个版本使用分三部分的版本号。用 X.Y.Z 格式表示版本,其中的 X 是主厂商版本号,Y 是次厂商版本号,Z 是厂商补丁修订号。按公式 ((X*10,000)+(Y*100)+(Z)) 计算出 LDAP_VENDOR_VERSION 的值。例如,使用 清单 4 所示的值计算 OpenLDAP 2.4.22 的 LDAP_VENDOR_VERSION

清单 4. 计算 LDAP_VENDOR_VERSION
LDAP_VENDOR_VERSION_MAJOR = X = 2
LDAP_VENDOR_VERSION_MINOR = Y = 4
LDAP_VENDOR_VERSION_PATCH = Z = 22

LDAP_VENDOR_VERSION = ((X*10000)+(Y*100)+(Z))
LDAP_VENDOR_VERSION = ((2*10000)+(4*100)+(22))
LDAP_VENDOR_VERSION = (20000+400+22)
LDAP_VENDOR_VERSION = (20422)

需要更新 ldap_features.h 以反映 OpenLDAP 源代码的版本。把 #undef 宏替换为 #define 并插入版本信息。例如,对于 OpenLDAP 2.4.22,应该做 清单 5 所示的修改。

清单 5. 针对 OpenLDAP 2.4.22 的修改
23 /* OpenLDAP API version macros */
24 #define LDAP_VENDOR_VERSION  20422
24 #define LDAP_VENDOR_VERSION_MAJOR 2
24 #define LDAP_VENDOR_VERSION_MINOR 4
24 #define LDAP_VENDOR_VERSION_PATCH 22

不需要修改文件的其他部分。

portable.hin

需要在 portable.hin 文件中设置在 iPhone SDK 中可用的库函数和头文件的相关信息。但是,这个文件的内容非常多,需要很小心地设置。幸运的是,OpenLDAP 使用 autoconf 执行多个平台必需的测试。可以使用 autoconf 脚本为 portable.hin 生成值。

为了使用 OpenLDAP autoconf 脚本,打开在 /Applications/Utilities/Terminal.app 中找到的 Terminal.app。输入命令 cd 和一个空格。然后,在 Xcode 中把包含 OpenLDAP 源代码树的文件夹拖到终端窗口中(见 图 4)。

图 4. 把 Xcode 组拖到 Terminal.app 中以获得文件夹路径的过程
把 Xcode 组拖到 Terminal.app 中以获得文件夹路径的过程

按回车,把 Terminal.app 中的目录改为 OpenLDAP 源代码树的位置。用 清单 6 所示的标志运行配置脚本。

清单 6. 运行配置脚本
./configure CC=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc \
   LD=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ld \
   --host=arm-apple-darwin --disable-slapd --without-cyrus-sasl \
   --without-tls --no-create

标志 CC=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc 指定 iPhone SDK 使用的编译器的位置,LD=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ld 指定链接器的位置。标志 --host=arm-apple-darwin 告诉 autoconf 将在哪种平台上使用编译后的代码。标志 --disable-slapd 禁用构建 LDAP 服务器所需的检查(OpenLDAP 附带这些检查)。iPhone SDK 不包含 Cyrus SASL 库、OpenSSL 库或 GNU SSL/TLS 库,所以标志 --without-cyrus-sasl--without-tls 禁用对这些库包含的函数的检查。最后,标志 --no-create 禁止 autoconf 创建 Makefile 和头文件。输出应该与 图 5 相似。

图 5. 运行配置脚本的前几行输出
运行配置脚本的前几行输出

运行以下命令,让 autoconf 根据模板文件 portable.hin 生成 portable.h:./config.status --header=include/portable.h:include/portable.hin


创建 libldap.a

既然源代码和配置文件已经准备好了,现在应该告诉 Xcode LDAP 库将使用哪些源代码文件。在 Xcode 界面中,找到 OpenLDAP 源代码树中的 libldap 目录(见 图 6)。

图 6. libldap 源代码文件在 Xcode 的 Groups & Files 面板中的位置
libldap 源代码文件在 Xcode 的 Groups & Files 面板中的位置

在 libldap 目录中,有一个名为 Makefile.in 的文件,其中包含用来构建 libldap.a 的文件列表。打开 Makefile.in,找到 清单 7 所示的代码行。

清单 7. Makefile.in
20 SRCS	= bind.c open.c result.c error.c compare.c search.c \
21 	controls.c messages.c references.c extended.c cyrus.c \
22 	modify.c add.c modrdn.c delete.c abandon.c \
23 	sasl.c gssapi.c sbind.c unbind.c cancel.c  \
24 	filter.c free.c sort.c passwd.c whoami.c \
25 	getdn.c getentry.c getattr.c getvalues.c addentry.c \
26 	request.c os-ip.c url.c pagectrl.c sortctrl.c vlvctrl.c \
27 	init.c options.c print.c string.c util-int.c schema.c \
28 	charray.c os-local.c dnssrv.c utf-8.c utf-8-conv.c \
29 	tls2.c tls_o.c tls_g.c tls_m.c \
30 	turn.c ppolicy.c dds.c txn.c ldap_sync.c stctrl.c \
31 	assertion.c deref.c

需要更新这个列表中的文件,从而把它们包含在 ldap 目标中。为此,右键单击列表中的一个文件并从菜单中选择 Get Info。在新窗口中,选择 Targets 选项卡并单击 Target Memberships 面板中的 ldap 目标。对于列表中的所有文件,重复这个步骤。


创建 liblber.a

liblber.a 是在编译应用程序时 libldap.a 需要的库。OpenLDAP 发行版包含这个库。为了构建它,首先必须为这个库创建一个 Xcode 目标。右键单击 Xcode 的 Groups & Files 面板中的项目图标。从菜单中选择 Add,然后从子菜单中选择 New Target。应该会出现 New Target 向导。在左面板中选择 Cocoa Touch,然后在右面板中选择 Static Library。单击 Next 继续。在 Target Name: 文本框中,输入 lber 并单击 Finish。这应该会创建新的库目标。

liblber.a 依赖于 Foundation 框架。为了配置 Foundation 框架,在 Xcode 的 Groups & Files 面板中滚动到 Targets 部分。展开 Targets 部分并双击目标 lber。这应该会打开 lber 的目标信息窗口。单击 General 选项卡,然后单击 Linked Libraries 面板下面的 + 按钮。在弹出窗口中,从 Device - iPhone OS 4.1 SDK 部分中选择 Foundation.framework。单击 Add 按钮把这个框架添加到库中。

最后,需要给 Xcode 配置在构建 liblber.a 时要编译的源代码文件。在 Xcode 界面中,找到 OpenLDAP 源代码树中的 liblber 目录。在 liblber 目录中,有一个名为 Makefile.in 的文件,其中包含用来构建 liblber.a 的文件列表。

打开 Makefile.in,找到 清单 8 所示的代码行。

清单 8. Makefile.in 中的代码行
21 UNIX_SRCS = stdio.c

26 SRCS= assert.c decode.c encode.c io.c bprint.c debug.c \
27 	memory.c options.c sockbuf.c $(@PLAT@_SRCS)

需要更新这个列表中的文件,从而把它们包含在 lber 目标中。为此,右键单击列表中的一个文件并从菜单中选择 Get Info。在新窗口中,选择 Targets 选项卡并单击 Target Memberships 面板中的 lber 目标。对于列表中的所有文件,重复这个步骤。

单击 Xcode 工具栏中的 Build 按钮构建这个库。要想在针对模拟器或设备的构建之间切换,应该从标签为 Overview 的下拉框中选择想要的 SDK。


结束语

与大多数软件开发方法一样,还有编译迁移到 iOS 的库的其他方法。本文使用 Xcode 执行编译,这样就可以利用 Xcode 的依赖项跟踪把库轻松地集成到其他软件包中,还可以用未来的 iPhone SDK 版本轻松地更新库。

本系列的第 2 部分将讲解如何创建第二个 Xcode 项目、作为依赖项添加本文中创建的 Xcode 项目以及使用静态库为 iPhone 创建 LDAP 客户端。


下载

描述名字大小
Zip 文件ldap.zip836KB

参考资料

学习

  • Android 和 iPhone 浏览器之战,第 1 部分:WebKit 成援兵(Frank Ableson,developerWorks,2009 年 12 月):通过这篇 developerWorks 文章了解如何使用移动浏览器的特性。
  • Introduction to LDAP: Part 1, Installation and simple Java LDAP programming(Jeng Yoong Tan,developerWorks,2010 年 6 月):了解 LDAP (Lightweight Directory Access Protocol) 的概况。
  • Start your learning with Open Source:阅读 Chris Walden 的这篇博客文章,了解可以用于几乎任何任务的各种开放源码包。
  • 让 UNIX 和 Linux 一起工作(Martin Brown,developerWorks,2006 年 4 月)讲解如何让传统的 UNIX 发行版和 Linux® 一起工作。
  • 访问 developerWorks Open source 专区,获得丰富的 how-to 信息、工具和项目更新,帮助您用开放源码技术进行开发并与 IBM 产品结合使用。
  • 访问 Xcode Port of OpenLDAP
  • AIX and UNIX 专区:developerWorks 的“AIX and UNIX 专区”提供了大量与 AIX 系统管理的所有方面相关的信息,您可以利用它们来扩展自己的 UNIX 技能。
  • AIX and UNIX 新手入门:访问“AIX and UNIX 新手入门”页面可了解更多关于 AIX 和 UNIX 的内容。
  • AIX and UNIX 专题汇总:AIX and UNIX 专区已经为您推出了很多的技术专题,为您总结了很多热门的知识点。我们在后面还会继续推出很多相关的热门专题给您,为了方便您的访问,我们在这里为您把本专区的所有专题进行汇总,让您更方便的找到您需要的内容。
  • AIX and UNIX 下载中心:在这里你可以下载到可以运行在 AIX 或者是 UNIX 系统上的 IBM 服务器软件以及工具,让您可以提前免费试用他们的强大功能。
  • IBM Systems Magazine for AIX 中文版:本杂志的内容更加关注于趋势和企业级架构应用方面的内容,同时对于新兴的技术、产品、应用方式等也有很深入的探讨。IBM Systems Magazine 的内容都是由十分资深的业内人士撰写的,包括 IBM 的合作伙伴、IBM 的主机工程师以及高级管理人员。所以,从这些内容中,您可以了解到更高层次的应用理念,让您在选择和应用 IBM 系统时有一个更好的认识。
  • 要收听面向软件开发人员的有趣访谈和讨论,请查看 developerWorks 播客
  • developerWorks 技术活动和网络广播:随时关注 developerWorks 技术活动和网络广播。

获得产品和技术

  • 获取 iPhone SDK。注册的 ADC 成员可以下载它。
  • 了解 GitHub project for iOS ports。它自动地构建 OpenSSL、Cyrus-SASL 和 OpenLDAP,已经用 SASL Auth、LDAPS 和 LDAP TLS 测试过。
  • 项目网站 下载 OpenLDAP。
  • 获取 OpenLDAP 的 Xcode Port
  • 使用 IBM 试用软件 改进您的下一个开放源码开发项目,这些软件可以通过下载或从 DVD 获得。

讨论

  • 加入 developerWorks 中文社区。查看开发人员推动的博客、论坛、组和维基,并与其他 developerWorks 用户交流。

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=AIX and UNIX, Open source
ArticleID=659404
ArticleTitle=LDAP 与 iPhone,第 1 部分: 使用 UNIX 库进行 iOS 开发
publish-date=05172011