描述
开 本: 16开纸 张: 胶版纸包 装: 平装-胶订是否套装: 否国际标准书号ISBN: 9787302581833
《Swift物联网程序设计》的目标是教会读者如何使用Apple公司的原生应用程序编程接口(Application Programming Interface,API)在Swift中构建iOS应用程序,该API可连接到流行的物联网(IoT)设备和服务。
《Swift物联网程序设计》详细阐述了与Swift 语言开发相关的基本解决方案,主要包括构建个物联网应用程序、Swift入门、使用HealthKit访问健康信息、使用Core Motion保存运动数据、使用Fitbit API集成第三方健身跟踪器和数据、构建个watchOS应用、构建交互式watchOS应用、构建独立的watchOS应用、连接到蓝牙低功耗设备、使用iBeacons进行定位、使用HomeKit实现家庭自动化、构建与Raspberry Pi交互的应用程序、使用钥匙串服务保护数据、使用Touch ID进行本地身份验证、使用Apple Pay接收付款等内容。此外,本书还提供了丰富的示例以及代码,以帮助读者进一步理解相关方案的实现过程。 本书适合作为高等院校计算机及相关专业的教材和教学参考书,也可作为相关开发人员的自学教材和参考手册。
第1篇 物联网应用程序开发和Swift编程语言基础知识
第1章 构建个物联网应用程序 3
1.1 设置项目 4
1.2 建立用户界面 8
1.2.1 创建表格视图控制器 9
1.2.2 创建地图视图控制器 19
1.3 请求位置许可 22
1.4 访问用户的位置 26
1.5 显示用户的位置 28
1.5.1 使用数据填充表格视图 28
1.5.2 使用数据填充地图 30
1.6 小结 33
第2章 Swift入门 35
2.1 使用Swift的理由 36
2.2 基本的Swift语法 37
2.2.1 调用方法 37
2.2.2 定义变量 38
2.2.3 复合数据类型 39
2.2.4 条件逻辑 40
2.2.5 枚举类型 41
2.2.6 循环 43
2.3 关于Swift中的面向对象编程 43
2.3.1 构建类 43
2.3.2 协议 45
2.3.3 方法签名 45
2.3.4 访问属性和方法 46
2.3.5 实例化对象 47
2.3.6 字符串 48
2.3.7 格式化字符串 49
2.3.8 集合 50
2.3.9 强制转换 52
2.4 关于Swift特定的语言功能 52
2.4.1 可选类型 53
2.4.2 关于try-catch块 55
2.5 在项目中混合使用Objective-C和Swift 57
2.6 小结 59
第2篇 Fitbit健康设备项目
第3章 使用HealthKit访问健康信息 63
3.1 核心框架和应用程序简介 63
3.2 初步设置 65
3.2.1 设置用户界面 65
3.2.2 设置HealthKit项目 78
3.3 提示用户以获得HealthKit权限 81
3.3.1 从HealthKit检索数据 86
3.3.2 在表格视图中显示结果 91
3.3.3 获取背景更新 95
3.4 小结 97
第4章 使用Core Motion保存运动数据 99
4.1 简介 99
4.2 使用Core Motion访问Motion硬件 99
4.3 查询步数 103
4.3.1 检测实时更新的步数 106
4.3.2 检测活动类型 109
4.4 将数据保存到HealthKit中 111
4.5 小结 120
第5章 使用Fitbit API集成第三方健身跟踪器和数据 121
5.1 关于Fitbit API 121
5.1.1 关于RESTful API 122
5.1.2 Fitbit RESTful API实现细节 124
5.1.3 使用Apache设置本地环境 125
5.1.4 OAuth 1.0a身份验证模型 127
5.1.5 Fitbit OAuth实现 128
5.1.6 Fitbit API调用速率限制 129
5.1.7 进行异步调用 130
5.1.8 使用回调作为参数 131
5.2 设置与Fitbit兼容的iOS项目 132
5.2.1 视图控制器 132
5.2.2 记录器库 136
5.2.3 设置基本的加密功能集 137
5.2.4 API客户端库 140
5.2.5 OAuth库 156
5.2.6 测试到目前为止我们拥有的代码 164
5.3 向Fitbit API发出请求 166
5.3.1 检索用户个人资料 168
5.3.2 在API中检索和设置数据 170
5.3.3 关于OAuth版本的问题 175
5.4 小结 176
第3篇 Apple Watch项目
第6章 构建个watchOS应用 179
6.1 简介 179
6.2 关于watchOS应用程序和iOS应用程序 180
6.3 设置项目 182
6.4 将表格添加到watchOS应用程序中 186
6.4.1 定义表格 190
6.4.2 从iOS应用程序中获取数据 196
6.5 使用自定义布局构建详细信息页面 199
6.6 显示详细信息界面控制器 204
6.6 小结 207
第7章 构建交互式watchOS应用 209
7.1 简介 209
7.2 使用压感触控显示菜单 209
7.2.1 重置位置列表 214
7.2.2 显示细节视图控制器 214
7.2.3 模拟压感触控 217
7.3 将按钮添加到界面控制器 218
7.4 在界面控制器之间传递信息 221
7.5 使用文本输入添加注释 225
7.6 将数据发送回父iOS应用 227
7.7 小结 231
第8章 构建独立的watchOS应用 233
8.1 使用Core Location请求当前位置 233
8.2 使用NSTimer创建提醒 242
8.3 从watchOS应用程序进行网络调用 247
8.4 处理JSON响应 253
8.5 小结 256
第4篇 蓝牙和WiFi连接
第9章 连接到蓝牙低功耗设备 259
9.1 Apple蓝牙协议栈简介 259
9.1.1 关键术语和概念 260
9.1.2 核心蓝牙对象 260
9.2 蓝牙低功耗应用程序构建思路 261
9.3 应用程序开发待办事项 261
9.3.1 基本应用和主场景 262
9.3.2 中心角色场景 263
9.3.3 外围角色场景 264
9.3.4 可编辑文本 265
9.4 设置项目 266
9.5 构建界面 266
9.6 使用中心设备管理器 272
9.7 在应用程序中连接到蓝牙低功耗设备 276
9.7.1 构建界面 276
9.7.2 通过委托保持代码的干净 280
9.7.3 扫描外围设备 284
9.7.4 发现并连接 288
9.7.5 探索服务和特征 289
9.7.6 订阅和接收数据 290
9.8 外围角色 293
9.8.1 构建界面 293
9.8.2 委托设置 294
9.8.3 设置服务 298
9.8.4 广告服务 299
9.8.5 发送数据 300
9.9 为应用程序启用后台通信 302
9.10 蓝牙实践 303
9.10.1 中心角色设备 303
9.10.2 外围角色设备 303
9.11 小结 303
第10章 使用iBeacon进行定位 305
10.1 iBeacon简介 305
10.1.1 iBeacon广告 305
10.1.2 iBeacon准确性 305
10.1.3 隐私 306
10.1.4 区域监视 306
10.2 测距 306
10.3 构建iBeaconApp应用程序 307
10.3.1 创建项目 307
10.3.2 设置背景功能 308
10.4 建立主场景 309
10.4.1 设置UI元素 310
10.4.2 创建出口连接 311
10.4.3 设置约束 312
10.4.4 创建一个自定义按钮 313
10.5 检测蓝牙状态 316
10.6 建立区域监视器场景 319
10.6.1 RegionMonitor类 325
10.6.2 使用委托模式 325
10.6.3 创建RegionMonitor类 326
10.6.4 委托方法 327
10.6.5 RegionMonitor方法 331
10.6.6 授权和请求许可 332
10.6.7 CLLocationManagerDelegate方法 333
10.6.8 配置区域监视 339
10.7 建立iBeacon场景 344
10.7.1 BeaconTransmitter类 347
10.7.2 定义BeaconTransmitterDelegate协议 348
10.7.3 将iOS设备配置为iBeacon 350
10.7.4 测试应用程序 353
10.8 小结 353
第11章 使用HomeKit实现家庭自动化 355
11.1 HomeKit概念介绍 355
11.2 HomeKit委托方法 356
11.3 构建一个HomeKit应用程序 356
11.3.1 需求 357
11.3.2 HomeKit附件模拟器 357
11.4 创建项目 358
11.4.1 启用HomeKit 360
11.4.2 建立家庭界面 360
11.4.3 实现家庭管理器委托方法 362
11.4.4 向家庭管理器添加新家庭 369
11.4.5 从家庭中删除附件 379
11.4.6 使用HomeKit附件模拟器 380
11.4.7 构建服务接口 389
11.4.8 实现UITableView方法 393
11.4.9 特征的子类 399
11.5 切换到服务场景 405
11.6 运行应用程序 405
11.7 小结 406
第12章 构建与Raspberry Pi交互的应用程序 407
12.1 关于Raspberry Pi 407
12.2 Raspberry Pi上的控制界面 408
12.3 设置Raspberry Pi 409
12.3.1 选择脚本语言 410
12.3.2 配置I2C 410
12.3.3 配置GPIO 414
12.3.4 安装PyGlow 414
12.4 提供用于控制设备的API 415
12.4.1 安装Flask 415
12.4.2 Hello World演示程序 416
12.4.3 构建一个非常简单的侦听器守护程序 417
12.5 为应用程序创建iOS项目 419
12.5.1 允许传出HTTP调用 419
12.5.2 视图控制器 420
12.5.3 日志库 423
12.5.4 API客户端库 425
12.6 小结 438
第5篇 安全物联网
第13章 使用钥匙串服务保护数据 441
13.1 关于iOS设备上的硬件安全 443
13.2 保护文件数据 444
13.3 关于Apple钥匙串 446
13.3.1 Apple钥匙串服务 446
13.3.2 钥匙串项目的组成 447
13.3.3 实现用于存储密码的钥匙串服务 447
13.3.4 从钥匙串服务中检索数据 448
13.3.5 删除钥匙串服务的记录 449
13.3.6 设置应用程序以测试钥匙串服务 451
13.3.7 视图控制器 451
13.4 小结 457
第14章 使用Touch ID进行本地身份验证 459
14.1 关于Touch ID 459
14.1.1 LocalAuthentication用例 460
14.1.2 构建Touch ID应用程序 460
14.2 创建项目 461
14.3 建立界面 462
14.4 实现UITableView方法 465
14.5 集成Touch ID以进行指纹认证 467
14.5.1 评估身份验证策略 467
14.5.2 无须钥匙串服务的Touch ID身份验证 467
14.5.3 自定义的身份验证后备计划 469
14.5.4 运行应用程序 470
14.6 注意事项 470
14.7 小结 471
第15章 使用Apple Pay接收付款 473
15.1 Apple Pay与其他支付系统比较 473
15.1.1 使用Apple Pay的先决条件 474
15.1.2 使用Apple Pay接收支付 475
15.1.3 为Apple Pay配置环境 482
15.1.4 使用Stripe实现Apple Pay支付 492
15.1.5 View Controller代码 498
15.2 小结 501
撰文:Ahmed Bakir
物联网的定义
物联网(Internet of Things,IoT)是指通过接收或记录来自互联网和其他事物的数据,来推动应用程序、硬件设备或“物”朝着“智能”的方向发展。物联网的目标是利用这些额外的数据源,让人们生活中的常见任务变得更丰富、更容易执行。
物联网早的驱动因素之一是量化自我(Quantified Self)的运动,这一趋势表明,人们可以通过不断记录和监控自己的饮食和锻炼信息,以便在更可持续的水平上减肥和增进健康。尽管这首先是从卡路里计数的日记账和计步器中收集的数据开始的,但在这之后开始出现了诸如MyFitnessPal之类的应用程序(可帮助用户查找午后零食的热量信息)和诸如Fitbit之类的设备,此类设备可以将用户的计步器数据自动记录到互联网上,从而推动“量化自我”运动成为一种让很多人都热衷的潮流。
运行中的物联网的另一个示例是智能电视。仅仅在几年之前,电视还只是一个“哑巴”屏幕,仅显示所连接的输入设备(如机顶盒、游戏机或VCR)的输出(这些东西你是不是都已经快忘记了)。随着软硬件产品的快速更新迭代,如今的电视通常包括WiFi卡和“智能”应用程序平台,这些平台使用户可以执行一些常见的任务,例如从Netflix播放流视频或直接通过电视浏览Instagram的照片,而无须连接计算机。许多电视当前已经达到堪称“智能”的程度(例如,当想要看电视时,可自动打开经常看的节目),这是由于在PC和手机上已经实现了此类功能,因此,连接了互联网的智能电视实现这样的功能不过是小事一桩,有很多开发人员为电视编写此类应用程序。
今天的物联网与之前将设备连接到互联网的尝试之间的一个显著区别是,进入的技术壁垒已经大大降低。以前,构建Internet连接设备的方法是让训练有素的硬件和软件工程师团队构建专有平台,并且可能需要几年的时间;而如今,则可以去任何电子商店或网站购买Arduino或Raspberry Pi,轻松将几年前的计算机主板纳入掌中,价格30美元左右。这些设备旨在为业余爱好者和学生提供一种简便的输入电子设备的方式(以前,这是一种非常昂贵的业余爱好—某个过来人的心声),还包括构建连接设备所需的所有核心功能—能够运行高级编程语言(如Python)的CPU、WiFi卡、显示端口(通常是HDMI)以及一系列通用输入/输出(General Purpose Input/Output,GPIO)引脚,这些引脚可以让开发人员连接电子组件,如计时器芯片和LED灯。
消费者和生产企业都已经注意到互联设备的需求,以及进入市场的便利性,这使得当前成为学习如何为物联网编程的时机!说不定哪一天你的应用也将推动某一款个性化产品或服务成为一种潮流!
本书目标
本书的目标是教会读者如何使用Apple公司的原生应用程序编程接口(Application Programming Interface,API)在Swift中构建iOS应用程序,该API可连接到流行的物联网(IoT)设备和服务。本书将围绕以下4类设备进行叙述。
? 健身和健康追踪器。
? Apple手表。
? 通用硬件配件。
? 认证和支付系统。
上述设备系列代表了一些非常流行的IoT配件类别,同时使我们可以教给读者若干种不同的方法来连接IoT设备,包括原生iOS库(如HealthKit和WatchKit)、通用硬件接口(如蓝牙)、第三方数据记录服务(如Fitbit)和本地网络(通过WiFi)。当今物联网的美妙之处在于,基于广泛采用的开放标准,有多种方法可以连接设备,从而减少了学习专有协议的需求。我们的目标是通过向读者展示连接到IoT设备的不同方式,帮助读者掌握一个方便的技能工具箱,以满足读者需要实现的大多数用例。
本书以教程风格进行介绍,该教程借鉴了现代软件工程实践的经验,如代码审查和敏捷编程。本书的每一章都围绕着一个将要学习如何实现的项目而展开,将通过假想的“故事”和需求进行描述,以阐述其重要之所在。以类似的方式,我们的解释将深入代码中,并从Apple的规范和其他应用程序中借鉴实践。必要时,我们将简要介绍基础主题,如委托编程和OAUTH身份验证,因此读者无须为了某个知识点而反复翻阅不同的书籍。本书的目标是使读者对将要实现的项目有深入的了解,而不是复制并粘贴的摘要记录。作为经历过重大iOS升级(例如,从iOS 6升级到iOS 7)的开发人员,我们可以证明,了解核心概念比记忆一次性使用的代码段更有助于读者修复自己的代码。
本书适合的读者
本书的目的是成为开发人员在iOS中实现特定主题的指导手册。它的结构可以引导初学者和中级程序员理解他们需要的信息,同时还可以使高级读者准确地找到他们想要的内容。换句话说,就是本书适合从初级到高级各个层次的读者,他们均可以从本书的阅读中受益。话虽如此,本书在撰写时也考虑了一些假设。
? 读者对核心编程概念(面向对象的编程、指针、函数等)有扎实的基础。
? 读者具有iOS开发基础知识(使用Xcode、Interface Builder和Cocoa Touch库)。
? 读者已有使用Swift或Objective-C编程的经验。
由于Swift和Xcode是不断发展的工具,因此本书的前两章将介绍集成开发环境(IDE)和语法基础。这些章节的目的是帮助从Objective-C过渡到Swift的开发人员,以及尚未有机会查看Apple烦琐的API更新文档的开发人员。
为了扩大对Swift编程语言、iOS编程和Xcode的讨论,我们建议读者阅读表P-1中列出的图书(这些图书也是Apress公司出版的)。
表P-1 推荐参考书目
主 题 书名和作者
iOS开发入门 书名为Beginning iPhone Development with Swift(用Swift开始iPhone开发),作者为David Mark、Jack Nutting、Kim Topley、Fredrik Olsson和Jeff LaMarche(Apress出版,2014年)
使用Xcode和调试器 书名为Beginning Xcode:Swift Edition(Xcode入门:Swift版),
作者为Matthew Knott(Apress出版,2014年)
中间iOS开发 书名为Learn iOS 8 App Development(学习iOS 8 App开发),
作者为James Bucanek(Apress出版,2014年)
Swift语法 书名为Swift for Absolute Beginners(Swift菜鸟入门教程),
作者为Gary Bennett和Brad Lees(Apress出版,2014年)
iOS编程的参考是Apple的官方iOS开发人员库,读者可以通过Xcode的Window(窗口)菜单中的Documentation and API Reference(文档和API参考)命令访问(见图P-1),也可以通过在线访问,其网址如下:
https://developer.apple.com/library/ios/navigation/
图P-1 从Xcode访问iOS开发人员库
注意:
请始终使用版本的iOS开发人员库作为你的API参考。Apple经常进行重大的弃用和参数更改,即使在次要版本中也是如此。
保持状态的方法是保持的Xcode版本或访问iOS Developer Library网站。
入门要求
本书是围绕在计算机上开发应用程序并在可能与硬件附件配对的物理设备上进行测试的工作流而设计的。本书中项目所需的API在iOS模拟器中是不提供的。
Apple使用物理设备开发和测试iOS应用程序的要求与将应用程序提交到App Store的要求相同,具体如下。
? 运行OS X Yosemite(10.10)或更高版本的基于Intel的Mac。
? Xcode 7或更高版本。
? 能够运行iOS 9.1或更高版本的iPhone或iPad(iPhone 5或更高版本、iPad 2/iPad mini或更高版本)。
? 有效的Apple ID,可以注册免费的基于设备的应用程序测试。
从2015年夏季开始,Apple取消了必须拥有付费iOS开发者计划会员资格才能在iOS设备上测试应用程序的要求,但仍需要付费会员资格才能将应用程序提交到App Store、使用TestFlight进行Beta测试以及调试基于Apple服务器的API(如Apple Pay)。可以通过登录Apple Developer Program网站(https://developer.apple.com/programs/,中文网址为https://developer.apple.com/cn/programs/)并单击Enroll(注册)按钮来注册Apple Developer Program会员资格,如图P-2所示。收到费用后,在Apple Store中,所选择的Apple ID将可在Apple Developer Program中使用。
图P-2 注册一个付费的Apple Developer Program账户
说明:
如果要注册一个企业开发人员账户,则需要向Apple提供其他信息以标识你的实体,如Dunn & Bradstreet号(邓白氏集团信用账号)。处理此类账户将需要更多的时间。
本书中的项目旨在“通用”,这意味着它们可以同时在iPhone或iPad上运行。这些用户界面主要是为iPhone设计的,但它们会按比例放大并在iPad上以相同的方式工作。
本书涵盖的内容
本书包含15章,分为5篇。
第1篇为“物联网应用程序开发和Swift编程语言基础知识”,包括第1~2章。第1章通过一个简单的实例介绍了在Xcode中创建应用程序的基本操作,第2章则介绍了Swift的基本语法和特定功能等,方便开发人员快速入门。
第2篇为“Fitbit健康设备项目”,包括第3~5章,要求开发人员拥有iPhone 5S或更高版本的设备,才能使用Core Motion框架。iPad和较旧的iPhone没有Core Motion提供的M系列运动协处理器芯片。该芯片包括一个高级计步器和陀螺仪,它们可以按小于GPS芯片功耗十分之一的速度进行跟踪(根据Apple的要求)。对于第5章,开发人员需要在Fitbit.com上有一个免费账户才能生成样本数据进行测试,但不需要Fitbit硬件设备。你可以在Fitbit网站上手动输入步数、卡路里摄入量和体重。
第3篇为“Apple Watch项目”,包括第6~8章,前两章可以使用Apple Watch模拟器来实现;但是,第8章则利用模拟器不支持的Core Location框架的功能。Apple Watch仍然是一个正在不断优化的硬件平台,因此好使用Apple Watch对应用程序进行测试以获取真实的性能数据。
第4篇为“蓝牙和WiFi连接”,包括第9~12章,它要求开发人员至少有两台iOS设备。第9章教给开发人员如何通过蓝牙在两台设备之间建立直接链接。为了使叙述重点突出,开发人员将学习如何为蓝牙的两个核心角色(中心设备管理器和外围设备管理器)配置iOS设备。拥有两台设备可以使开发人员快速而可靠地进行测试。在第10章中,开发人员将学习如何将iPhone配置为iBeacon发射器,但是也可以使用硬件信标进行测试 (在大多数电子产品网站上,它们都可以作为USB加密狗使用,价格约20~30美元)。
第5篇为“安全物联网”,包括第13~15章,介绍了与身份验证和支付系统相关的内容,要求开发人员拥有iPhone 5S或更高版本的设备以获得Touch ID。第15章有关Apple Pay的项目则需要iPhone 6或更高版本的设备。自iPhone 5S起,每部iPhone上均配备Touch ID传感器(由HOME按键周围的金属环标识),自iPad mini 3和iPad Air起,每台iPad上均可使用。它不能在软件中模拟。同样,Apple Pay需要近场通信(Near Field Communication,NFC)传感器和附加的身份验证芯片,这些功能仅在iPhone 6/6 Plus或更高版本以及iPad mini 3/iPad Air 2或更高版本中可用。
本书约定
在本书中,读者将可以看到许多区分不同类型信息的文本样式。以下是这些样式的一些示例以及对它们的含义的解释。
(1)界面词汇的后面使用括号附加对应的中文含义,以方便读者对照查看。以下段落就是一个示例:
在选中Map View(地图视图)后,单击Pin(固定)工具,在弹出的对话框中,取消选中Constrain to margins(约束到边距)复选框,并将所有邻近约束(框周围的约束)设置为0,如图1-22所示。
(2)代码块显示如下:
funcset(text: String?=””) {
dispatch_async(dispatch_get_main_queue()) {
self.textArea!.text = text
};
}
(3)当我们希望引起读者对代码块特定部分的注意时,相关的行或项目将以粗体显示。示例如下:
import UIKit
import MapKit
class SecondViewController: UIViewController {
@IBOutlet var mapView : MKMapView?
}
(4)新术语和重要单词提供了中英文对照的形式。以下段落就是一个示例:
peripheralDataWithMeasuredPower采用一个参数代表所测量的功率。设备的测量功率是在接收信号强度指示器(Received Signal Strength Indicator,RSSI)中测得的1m处的信号强度。iOS提供的距离以米为单位,是基于信标信号强度与发射功率之比的估算值。
下载示例代码文件
读者可以从Apress网站(www.apress.com)中下载本书的示例代码文件。本书的所有源代码都打包在一个zip文件中,具体网址如下:
http://Apress.com/9781484211953
也可以直接访问以下GitHub页面:
https://github.com/apress/program-internet-of-things-w-swift-for-ios
关于作者
Ahmed Bakir是devAtelier LLC(www.devatelier.com)的创始人和首席开发人员,devAtelier是一家位于圣地亚哥的移动应用开发公司。Ahmed Bakir在花了几年时间编写嵌入式系统软件之后,他开始在业余时间开发移动App,并以此为乐。消息传开后,就有客户络绎不绝地登门拜访他,以至于他不得不辞掉正式工作,全职投入移动App的开发中。
从那以后,Ahmed Bakir参与了20多个移动项目的开发,其中有若干个项目进入了App Store的前25名,包括在同类产品中排名的App(Video Scheduler)。他的客户中既有雄心勃勃的初创公司,也有一些大型企业,如Citrix等。业余时间他喜欢谈论的还是移动开发。
Gheorghe Chesler是一名高级软件工程师,在质量保证、系统自动化、性能工程和电子出版方面具有专长。他是ServiceNow公司的一名高级性能工程师,同时也是Plural Publishing公司的首席技术顾问。他喜欢的编程语言是Perl(以至于他乐于使用Perl的吉祥物来标识自己,也就是右面的这幅骆驼头像图),但他也参与了许多Java和Objective-C项目。
Manny de la Torriente拥有超过30年的软件开发经验,曾从事从工程到管理各个级别的工作。Manny初从事软件方面的工作,为声音工程编写程序,然后进入游戏引擎和低级视频回放系统的开发。Manny比较出名的是,他会根据对项目的感兴趣程度在iOS和Android之间做出选择。
关于审稿者
Charles Cruz是iOS、Windows Phone和Android平台的移动应用程序开发人员。他毕业于斯坦福大学,获得工程学士和硕士学位。他住在南加州,和他的妻子一起经营一家摄影公司(www.bellalentestudios.com)。当他不做技术方面的工作时,他会担任原创金属乐队(www. taintedsociety.com)的主音吉他手。要联系Charles,可以发邮件到[email protected]或在Twitter上@codingnpick。
评论
还没有评论。