Coder Social home page Coder Social logo

mdznr / rewritten-apis Goto Github PK

View Code? Open in Web Editor NEW
2.0 3.0 1.0 6.39 MB

Rewriting the APIs of classes in UIKit (like UIActionSheet and UIAlertView) to make them more sensical and easier to use.

License: BSD 3-Clause "New" or "Revised" License

Objective-C 100.00%

rewritten-apis's Introduction

Rewritten APIs

Overview

This is a project to redesign and rewrite the APIs for some of the UIKit classes. It currently includes replacements for: UIActionSheet UIAlertView

These are not recreations of UIKit classes, but are classes that interface with the corresponding original UIKit class. This project started to ease some of my own annoyances with the original APIs. UIKit has a ton of phenomenal APIs, but there are some places where things could be improved. It’s been a lot of fun to practice and experiment with API design.

Keynote Presentation (HTML)

Presentation with notes (PDF)

Current API

A simple use-case example with the original UIActionSheet:

In a method in of a view controller:

UIActionSheet *myActionSheet = [[UIActionSheet alloc] initWithTitle:NSLocalizedString(@"Title", nil)
															   delegate:self
													  cancelButtonTitle:NSLocalizedString(@"Cancel", nil)
												 destructiveButtonTitle:nil
													  otherButtonTitles:NSLocalizedString(@"Open", nil), NSLocalizedString(@"Copy", nil), nil];
	[myActionSheet showInView:self.view];

The view controller is set as the delegate, and has to implement actionSheet:clickedButtonAtIndex::

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
	switch (buttonIndex) {
		case 0: // Open
			[self openActionSheetButtonTapped];
			break;
		case 1: // Copy
			[self copyActionSheetButtonTapped];
			break;
		default:
			break;
	}
}

The current API is complicated. The initializer method has four required parameters, one of them being a nil-terminated list. Nil-terminated lists don’t work well with data in data structures like arrays.

It’s misleading. UIActionSheet and UIAlertView are subclasses of UIView, which it may technically be, but that creates a confusing interface. To show either one of these classes, you use showInView: or show, instead of adding it as a subview of another view. The user should not be lead to believe they have to do this to get it to work. The view’s frame shouldn’t be an exposed part of the API, but it has to be since it is a subclass of UIView. Autocomplete in Xcode will suggest UIView-related suggestions like initWithFrame:, transform, and backgroundColor, all of which should not be used in these classes.

These classes do not have enough encapsulation. They push responsibility of mapping indices to actions, even though the delegate should not need to worry about a bunch of indices. Things get especially more complicated when using a cancel button and destructive button. Things get even more complicated when action sheets are created dynamically. If certain buttons aren’t always presented, the delegate has to account for the change in index values.

Rewritten API

The same example as above but using the rewritten API:

MTZActionSheet *as = [[MTZActionSheet alloc] init];
as.title = @"Title";
as.cancelButtonTitle = NSLocalizedString(@"Cancel", nil)
[as addButtonWithTitle:NSLocalizedString(@"Open", nil) andSelector:@selector(openActionSheetButtonTapped)];
[as addButtonWithTitle:NSLocalizedString(@"Copy", nil) andSelector:@selector(copyActionSheetButtonTapped)];
[as showInView:self.view];

The examples used are quite simple, but representative of most uses of the action sheet. Comparatively, this code is much more concise. Concise code isn’t always better as it can often compromise clarity. However, just the opposite is shown here. The change to more concise code actually enhanced clarity.

The connection between button titles and their corresponding actions is much more clear. The code to handle this is no longer spread out across the file, making a mess of complicated code paths. The delegate no longest has to keep track of button indices, making it easier to dynamically populate the action sheet.

The intended use for this class is clarified by making it a UIView-backed subclass of NSObject. The developer is never mislead into thinking they’re responsible for handling how to display the view. The show, showInView:, etc. methods are the only available methods having to do with presenting the view. Irrelevant UIView properties and methods no longer clutter the API of these classes.

rewritten-apis's People

Contributors

mdznr avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

freemansion

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.