<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Alexey Kuznetsov on Medium]]></title>
        <description><![CDATA[Stories by Alexey Kuznetsov on Medium]]></description>
        <link>https://medium.com/@eofster?source=rss-bcabc85149dc------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*CyavcKQ1USvoNr07LSsCHg.jpeg</url>
            <title>Stories by Alexey Kuznetsov on Medium</title>
            <link>https://medium.com/@eofster?source=rss-bcabc85149dc------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 14:12:01 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@eofster/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[What’s new in Telephone 1.5]]></title>
            <link>https://medium.com/64-characters/whats-new-in-telephone-1-5-d49b8c81073?source=rss-bcabc85149dc------2</link>
            <guid isPermaLink="false">https://medium.com/p/d49b8c81073</guid>
            <category><![CDATA[encryption]]></category>
            <category><![CDATA[voip]]></category>
            <category><![CDATA[release-notes]]></category>
            <category><![CDATA[mac]]></category>
            <category><![CDATA[apps]]></category>
            <dc:creator><![CDATA[Alexey Kuznetsov]]></dc:creator>
            <pubDate>Fri, 28 Aug 2020 00:00:00 GMT</pubDate>
            <atom:updated>2020-08-28T10:10:04.976Z</atom:updated>
            <content:encoded><![CDATA[<p>Telephone 1.5 is there, and it supports encryption.</p><p>UDP is probably the most widely used protocol for SIP. It is also used by default in Telephone. If you haven’t changed SIP transport in settings, UDP is used. Some public SIP providers or company servers may also work with TCP, but UDP still seems to be the default.</p><p>Neither UDP nor TCP transport provides encryption. The communication between the phone and the SIP server happens in the clear. One way of solving this problem is to use a VPN connection between your computer and your SIP provider or company network.</p><p>Such remote access VPN is typical for remote workers in a company. But it is not typical for a public SIP provider to offer access to their servers via VPN.</p><h3>TLS as SIP transport</h3><p>There is another standard transport protocol. It is called <a href="https://en.wikipedia.org/wiki/Transport_Layer_Security">TLS</a>, and it supports encryption. It is the same TLS that is widely used on the web where you can recognize it by a padlock icon in the browser or https scheme in the site address.</p><p>The same TLS transport that is used on the web can also be used for SIP. Of course, both the phone and the SIP server have to support it. In this update, Telephone has gotten support for it, so you might want to ask your SIP provider or IT service about the support on the server.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/308/0*1sRRDzQ4LXTMloo9" /></figure><p>When TLS is used, the server presents its cryptographic certificate to the phone. The phone allows the connection only if the server’s certificate has been issued by an authority that is trusted by the phone. Telephone has a built-in list of trusted public certificate authorities in a similar way as an operating system or a web browser does.</p><p>This means that for TLS to work, the server must get a certificate from one of the public certificate authorities. Self-signed certificates would not currently work.</p><h3>SRTP for voice</h3><p>In SIP VoIP, the SIP protocol itself is only part of the story. It is responsible for establishing calls and controlling the call flow, but it doesn’t transmit voice. For the voice, another protocol called RTP is used.</p><p>By default, the voice transmission isn’t encrypted either. As with SIP above, one way of solving this problem is to use a VPN tunnel. In a VPN tunnel, all traffic is usually encrypted, being it SIP or RTP.</p><p>However, there is a specially designed protocol for encrypted voice transmission called <a href="https://en.wikipedia.org/wiki/Secure_Real-time_Transport_Protocol">SRTP</a>, and Telephone now also supports it.</p><h3>TLS and SRTP together</h3><p>To negotiate its encryption keys, SRTP relies on SIP. To make voice transmission with SRTP secure, secure transport has to be used for SIP. That’s why SRTP for voice is usually used together with TLS for SIP.</p><p>In Telephone, when TLS is chosen as a SIP transport, SRTP is automatically required instead of plain RTP. If the server doesn’t support SRTP, the call will not succeed. This way you may be sure that when TLS is selected, your voice between Telephone and the SIP server will also be encrypted.</p><h3>No end-to-end encryption</h3><p>You need to keep in mind that the standard encryption protocols above don’t give you end-to-end encryption between two phones. In SIP telephony, your phone connects to a SIP server. And that in turn connects either to the server of your conversation partner or to their phone directly. There’s no guarantee of what happens to the network traffic after the first server decrypts it. And when a normal phone number is called, there is no guarantee of encryption in the traditional phone network.</p><p>However, encryption between the phone and your SIP server alone is also important. You often don’t have a choice but to trust your SIP server. Otherwise, you wouldn’t have chosen this provider in the first place. But it is a good idea not to trust the network between you and the server and to encrypt all communications with it.</p><p><em>Originally published at </em><a href="https://www.64characters.com/blog/whats-new-in-telephone-15"><em>https://www.64characters.com</em></a><em> on August 28, 2020.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d49b8c81073" width="1" height="1" alt=""><hr><p><a href="https://medium.com/64-characters/whats-new-in-telephone-1-5-d49b8c81073">What’s new in Telephone 1.5</a> was originally published in <a href="https://medium.com/64-characters">64 Characters</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What is VoIP]]></title>
            <link>https://medium.com/64-characters/what-is-voip-d20d43850eb5?source=rss-bcabc85149dc------2</link>
            <guid isPermaLink="false">https://medium.com/p/d20d43850eb5</guid>
            <category><![CDATA[voip]]></category>
            <category><![CDATA[sip]]></category>
            <category><![CDATA[softphone]]></category>
            <category><![CDATA[what-is]]></category>
            <dc:creator><![CDATA[Alexey Kuznetsov]]></dc:creator>
            <pubDate>Tue, 03 Mar 2020 21:31:09 GMT</pubDate>
            <atom:updated>2020-03-03T21:31:09.005Z</atom:updated>
            <content:encoded><![CDATA[<p>Voice over IP is a way of having phone calls via the Internet or local computer network. Calls on Face Time, Skype, WhatsApp, Messenger, or Telegram are VoIP calls. But these services are locked to itself. You can’t call somebody on WhatsApp from Skype.</p><p>Luckily, VoIP is not limited to locked services. The technology is open and widely used in combination with traditional phone services. If you want to call somebody on a regular phone number, you can make it using VoIP. Similarly, you can answer regular phone calls with VoIP.</p><p>VoIP is supported by hardware IP phones or apps. The apps exist for all platforms: iOS, Android, <a href="https://www.64characters.com/telephone">Mac</a>, Windows. These apps are often called softphones. You can talk either using the built-in microphone and speaker or connect a headset.</p><p>Like with traditional or mobile phones, to make calls using softphones you need a phone provider. To be able to call on a mobile phone, you need to insert a SIM card into it. The SIM card stores phone provider settings for your account. To configure a softphone, you need to enter your account settings manually. These settings you receive from your phone provider. In the simplest case, it’s a server name, a user name, and a password. Configuring a softphone is often easier than setting up an email app.</p><h3>It’s already there</h3><p>Many people already use VoIP at work. That phone at your desk is very likely an IP phone. An IP phone is just a computer running software. The same kind of software can be run on a normal computer or mobile phone as an app.</p><p>Many people already use VoIP at home. Some home routers like FritzBox are VoIP servers. You can plug a normal analog phone into it. You can also configure a softphone with router VoIP settings. When you answer or make a call, you’re free to choose what is most convenient for you at the moment: a normal phone or an app.</p><h3>Why VoIP</h3><p>VoIP gives you freedom. Many phone providers work over the Internet. You can choose almost any of them. You can choose better prices, better services, better customer support. You’re not locked to your local phone provider anymore.</p><p>Many VoIP providers offer more features than normal phone providers. You can have multiple simultaneous calls for a single phone number. You can transfer calls between colleagues. Your team members can be located anywhere in the world. No roaming fees for calling a colleague in another country. You can have those voice menus like “Press one to connect to customer support.” You can redirect incoming calls to your mobile phone during business hours and to a mailbox otherwise. You can have call conferences. You can have local phone numbers in several countries redirected to your mobile. All of that is available for big and small teams or individuals without buying expensive phone hardware.</p><h3>Where to start</h3><p>You can start using VoIP by asking your current phone provider. They may offer their services via VoIP in addition to the normal way. If they do, they’ll send you settings to use in an app.</p><p>If your current provider doesn’t offer that, you can search the Internet for a <em>SIP provider</em>. SIP is a standard protocol for VoIP that the providers and the phones support. After the registration, the provider will send you settings to use in an app.</p><p>If you have a VoIP-capable router like FritzBox at home or office, you can create a SIP account for your softphone yourself. Then you use the router’s address and the created user name and password in a softphone.</p><p>If you have an IP phone at your desk at work and would like the flexibility of calling from your computer, you can ask your company IT service to give you SIP settings for your account.</p><h3>Conclusion</h3><p>VoIP is a technology for phone calls over the Internet or local computer network. It is already everywhere and integrated with the traditional phone network. It gives you the freedom to choose better prices and more possibilities than the traditional phone providers usually offer. You can carry your personal or business phone number with you anywhere without roaming fees and without anybody noticing it.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d20d43850eb5" width="1" height="1" alt=""><hr><p><a href="https://medium.com/64-characters/what-is-voip-d20d43850eb5">What is VoIP</a> was originally published in <a href="https://medium.com/64-characters">64 Characters</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ten years of Telephone]]></title>
            <link>https://medium.com/64-characters/ten-years-of-telephone-2b95c248be9c?source=rss-bcabc85149dc------2</link>
            <guid isPermaLink="false">https://medium.com/p/2b95c248be9c</guid>
            <category><![CDATA[mac]]></category>
            <category><![CDATA[anniversary]]></category>
            <category><![CDATA[apps]]></category>
            <category><![CDATA[celebration]]></category>
            <category><![CDATA[voip]]></category>
            <dc:creator><![CDATA[Alexey Kuznetsov]]></dc:creator>
            <pubDate>Fri, 21 Dec 2018 00:00:00 GMT</pubDate>
            <atom:updated>2018-12-21T23:39:51.697Z</atom:updated>
            <content:encoded><![CDATA[<p>Earlier this week, Telephone turned 10. On December 17, 2008, I released the first version 0.8 to the public. It was on Google Code — a go-to place for hosting and publishing opensource projects.</p><p>Since then, it’s come a long way. The source code repository has been migrated two times: from SVN to Mercurial to git. The project hosting has moved from Google Code to GitHub. The distribution — from Google Code to the Mac App Store.</p><p>My original goal for Telephone was to have a streamlined softphone that would be a native citizen on the Mac. As someone who wanted to use VoIP and loved Mac, I struggled with other apps being clunky and feeling foreign on the platform.</p><p>Fast-forwarding ten years, and my goal still stands. Telephone has become a full-featured softphone while keeping its streamlined interface and its nativeness to the Mac.</p><p>Over the years, Telephone was downloaded more than a million times. The vast majority of the feedback has been very positive, and that is what’s been keeping me going forward. I always wanted to dedicate more of my time to this app, and the introduction of subscriptions a couple of years ago finally made it possible.</p><p>Making something sophisticated and full-featured while keeping it easy-to-use is a big challenge. That is what I’m trying to do with the app, and that is what people seem to like in Telephone. History shows a lot of examples of apps getting bloated as the businesses put more and more unneeded features into them only to justify another paid update. And that’s where Telephone Pro subscription comes into play, allowing the app not to be flooded with unnecessary features.</p><p>I want to say thank you to all people who use the app! We often read these words in posts like that, but they are really true. Without you, without your positive feedback that inspires me, without your negative feedback that makes the app better, without your support Telephone wouldn’t have lasted this long.</p><p>Alexey</p><p><em>Originally published at </em><a href="https://www.64characters.com/blog/ten-years-of-telephone"><em>www.64characters.com</em></a><em> on December 21, 2018.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2b95c248be9c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/64-characters/ten-years-of-telephone-2b95c248be9c">Ten years of Telephone</a> was originally published in <a href="https://medium.com/64-characters">64 Characters</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What’s new in Telephone 1.4]]></title>
            <link>https://medium.com/64-characters/whats-new-in-telephone-1-4-82cade798f0b?source=rss-bcabc85149dc------2</link>
            <guid isPermaLink="false">https://medium.com/p/82cade798f0b</guid>
            <category><![CDATA[release-notes]]></category>
            <category><![CDATA[apps]]></category>
            <category><![CDATA[mac]]></category>
            <category><![CDATA[voip]]></category>
            <dc:creator><![CDATA[Alexey Kuznetsov]]></dc:creator>
            <pubDate>Thu, 22 Nov 2018 00:00:00 GMT</pubDate>
            <atom:updated>2018-11-22T11:42:18.180Z</atom:updated>
            <content:encoded><![CDATA[<p>It’s been quite some time since the last release and I’m glad to present Telephone 1.4 to you.</p><h3>Dark Mode</h3><p>Dark Mode is a feature of macOS Mojave and Telephone now fully supports it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/852/0*xb11a5rurkvjUO-l.png" /></figure><h3>Same as system</h3><p>Historically, Telephone has been using built-in devices for playing and capturing audio unless a specific device is selected in preferences. This had been the expected behavior of Mac apps in the past and it changed over time. Now we expect an app to use the same audio devices that are currently selected in the system.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/726/0*iakdgvlcMMLov6Nu.png" /></figure><p>This change has another practical advantage. The audio device for a call and the sound volume can quickly be changed from the sound indicator in the menu bar.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/492/0*ztSNtA2tpos6ABQI.png" /></figure><p>Hold the <em>Option</em> key while clicking the sound icon to see the extended menu that allows selecting the input device.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/492/0*qGENVXwi8aOt8gKD.png" /></figure><h3>History context menu</h3><p>Introduced in the last release call history now has a context menu.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/0*rZ88-BKh3xZLPkUF.png" /></figure><p>Not only does it allow copying the phone number for a record but also deleting all call history records with one action. The standard keyboard shortcut <em>Command-C</em> will also work for copying phone numbers.</p><h3>History facelift</h3><p>Call history has received a facelift. The most important information — the names — is emphasized with a stronger font face. The secondary information is deemphasized for easier skimming through the history.</p><p>Before:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/852/0*peGSAOoDnytlgoFv.png" /></figure><p>After:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/852/0*WGfXpm12Dg9Sw3ZM.png" /></figure><h3>Swipe to delete</h3><p>Records can be deleted from the history without touching the keyboard. Swipe to the left to reveal the delete button.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/628/0*DzfnCnfAUndGn_17.png" /></figure><h3>Call windows on top</h3><p>To make it easier to find call windows during conversations or incoming calls, call windows are now kept on top. This option can be turned on and off in the <em>Call</em> menu.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/364/0*srKBHFbG6o2rntIx.png" /></figure><h3>30 simultaneous calls</h3><p>In the Pro version, the app now supports up to 30 simultaneous calls. In the free version — up to three.</p><h3>QoS</h3><p>QoS is a technology to give more priority to the voice traffic on the network. It makes it less likely for the voice traffic to be delayed or lost, which increases the quality of the phone calls. There are several types of QoS, and Telephone now supports the one that is called DiffServ QoS. This method works on the IP level of the network marking the packets with special numbers. These numbers can then be interpreted by other network devices giving higher priority to phone calls.</p><p>There are two major types of traffic in SIP telephony: signaling (SIP) that controls call flow and voice (RTP) that transmits the actual voice in real time. Telephone marks packets with the following DiffServ DSCP values: SIP packets are marked with the value 24 and RTP packets — with the value 46.</p><p>What should change now is that if your network supports DiffServ QoS, your call quality should increase under heavier network load. For example, when your internet connection is congested when downloading a big file.</p><h3>Hardened Runtime</h3><p>Hardened Runtime is a new security feature of macOS Mojave. This is another security layer — similar to App Sandbox — ensuring that the apps do only what they’re intended to do. The operating system isolates the apps from the critical system components, personal data, and other apps.</p><p>In practice, this means that if an app is compromised by malicious software, it is automatically blocked keeping the system and personal information safe.</p><p>Telephone has supported App Sandbox since its introduction in macOS Lion in 2011. And following the latest Apple security recommendations, the app now also supports Hardened Runtime.</p><p><em>Originally published at </em><a href="https://www.64characters.com/blog/whats-new-in-telephone-14"><em>www.64characters.com</em></a><em> on November 22, 2018.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=82cade798f0b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/64-characters/whats-new-in-telephone-1-4-82cade798f0b">What’s new in Telephone 1.4</a> was originally published in <a href="https://medium.com/64-characters">64 Characters</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What’s new in Telephone 1.3]]></title>
            <link>https://medium.com/64-characters/whats-new-in-telephone-1-3-ba36aa9a62d8?source=rss-bcabc85149dc------2</link>
            <guid isPermaLink="false">https://medium.com/p/ba36aa9a62d8</guid>
            <category><![CDATA[apps]]></category>
            <category><![CDATA[voip]]></category>
            <category><![CDATA[mac]]></category>
            <category><![CDATA[release-notes]]></category>
            <dc:creator><![CDATA[Alexey Kuznetsov]]></dc:creator>
            <pubDate>Mon, 15 Jan 2018 00:00:00 GMT</pubDate>
            <atom:updated>2018-01-15T15:30:25.822Z</atom:updated>
            <content:encoded><![CDATA[<p>Telephone 1.3 has been released and I’m thrilled to tell you about this update.</p><h3>Call history</h3><p>The long-awaited call history is finally here!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/852/0*4Llfsi3fWOnE0GLP.png" /></figure><p>It conveniently looks up names in your macOS Contacts, just as one of the app’s favorite features — contacts autocompletion — already does.</p><p>Press Tab to switch the keyboard focus between the text field and the history. Press Return to make a call. Press Delete to remove the call from the history.</p><p>With call history, it finally became possible to automatically close call windows reducing window clutter.</p><p>In the free version, only the last three calls are visible. However, the last thousand calls are saved and revealed after purchasing Telephone Pro.</p><h3>Telephone Pro</h3><p>Thank you to all the project patrons! Without you, this release would not be possible. I love working on Telephone and want to continue making it more and more useful to you and your business.</p><p>The patronage allowed me to spend much more time in evolving the app but didn’t make it possible to work on it full-time, which I’d love to. The call history introduces the first pro feature to the app, with more to come. All patrons have automatically become Telephone Pro subscribers. As before, the subscription supports ongoing development, and now also unlocks the full call history.</p><h3>Answer calls from notifications</h3><p>Another often requested feature was answering calls from the notifications, and it’s there! It is also possible to decline calls from notifications, but because of the macOS limitations, it is rather obscure. You need to click and hold the Answer button to show the Decline button as another possible action. And as before, just click the notification itself to activate the corresponding call window and bring it to the front.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/770/0*srcVJizxxhl8s2_l.jpg" /></figure><p>This feature also should help with a problem with multiple monitors or many open windows. Sometimes it can be hard to find the window of the currently ringing call, but the notification is always at the same place, easy to find and reach.</p><h3>New app icon</h3><p>The old icon was… old. Bought as part of an icon set back in 2008 it served its purpose for good ten years, until 2018. Again, thanks to the project supporters, I could finally spend some time on the new one, and here it is. Many of us are used to the black Telephone icon, so I kept the color.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/512/0*s1O08MQMwBt1Ri2e.jpg" /></figure><h3>Color status indicators</h3><p>This is one of those small but convenient features. Just quickly glancing at the app window it is now clear if the phone line is currently available for incoming calls or not.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/377/0*sGwnMX4r4lQK6KF9.png" /></figure><h3>What’s next</h3><p>Now, I’ll be focusing on other features that you often ask for: hide the Dock icon and show only the menu bar icon, calling scripts on new calls, new contact search that displays phone types, showing company names next to contacts, better phone number formatting, IPv6 support, and many others.</p><p>Your feedback is always welcome! I read all suggestions and problems that you send me. Feel free to <a href="https://www.64characters.com/support">contact me</a> anytime.</p><p><em>Originally published at </em><a href="https://www.64characters.com/blog/whats-new-in-telephone-13"><em>www.64characters.com</em></a><em> on January 15, 2018.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ba36aa9a62d8" width="1" height="1" alt=""><hr><p><a href="https://medium.com/64-characters/whats-new-in-telephone-1-3-ba36aa9a62d8">What’s new in Telephone 1.3</a> was originally published in <a href="https://medium.com/64-characters">64 Characters</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Overblown Delegates]]></title>
            <link>https://medium.com/ios-os-x-development/overblown-delegates-2e2c9048ac23?source=rss-bcabc85149dc------2</link>
            <guid isPermaLink="false">https://medium.com/p/2e2c9048ac23</guid>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[software-design-patterns]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <dc:creator><![CDATA[Alexey Kuznetsov]]></dc:creator>
            <pubDate>Mon, 19 Dec 2016 14:08:56 GMT</pubDate>
            <atom:updated>2016-12-19T14:08:56.924Z</atom:updated>
            <content:encoded><![CDATA[<p>Over a year ago <a href="https://medium.com/@eofster/observer-pattern-867a03769d1d">I stopped using NSNotifications and KVO</a> in favor of a plain old observer pattern. Here’s what I have to say after using it for a year.</p><h3>Not going back</h3><p>I never regretted making this decision during this year. My APIs became more obvious and testable. I forgot about the huge decoupling of NSNotifications. I never suffer from the inconvenient KVO API and crashes because I forgot to remove a KVO observer.</p><h3>Naming and roles</h3><p>One can say that using the observer pattern is the same as a wide-spread delegation in iOS and Mac development world. I’d say, it’s the same from the implementation point of view, but different on the higher level.</p><p>The problem with the word <em>delegate</em> is that the role is not very specific. Just by looking at a type called <em>StoreDelegate</em> it is not immediately clear what to expect from it. Is it supposed to handle <em>Store</em> events? Is it supposed to provide additional information for the <em>Store?</em></p><p>The fact is, Cocoa and Cocoa Touch APIs tend to have overblown delegates. Just look at the <em>UITableViewDelegate!</em> It configures rows, handles selection events, reorders rows, manages table view focus and much more.</p><h3>Interface segregation principle</h3><p>The <em>UITableViewDelegate</em> API promotes the violation of the <a href="https://en.wikipedia.org/wiki/Interface_segregation_principle">Interface Segregation Principle</a>. The principle suggests that no client should be forced to depend on methods it does not use. The interfaces should be split into smaller and more specific ones. It makes the whole system more decoupled and thus easier to refactor, change, and test.</p><p>In a project, you come across some <em>UITableViewDelegate</em> implementation and ask yourself, what exactly it does. And you don’t know! It may do anything from what that huge protocol declares.</p><p>The first step in solving this problem could be to split that big protocol into the smaller ones. There could be:</p><p><em>UITableViewRowConfigurationDelegate<br>UITableViewAccessoryViewConfigurationDelegate <br>UITableViewHeaderFooterConfigurationDelegate<br>UITableViewSelectionDelegate<br>UITableViewDisplayDelegate<br>UITableViewRowEditingDelegate</em></p><p>and so forth.</p><p>You might argue that it’s too many types. I would say it reveals the truth instead of hiding it from us. It shows the real situation in which a table view may depend on objects with so many different roles.</p><p>In fact, if we were the designers of the <em>UITableView,</em> that would be a signal for us to decompose the <em>UITableView</em> itself into several objects, each of which having a distinct role and a single delegate.</p><h3>Event targets</h3><p>I personally still don’t like that every decomposed protocol is a delegate. (Or if everything was an observer as I started to name them a year ago.) One of the typical roles of Cocoa and Cocoa Touch delegates is event handling. Such types can be called <em>event targets.</em> This is how the list of decomposed protocols looks now:</p><p><em>UITableViewRowDelegate<br>UITableViewAccessoryViewDelegate <br>UITableViewHeaderFooterDelegate<br>UITableViewSelectionEventTarget<br>UITableViewDisplayEventTarget<br>UITableViewRowEditingEventTarget</em></p><p>The word <em>delegate</em> is kept only for the configuration roles (by the way, do you have a better name?). And the expression <em>event target</em> is only used for the event handling role.</p><p>Now the implementations responsible for configuration can be separated from those responsible for events.</p><h3>Event sources</h3><p>Imagine you wanted to react when the list of audio devices in the system changes. You make your use case implement, say, an <em>AudioDevicesChangeEventTarget</em> protocol. But which name do you give to a type that produces those events? The system libraries may just provide a low-level C API with function callbacks. You build a wrapper and name it what? A <em>DevicesChangeNotifier?</em> Could be, but I like how well an <em>EventSource</em> plays with an <em>EventTarget:</em></p><p><em>AudioDevicesChangeEventSource<br>AudioDevicesChangeEventTarget</em></p><h3>Conclusion</h3><p>We can’t change the UIKit API, but we could design our own APIs better. The overblown delegate protocols promote the violation of the <a href="https://en.wikipedia.org/wiki/Interface_segregation_principle">Interface Segregation Principle</a> making our systems more coupled and harder to refactor, change, and test. Making smaller delegate protocols and picking more specific names for them improves the app architecture.</p><h3>Related Articles</h3><ul><li><a href="https://medium.com/@eofster/observer-pattern-867a03769d1d">Observer Pattern</a></li><li><a href="https://medium.com/@eofster/composite-observer-9c836f49abb1">Composite Observer</a></li><li><a href="https://medium.com/ios-os-x-development/dependency-injection-in-swift-a959c6eee0ab">Dependency Injection in Swift</a></li><li><a href="https://medium.com/ios-os-x-development/dependency-injection-in-view-controllers-9fd7d2c77e55">Dependency Injection in View Controllers</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2e2c9048ac23" width="1" height="1" alt=""><hr><p><a href="https://medium.com/ios-os-x-development/overblown-delegates-2e2c9048ac23">Overblown Delegates</a> was originally published in <a href="https://medium.com/ios-os-x-development">iOS App Development</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Conciseness of Swift]]></title>
            <link>https://medium.com/swift-programming/the-conciseness-of-swift-20522df78210?source=rss-bcabc85149dc------2</link>
            <guid isPermaLink="false">https://medium.com/p/20522df78210</guid>
            <category><![CDATA[xcode]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[apple]]></category>
            <dc:creator><![CDATA[Alexey Kuznetsov]]></dc:creator>
            <pubDate>Mon, 08 Aug 2016 13:08:56 GMT</pubDate>
            <atom:updated>2016-08-08T23:02:10.225Z</atom:updated>
            <content:encoded><![CDATA[<p>After writing in Swift for about a year almost exclusively, I sometimes forget how concise it is compared to Objective-C. Especially when you use similar safety features like nullability and designated initializer declarations.</p><p>Take a look at this example of an app receipt validation. It’s a simple <a href="https://en.wikipedia.org/wiki/Decorator_pattern">decorator</a> implementing one of the steps in the validation process and its goal is to verify the receipt’s attributes.</p><p><em>ReceiptAttributesValidation</em> is an immutable object that doesn’t use <em>nil.</em> It doesn’t have accessors to protect its internals and avoid the <a href="https://en.wikipedia.org/wiki/Law_of_Demeter">Law of Demeter</a> violations. It explicitly declares its designated initializer and prevents an accidental initialization with an initializer inherited from the parent.</p><p>The object’s API doesn’t allow an incorrect usage. The client can only create an object using a single (in this case) initializer and tell the object to do work.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2fa5be8465b1349600cb00c99ff0e87c/href">https://medium.com/media/2fa5be8465b1349600cb00c99ff0e87c/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/198ed6193e57dca7d03060aaa1648e10/href">https://medium.com/media/198ed6193e57dca7d03060aaa1648e10/href</a></iframe><p>And here’s the same class implemented in Swift. Note also how the possibility to use a <em>where</em> clause in optional bindings allowed us to remove one method (assuming we wanted to keep methods small).</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c790334bbf259c8d5f12cbcbec85f025/href">https://medium.com/media/c790334bbf259c8d5f12cbcbec85f025/href</a></iframe><p>And what do you think about Swift’s brevity? Do you miss Objective-C’s verboseness in your code?</p><h3>Other Articles</h3><ul><li><a href="https://medium.com/@eofster/too-many-private-methods-9a4b6bfe9579#.8vkifcfqx">Too Many Private Methods</a></li><li><a href="https://medium.com/ios-os-x-development/view-event-testing-in-swift-bce860bb682f#.7jfnvbxc6">View Event Testing in Swift</a></li><li><a href="https://medium.com/ios-os-x-development/humble-object-pattern-in-swift-de5efe8fe05a#.yizsetg7g">Humble Object Pattern in Swift</a></li><li><a href="https://medium.com/ios-os-x-development/dependency-injection-in-view-controllers-9fd7d2c77e55#.jo51srrai">Dependency Injection in View Controllers</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=20522df78210" width="1" height="1" alt=""><hr><p><a href="https://medium.com/swift-programming/the-conciseness-of-swift-20522df78210">The Conciseness of Swift</a> was originally published in <a href="https://medium.com/swift-programming">Swift Programming</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Too Many Private Methods]]></title>
            <link>https://medium.com/@eofster/too-many-private-methods-9a4b6bfe9579?source=rss-bcabc85149dc------2</link>
            <guid isPermaLink="false">https://medium.com/p/9a4b6bfe9579</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Alexey Kuznetsov]]></dc:creator>
            <pubDate>Tue, 26 Apr 2016 09:48:21 GMT</pubDate>
            <atom:updated>2016-04-26T10:06:08.114Z</atom:updated>
            <content:encoded><![CDATA[<p>The refactoring in the <a href="https://medium.com/swift-programming/why-swift-guard-should-be-avoided-484cfc2603c5">previous article</a> stopped at breaking down a big public method into several smaller and private ones. While the violation of the single responsibility principle on the function level was reduced, the violation on the object level stayed the same. This is a code smell that can be called Too Many Private Methods.</p><p>The fact that an object does too many things is often not obvious right away. That’s where the <a href="http://refactoring.com/catalog/extractMethod.html">Extract Method</a> refactoring performed in the aforementioned article became handy. Seven private methods of the <em>VendingMachine</em> started screaming too many roles of the object.</p><h3>Code Rot</h3><p>The single responsibility principle violation on the object level always goes together with testability problems. When a lot is happening in an object privately, there’s a desire to reveal its internals for testing. The so precious object’s encapsulation weakens leading to more complicated future refactoring and fragile tests. Both of these, in turn, result in a situation when nobody wants to change the code even when it really needs a change, making the code <a href="https://en.wikipedia.org/wiki/Software_rot">rot</a>.</p><h3>Big Building Blocks</h3><p>Another problem that arises when the principle on the object level is violated is the bigger object size. In object-oriented programming, the software is composed of building blocks represented by objects. The smaller and more focused those blocks are, the easier it is to build a structure from them and, more importantly, to adapt the existing structure to the new requirements.</p><h3>Extract Class</h3><p>How can the new <em>VendingMachine’s </em>code smell be eliminated? An object does more than one thing if there are several reasons for it to change. The <em>VendingMachine</em> will have to be changed if the overall vending process changes. This seems to be its primary responsibility. The object will also have to be changed if the details of the inventory implementation change. And that is a candidate for an extraction.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/83635c75d0ae3431526f65d6855dbf6f/href">https://medium.com/media/83635c75d0ae3431526f65d6855dbf6f/href</a></iframe><p>The <em>VendingMachine</em> now <a href="https://medium.com/ios-os-x-development/dependency-injection-in-swift-a959c6eee0ab">depends</a> on the <em>Inventory</em> expressed as a protocol. Not only is the inventory logic now encapsulated in a separate, smaller piece of code—the <em>SimpleInventory</em> object—but the <em>VendingMachine</em> has also become more testable. It is trivial to write a test double implementing the <em>Inventory</em> protocol and use it in tests instead of a real inventory.</p><h3>Conclusion</h3><p>The single responsibility principle helps structure code better. It stimulates the creation of smaller and more composable building blocks. The principle can be applied on several levels. Applying it on the <em>function</em> level makes it easier to reveal the principle violation on the object level. Adhering to the principle on the <em>object</em> level keeps the objects small, self-contained, and better encapsulated. Building complex and testable structures from such objects becomes much easier.</p><h3>Related Articles</h3><ul><li><a href="https://medium.com/swift-programming/why-swift-guard-should-be-avoided-484cfc2603c5">Why Swift guard Should Be Avoided</a></li><li><a href="https://medium.com/ios-os-x-development/view-event-testing-in-swift-bce860bb682f">View Event Testing in Swift</a></li><li><a href="https://medium.com/ios-os-x-development/humble-object-pattern-in-swift-de5efe8fe05a">Humble Object Pattern in Swift</a></li><li><a href="https://medium.com/ios-os-x-development/dependency-injection-in-view-controllers-9fd7d2c77e55">Dependency Injection in View Controllers</a></li><li><a href="https://medium.com/ios-os-x-development/dependency-injection-in-swift-a959c6eee0ab">Dependency Injection in Swift</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9a4b6bfe9579" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why Swift guard Should Be Avoided]]></title>
            <link>https://medium.com/swift-programming/why-swift-guard-should-be-avoided-484cfc2603c5?source=rss-bcabc85149dc------2</link>
            <guid isPermaLink="false">https://medium.com/p/484cfc2603c5</guid>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[clean-code]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Alexey Kuznetsov]]></dc:creator>
            <pubDate>Tue, 22 Dec 2015 14:39:34 GMT</pubDate>
            <atom:updated>2016-04-26T09:49:59.574Z</atom:updated>
            <content:encoded><![CDATA[<p>A lot has been told about the <em>guard</em> statement since its appearance in Swift. Indeed, it simplifies code and makes it more readable. But is <em>guard</em> really a silver bullet?</p><h3>Small Functions</h3><p>A lot has been told about the function size. It’s obvious to everyone that functions should be small. They should be as small as possible. Nobody likes to read, understand, and refactor big functions. But how small they should be exactly?</p><blockquote>The first rule of functions is that they should be small. The second rule of functions is that <em>they should be smaller than that</em>. — Robert C. Martin, Clean Code book</blockquote><p>More specifically, Robert C. Martin recommends keeping functions not more than six lines long and definitely not more than ten lines.</p><p>Following this simple rule makes magic. The code suddenly becomes more understandable. What previously was a thirty-line function with several indentation levels and intermediate variables that had to be kept in the head is now ten functions, each having a self-documenting specific name.</p><h3>Single Responsibility</h3><p>A lot has been told about the single responsibility. It applies not only to objects but to functions as well. It’s not a secret to anybody that <em>functions should do one thing and one thing only.</em></p><p>Yet this is violated over and over again. The function size seems to play the major role here. So if a thirty-line function is refactored to be ten three-line functions, the following of the single responsibility principle on the function level is automatically improved.</p><h3>One Level of Abstraction</h3><p>Not that much has been told about functions having one level of abstraction. It is another instrument that helps creating functions with single responsibilities.</p><p>What does it mean? In short, high-level code, like controlling the whole process, shouldn’t be mixed with small details, like variable increments or Boolean checks.</p><h3>Example</h3><p>This example is taken from The Swift Programming Language book.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/93b3d2fc2d0c2661b5b5ae9761370441/href">https://medium.com/media/93b3d2fc2d0c2661b5b5ae9761370441/href</a></iframe><p>Of course, the <em>vend(itemNamed:)</em> function is just an example of using the <em>guard</em> statement but one can often see similar functions in the production code. This function has all three problems described above.</p><ol><li>It is pretty long, sixteen lines, multiple parts separated by empty lines.</li><li>It does several things. It gets an item by name, validates parameters, and it implements the logic of vending an item.</li><li>It has several abstraction levels. The high-level vending process is hidden among the finer-level details like Boolean checks, usage of specific constants, math operations, etc.</li></ol><p>How could the function look like after refactoring?</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6990b7b07da84bbc1ebe37f8f37f677b/href">https://medium.com/media/6990b7b07da84bbc1ebe37f8f37f677b/href</a></iframe><p>The total number of lines increased, but it should not be forgotten that the number of lines is not an end in itself. The refactored code provides a number of benefits compared to the old one.</p><ol><li>The main vending function is now short and contains only high-level steps of vending an item. If the reader is not interested in the details, she can understand the vending process by quickly looking at this high-level function.</li><li>The functions have more respect for the single responsibility principle. Some of them could be broken down even further, but even in their current form, each one is more understandable and readable. They separate the old bigger chunk of code into smaller, self-documenting pieces.</li><li>Each function operates on a single level of abstraction. The reader can easily move between these levels as needed. How does the vending process look like? The item is determined by name and validated, the deposit is reduced, the item is removed from the inventory, and dispensed. How the item is validated? The count and the price are checked. How exactly the count is checked? The count is compared to zero. If small details don’t interest the reader, they can always be skipped.</li></ol><h3>Conclusion</h3><p>The <em>guard</em> statement is a handy instrument for reducing the number of nested structures in functions. The problem lies not in the instrument itself but in its usage. The <em>guard</em> statement promotes the creation of bigger functions that do several things and act on multiple levels of abstractions. By writing small and focused functions, one can find herself not needing the <em>guard</em> statement at all.</p><h3>Related Articles</h3><ul><li><a href="https://medium.com/@eofster/too-many-private-methods-9a4b6bfe9579">Too Many Private Methods</a></li><li><a href="https://medium.com/ios-os-x-development/view-event-testing-in-swift-bce860bb682f#.it6x27j4d">View Event Testing in Swift</a></li><li><a href="https://medium.com/ios-os-x-development/humble-object-pattern-in-swift-de5efe8fe05a#.g38pz3i8g">Humble Object Pattern in Swift</a></li><li><a href="https://medium.com/ios-os-x-development/dependency-injection-in-view-controllers-9fd7d2c77e55#.n6x8wdjgi">Dependency Injection in View Controllers</a></li><li><a href="https://medium.com/ios-os-x-development/dependency-injection-in-swift-a959c6eee0ab#.vthgvblqr">Dependency Injection in Swift</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=484cfc2603c5" width="1" height="1" alt=""><hr><p><a href="https://medium.com/swift-programming/why-swift-guard-should-be-avoided-484cfc2603c5">Why Swift guard Should Be Avoided</a> was originally published in <a href="https://medium.com/swift-programming">Swift Programming</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[View Event Testing in Swift]]></title>
            <link>https://medium.com/ios-os-x-development/view-event-testing-in-swift-bce860bb682f?source=rss-bcabc85149dc------2</link>
            <guid isPermaLink="false">https://medium.com/p/bce860bb682f</guid>
            <category><![CDATA[clean-code]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Alexey Kuznetsov]]></dc:creator>
            <pubDate>Tue, 15 Dec 2015 14:48:02 GMT</pubDate>
            <atom:updated>2015-12-17T21:04:53.401Z</atom:updated>
            <content:encoded><![CDATA[<p>The <a href="https://medium.com/ios-os-x-development/humble-object-pattern-in-swift-de5efe8fe05a#.fyn3pwype">Humble Object Pattern in Swift</a> article demonstrated a way of testing the UI update logic. However, it didn’t provide an example of handling and testing view events. Which object should be responsible for the event handling? Should it be a presenter, like VIPER proposes?</p><p><a href="http://mutualmobile.github.io/blog/2013/12/04/viper-introduction/">Introduction to VIPER</a> states that a presenter contains view logic for preparing content for display and reacting to user inputs. This definition reveals two problems.</p><p>First, if the presenter prepares content <em>and</em> reacts to inputs, this sounds very much like a <a href="https://en.wikipedia.org/wiki/Single_responsibility_principle">Single Responsibility Principle</a> violation.</p><p>Second, this approach imposes a <a href="https://en.wikipedia.org/wiki/Circular_dependency">circular dependency</a> between the presenter and the interactor. This is <a href="http://programmers.stackexchange.com/a/12030">often</a> <a href="http://stackoverflow.com/a/1356344/1812858">considered</a> to be a design smell, which leads to further implications. For example, inability to compose the graph of objects using the <a href="https://medium.com/ios-os-x-development/dependency-injection-in-swift-a959c6eee0ab#.vthgvblqr">constructor dependency injection</a>.</p><p>The idea of handling events in a presenter is <a href="http://martinfowler.com/eaaDev/uiArchs.html">not new</a> to VIPER and surely has its use. But can it be improved?</p><h3>Flow of Control</h3><p><a href="http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html">The Clean Architecture</a>, the architecture which VIPER applies to iOS development, illustrates the typical control flow. An event starts in a controller, goes through an interactor, and ends up in a presenter.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/772/1*B7LkQDyDqLN3rRSrNYkETA.jpeg" /></figure><p>The controller here is not necessarily a view controller. It’s just some object, other than the presenter, that is the first one along the way of handling events. To avoid confusion, it’ll be referred to as an event handler in this article.</p><p>On the diagram, it can be seen that the event handler depends on the interactor to implement the use case. The interactor depends—via the output port it defines using a protocol—on the presenter to deliver the result.</p><p>Each object focuses on a single concern. The dependencies of each object can be passed in the constructor providing the maximum safety and help from the compiler.</p><h3>Breaking Circular Dependencies</h3><p>Although the concerns are now separated, circular dependencies still exist when the whole object graph, including the view, is taken into account.</p><p>The whole graph looks like this: view–event handler–interactor–presenter–view, and it can’t be composed in the initializers. To create the view, an event handler has to be created, which requires an interactor, which requires a presenter, which requires a view. How can this be resolved?</p><p>Factories and observer pattern can become handy for breaking circular dependencies.</p><p>Instead of taking an already instantiated interactor object, the event handler can depend on a factory that knows how to create interactors. The first thought could also be to make the event handler create interactors directly. However, that would undermine all <a href="https://medium.com/ios-os-x-development/dependency-injection-in-swift-a959c6eee0ab#.vthgvblqr">dependency injection advantages</a>, testability being one of them.</p><h3>Example</h3><p>The example shows how a GPS tracking app could present track summary and handle a track name change actions. Because this article is about the event handling, presenter tests will not be shown here and can be found in the <a href="https://medium.com/ios-os-x-development/humble-object-pattern-in-swift-de5efe8fe05a#.fyn3pwype">previous article</a>.</p><h4>Business Logic</h4><p>The interactors are basically commands. The code that executes them may not care about how they are created. Therefore, the interactors have only one method.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/57176e2b96c252e5fdcd1dd78db3c5d1/href">https://medium.com/media/57176e2b96c252e5fdcd1dd78db3c5d1/href</a></iframe><p>There are two interactors conforming to this protocol.</p><p>The <em>TrackSummaryInteractor</em> is responsible for preparing the track summary data for display.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f1eba1b3880a43f3f416500618f79a9f/href">https://medium.com/media/f1eba1b3880a43f3f416500618f79a9f/href</a></iframe><p>The <em>TrackNameUpdateInteractor</em> is responsible for updating the track name in the store.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1da28e31c77b2105eec8bfd0e54e98a2/href">https://medium.com/media/1da28e31c77b2105eec8bfd0e54e98a2/href</a></iframe><p>Both interactors need a persistent store, which is represented by a protocol. The concrete implementation of the persistent store is not interactors’ business and out of the scope of this article.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/30e2c90ae9ac1f3e81b31e2850274746/href">https://medium.com/media/30e2c90ae9ac1f3e81b31e2850274746/href</a></iframe><p>The track summary data structure contains an identifier that might not be displayed to the user but is used for updating the track name.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/35c7e3693aeb8ceddd0779b4873d5dd4/href">https://medium.com/media/35c7e3693aeb8ceddd0779b4873d5dd4/href</a></iframe><p>It is trivial to test the interactors by writing test doubles that implement the boundary protocols.</p><h4>Presentation</h4><p>The <em>TrackSummaryPresenter</em> is responsible for preparing data for presentation.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e1da4125a06d96193deedf4ab88baff8/href">https://medium.com/media/e1da4125a06d96193deedf4ab88baff8/href</a></iframe><h4>View</h4><p>The view is defined as a protocol inheriting the presenter’s output protocol. It is not uncommon for the more complex views to inherit multiple protocols declared by several presenters.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4fcdaa4d8556610c8f178b537572e3c0/href">https://medium.com/media/4fcdaa4d8556610c8f178b537572e3c0/href</a></iframe><p>The protocol defining the view events is to be implemented by the view observers. The <em>view</em> parameter makes it possible to break the circular dependency.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/daa9484567bf5c1bc92bdf170e58f7d2/href">https://medium.com/media/daa9484567bf5c1bc92bdf170e58f7d2/href</a></iframe><p>Due to its tight coupling with the view, the view controller, as discussed <a href="https://medium.com/ios-os-x-development/humble-object-pattern-in-swift-de5efe8fe05a#.fyn3pwype">before</a>, represents the view to the outside world. It’s the view controller who implements the <em>TrackSummaryView</em> protocol.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c96274861dc64cb69b01ff5501598d8c/href">https://medium.com/media/c96274861dc64cb69b01ff5501598d8c/href</a></iframe><p>The view controller is very humble, passively accepting the data for presentation and delegating event handling to the observer. Because of the constructor injection, the view controller can’t be created without an observer by mistake.</p><p>The event handler object acts as a view observer.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/821a826283d0b4c25229d42084849c03/href">https://medium.com/media/821a826283d0b4c25229d42084849c03/href</a></iframe><p>To improve testability, it doesn’t create the interactors by itself, but rather depends on factories to do that.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c11f32c7a28c7607eaaa487ba5172047/href">https://medium.com/media/c11f32c7a28c7607eaaa487ba5172047/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/230af5aeb0f7b1f849d8c4eeb15e47bf/href">https://medium.com/media/230af5aeb0f7b1f849d8c4eeb15e47bf/href</a></iframe><p>The event handler can be tested easily.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/dc7177c373c7a6206fba787bf18ad0a6/href">https://medium.com/media/dc7177c373c7a6206fba787bf18ad0a6/href</a></iframe><p>If needed, the test doubles can be created manually.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/96804e562567d7564ed7986c8657cf1c/href">https://medium.com/media/96804e562567d7564ed7986c8657cf1c/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5405f82933ce6b7c5157d3f60b598885/href">https://medium.com/media/5405f82933ce6b7c5157d3f60b598885/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f19956553bf9627e946f8602f7b060b2/href">https://medium.com/media/f19956553bf9627e946f8602f7b060b2/href</a></iframe><p>Composing all objects together.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/83905a0e76a3f4b654ddb24b080a74a1/href">https://medium.com/media/83905a0e76a3f4b654ddb24b080a74a1/href</a></iframe><h3>Conclusion</h3><p>The becoming more and more popular VIPER architecture combines both presentation and event handling logic inside a presenter. This leads to often unwanted circular dependencies, puts two responsibilities into a single object, and may over time grow into the Massive Presenter problem. The event handling and presentation logic could be separated using The Clean Architecture event flow approach. As a result, the objects become smaller, more testable, and responsible for one thing only.</p><h3>Related Articles</h3><ul><li><a href="https://medium.com/ios-os-x-development/humble-object-pattern-in-swift-de5efe8fe05a#.g38pz3i8g">Humble Object Pattern in Swift</a></li><li><a href="https://medium.com/ios-os-x-development/safer-uiviewcontroller-creation-when-using-storyboards-1915ac2b2c80#.km63h87vp">Safer UIViewController Creation When Using Storyboards</a></li><li><a href="https://medium.com/ios-os-x-development/dependency-injection-in-view-controllers-9fd7d2c77e55#.n6x8wdjgi">Dependency Injection in View Controllers</a></li><li><a href="https://medium.com/ios-os-x-development/dependency-injection-in-swift-a959c6eee0ab#.vthgvblqr">Dependency Injection in Swift</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bce860bb682f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/ios-os-x-development/view-event-testing-in-swift-bce860bb682f">View Event Testing in Swift</a> was originally published in <a href="https://medium.com/ios-os-x-development">iOS App Development</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>