rubymotion inspect conference - 2013. (with speaker notes.)

41
CocoaPods @CocoaPods • cocoapods.org • github.com/CocoaPods Eloy Durán • @alloy More than you need to know. I will not be speaking about testing today, but please feel free to ask me anything on the subject. After the talk, of course ;) So, CocoaPods, what is it?

Upload: alloy020

Post on 07-May-2015

510 views

Category:

Technology


1 download

DESCRIPTION

CocoaPods talk given at the RubyMotion Inspect 2013 conference. There is another version that does not include speaker notes available at: https://www.slideshare.net/alloy020/ruby-motion-inspect-2013-without-notes-18676749 The videos that were shown on slide 5 and 6 are available at: https://vimeo.com/63891717 & https://vimeo.com/63891716.

TRANSCRIPT

Page 1: RubyMotion Inspect Conference - 2013. (With speaker notes.)

CocoaPods@CocoaPods • cocoapods.org • github.com/CocoaPods

Eloy Durán • @alloy

More than you need to know.

I will not be speaking about testing today, but please feel free to ask me anything on the subject. After the talk, of course ;)

So, CocoaPods, what is it?

Page 2: RubyMotion Inspect Conference - 2013. (With speaker notes.)

What is it?

It’s a... [DRUMROLL] ... dependency manager. Boring, I know :)

Page 3: RubyMotion Inspect Conference - 2013. (With speaker notes.)

CocoaPods is like a combination of the RubyGems and Bundler projects. For those not familiar with them (which I highly doubt); RubyGems is a Ruby source package manager. It takes care of fetching and installing a package, _plus_ its dependencies, into a central location on the system. Bundler uses RubyGems to retrieve packages, but instead installs these locally on a per-project basis.

In addition, RubyGems provides an ‘ecosystem’ where open-source libraries can more easily be discovered.

So like I said before, CocoaPods is a combination of these projects. That is, it provides the tools to manage dependencies on a per-project basis and it provides an ‘ecosystem’ for open-source libraries to be found and flourish in the form of a repository of specifications for open-source libraries, which are searchable through cocoapods.org or from the command-line.

The complete ‘CocoaPods’ project encompasses the tools – ‘Xcodeproj’ and ‘CocoaPods’ – and the library specifications. These are all written in Ruby. In fact, CocoaPods re-uses some classes from RubyGems.

So how does working with CocoaPods work?

Page 4: RubyMotion Inspect Conference - 2013. (With speaker notes.)

How is it used inObjective-C projects?

The average CocoaPods user will be a Objective-C user, so first let me do a quick rundown of what that looks like.

‘Normal’ usage:* DRAG THE SOURCES, LUKE!* Add subproject* Then apply all the required settings.

Doing it the ‘normal’ way leads to issues with for instance shared dependencies. This will lead to duplicated symbols, which can be solved manually, but if you’re using for instance submodules, then you have local changes, so you need a fork, yada yada yada. It’s a pain.

[Show AFNetworking example movie 1]

Page 5: RubyMotion Inspect Conference - 2013. (With speaker notes.)

TODO Add video that shows manual process.

Video showing the ‘normal’ way of including third-party code. See https://vimeo.com/63891717.

Page 6: RubyMotion Inspect Conference - 2013. (With speaker notes.)

Video showing the same process, but handled by CocoaPods. See https://vimeo.com/63891716.

Page 7: RubyMotion Inspect Conference - 2013. (With speaker notes.)

RubyMotion greatly simplifies the build process.

There are no pesky platform or deployment target specific build settings or any compiler flags.

[Show Pods.xcconfig in Terminal]

Page 8: RubyMotion Inspect Conference - 2013. (With speaker notes.)

Can’t we just RubyifyALL THE LIBS?!

There are good reasons to use battle-tested objective-c libraries vs creating new ones.

* In general, it’s often a good idea to use a lib that others use as well, because there is more chance that others will be contributing to make the lib better. And since there are in general more Objective-C devs than RubyMotion devs (which I totally pull out of thin air, I have no empirical data to back this up), this makes sense.

But more importantly... [Next slide!]

Page 9: RubyMotion Inspect Conference - 2013. (With speaker notes.)

Too much dependencieswill kill you.

Some feel that dependency managers are bad for communities/produced products, because it makes it too easy to fall for ‘widget shopping’.

There are all sorts of philosophical debates we could have about this, but for now let’s keep it at that it’s the users that need to be responsible, not the tool.

In this context, it is of the utmost importance to remember that deploying updates on iOS through the AppStore is very expensive. By which I mean, releasing a bug-fix update can quickly take around a week to be available. Given this, it’s very important to keep being responsible in mind.

Page 10: RubyMotion Inspect Conference - 2013. (With speaker notes.)

Minimal Dependency Policy.

For instance, at Fingertips we have a ‘minimal dependency policy’. It’s surprisingly easy to follow; when you work on a new feature and want to add a dependency you ask yourself if you really need it.

Minimal dependency is not just about the number of libraries you use, but also about the total amount of code you pull into your project. Less code means less bugs.

Finally, less dependencies makes long-term maintenance easier because there is less that can go wrong when it’s time to upgrade to a new major iOS version.

So, with that all in mind:

Page 11: RubyMotion Inspect Conference - 2013. (With speaker notes.)

1. Second guess yourself.

Do I really, really need this? Or is my object-oriented-abstract-away-all-the-details mind playing tricks on me?

Page 12: RubyMotion Inspect Conference - 2013. (With speaker notes.)

1. Second guess yourself.2. Will it solve my problem?

Does the library I want to use fit my problem really well or am I better off writing 20 lines of code myself? For example: pull in AFNetworking or use plain NSURLConnection?

Page 13: RubyMotion Inspect Conference - 2013. (With speaker notes.)

1. Second guess yourself.2. Will it solve my problem?3. Should I use this library?

Sometimes using another library allows you to drop one you were using for another feature. For example: use AFNetworking for both networking and JSON serialization/de-serialization and drop JSONKit. (AFNetworking will use NSJSONSerialization when available.)

[Actually I think they dropped any other support than NSJSONSerialization, but the general idea still holds.]

Page 14: RubyMotion Inspect Conference - 2013. (With speaker notes.)

1. Second guess yourself.2. Will it solve my problem?3. Should I use this library?4. Check child dependencies

and weigh it against the benefit of using it.

For example: add your own UIAlertView block delegate custom class instead of using BlocksKit, which pulls in libffi.

Page 15: RubyMotion Inspect Conference - 2013. (With speaker notes.)

Details, details, details…

Page 16: RubyMotion Inspect Conference - 2013. (With speaker notes.)

“Bundler hasdestroyed my life”

– Carl Lerche

This quote has been my guide to staying sane. There is only so much that we can, but more importantly, *want* to do in our spare-time. So we took a conservative naive approach and followed it religiously.

Page 17: RubyMotion Inspect Conference - 2013. (With speaker notes.)

Git ‘spec repo’ architectureversus hosted like

rubygems.org?

It has allowed us to focus on the important work first, which is obviously the actual dependency resolving and installation, instead of having to first create a specification server as well.

The thing is, we take a very agile approach to this whole thing, meaning that until CP 1.0, we reserve the right to add/update/remove any of the spec DSL at will. (We do generally deprecate, but we won’t allow ourselves to be restricted by this.) So given this, it would have been very hard to keep the specs themselves up-to-date and the server features might influence the design process in a limiting fashion.

We don’t want that, so we ‘keep it simple, silly’.

Page 18: RubyMotion Inspect Conference - 2013. (With speaker notes.)

Using the filesystem as the ‘database’ and distributing it through Git has proven to be an extremely flexible way to deal with these types of spec changes.

That is, when we add, remove, or update an attribute, we can very easily go back and update all of the specifications or even merge those changes back into to the ‘master’ branch only once a new version is released.

Finally, in order to push adoption, it is **very** important to recognize that Objective-C has been used in commercial settings for a very long time already. Companies already tend to have _private_ internal frameworks and not catering to those would make it hard for them to adopt CocoaPods for all of their open-source needs and in turn wouldn’t push them to open-source more of their internal code. With CocoaPods, these companies only need to add an extra Git repository in `~/.cocoapods/` that contains specifications for their _private_ frameworks and **BOOM**, they’re in business.

Page 19: RubyMotion Inspect Conference - 2013. (With speaker notes.)

The future is out there.

Page 20: RubyMotion Inspect Conference - 2013. (With speaker notes.)

Centralized specificationauthority service

This is primarily meant to have access-control. This will work exactly the same as RubyGems currently does: first pusher is owner and owners can add other owners.

This has a very high priority, because the number of spec contributors has grown too large to rely purely on a trust based system. For instance, not too long ago, someone pushed a spec for AFNetworking for an non-existing version, this is obviously NOT cool when the author of the lib actually maintains the lib specs.

The way it will work is roughly like follows:* Person creates spec and lints it locally.* CP creates a serialized version of the spec (YAML/JSON) and posts it together with the actual spec to the ‘push’ service.* The ‘push’ service checks if a previous version of the lib has been pushed and if so checks wether the person is authorized to push a new version.* The ‘push’ service creates a pull-request on the spec repo, which in turn notifies Travis to perform a full-lint. (Yes, Travis has mac workers in beta.) Once Travis notifies the ‘push’ service that the spec has passed, it will automatically merge the pull-request.* If for some reason the build doesn’t finish (e.g. network outage), we can easily trigger a new build or even perform the lint checks ourselves.

This process means we can add a control layer, while still keeping the flexibility of dealing with the specs through Git and GitHub.

Page 21: RubyMotion Inspect Conference - 2013. (With speaker notes.)

Download countweb-application

Something that has been asked for by the community on many occasions, is stats on things like download-count of libs.

Since in our architecture we don’t actually serve any packages, we aren’t able to count downloads this way. Together with Mattt (of Heroku), we’ve been thinking about this and concluded that the best way to go about it is to, again, be naive. The app will have a ‘counter’ endpoint, to which CP will post the libraries that it has downloaded during installation.

One problem with this was that we don’t want to count libs that we don’t actually host through the ‘master’ spec repo (e.g. private libs), but with the ‘push’ service on the horizon this will no longer be an issue, as we already have a DB in the cloud that contains a list of all the libs it knows of.

In short, sometime in the near future, our website will not only provide info on the available libs, but also how many times they have been downloaded.

Now to be clear, this stat is only really meant for the owners. For end-users this metric is nice to have, but it doesn’t say anything about the quality of a lib.

Moreover, since we count by accepting count POSTs, we will not show overall ranks, because we do not want people to try and game the system.

Page 22: RubyMotion Inspect Conference - 2013. (With speaker notes.)

CocoaDocs.org

CocoaDocs is a side project created by one of our spec maintainers, namely Orta Therox.

If you’re familiar to rubydoc.info, this is essentially the same kind of service. So everytime a new spec is pushed to the spec repo, this application receives a notification and will build documentation for the lib by using the appledoc tool.

It’s still very much in development and currently only has docs for the most recent libs. Then again, this is not yet officially released, but it’s a great example of how we can help the community, even if they wouldn’t use CocoaPods.

Actually, he at some point generated docs for ALL OF THE LIBRARIES an it works, but obviously this takes at least a whole night, so it’s not very helpful while he’s still working on it.

Page 23: RubyMotion Inspect Conference - 2013. (With speaker notes.)

Magic is hard work.

Page 24: RubyMotion Inspect Conference - 2013. (With speaker notes.)

1. Resolve dependencies

Find child dependencies and fail in case of a conflict.

CocoaPods does do dependency resolution, but it does not automatically resolve conflicts. This means that, when a conflict occurs, CocoaPods will raise an error and leave conflict resolving up to the user. (The user can do this by depending on a specific version of a common dependency before requiring the dependencies that lead to the conflict.)

If you’re familiar with Ruby then you can compare the former (the current CocoaPods style) to RubyGems’ style resolution and the latter (with conflict resolving) to Bundler’s.

Adding conflict resolution to CocoaPods is on our TODO list and we will try to work with the Bundler team to see if we can share their algorithm, but this will be one of the last things we’ll work on. A feature like this will require a stable basis and since we’re not there yet, working on it now would only make working on the basis more complex than necessary.

Page 25: RubyMotion Inspect Conference - 2013. (With speaker notes.)

1. Resolve dependencies 2. Fetch library sources

From git/svn/mercurial, http tarballs/zipballs, or a local development repo.

Page 26: RubyMotion Inspect Conference - 2013. (With speaker notes.)

1. Resolve dependencies 2. Fetch library sources3. Collect build-settings

Per Pods target.

Page 27: RubyMotion Inspect Conference - 2013. (With speaker notes.)

1. Resolve dependencies 2. Fetch library sources3. Collect build-settings4. Create Xcode project

Ah yes, the Xcode document format.

Page 28: RubyMotion Inspect Conference - 2013. (With speaker notes.)

1. Resolve dependencies 2. Fetch library sources3. Collect build-settings4. Create Xcode project

5. User project integration

Ah yes, the Xcode document format, again.

Page 29: RubyMotion Inspect Conference - 2013. (With speaker notes.)

1. Resolve dependencies 2. Fetch library sources3. Collect build-settings4. Create Xcode project

5. User project integration6. Create API documention

Like RubyGems does, we generate API documentation for each library by using the appledoc tool and we install that into the Xcode documentation viewer. (This also works with Dash.app in case you do not love Xcode, for some reason…)

[SHOW example of AFNetworking docs in Xcode]

The appledoc tool is unfortunately not complete yet and misses some information like constants, but hopefully work on CocoaDocs.org will eventually lead to completing appledoc coverage.

Page 30: RubyMotion Inspect Conference - 2013. (With speaker notes.)

0

250

500

750

1000

1250

Sep 2011 Nov Jan 2012 Mar May Jul Sep Nov Jan 2013 Mar

Available Libraries

You can definitely see that people have better things to do in the summer than creating specs. (June/July)

Page 31: RubyMotion Inspect Conference - 2013. (With speaker notes.)

0

26250

52500

78750

105000

.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .10 .11 .12 .13 .14 .15 .16

CocoaPods Downloads Over All Minor Versions

The only version range that had 0 downloads was 0.4.x, because I accidentally skipped it :)

Page 32: RubyMotion Inspect Conference - 2013. (With speaker notes.)

It needs a lot more attention.

Page 33: RubyMotion Inspect Conference - 2013. (With speaker notes.)

Improve command-lineinterface experience.

With objc projects, people run `pod install` only when they need it. RubyMotion’s build process runs every time a build has to be made, so it needs better heuristics on when to do any work at all. As CocoaPods becomes smarter itself, this becomes less of an issue during normal usage, but things like updating the spec repos when there is no internet connection available should be avoided.

Actually, we have improved this a lot in the upcoming 0.17 version and it should already be a lot nicer. But there is probably still room for improvement.

Page 34: RubyMotion Inspect Conference - 2013. (With speaker notes.)

Support multiple targets.

In objc projects it is quite common to build multiple ‘targets’, e.g. apps, from one project. RubyMotion does this too, but is normally limited to an ‘app’ target and a ‘test’ target. Currently the CocoaPods integration is limited to just the ‘app’ target, though. While I think it might be uncessary to open up full multiple target support, there should be standard support for including dependencies specific to the RubyMotion test target.

Page 35: RubyMotion Inspect Conference - 2013. (With speaker notes.)

Support different configurations.

E.g. within one target, configure dependencies differently based on debug / release / deploy.

This is still lacking form CocoaPods itself and should really be fixed there. Having said that, I can imagine that with RubyMotion’s build system and handling of configurations it might be very simple to already implement this in motion-cocoapods.

Page 36: RubyMotion Inspect Conference - 2013. (With speaker notes.)

Translate API documentation for

RubyMotion

As we saw before, CocoaPods already generates API docs for each library, however, these are of course all in Objective-C. What would be great is to integrate the RubyMotion doc tool to translate these generated docs for RubyMotion.

[Where does the tool actually live? Is it on GitHub?]

Page 37: RubyMotion Inspect Conference - 2013. (With speaker notes.)

We Need You

github.com/HipByte/motion-cocoapods

Page 38: RubyMotion Inspect Conference - 2013. (With speaker notes.)

63 contributors to the CocoaPods tool repo and 100 contributors on the specs repo.

For all of these people, and companies that have sponsored work on CocoaPods or provide services, I’d like a big applause, for this would never have been possible without all of their love and care.

[MAKE HEART LOVE SIGN]

Oh, and one more thing…

Page 39: RubyMotion Inspect Conference - 2013. (With speaker notes.)

One More Thing

Page 40: RubyMotion Inspect Conference - 2013. (With speaker notes.)

Version 0.17 NOW!

$ gem install cocoapods$ gem install motion-cocoapods

Page 41: RubyMotion Inspect Conference - 2013. (With speaker notes.)

@CocoaPodscocoapods.org

github.com/CocoaPods

@alloy@fabiopelosin@SmileyKeith

@orta