Some days ago, I read a brilliant article by Quil, ranting about how computer software, specially applications, are progressively tending towards complicated, dull user experiences by giving options to the users and requiring tedious pre-configuration processes when we should be offering pre-configured, ready to use software and writing software that 95% of people should be able to use immediately without manuals or learning curves. She specifically addressed, as an example, her experience trying to get started with a simple Babel v6 “hello world” example.
Some time ago, I received a request from github to add a CocoaPod for DLHamburgerMenu, my most downloaded project in GitHub and a very popular cocoa control. Even though I think pods are a great idea, and when used wisely can be really useful, I don’t quite like them much, because it’s so easy to abuse them today, and I have found myself trying to update or maintain projects with 25-30 or more what-the-fuck-does-this-thing-do CocoaPods.
However, I thought it was a fair request, and I’d never written a CocoaPod before, so I thought it would be nice learning to do so. However, while trying to do something supposedly as simple (as stated in cocoapods.org page) as publishing a pod, I couldn’t help but remember Quil’s article and think “WTF! She’s completely right! Why is this process so complicated?”. Let me expand on how was my experience step by step.
I started by checking the documentation, specifically the page about pod creation in cocoapods webpage. The first line of the documentation looked promising:
Creating your own CocoaPod is fairly straight forward.
I thought: “with such a starting line, this process should be easy, right?”, man, was I mistaken.
The first step was apparently creating the basic pod project structure. I was planning to copy and paste the files that I had already in the Github repository, so I was instructed to write this magic line that would ask me a few questions and then setup everything for me:
$ pod lib create DLHamburgerMenu Cloning `https://github.com/CocoaPods/pod-template.git` into `DLHamburgerMenu`. Configuring DLHamburgerMenu template. ------------------------------ To get you started we need to ask a few questions, this should only take a minute. If this is your first time we recommend running through with the guide: - http://guides.cocoapods.org/making/using-pod-lib-create.html ( hold cmd and double click links to open in a browser. ) What language do you want to use?? [ Swift / ObjC ] > swift Would you like to include a demo application with your library? [ Yes / No ] > yes Which testing frameworks will you use? [ Quick / None ] > None Would you like to do view based testing? [ Yes / No ] > No Running pod install on your new library. [!] No `Podfile' found in the project directory. Ace! you're ready to go! We will start you off by opening your project in Xcode open 'DLHamburgerMenu/Example/DLHamburgerMenu.xcworkspace' The file /Users/Nacho/Desarrollo/iOS/DLHamburgerCocoaPod/DLHamburgerMenu/Example/DLHamburgerMenu.xcworkspace does not exist.
Mmmmmm, that was not good. Of course there was no xcworkspace file created and the error was not really informative (I was creating a Pod, right? so I suppose there wouldn’t be a Podfile before you create one, Mr. PodLib).
So I started looking on internet for some help. I found a proposed fix that instructed you to run this line at the root dir:
echo "3.0" >> .swift-version
But of course it wasn’t helpful at all. Another question on a forum (ok! ok! Yes, it was stackoverflow, so what?) sounded really weird but actually worked. It implied entering a directory called “Example” and running “pod install”. I have no idea why this worked, because an “Example” directory is not where I would usually look to find something that would make the whole process fail or work… but anyway…
So, after that, I did run “pod lib create” again and this time I succeeded. Yay! I opened the project file and immediately XCode 8 offered me to update swift to version 3. However, when I clicked on “next”, I was taken to an empty “Select playground to convert” screen that won’t allow me to continue. That didn’t look right.
Anyway, I decided to continue. I actually prefer Swift 2 to Swift 3, and I could take care of that issue later. Then I tried to compile and Bum! I get this “Use Legacy Swift Language Version” error (I have to give some credit here to XCode for being able, after all these years, to present me new, unknown error messages week after week):
So I did some further research and found a fix that required me to edit the file Example/Podfile. At that moment, I was already starting to think that the opening line on the documentation page might be lying me after all:
post_install do |installer| installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['SWIFT_VERSION'] = '3.0' end end end
So I changed the file, opened the project again, and Hooray! It showed me the migration dialog but allowed me to migrate to swift 3 this time.
After that, I started adding my files, and went through the painful process of migrating them to swift 3. I changed all my classes to public following the documentation’s instructions, clicked compile and… Bum! Another weird compilation error:
“Swift is not supported for static libraries.”… mmmmm… “the plot thickens” I thought, and jumped again to my browser to look for this error message on the global network oceans… I was lucky enough to get an indication to solve the problem:
[!] Note: Due to a Development Pods implementation detail, when you add new/existing files to Pod/Classes or Pod/Assets or update your podspec, you should run pod install or pod update.
Ok, so each time I add a new file I need to run pod install or pod update. That’s not exactly ideal for working in a project, but ok, I tried it and it worked. Now I had a project that would compile, but I can’t run because I couldn’t see any target defined in the project. I navigated to the project settings and enabled the different schemas, but I was unable to run the project (more weird errors). At that point, I was so sick of errors and so eager to publish the pod, that I decided to publish it without testing it. After all, I had already tested it before on the original project and it was working perfectly.
So for publishing, I was first instructed to test locally the validity of the pod by invoking “pod lib lint”:
$ pod lib lint -> DLHamburgerMenu (1.0.1) - ERROR | [iOS] unknown: Encountered an unknown error (Must be in the root of the repo (/Users/Nacho/.cocoapods/repos/master), instead in /Users/Nacho/Desarrollo/iOS/DLHamburgerCocoaPod/DLHamburgerMenu.) during validation. [!] DLHamburgerMenu did not pass validation, due to 1 error. You can use the `--no-clean` option to inspect any issue.
When I did read that error, I was tempted to tell the guy at Github to go f**k off and publish the pod himself, but I took a deep breath and decided to look for an answer again on the trustworthy internet. I got to this extract:
@senchi - please use the 1.1.0 release candidate, 1.0.1 does not support Xcode 8 (going frantically to the computer, opening a terminal...) $ pod --version 1.0.1 (crying and invoking all known deities) $ sudo gem install cocoapods --pre
Ok, so after changing cocoapods to a release candidate version, I was able to run pod lib lint successfully. The last step was just a command, “pod spec lint”. With trembling hands, I typed this in the terminal and clicked enter:
pod spec lint -> DLHamburgerMenu (1.0.1) - ERROR | [iOS] unknown: Encountered an unknown error ([!] /Applications/Xcode.app/Contents/Developer/usr/bin/git clone https://github.com/DigitalLeaves/DLHamburgerMenuCocoaPod.git /var/folders/gq/x69z_8x949q8q4y8z18jkp640000gn/T/d20161006-23197-3kjdhc --template= --single-branch --depth 1 --branch 1.0.1 Cloning into '/var/folders/gq/x69z_8x949q8q4y8z18jkp640000gn/T/d20161006-23197-3kjdhc'... fatal: Remote branch 1.0.1 not found in upstream origin ) during validation. Analyzed 1 podspec. [!] The spec did not pass validation, due to 1 error.
With that last error, it was official, I have obtained a cryptic error on every step of the “straight forward” process of creating a cocoa pod. I tried pushing the code manually to the Github repository:
$ git remote add origin https://github.com/DigitalLeaves/DLHamburgerMenuCocoaPod.git $ git add -A * $ git commit -m "initial commit" $ git push --set-upstream origin master
But it didn’t work. Finally, after many trial and error efforts, I had the crazy idea of creating a remote “1.0.1” branch in Github for the repository, tried to push again, and it worked! Yay! My pod was ready to be published.
Then the next step was registering an account. Honestly, this process could also be improved. I spent some minutes looking everywhere in the webpage for a registration link until I realized that I had to register my account with a terminal command (in 2016, go figure ;). So I did a “pod trunk register” clicked on the link, and finally performed a “pod trunk push DLHamburgerMenu”, and voila! My pod was published…
… or so I imagined, as I couldn’t find my pod as “pending approval” or “publishing process” anywhere. That’s something that needs to be improved too. After so many errors, I didn’t trust that my pod had been published. What’s even worse, I discovered that someone else had already published DLHamburgerMenu claiming it as his own pod previously…
So all in all, during the whole process, I was reminded of Quil’s article and, even though it was so comical for me being in the same situation after reading about it, I thought to myself: “I will never publish a CocoaPod again”. And I had to agree with her again, we are building software, frameworks and libraries that are opinionated, difficult to use and requiring decisions, options and pre-configurations that should be removed. This is what Apple used to do so well some years ago, software and tools that were ready to use and preconfigured to be used comfortable and instantaneously intuitive for 95% of the population.