/
cocoapods-how-to-create-your-own-pod.html
76 lines (70 loc) · 11.7 KB
/
cocoapods-how-to-create-your-own-pod.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<!DOCTYPE html><html lang="en"><head><title>CocoaPods - How to create your own Pod | mokacoding</title><meta name="description" content="A step by step guide to create a basic CocoaPod."><link href="/css/griddy.css" rel="stylesheet"><link href="/css/style.css" rel="stylesheet"><link href="/css/font-awesome.min.css" rel="stylesheet"><link href="/css/zenburn.css" rel="stylesheet"><link href="//cdn-images.mailchimp.com/embedcode/slim-081711.css" rel="stylesheet" type="text/css"><link href="/css/mailchimp-form-override.css" rel="stylesheet"><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1"></head><body><div class="page"><div class="row-12"><div class="col-12 header"><h1 class="brand"><a href="/">mokacoding</a></h1><div class="punchline">unit and acceptance testing, automation, productivity</div><div class="links"><a href="/archive.html">Archive</a><a href="/tags.html">Tags</a><a href="http://giovannilodi.com">About</a><a href="#subscribe">Subscribe</a></div></div><div class="col-12"><div class="post-container"><h2 class="post-title"><a href="/blog/cocoapods-how-to-create-your-own-pod">CocoaPods - How to create your own Pod</a></h2><p class="post-meta"><span class="post-date">Mon Jan 21 2013 </span><a href="/tag/CocoaPods/index.html" class="post-tag">-CocoaPods</a><a href="/tag/iOS/index.html" class="post-tag">-iOS</a></p><div class="post"><p>Like I said in the <a href="http://amokafullofstuff.wordpress.com/2013/01/05/cocoapods/">first part</a> of my exploration of CocoaPods, using this iOS dependencies management is freaking easy, and reading what's on the homepage is more than enough to get started. Anyway let's see how we can create our how Pods.</p>
<p>To learn how to do it I started the development of a little "framework" I called <a href="https://github.com/mokagio/MGCraftman">MGCraftman</a>, where I'll put some utils methods I sometimes write to speed up UI development when I'm not using Interface Builder. But let's stop the chitchat and let's code!</p>
<p><h3>Step 1 - Code the Library!</h3>
The first step is to have something to make a pod of, I guess every developer has his own little set of smart methods that make his life easier. Don't be greedy, share them with the community!</p>
<p><h3>Step 2 - Tag your pod properly</h3>
Since we're gonna work with a dependency manager we need to take care of the version number of our pod.</p>
<pre><code class="">git tag -<span class="hljs-tag">a</span> <span class="hljs-number">1.0</span>.<span class="hljs-number">0</span> -m <span class="hljs-string">"Tag release 1.0.0"</span>
</code></pre><p>Take a couple of minutes to read through the <a href="http://semver.org/">Semantic Versioning</a> to learn how to use tagging for version numbers properly and in a way that allows for <a href="https://github.com/CocoaPods/Specs/wiki/Cross-dependencies-resolution-example">resolution of cross-dependencies</a>.</p>
<p><h3>Step 3 - The podspec</h3>
Once our project is tagged properly we can create the <code>.podspec</code> file. The extension name explains that it will contain the "specs" of our "pod".</p>
<pre><code class="">pod spec create <span class="hljs-keyword">Do</span><span class="hljs-label">nut</span>
</code></pre><p>This will generate the <code>Donut.podspec</code> file.</p>
<p>You can also generate the <code>podspec</code> from a GitHub repo using the GitHub url instead of the name.</p>
<p><h3>Step 4 - Leave your mark on the podspec</h3>
If you open the freshly generated <code>Donut.podspec</code> you'll find a lot of comments explaining the information you need to provide. There are a lot of options, but you don't need to set them all. You'll also notice that its nothing more that a Ruby file.</p>
<p>Here's how the podspec of my toy framework, looks like.</p>
<pre><code class="">{<span class="hljs-subst">%</span> highlight objective<span class="hljs-attribute">-c</span> <span class="hljs-subst">%</span>}
Pod<span class="hljs-tag">::Spec.new</span> <span class="hljs-keyword">do</span> <span class="hljs-subst">|</span>s<span class="hljs-subst">|</span>
s<span class="hljs-built_in">.</span>name <span class="hljs-subst">=</span> <span class="hljs-string">"MGCraftman"</span>
s<span class="hljs-built_in">.</span>version <span class="hljs-subst">=</span> <span class="hljs-string">"0.1.0"</span>
s<span class="hljs-built_in">.</span>summary <span class="hljs-subst">=</span> <span class="hljs-string">"A framework to speedup development when you can't (or don't want to) use Interface Builder."</span>
s<span class="hljs-built_in">.</span>homepage <span class="hljs-subst">=</span> <span class="hljs-string">"https://github.com/mokagio/MGCraftman"</span>
s<span class="hljs-built_in">.</span>license <span class="hljs-subst">=</span> { :<span class="hljs-keyword">type</span> <span class="hljs-subst">=&</span><span class="hljs-literal">gt</span>; <span class="hljs-string">'MIT'</span>, :file <span class="hljs-subst">=&</span><span class="hljs-literal">gt</span>; <span class="hljs-string">'LICENSE'</span> }
s<span class="hljs-built_in">.</span>author <span class="hljs-subst">=</span> { <span class="hljs-string">"Giovanni Lodi"</span> <span class="hljs-subst">=&</span><span class="hljs-literal">gt</span>; <span class="hljs-string">"mokagio42@gmail.com"</span> }
s<span class="hljs-built_in">.</span>source <span class="hljs-subst">=</span> { :git <span class="hljs-subst">=&</span><span class="hljs-literal">gt</span>; <span class="hljs-string">"https://github.com/mokagio/MGCraftman.git"</span>, :<span class="hljs-built_in">tag</span> <span class="hljs-subst">=&</span><span class="hljs-literal">gt</span>; <span class="hljs-string">"0.1.0"</span> }
s<span class="hljs-built_in">.</span>source_files <span class="hljs-subst">=</span> <span class="hljs-string">'MGCraftman/*.{h,m}'</span>
s<span class="hljs-built_in">.</span>platform <span class="hljs-subst">=</span> :ios
end
{<span class="hljs-subst">%</span> endhighlight <span class="hljs-subst">%</span>}
</code></pre><p><h3>Step 5 - Is my podspec ok?</h3>
Once your <code>podspec</code> its ready validate it running</p>
<pre><code class=""><span class="hljs-title">pod</span> spec lint Peanut.podspec
</code></pre><p>If everything is fine you'll read</p>
<pre><code class="">pod spec lint Peanut<span class="hljs-class">.podspec</span>
-> Peanut (<span class="hljs-number">1.0</span>.<span class="hljs-number">0</span>)
Analyzed <span class="hljs-number">1</span> podspec.
Peanut<span class="hljs-class">.podspec</span> passed validation.
</code></pre><p>Otherwise <code>pod spec</code> will explain the error or warning, as everything is so simple also fixing the problems will be. Anyway the error report is already formatted in <a href="http://daringfireball.net/projects/markdown/">Markdown</a> so you can copy it and paste it in an issue on the <a href="https://github.com/CocoaPods/CocoaPods/issues/new">CocoaPods Issues page</a>.</p>
<p><h3>Step 6 - Let your pod fly</h3>
We're almost done here. Now to make our pod available to the community, or just to ourselves and feel cool, we have two options. The rookie way is open an issue, but we've just coded an iOS library, with it's own repo on GitHub, and generated the <code>podspec</code> fetching the data from there, so we're not rookies. The second option is to fork the <a href="https://github.com/CocoaPods/Specs">Specs repo</a>, add our pod, submit the PR and wait.</p>
<p>I submitted my PR at 8:44 GTM+0 on a Sunday<span style="text-decoration:line-through;">, let's see how long it takes to merge it</span>. The PR approved and merged in less that 2 hours. That's what I call efficiency. Also you can ask for push rights, in order to maintain your pod without submitting a pull request every time.</p>
<p>And here we are. My MGCraftman framework is ready to be imported via CocoaPods, and all the world will be happy to use it, or not.</p>
<p>That's all folks, happy coding!</p>
</div><div class="bottom-box no-border"><div class="col-12"><a href="https://twitter.com/share" data-url="http://mokacoding.com/blog/cocoapods-how-to-create-your-own-pod" data-via="mokacoding" data-text="CocoaPods - How to create your own Pod" class="twitter-share-button"><Tweet></Tweet></a><script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');
</script></div></div><div id="paginator" class="bottom-box clearfixed"><div class="col-6"><div><a href="/blog/multiple-builds-of-the-same-app-and-testflight"><< Multiple builds of the same app and TestFlight</a></div></div><div class="col-6"><div style="text-align: right"><a href="/blog/cocoapods">CocoaPods! >></a></div></div></div><div id="subscribe" class="bottom-box"><!-- Begin MailChimp Signup Form -->
<div id="mc_embed_signup">
<form action="//mokacoding.us10.list-manage.com/subscribe/post?u=45a265e2a9d2b9dbec5f98d51&id=0f2ccfb0fa" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate>
<div id="mc_embed_signup_scroll">
<label for="mce-EMAIL">Subscribe to our mailing list</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required>
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;"><input type="text" name="b_45a265e2a9d2b9dbec5f98d51_0f2ccfb0fa" tabindex="-1" value=""></div>
<div class="clear"><input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button"></div>
</div>
</form>
</div>
</div><div class="bottom-box"><div id="disqus_thread"></div><script type="text/javascript" src="/js/disqus.js"></script><noscript>Please enable JavaScript to view the<a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript></div></div></div></div><div class="row-12 footer"><div class="col-12"><h3><a href="/">mokacoding</a></h3></div><div id="copy" class="col-9"><p>Hi I'm <a href="http://giovannilodi.com">Giovanni Lodi</a> and this is my blog. I write here at least once a month, on software testing, productivity, and iOS development.</p>
<p>I'm a freelance iOS engineer, and <a href="mailto:giovanni.lodi42+blog@gmail.com">I'm available for contract work</a>.</p>
<p>Check out my <a href="http://mokagio.github.io/tech-journal">tech journal</a>, and my app <a href="https://itunes.apple.com/au/app/fineants-savings-tracker/id888444078?mt=8">Fineants</a>.</p>
</div><div id="links" class="col-3"><p><i class="fa fa-twitter"></i> <a href="https://twitter.com/mokagio">@mokagio</a></p><p><i class="fa fa-github"></i> <a href="https://github.com/mokagio">mokagio</a></p></div></div></div></body><script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-43554041-1', 'auto');
ga('send', 'pageview');</script><script>var external_links = document.querySelectorAll('a:not([href^="/"]):not([href$="#subscribe"])');
// external_links is an HTMLCollection, not an Array, so we can't call forEach
for (var i = 0; i < external_links.length; i++) {
var link = external_links[i];
link.setAttribute("target", "_blank");
}</script></html>