Code Monkey home page Code Monkey logo

ios-playbook's Introduction

Hyper's iOS Playbook

Author: Randall Munroe, xkcd.com

This is our playbook, there are many like it, but this one is ours.

Wanna work with us? We have a fun assigment that you might be interested in.

Email us your GitHub repo!


Should my guideline be in code style or best practices?

If your guideline applies to both Swift and Objective-C, then it's probably a best practice.

ios-playbook's People

Contributors

3lvis avatar attila-bardos avatar bcapps avatar brow avatar ded avatar dlo avatar eerwitt avatar jacobvanorder avatar jasonm23 avatar jawwad avatar jeffleeismyhero avatar jfiore avatar jgorset avatar kostiakoval avatar mattbischoff avatar maxgabriel avatar murdocdv avatar naeemshaikh90 avatar nselvis avatar onmyway133 avatar paulbruneau avatar peteog avatar phelps avatar ramongilabert avatar robrix avatar twigz avatar vadymmarkov avatar yas375 avatar zenangst avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ios-playbook's Issues

Missing .gitignore and travis.yml

The ui-component-template.zip file you have linked from COMPONENTS.md doesn't seem to contain .gitignore and travis.yml files. Maybe the zip file is a snapshot of an earlier version?

Required and optional blocks

We've been adding the check for completion

if (completion) {
    completion(....)
}

To our methods that have a completion method but you shouldn't need that always. It should only be needed when the block is optional meaning that not providing a completion block doesn't change the behavior of the method.

One example of optional block is the dismissViewControllerAnimated:completion: method on UIViewController

An example of a required block is the method enumerateObjectsUsingBlock: on NSArray

Preprocessed header

Where to put #import statements, In .h, .m or .pch file?
Where to use class forward declaration
@Class SomeClass

NotificationCenter best practices

Notification Center

Very rarely Notification Center is a good choice. But when is needed make sure to not hard code the notification name, but make a constant for it.

Custom mogenerator template

  • Remove strong from variables
  • Add convenience methods to create NSFetchRequest for an entity by sending a NSPredicate

Functions that do asynchronous work should have a completion block

Example:

I had a method persistContext in DATAStack that did asynchronous saving.

When testing some behaviour I was calling [dataStack persistContext] but I was getting the wrong behaviour, then I realised that it was because of the asynchronous work on the method.

Making this method return a completion from the beginning would give me the clue that it was async.

We've experienced this also in other methods, been super clear on the async nature of your methods will make them easier to understand and test.

Code style when declaring and calling methods

We should add a section about coding styles for declaring methods and doing method calls. Me and @NSElvis have discussed this multiple times on Slack, but Slack has Goldfish memory when it comes to keeping logs (NAME DROP!). So I thought I'd bring the discussion here instead.

I propose the following;

Declaring methods should always be done on one line, they should not conform to the align colons convention that the method calls conform to.

So you would do this:

- (BOOL)conformsToProtocol:(Protocol *)protocol requiringSelectors:(NSArray *)selectors
{}

And not this

- (BOOL)conformsToProtocol:(Protocol *)protocol 
        requiringSelectors:(NSArray *)selectors
{}

Method calls however should use colon alignment which would look like this.

return [self conformsToProtocol:NSProtocolFromString(@"GOLDPlugIn")
             requiringSelectors:arraySelectors];

And not like this

return [self conformsToProtocol:NSProtocolFromString(@"GOLDPlugIn") requiringSelectors:arraySelectors];

UNLESS!... unless you are working with blocks, then they should not be aligned because that would totally screw up the readability.

What do you guys think?

Hyper pods

Create a list of existing Hyper pods with their use cases:
Easer to discover existing pods for new team members

Example:
Sync - Syncing JSON to CoreData
..

Custom Xcode template

  • Use modules
  • Remove AppDelegate useless methods
  • Remove attribution comments
  • Add private header
  • Remove boilerplate (ViewController methods)

Core Data Stack

Core Data

Your Core Data stack should be referenced as dataStack, not data or stack.

iOS, the new wave

iOS, mainly thanks to Swift, is transitioning to a whole new level. Now you hear more about Functional Programming, Reactive Programming, Immutability and so much more.

I thought I would start this issue to compile some resources that could help us to get to the next level.

Would be great if (besides the link) you added why the resource is relevant or how it could help us.


Great introduction by Andy Matuschak about why this concepts are important and how they help to make better software
https://developer.apple.com/videos/wwdc/2014/
http://realm.io/news/andy-matuschak-controlling-complexity/

Rich Hickey, the author of Clojure, is an independent software designer, consultant and application architect with over 20 years of experience in all facets of software development.

http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey
http://www.infoq.com/presentations/Simple-Made-Easy

Haskell and Scala are probably some of the most relevant functional languages out there, learning them is embracing the new wave

Learn Haskell
http://learnyouahaskell.com/

Principles of Reactive Programming
https://www.coursera.org/course/reactive

Dan Grossman’s Programming Languages Course
http://oleb.net/blog/2014/12/programming-languages-mooc/

Functional Programming Principles in Scala
https://www.coursera.org/course/progfun

Xcode folder structure

I propose something like this.

ProjectName
|
|— External
|—— 3rd party code that doesn't use CocoaPods or is heavily customized.
|
|— Shared
|—— Custom Containers
|—— Base Classes
|—— Utils
|—— Networking (Base)
|
|— AppDelegate
|
|— Controllers
|—— Recipes
|——— Controllers
|——— Views
|——— Images
|——— Networking
|
|—— Ingredients
|——— Controllers
|——— Views
|——— Images
|——— Networking
|
|—— Comments
|——— Controllers
|——— Views
|——— Images
|——— Networking
|
|— Model
|
|— Supporting Files

Clarify APIs with inmmutable and mutable params

If the parameter been sent is going to be mutated then return a new instance or add it to the completion block as updated{ParamaterName}, otherwise is expected that the variable will not be mutated so it also could be inmmutable.

Semantic Versioning

Guys, we need to perfect this, we need to agree on something and make it happen.

The most common thing that comes when this topic is discussed is:

http://semver.org

But what about a workflow of:

Current deployed version: 1.1.0

  • You fix a bug
  • You make a new version 1.1.1, you make a build (ipa), upload it to Hockey/TestFlight, make a tag/release on git/GitHub then when you're ready to get some coffee and eat 🍰 then...
  • The QA department finds an issue with your 🐛 fix
  • You go back, fix the thing, your code compiles then, what the semantic versioning of your build?

We've been playing with RC postfix but I'm not sure if it's the best idea (I like it). Also @attila-at-hyper pointed out that HockeyApp doesn't play well with this.

So, what to do? What would be the proper version number for the release that fixes the issue with your bug fix?

cc @hyperoslo/ios @marcel-eggum @jacob-andersson (sorry if I'm forgetting someone) 🔔

Multiple return statements in methods

I think having multiple returns in methods it's a bad pattern since I've faced that many bugs can be introduced in this way.

Good

- (NSInteger)elementsCount
{
    NSInteger elementsCount;

    if (self.employee.hasChildren) {
        elementsCount = 3;
    } else if (self.employee.isSingle) {
        elementsCount = [self.employee numberOfRelatives];
    }

   return elementsCount;
}

Bad

- (NSInteger)elementsCount
{
    if (self.employee.hasChildren) {
        return 3;
    } else if (self.employee.isSingle) {
        return [self.employee numberOfRelatives];
    }

   return 0;
}

Bad Singletons

Singletons are bad, try to avoid them unless they are really necessary.

Enable all warnings in Xcode.

Add -Wall to "Other warning flags"
could be even better to add -Weverything

  • second part of this issue: Fix all (possible) warning

Where do you put your constants

On my current project I was thinking about adding a header file (Constants.h) that would contain all global constants used thru out the project. Where would you put this?

I don't think it should go into Source because constants should more or less be immune to change (ish).

Would it make sense to put it into the top level of the Library? I don't really like this...
It will always be tightly coupled to the application, hence my objection to putting it into the Library folder.

You could also argue that the place for it is in Source because all other app specific files go in there.

I've been going back and forth on this and haven't really landed on anything that I think really fits...

Help me Obi-Wan Nuñez (@NSElvis), you're my only hope..... ish.

Avoid app logic in view life cycle methods

Initialization logic should live in init method, if there's logic that has to run on viewDidAppear for example syncing data from the backend, then this should be exposed on public methods so they can be run by automatic tests.

Mutable copies

Don't

 NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithDictionary:dic];

Do

 NSMutableDictionary *dictionary = [dic mutableCopy];

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.