SoftwareEngineering.APIDesign.iOS

API Design for iOS/Mac (Objective-c Edition)

1. UI Control Library API的设计

和已有组件保持一致(例如: 使用标准的API, 模型,模式)可以使Developer更易理解。

Class interface

Rule1: 使用该平台常用/通用的术语或者名字 (Use the local dialect)

在编码前学习该平台的习俗或者惯例;学习并理解protocol, delegate, category分别是什么;遵循内存管理规则;

Rule2: 解耦的设计 (Design decoupled)

"Any component should be designed such that it’s not coupled to the project you created it for,

and if it’s a GUI control or view, it should at least display something by default."  Ref[1]

Rule3: 必须的设置应该作为初始器的参数 (Required settings should be initializer parameters)

- (id)initWithDelegate:(id<MGTileMenuDelegate>)theDelegate; // required parameter; cannot be nil.

Rule4: 允许访问初始器的参数

1 @property (nonatomic, weak, readonly) id<MGTileMenuDelegate> delegate; // must be specified via initializer method.

Rule5: 为头文件添加注释 (Comment your header files (including defaults))

"you should briefly note default values beside properties or accessors" Ref[1]

1 @property (nonatomic) CGGradientRef tileGradient; // gradient to apply to tile backgrounds (default: a lovely blue)
2 @property (nonatomic) NSInteger selectionBorderWidth; // default: 5 pixels
3 @property (nonatomic) CGGradientRef selectionGradient; // default: a subtle white (top) to grey (bottom) gradient

Rule 6: 确保可以用3行代码来使用组件 (Get up and running in 3 lines)

这条值得商榷!

1 // Instantiate.
2 tileController = [[MGTileMenuController alloc] initWithDelegate:self];
3
4 // Configure.
5 tileController.dismissAfterTileActivated = NO; // to make it easier to play with in the demo app.
6
7 // Display.
8 [tileController displayMenuCenteredOnPoint:loc inView:self.view];

Rule 7: 组件的demo越小,反映组件越好 (A fat demo usually means a broken component)

Rule 8: 提前考虑并满足定制场景 (Anticipate customisation scenarios)

"I approach this by trying not to think of customisation at the instance-variable level,

but rather at the “aspect” level." Ref[1]

Rule 9: 更多的属性,更少的行为/方法 (More properties, fewer actions)

Rule 10: 在你的组件中使用存在的组件 (Use controls in your controls)

Rule 11: 考虑将便利方法暴露给developer (Convenient for you is convenient for me)

Rule 12: (Magic is OK. Numbers aren’t)

"What’s not OK, though, is needlessly putting mysterious raw values throughout your code, and it’s

especially not OK to expose that in the API." Ref[1]

Delegate and data-source protocols

Data-source Protocol关注的事项:

  1. How many things do I have?
  2. What’s the value for property Y of thing X?

Delegate 关注的事项:

  1. Should this thing do that?
  2. This thing is about to do that.
  3. This thing just did that.

should, will, did

Rule 13: 限制required方法的数量 (Limit ‘required’ delegate methods)

"A well-designed component should need very, very few required delegate methods - just the

bare minimum to do whatever it does." Ref[1]

Rule 14: 为可访问性进行设计 (Design for accessibility)

"make things accessible" Ref[1]

accessibility programming VoiceOver

Rule 15: 为参数使用语义明确的对象 (Use semantic objects for parameters)

"If you’re asking for a date, don’t accept numbers - get an actual NSDate object. " Ref[1]

Rule 16: 当语义不合适时,可以使用增强API的方式 (Enhance the API if semantics don’t fit)

例如: "A contact list implemented with a table should have a contacts-related API" Ref[1]

Rule: 17 UI组件的高亮令人关注 (Highlighting is interesting)

Rule: 18 可选方法并不是一个承诺 (Optional methods aren’t a commitment)

"Many of us approach optional delegate methods as an either-or situation: if you don’t implement them,

you get the default behaviour, and if you do, then you’re totally responsible for what happens.

That’s not ideal."  ref[1]

可选方法可能并没有返回我们期望的值。比如:我们期望可选方法返回一个UIColor对象,但是可选方法返回了nil。那么我们

跳回默认逻辑是更好的选择。

Rule 19: 总是指明谁在"讲话" (Always say who’s talking)

1 - (void)tileMenu:(MGTileMenuController *)tileMenu didActivateTile:(NSInteger)tileNumber; // zero-based tileNumber
1 - (void)tileMenuDidActivateTile:(NSInteger)tileNumber; // zero-based tileNumber
2 // Um, WHICH menu?

Rule 20: 把不同的参数放在前面 (Put distinguishing params first in query methods)

1 - (UIImage *)imageForTile:(NSInteger)tileNumber inMenu:(MGTileMenuController *)tileMenu; // zero-based tileNumber
1 - (UIImage *)tileMenu:(MGTileMenuController *)tileMenu imageForTile:(NSInteger)tileNumber;

但是Apple API确实和该Rule相反。例如:

1 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

Rule 21: 将sender放在notification方法的第一个参数 (Put the sender first in notification methods)

"The One True Delegate Protocol, however, isn’t for queries but rather for notifications." Ref[1]

1 - (void)tileMenu:(MGTileMenuController *)tileMenu willSwitchToPage:(NSInteger)pageNumber; // zero-based pageNumber

Rule 22: If a convention is broken, throw it away (*)

Notification

"Notifications are the other half of delegate protocols. My position is that, if you’re using a delegate

protocol (you should, if it’s at all appropriate), then it’s incomplete until you add the notifications

that naturally follow from it." Ref[1]

Rule 23: 通知和delegate方法保持一致 (Notifications follow delegate methods)

"If you have a delegate method that tells the delegate about something happening, you should

usually provide a notification for that same purpose." Ref[1]

Rule 24: 为notification提供足够的数据 (Be generous with notifications’ userInfo)

"At the very least, you must ensure that all arguments provided to the corresponding delegate

method are wrapped up in the userInfo object." Ref[1]

Rule 25: 进行测试 (Test the hell out of it)

如果时间紧迫,可以减少feature来支持测试

Todo: article on releasing open source code

2. About iOS API Design

2.1 Aviary team’s best practices for developing APIs

"The design goals for an API are similar to those of a user interface: exposing the product’s features

and communicating how to use them."  Ref[2]

2.1.1 编写的文档要遵守平台的约定。

2.1.2 平台一致性

"This manifests itself in long, descriptive method names, the organization of functionality around view controllers,

and design patterns like delegation and target-action. "   Ref[2]

遵守Apple的Cocoa Touch规范: naming conventions and design patterns

2.1.3 SDK可以快速集成

2.1.4 选择合适工具: Best Pattern

"Choosing the best pattern makes your code both easier to understand and to use."

Delegate

"the delegate version breaks up the processing code into pieces and makes it more difficult to read and understand."

"Delegation is best suited for situations when the response to a notification relies primarily on the information

contained in the delegate method’s parameters."

2.1.5 提供默认值

"By providing a convenience initializer, the integrating developer does not need to consider the more advanced

options until their application demands them."

2.1.6 维护SDK的向后兼容性和版本信息


Reference

1. API Design

http://mattgemmell.com/api-design/

主要是UI方面库和API的设计

2. Best Practices for iOS API Design

https://blog.creativesdk.com/2015/03/best-practices-for-ios-api-design/

"Aviary team’s best practices for developing APIs"



Todo

1. google "how to design interface of library for iOS"

2. WWDC 2014 Session 416

3. adobe creative sdk

4. Delegate vs. Block

时间: 2024-11-04 11:08:41

SoftwareEngineering.APIDesign.iOS的相关文章

唐巧的iOS技术博客选摘

1. 那些被遗漏的objective-c保留字:http://blog.devtang.com/blog/2013/04/29/the-missing-objc-keywords/ 2. 使用crashlytics来保存应用崩溃信息:http://blog.devtang.com/blog/2013/07/24/use-crashlytics/ 3. iOS开发工具篇,AppStore统计工具:http://blog.devtang.com/blog/2013/06/16/ios-dev-too

iOS -- SKSpriteNode类

SKSpriteNode类 继承自 SKNode:UIResponder:NSObject 符合 NSCoding(SKNode)NSCopying(SKNode)NSObject(NSObject) 框架  /System/Library/Frameworks/SpriteKit.framework 可用性 可用于iOS 7.0或者更晚的版本 声明于 SKSpriteNode.h 参考指南 Sprite Kit Progamming Guide 概览 重要提示:这是一个初步的API或者开发技术

使用fruitstrap实现命令行将IPA包安装到iOS设备上

Requirements Mac OS X. Tested on Snow Leopard only. You need to have a valid iPhone development certificate installed. Xcode must be installed, along with the SDK for your iOS version. Usage fruitstrap [-d] -b <app> [device_id] Optional -d flag laun

iOS -- SKScene类

SKScene类 继承自 SKEffectNode:SKNode:UIResponder:NSObject 符合 NSCoding(SKNode)NSCopying(SKNode)NSObject(NSObject) 框架  /System/Library/Frameworks/SpriteKit.framework 可用性 可用于iOS 7.0或者更晚的版本 声明于 SKScene.h 参考指南 Sprite Kit Progamming Guide 概览 重要提示:这是一个初步的API或者开

iOS -- SKPhysicsWorld类

SKPhysicsWorld类 继承自 NSObject 符合 NSCodingNSObject(NSObject) 框架  /System/Library/Frameworks/SpriteKit.framework 可用性 可用于iOS 7.0或者更晚的版本 声明于 SKPhysicsWorld.h 参考指南 Sprite Kit Progamming Guide 概览 重要提示:这是一个初步的API或者开发技术文档.虽然已经审阅了本文档的技术准确性,但是它不是最终的版本.本机密信息仅适用于

iOS证书说明和发布

1.首先通过钥匙串访问——证书助理——从证书颁发机构请求证书——填写证书信息(邮箱,常用名称,存储到磁盘)——存储为(自定义名称.certSigningReuqest,简称CSR文件,只是为了提交到苹果开发者账号中,然后就没用了)到本地 2.苹果开发者账号中,创建证书(Development和Production)——上传CSR文件——下载证书运行 ( xxx.cer文件) 注意:只有在当前电脑中生成本地生成证书,上传到苹果开发账号,然后下载cer文件运行后,钥匙串中才有证书以及对应的秘钥 如果

iOS开发——项目实战总结&amp;UITableView性能优化与卡顿问题

UITableView性能优化与卡顿问题 1.最常用的就是cell的重用, 注册重用标识符 如果不重用cell时,每当一个cell显示到屏幕上时,就会重新创建一个新的cell 如果有很多数据的时候,就会堆积很多cell.如果重用cell,为cell创建一个ID 每当需要显示cell 的时候,都会先去缓冲池中寻找可循环利用的cell,如果没有再重新创建cell 2.避免cell的重新布局 cell的布局填充等操作 比较耗时,一般创建时就布局好 如可以将cell单独放到一个自定义类,初始化时就布局好

解决ios下的微信打开的页面背景音乐无法自动播放

后面的项目发现,还有两个坑,需要注意下: ·本文的解决方案的核心是利用了 微信/易信 在ready的时候会有个 WeixinJSBridgeReady/YixinJSBridgeReady事件,通过监听这个事件来触发的.那有个坑就是 如果微信已经ready了,但还没执行到你监听这个ready事件的代码,那么你的监听是没用的,所以最理想的情况是,监听的js放在head前面(放在css外链之前),确保最新执行,切记!切记!. ·另一个坑就是,本文的解决方案只适合一开始就播放的背景音乐.如果你是做那种

iOS程序执行顺序和UIViewController 的生命周期(整理)

说明:此文是自己的总结笔记,主要参考: iOS程序的启动执行顺序 AppDelegate 及 UIViewController 的生命周期 UIView的生命周期 言叶之庭.jpeg 一. iOS程序的启动执行顺序 程序启动顺序图 iOS启动原理图.png 具体执行流程 程序入口进入main函数,设置AppDelegate称为函数的代理 程序完成加载[AppDelegate application:didFinishLaunchingWithOptions:] 创建window窗口 程序被激活[