Hacker News new | past | comments | ask | show | jobs | submit login
Open sourcing our Android and iOS apps (kickstarter.engineering)
571 points by mecredis on Dec 14, 2016 | hide | past | favorite | 73 comments



Kudos to them. Compared to the web it's rather cumbersome to poke into packaged and released mobile apps, so I really appreciate access to the source of a real world app for learning and comparison.

The Android codebase looks very modern and well structured. I think it makes great use of many of the goodies (gradle, rxjava, retrofit, dagger, android support lib, ...) and learnings (bring your own MV*; use Fragments when you need them, stick to Activities if you can) that is state of the art in Android development. I think it's a great thing to skim through if you are interested in developing for Android or to compare it to you own app.

I can only assume that the same is true for I iOS. I'll certainly check it out should I start developing for that platform.


And actual tests for the Android app! It's a rarity, and especially annoying since the "sample" apps that Google provides pretends that testing doesn't exist.


Agreed! But some great companies has been Open Source'ing their Android applications for a while. I.e. DuckDuckGo's app (https://github.com/duckduckgo/android) and the Forcastie weather app (https://github.com/martykan/forecastie). They are great references!


I quickly looked up DuckDuckGo, and - unlike this one - boy is it spaghetti: https://github.com/duckduckgo/android/blob/master/src/com/du...

Yes I've seen worse, but this most certainly isn't a great example of how to structure an Android app, not to mention the overall untidiness (commented out lines, messed up indentations etc.)


Unit tests or integration tests? It may be better now, but android used to be a real pain to unit test, so much important functionality was baked into the Activity base class that was hard to substitute.


They seem to favour unit tests over integration tests, which is achieved by abstracting the layout logic away from Activities and into view models that can be unit tested with no fuss.


Was thinking about this the other day, now in the context of this release it comes to mind again - it would be kinda cool if it was a common practice for tutorial folks to make a repo where they forked the entire thing and placed comments all over which were links to videos that broke down those sections in an easy to understand way.


Yeah, they sort of rolled out their own MVVM implementation, based on RxJava and RxLifecycle.

On Android MVVM is more difficult than MVP in my opinion (the most popular choice, not counting spaghetti projects), mostly because the platform doesn't provide the "glue" needed to bind viewmodels to the UI layer. At first glance it looks like they did it without overengineering, which is another trap as far as these matters go.

Clearly a work of very good experts


That "glue" can be Android's Databinding library. I've used it to bind ViewModel data to views. Works really well.


I'm aware of it, but last I checked it didn't seem production-ready and lacked features. I believe they updated it at some point, but other than some talk at Google IO not much came out of it - even the docs didn't reflect it back then. Perhaps it's up to the task now, I admit I'm not looking it up regularly.


It is definitely production ready now.


> In less than eight months, four engineers who had never written production Java code, let alone production Android code, shipped a 1.0.

Wow. That's pretty impressive


It's impressive that it took almost 3 person years to ship a 1.0 of a basic app?


it's impressive that 3 person years from _no Java experience_ was all it took. Java and Android are complex ecosystems.

Not to say they couldn't have shipped it in less time. Of course they could have. But it sounds like they shipped something very well built.


But what other languages did the have experience with? If it was something similar like c#/c++/ruby/python then the time to learn java should not be significant.


When it comes to Android, Java by itself is the least of problems. It's the SDK and framework that are tricky, ridden with technical debt and often far from developer-friendly.


I was about to say this. In fact, you have to unlearn a lot of what works and is accepted in server side java when you move to Android. Learning the SDK and Android gotchas was by far the hardest part of my first Android app.


Yes Android is particularly complicated, but not to the point where 3 experienced developers building an app in 8 months is in any way remarkable.


I have never used this app myself, I don't know whether it's complex. I only peeked at the source code. And yes I was referring to the contrast between how neatly written it is, and their lack of experience with the platform, not how fast they did it.

Development on Android tends to be slow overall, owing to numerous intricacies of the platform, but I believe that in general taking some extra time to roll out a clean and polished version 1.0 will pay off when it comes to 2.0 and 3.0. It's always easy to move fast in the beginning, use lots of duct tape and snap something out rapidly, but it comes at a cost and then you get bogged down further down the line


When dealing with MVP on Android, how did you deal with dynamic view creation?

Right now we are working on a rearchitecture and are finding that creating dynamic views in the Activity/View requires business rules we are putting in Presenter. But the Presenter doesn't have context.


Speaking of MVP, check here too:

https://github.com/6thsolution/EasyMVP


I'm actually surprised they're relying on Activities for the views in the app. I'm not familiar with how the app works, but this is typically an out-dated approach. Activities should really only be treated as entry points into your app.

Also, not a huge deal for an app, but the package structure is organized by layers, not features. Makes Java's non-private access modifiers essentially useless.

The general style of the source code is solid though. I wouldn't be upset if I had to work in this code base on a daily basis.


I disagree with you regarding Activities. For apps they do most of the screen management the developer needs just fine, especially if they are backed by a strong view and data model. If you download the App you can actually really quickly make out where they leverage the single Fragment (switch the project category via the drawer) and it makes sense there; but I think the same App build with a single Activity and Fragments would be much messier (especially regarding animations and back-navigation) and they'd gain (next to) nothing.


I'm not a fan of Fragments when it comes to navigation either, but there are other solutions as well (see Conductor). But there are limitations to using a new Activity for each screen, which I mention in my other comment below. They really only make sense for specific features in an app that require a specific entry point. Things like external intents (other apps, push notifications, etc...) or deep linking, as another user mentioned. They may be useful for Google Instant Apps too depending on how it ends up working.


Fully agreed that there are limitations, but I still think calling it an out-dated approach is unfair.

I don't see a simple, low on boilerplate, one-size-fits-all solution for reusable and separated components on Android at the moment. I love that the community didn't settle with just Activities or just Fragments and is actively trying new stuff (after all, if you look at React or Vue or even freaking backbone.marionette, the web is in a much better spot right now regarding UI composition), but right now the right solutions always seems to take the path of least resistance and use whatever mix of pattern that gets you to your goal as easily as possible.


I agree with you as well. It makes deep linking easier since you don't need to recreate an entire fragment backstack.


Just curious, why should activities only be treated as entry points to the app? What are the downsides of the only-use-fragments-if-you-need-to approach?


Fragments are one option. Another is just to use regular Views. There are libraries to help you with this such as Conductor.

As for Activities, they are usually overkill for most screens. They don't allow for seamless transitions between screens and prevent sharing UI components across screens (e.g. a Toolbar). Fragments and/or regular views have the added flexibility of being able to use more than one at a time and allows for easy re-use and view composition.

Like I said in my previous comment, the only really good reason to create additional Activities is to provide additional entry points into your app. Otherwise Fragments or Views will suffice and provide greater flexibility and improve the UX in many cases.


For one, the backstack story for Fragments is a lot more sane than whole "Task" concept for activities (The backstack for fragments is a list of fragments you can manipulate and debug very easily).


I'm not a mobile app developer by profession. But I always wanted to start learning and developing real world apps. The problem I always ran into the tutorials and demos, that they are mostly limited(i.e not close to solving real world problems). I think browsing their code, will give me a good start. And I would know how it's done right! Thank You!


Having looked through this project I would not recommend using it as a basis for learning how an iOS app is "done right", as they've deviated from standard iOS/Swift paradigms significantly. In particular, the use of ReactiveCocoa and MVVM creates an app that is structured completely differently from a "traditional" iOS app. They've also used (abused?) Swift's ability to define custom operators which results in a lot of code like this:

    self.youLabel
      |> authorBadgeLabelStyle
      |> UILabel.lens.textColor .~ .whiteColor()
      |> UILabel.lens.text %~ { _ in Strings.update_comments_you() }
Which again is very different from regular iOS/Swift code.

That said, I think this project is interesting to look at from the perspective of "this is what it would look like to go all-in with ReactiveCocoa and MVVM". It's kinda like Twisted in Python: Twisted code looks very different from normal Python code, cause once you start using Twisted, it becomes Twisted all the way down.


Truthfully, I think you're better off with the tutorials and demos. Good ones will split up how to achieve what you need to achieve. Diving into a huge app like this will be confusing to figure out how everything is working. If you are already familiar with Android/iOS, then I think looking at these bigger projects can really piece everything together (but you wouldn't start with say rxjava and rxlifecycle on your own before understanding Android).


I have the same problem. If anybody has any good resources, please let me know.


Lots more open source Android apps on f-droid:

https://f-droid.org/


I had a chance to see Brandon from Kickstarter talk about their functional approach at the Functional Swift Conference in Budapest. I highly recommend watching it!

https://www.youtube.com/watch?v=A0VaIKK2ijM


Thanks for the link. Watching so far, many of the points Brandon makes vaguely resonate with how I approach structuring my code, but knowing the common vocabulary (f.ex. the term ‘co-effect’) enables me to communicate how and why I do things, and ultimately to improve.

Out of curiosity, how much were the tickets and how early was it sold out? I was in Budapest right at that time to attend our remote team meeting, and I’m cursing myself for not knowing about this conference.


Last year when I was working on a startup's mobile app for Android, it was almost impossible to find good quality code that was open sourced.

I am really happy that Kickstarter has released their android app as open source - would definitely be a great learning experience!


There are quite a few "sample" open source projects that demonstrate best practices and various Android architectures. However, they are not fully fledged production applications like the Kickstarter app.


That's the entire issue, I've seen quite a lot of "sample" apps that do one thing (like nav bar, or fragments, or animations etc.)

But each of htem brings their own libraries, and don't explain what what's necessary and it's left to the user ot decide to how stitch all of this together.

Don't get me wrong...I'm happy for the demo apps (they had made my life a lot easier), but a production grade app is a whole different ballgame.


F-Droid is full of "real" apps that are completely open source. You can look at any of them to see how they work.


For anyone reading their post, we're so humbled by Kickstarter mentioning the tiny Artsy for having inspired some of this work. If you're interested in the open-source by default conversation and need some ammo to bring this to your team, start at http://code.dblock.org/2015/02/09/becoming-open-source-by-de...


They use Swift Playgrounds to do a lot of development:

"Swift Playgrounds for iterative development and styling. Most major screens in the app get a corresponding playground where we can see a wide variety of devices, languages, and data in real time."

https://github.com/kickstarter/ios-oss/tree/master/Kickstart...

I've recently bought into this development method too. It's not quite what Bret Victor dreamed up, but it's a big step in the right direction.



This is pretty awesome. Just because an app connects to a single website/service doesn't mean there isn't a benefit to being open! It's good to be able to trust (and verify) the software running on our devices.


This. There is really no downside to doing this, and lots of potential upside. I honestly think most companies could do this with zero effect to their bottom line.


If your code is bad, then there's risk of making security vulnerabilities more visible. Not that that's a good reason to avoid open sourcing, but it's a reason.


Which is also a good reason to open your code and let those that know better help you fix it.


If widely used and critically important open source projects like OpenSSL can have latent security bugs lying in them for years (Heartbleed?) - I don't think it's practical to assume "the open source community" will security-audit and send pull requests for your "open sourced" product app.

If you want your code security audited, pay a reputable firm to conduct an audit. Throwing it up on Github and thinking "the good guys" will spend time looking and contact you for free when they discover problems is misguided at best.


> Which is also a good reason to open your code and let those that know better help you fix it.

This is a fantastic mentality, but unfortunately doesn't really play out in reality.

I'm a huge Open Source fanboy, but we need to be "real". How many people are really going to read every line of every open source program? Very-few-to-none is the real answer. Massively popular software gets eyeballs, but few others do.

Most of us just use the software and trust/hope someone else reviewed it for security et al.

The problem with that is, we are all trusting/hoping someone else did a review, but that someone else is trusting/hoping someone else did a review.


How many of the people that do review your code would exploit it vs reporting it to you? Combine it with a bounty program, and chances are you will get useful feedback at a fraction of the cost of a full on audit.


I agree with the sentiment of your post, however I believe it is based on an ideal world, which we don't live in.

> How many of the people that do review your code would exploit it vs reporting it to you

By nature, attackers would be reviewing your code as well.

> Combine it with a bounty program

The overwhelming majority of Open Source software was created-by and is curated-by a single person who makes negative profit by working on the software for free in their spare time. Even some of the most popular projects are still total losses for their curators. You're not going to get bug bounty programs here.

For example, take a look at Crosstool-ng[1] (a popular project used to build cross-compilers for various architectures). Companies and individuals are all using this project to build cross-compilers that they trust to build other software with. A bug in Crosstool-ng could propagate into bugs in the compiled software it produces. Bryan Hundven does most of the heavy lifting on this project by himself, and as far as I know, he's paid nothing for it. You're not going to get a bug bounty program here either.

Heck, it's doubtful even a project as large as the Linux Kernel would be able to afford an ongoing bug bounty program. They're trying with the Linux Foundation and the Core Infrastructure program, but how many years before did it have none of that?

Essentially, these programs only work for commercially-backed software, which is only a small sliver of open source software.

[1] https://github.com/crosstool-ng/crosstool-ng


But I am specifically talking about companies with closed source apps and services open sourcing them, not tools that are already open. Examples are Uber, AirBnB, and Groupon, not gpg or OpenSSL.


> But I am specifically talking about companies with closed source apps and services open sourcing them

Ah, I see. I misunderstood. Yes, I think we are in agreement then, although I have my doubts most companies want their "secret sauce" or code-indiscretions flapping in the wild.


I think it depends. The exact PageRank algorithm, or the process that Uber uses to route drivers: probably not. The UI to any of that: why not? I think there is very little secret sauce out there and most of the stuff is just bog standard code that would do no harm being in the open.


Couldn't agree more.

I think the largest hurdle for getting more stuff open sourced is two-fold.

1) A large amount of software is sub-par, and likely commits many atrocities including having business logic in the UI.

2) Companies are afraid they'll be embarrassed by their code, and would rather not take the risk of being branded as a company that doesn't do things right.

For number 1, there are potential solutions by hiring better engineers etc... but number 2 is always a (perceived) risk, even if their codebase is "perfect".


> This. There is really no downside to doing this, and lots of potential upside. I honestly think most companies could do this with zero effect to their bottom line.

And - if the code is good, clean, modern - attracting talented coders that way. Showing me such code is million times more convincing than all the usual slogans


Not that it would be easy to compete with Kickstarter anyway, but what about enabling clone competitors?


The apps don't really matter. I was the Android lead at Gilt and we often talked about open sourcing our app. We ended up open sourcing our iOS one (https://github.com/gilt/cleanroom). We were a company with a thousand employees, most of them not writing code. If you wanted to compete with us, copying our app was 5% of the overall effort, and what would you really get from our app that connects to our (closed source) backend anyway? The upside was enormous in terms of recruiting, retention, and keeping engineers excited.

Kickstarter is in an even better position. Their defendable advantage is the network effect of being the go-to place for crowd sourcing.


People can also learn from, and build upon the code that they've written.


Yeah, definitely! Another cool example is the pre-alpha for Linode's new management UI:

https://github.com/linode/manager


This is very exciting. There simply aren't a lot of open source "full scale" Android apps. Most of what you find are quick sample apps which simply don't show the complexity inherent in most professional apps. The largest other ones I'm aware of are Github, Google I/O, and some of the AOSP apps.


The iOS app looks like a treasure trove, I can't wait to download it and dissect it. It'll be interesting to see how they integrated playgrounds into their development cycle.

I just wish they had upgraded to Swift 3.0


This is great. I hope they also provided good documentation / commenting. This can be a fantastic learning tool for programmers at all stages.

Kudos to kickstarter.


iOS Project does not build - Xcode 8.2... There is a guard statement with no else clause, that's the first error I got. I didn't bother looking further because... a guard without an else could never compile, so what am I looking at?

I'm getting flashbacks from my last workplace where people merged in code that didn't compile and then went 'oh really? let me fix that real quick'...

Code wouldn't compile in master but the codebase... everything had to be clever. We can't just have a model, a network request to fetch/update for it, a view controller and view cells. A few storyboards and of course no bloody tests - it's a phone app.

No, we need protocols everywhere we can fit them, third party libraries - ones that haven't been out a few years (Reactive whatever), a third party library to make a basic GET request (Alamofire looking at you), a CSS styling library, a JSON to Model library, list goes on.

What we don't need is folder structure that lets you know this is the initial VC, the two folders beneath it are the 2 possible places you can go, the sub-folders in there are the places you can go from that VC and on and on.

Let's just dump all VCs in one folder, all cells in another. Nevermind that in 90% of the cases, that one cell is only ever used in that one tableview - no need to group those together.

I don't know - maybe it's just me - I'd rather I download a zip, open the project, click that triangle and it runs - this thing makes me jump through hoops, and it still doesn't work... And nothing makes sense, unless you go learn reactive cocoa - based on the amount of files/code, a clear waste of time.


> Download the Xcode 7.3.1 release.

The app requires a different version.

https://github.com/kickstarter/ios-oss/blob/master/README.md

I concede. There are issues getting the dev environment configured.


What's the purpose of Android's ApplicationGraph interface?

https://github.com/kickstarter/android-oss/blob/888a37468358...


Looks like they're using Dagger2 (https://google.github.io/dagger/) for dependency injection.


Good! I try to avoid closed applications on my mobile devices if possible.


I wonder if they've considered using something like React Native or Xamarin so they can share some of that functional-style code between the two platforms.


This is a really great example of how to do it right when it comes to Swift, MVVM, Reactive Cocoa, Testing, CI etc. Lovely code and architecture!


This is awesome! Open source production apps are always useful.


Does this mean we can clone it now or does the license prohibit that?


Open sourcing a client is pretty useless when the bulk of the logic happens inside a company's server somewhere.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: