<?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[Stanfy Engineering Practices - Medium]]></title>
        <description><![CDATA[Sharing latest thoughts on our development-focused blog - Medium]]></description>
        <link>https://medium.com/stanfy-engineering-practices?source=rss----18a296d8704a---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Stanfy Engineering Practices - Medium</title>
            <link>https://medium.com/stanfy-engineering-practices?source=rss----18a296d8704a---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 18 Oct 2026 10:12:12 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/stanfy-engineering-practices" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Life After Parse: What To Do Next?]]></title>
            <link>https://medium.com/stanfy-engineering-practices/life-after-parse-what-to-do-next-97d7fc432c5?source=rss----18a296d8704a---4</link>
            <guid isPermaLink="false">https://medium.com/p/97d7fc432c5</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[parse]]></category>
            <category><![CDATA[parse-shut-down]]></category>
            <dc:creator><![CDATA[Stanfy]]></dc:creator>
            <pubDate>Wed, 24 Feb 2016 23:06:25 GMT</pubDate>
            <atom:updated>2016-02-25T11:29:01.483Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*h8XkinMLL95ytQ-4CDVhyg.jpeg" /></figure><p><em>Special thank you to our iOS Engineers </em><a href="https://medium.com/@vixentael"><em>Anastasiia</em></a><em> and Vitalii Bogdan for contribution to this article.</em></p><p>Since Facebook announced shutting down its mobile backend as a service (mBaaS) platform Parse, a huge number of developers have taken their frustration to all corners of the Internet. From a lengthy <a href="https://www.quora.com/Why-is-Parse-shutting-down">discussion of the reasons on Quora</a> to a <a href="https://www.change.org/p/facebook-don-t-shut-down-parse-com">petition on Change.org</a> signed by over 700 people, the community feels gutted and is starting to look for alternatives.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/768/1*rm_Y0uuwOP7NzOiTSfxRPg.jpeg" /><figcaption>From the Shutdown to the Brave New World!</figcaption></figure><p>A platform that allowed to deploy backend for mobile apps without code, Parse was about perfect in terms of pricing, reliability, and feature set. Developers at Stanfy were avid Parse users as well, as <a href="https://stanfy.com/blog/parse-myth-vs-reality/">Anastasiia put it almost a year ago</a>:</p><blockquote>We use Parse.com because it solves our problems. We tried it several years ago and built many applications using it. Some of them support features like anonymous login, geo-based push notifications, and offline synchronization. There were social apps (post-like-comment-share actions included) and personal apps (on-the-fly customization and offline mode).</blockquote><p>Here’s a look at the alternative solutions available on the market now, from other mBaaS to full-fledged self-hosted backend.</p><h4>Taking Matter In Your Own Hands</h4><p>For the brave people among us, there’s the ultimate solution: <strong>create your own backend from scratch</strong>. Allocate cloud server instance or whole server rack, define hardware you want, use operating system that you prefer, deploy database that suits better, install modules that you like.</p><p>Then learn how to handle load balancing of your servers and version compatibility of your tools, and don’t forget to install security updates and add more RAM modules. What could possibly go wrong? ;)</p><p>Jokes aside, building your own backend solution is the most future-proof idea of all. You can be sure no one’s going to pull the plug on your service of choice, and you have full control of each and every aspect of your hardware and software stack.</p><p>The obvious downside is that <strong>building and maintaining your backend is an extremely time-consuming thing</strong>. This is a viable solution for a larger company with special requirements, applications with many data objects and tasks that require wide bandwidth like multimedia streaming.</p><h4>Run Your Own Parse Server Instance</h4><p>If you’re not that fond of tackling with hardware and adjusting load-balancing servers, it might be a good idea to <strong>deploy your own Parse Server to a cloud server</strong>. Thankfully, <a href="https://github.com/ParsePlatform/parse-server-example">Parse has open-sourced it</a>, so you can migrate data to your own MongoDB instance.</p><p>Unfortunately, not everything is working properly. Parse had lots of integrations like Facebook and Twitter login and third-party modules like Twilio or Mailchimp support, which won’t be available in Parse Server out of the box.</p><p><strong>UPD:</strong> Parse Server now supports <a href="https://github.com/ParsePlatform/parse-server/wiki/Push">push notifications for iOS and Android</a>!</p><p>The situation, however, may get better over time. In addition, Parse team is expected to open-source their awesome web admin dashboard, a place where you can rule everything.</p><p>Here’s how you can run your own parse instance in the cloud.</p><h4><a href="https://www.heroku.com/">Heroku</a> + <a href="https://mongolab.com/">MongoLab</a></h4><p>If you’re after a simple and cheap alternative to Parse but don’t want to buy into another mBaaS, this one might be good for you. It’s definitely good for us, as that’s what Stanfy is going to do with current projects.</p><p>The main idea is that you can migrate your app from Parse to Parse Server by using a free Heroku instance and deploying your database to MongoLab.</p><p>Granted, this looks like yet another vendor-locked solution, however it brings more diversification than going for an alternative mBaaS. Moreover, Heroku doesn’t look like a project that’s about to go under in the near future.</p><p>Here’s a thoroughly crafted walkthrough on <a href="https://learnappmaking.com/how-to-migrate-parse-app-parse-server-heroku-mongolab/">how to migrate your app to Parse Server</a> using Heroku and MongoLab.</p><h4><a href="https://azure.microsoft.com/">Microsoft Azure</a></h4><p>Another cloud service you can choose to deploy your Parse Server instance to is Azure. You’d still need find a platform to run your MongoDB database–that could be MongoLab or any other one.</p><p>As many other Parse alternatives, the cloud by Microsoft is waiting for new users:</p><p>Azure App Service makes a great alternative for hosting your Parse server implementation. After all, the Node.js backend for Mobile Apps in Azure App Service is also an Express app. To make things even easier for you to get started, the Azure App Service team has created a streamlined provisioning process that makes it very easy to get your Parse server running in App Service.</p><p>If that sounds compelling to you, check out <a href="https://azure.microsoft.com/en-us/blog/azure-welcomes-parse-developers/">this migration guide</a>.</p><h4><a href="https://aws.amazon.com/">Amazon Web Services</a></h4><p>Another cloud solution popular among mobile app developers, AWS also sounds like a decent choice. There’s also a <a href="https://gist.github.com/hassy/48bae515c393e9214d3f">migration guide</a> that outlines the benefits of going all Amazon in a rather authoritative manner:</p><blockquote>Why AWS? It’s an enterprise-grade cloud platform which is miles ahead of competitors when it comes to features, price, and support. IMO if you’re not using Heroku (good for when you don’t want to manage anything) or bare metal (good for when you want to manage everything), you should be on AWS.</blockquote><p>In addition to deploying Parse Server itself, you’ll need to get MongoDB running and set up Elastic Beanstalk, which is something like Heroku but compatible with all things AWS.</p><h4><a href="https://github.com/ParsePlatform/parse-server-example#getting-started-with-heroku--mongolab-development">One Button To Rule Them All</a></h4><p>Don’t want to read long tutorials? Community takes care of you! Deploy Parse Server to one of the above-mentioned clouds just tapping a button from ReadMe!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/768/1*BcQ68_74cauz4wI94RdXYQ.jpeg" /><figcaption>Use Single-Button Deploy right from Parse Server readme on GitHub</figcaption></figure><h4>Go For Another mBaaS</h4><p>Shutting down of Parse has definitely weakened developers’ faith in ready-made BaaS solutions.</p><blockquote><em>“Fool me once, shame on you. Fool me twice, shame on me. There will be no “fool me three times”. Until mBaaS can come up with a credible response to the question of vendor lock-in, it’s dead. No sane developer would touch this now.”</em><a href="https://www.quora.com/Why-is-Parse-shutting-down/answer/Tim-Hampson-1"><em> Tim Hampson on Quora</em></a></blockquote><p>However, mBaaS is still good for lazy developers, pet projects and proof of concept apps that aren’t meant to be running for years to come. We’ve looked around and found a few good ones for you.</p><h4><a href="https://developer.apple.com/icloud/">Apple CloudKit</a></h4><p>Recently updated by Apple in the wake of the news of Parse shutting down, CloudKit in its current state looks like a good mBaaS for iOS applications.</p><p>Up until this week, developers using CloudKit could only access user data stored in iCloud from directly within the app. The <a href="https://developer.apple.com/news/?id=02042016a">last update</a>, however, brought the possibility to “easily read and write to the CloudKit public database from a server-side process or script with a server-to-server key.”</p><h4><a href="https://www.firebase.com/">Firebase</a></h4><p>Acquired by Google in 2014, Firebase is a general BaaS platform for mobile and web apps that provides Android, iOS, and JavaScript SDKs. We featured Firebase earlier as one of the <a href="https://stanfy.com/blog/cloud-platforms-for-internet-of-things/">most interesting platforms for use with the Internet of Things</a>.</p><p>The main issue of using Firebase as a backend for mobile apps used to be that it didn’t support push notifications. In early February, however, this issue was <a href="http://techcrunch.com/2016/02/02/batch-now-integrates-with-firebase-to-create-a-parse-alternative/">addressed</a> by providing a way to integrate with Batch, a push notification backend that has already built a <a href="https://batch.com/parse-alternative">migration tool</a> for Parse users.</p><h4><a href="https://backendless.com/">Backendless</a></h4><p>Another popular mBaaS solution, Backendless provides everything an app developer might want to see in a cloud backend. It includes push notifications, media streaming, geolocation, analytics dashboard, etc.</p><p>Same as many other mBaaS platforms, Backendless has already published a <a href="https://backendless.com/parse-to-backendless-migration-guide/">migration guide</a> to make the transition easier for developers.</p><h4>Moving on</h4><p>Of course, it’s next to impossible to go over all the available alternatives to Parse. If you’re interested in digging deeper and discovering more service providers, both ready-made mBaaS and different DIY components, check out <a href="https://github.com/relatedcode/ParseAlternatives">this crowdsourced list on GitHub</a> and make your informed choice.</p><p>At the moment, it’s still unclear what solution will prevail and where the mobile app developers’ community will move. There’s still almost a year until Parse is fully shut down, and the landscape of its alternatives can change significantly.</p><p>Parse really solved lots of problems that are typical for different groups of customers, from students and startups to huge enterprise companies. We believe that at the end of the day every group will find its unique way of doing things.</p><p><strong><em>Originally published at </em></strong><a href="https://stanfy.com/blog/life-after-parse-what-to-do-next/"><strong><em>stanfy.com</em></strong></a></p><p><em>If you enjoyed reading this, please click “</em><strong><em>Recommend</em></strong><em>”(the heart button) below.<br>This will help to share the story with others.</em></p><h4>Read more:</h4><ul><li><a href="https://stanfy.com/blog/parse-myth-vs-reality/">MadCode Meetup: Backend without code. Parse: Myth vs Reality</a></li><li><a href="https://stanfy.com/blog/cloud-platforms-for-internet-of-things/">Cloud Platforms for the Internet of Things</a></li><li><a href="https://stanfy.com/blog/10-of-the-best-mobile-app-prototyping-tools/">10 of the Best Mobile App Prototyping Tools</a></li><li><a href="https://stanfy.com/blog/data-transfer-security-for-mobile-apps/">Data Transfer Security for Mobile Apps</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=97d7fc432c5" width="1" height="1" alt=""><hr><p><a href="https://medium.com/stanfy-engineering-practices/life-after-parse-what-to-do-next-97d7fc432c5">Life After Parse: What To Do Next?</a> was originally published in <a href="https://medium.com/stanfy-engineering-practices">Stanfy Engineering Practices</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Data Protection For Mobile Client-Server Architectures]]></title>
            <link>https://medium.com/stanfy-engineering-practices/data-protection-for-mobile-client-server-architectures-6e6dcabd871a?source=rss----18a296d8704a---4</link>
            <guid isPermaLink="false">https://medium.com/p/6e6dcabd871a</guid>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[security]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[vixentael]]></dc:creator>
            <pubDate>Mon, 22 Feb 2016 10:07:52 GMT</pubDate>
            <atom:updated>2016-02-22T10:07:52.500Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kkAMlq-gGym9mzi2KOlHnA.png" /></figure><p><em>That’s the follow-up of several talks about data protection for mobile applications I gave at the end of 2015. Geography is wide: twice in Ukraine (</em><a href="http://mdday.lviv.ua/team_member/anastasiia_voitova/"><em>mdday.lviv.ua</em></a><em>, </em><a href="https://www.facebook.com/CocoaHeadsUkraine/photos/a.597462120299311.1073741830.558275340884656/964782386900614/?type=3&amp;theater"><em>CocoaHeads Kyiv #7</em></a><em>); once in Amsterdam, Netherlands at </em><a href="http://www.do-ios.com"><em>do{iOS} conf</em></a><em>; and in Minsk, Belarus at </em><a href="http://conf.cocoaheads.by/"><em>CocoaConfBy</em></a><em>.</em></p><p>We, mobile app developers, usually consider security to be a complicated topic, and that is why security talks are rather tedious. I also watched lots of talks like those. While some security concepts are very difficult to understand, it’s also almost impossible to remember and implement them. I decided to take the other way round and make my talk about data protection easy to grasp, with a plenty of cute pictures.</p><p>Look on the slides, watch the video of my talk at do{iOS} conf, or read the whole story.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fround-lake.dustinice.workers.dev%3A443%2Fhttps%2Fspeakerdeck.com%2Fplayer%2F37b20b81d330432c9793164865783ae0&amp;url=https%3A%2F%2Fround-lake.dustinice.workers.dev%3A443%2Fhttps%2Fspeakerdeck.com%2Fvixentael%2Favoiding-damage-shame-and-regrets-data-protection-for-mobile-client-server-architectures&amp;image=https%3A%2F%2Fround-lake.dustinice.workers.dev%3A443%2Fhttps%2Fspeakerd.s3.amazonaws.com%2Fpresentations%2F37b20b81d330432c9793164865783ae0%2Fslide_0.jpg&amp;key=d04bfffea46d4aeda930ec88cc64b87c&amp;type=text%2Fhtml&amp;schema=speakerdeck" width="710" height="596" frameborder="0" scrolling="no"><a href="https://medium.com/media/3b558feb2e69b1220051d973260003d2/href">https://medium.com/media/3b558feb2e69b1220051d973260003d2/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fround-lake.dustinice.workers.dev%3A443%2Fhttps%2Fwww.youtube.com%2Fembed%2FzKvt0fv_mkc%3Ffeature%3Doembed&amp;url=https%3A%2F%2Fround-lake.dustinice.workers.dev%3A443%2Fhttps%2Fwww.youtube.com%2Fwatch%3Fv%3DzKvt0fv_mkc&amp;image=https%3A%2F%2Fround-lake.dustinice.workers.dev%3A443%2Fhttps%2Fi.ytimg.com%2Fvi%2FzKvt0fv_mkc%2Fhqdefault.jpg&amp;key=d04bfffea46d4aeda930ec88cc64b87c&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/36d895b876bde77fe48abf674a48b2ea/href">https://medium.com/media/36d895b876bde77fe48abf674a48b2ea/href</a></iframe><h3>Real world security vs cyber world security</h3><p>Let’s start with <strong>a real-world security</strong>. Meet two dodo birds: Alice and Bob. They are rare species and want to secure themselves from Eve, a Fennec Fox with looooong ears intended to listen all birds’ secrets. When birds notice Eve, they fly away to the bushes.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Ax9_L-8RhDvUjjGD.png" /><figcaption>Eve-the-Fox eavesdrops birds chatting, but they can fly away to the bushes</figcaption></figure><p>Well, in the real world things are clear:<strong> when somebody wants to hear your secrets — you can physically move away.</strong> Avoiding dangers is a part of our nature.</p><p>In the cyber world information security requires us to solve puzzling problems for which <strong>we don’t have intuitive instruments.</strong></p><p>We only know the general direction:</p><ul><li>make communication confidential</li><li>and limit access to the stored goods</li></ul><p>It can be surprising, but every program is a potential target for attackers who will try to find a security vulnerabilities in our apps.</p><blockquote>We — developers — are responsible for keeping things secure from bad guys.</blockquote><p>We really care about users’ data. We want to protect data in the storage (saved to the database, files, NSUserDefaults, etc) and on it’s way from an app to a server.</p><h3>Protect the data on its way to the server</h3><p>Developers tend to think mobile apps are quite safe from malicious attacks in their neat sandboxed environments. This is only partially true: data-in-motion is still at risk, and the risk is high: all sorts of man-in-the-middle and passive eavesdropping attacks are still efficient, if you don’t protect the data the right way.</p><p><strong>Why is this happening?</strong> Security is thought to be tangled and hard to implement. Instead of thinking about building the app based on the fundamental security principles, developers prefer to copy the quick solution from StackOverflow or to implement already existing cryptoalgorithms themselves. It leads to buggy software, full of vulnerabilities and security holes that can be easily cracked.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_5vk-Z7TdOFVJpNx6qj0xA.png" /></figure><p>Thanks to the Apple ATS policies, now almost every iOS9 application uses HTTPS. HTTPS relies on SSL/TLS protocol, that — unfortunately — has a <a href="https://www.cossacklabs.com/avoid-ssl-for-your-next-app.html">number of security issues</a> and a lot of moving parts, which are easy to break.</p><p><strong>Using HTTPS alone doesn’t make your app very secure: </strong>there are lots ways to break SSL encryption. From the attacker perspective, it looks like Alice wears a paper hat and Bob encircles himself with a handmade fence, and they feel secure. But they are not.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*JHCNiurLQoAa2wFX.png" /><figcaption>Using HTTPS with default setup is like using paper hat and handmade fence against Eve</figcaption></figure><p>It’s very important to do SSL right to be more secure: disable old protocols (like sslv3), use long encryption keys and pin certificate inside the client. Well, you can read more in that <a href="https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet">tiny cheat sheet.</a></p><p><strong>SSL pinning</strong> is one of the easiest things to implement inside iOS app that complicates MitM attacks. You just need to pin server’s certificate inside the app, encrypt it and store in a secure place. Well, of course, don’t forget to update certificate before it expires. Many apps are already using SSL pinning, for example, <a href="https://www.paypal-engineering.com/2015/10/14/key-pinning-in-mobile-applications/">Paypal</a>. As usual, there are amazing libs that can be helpful! For example, it takes only three lines of code on Swift to pin certificate using <a href="https://github.com/johnlui/Pitaya">Pitaya</a> lib.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ncAd9YP59SOP5bRj4q4EYA.png" /></figure><p><strong>But using SSL encryption is not enough.</strong> SSL <a href="https://weakdh.org/imperfect-forward-secrecy-ccs15.pdf">was proven to have weak Forward Secrecy</a>, which means that if the encryption key is leaked, all past and future(!) messages can be decrypted. Forward Secrecy is based on using ephemeral keys — keys that are constantly changing — and even if current key is revealed, only small portion of messages is decrypted.</p><p><strong>Encrypting data with persistent keys causes the illusion of safety, but it’s just an illusion.</strong></p><p>Always encrypt crucial data with ephemeral keys that are re-generated each session, and no one will be able to grab it using the soldering iron.</p><p>Before sending data, client and server negotiate about temporary key and use it only during current — rather short — session. Opening new session requires to generate new temporary key. It sounds quite tricky, but there are cool libs for that! <a href="https://github.com/cossacklabs/themis">Themis</a> and <a href="https://github.com/ChatSecure/OTRKit">OTRKit</a> libs provide easy client and server interfaces to add encryption to your current client-server architecture.</p><h3>Keep users data correctly</h3><p>Okay, enough about data in motion, securing data in storage is also important. iOS has own crypto, protecting user’s data while your device is locked. But what if device is stolen and unlocked?</p><blockquote>Wherever you store sensitive data, please, make sure it’s encrypted.</blockquote><p>You don’t need to implement everything yourself. Realize possible security risks for your specific app, build the stout architecture based on CIA principle (confidentiality, integrity, authentication), use right tools, and <em>own brains</em> — this is a proper way to create the app that will take lots of time to break.</p><p>It’s quite simple: pick the good library, generate the encryption key (aka master password), encrypt data before writing to the storage, decrypt it after reading back. And of course, don’t put your master password plaintext inside your app or in the NSUserDefaults. Use Keychain (<a href="https://github.com/soffes/sskeychain">SSKeychain</a> and <a href="https://github.com/square/Valet">Valet</a> are nice wrappers) or generate master password ‘on the fly’ using custom math formula and <a href="https://en.wikipedia.org/wiki/Key_derivation_function">KDF</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*6Iqppoojgj-1R4PN.png" /><figcaption>Alice and Bob build stout secure architecture, poor Eve is crying in the corner</figcaption></figure><h3><strong>To summarize, securing your app is rather simple:</strong></h3><p>– use HTTPS and make sure you’ve disabled old and weak ciphers;<br>– implement SSL pinning, but encrypt the certificate and keep it safe;<br>– encrypt data in motion with the additional layer of encryption using the ephemeral keys;<br>– encrypt data before putting it in the storage and remember to store master key secure or to compute it “on the fly”.</p><h3><strong>What to see next</strong></h3><ul><li>Look at <a href="https://speakerdeck.com/vixentael/avoiding-damage-shame-and-regrets-data-protection-for-mobile-client-server-architectures">my slides</a> to catch the full story.</li><li>Read amazing blog posts by <a href="http://nabla-c0d3.github.io/">nabla-c0d3</a>, pay attention on the audit of <a href="https://nabla-c0d3.github.io/documents/iSEC_Cryptocat_iOS.pdf">CryptoCat iOS app</a>.</li><li>Watch <a href="https://realm.io/news/seth-law-swift-security/">the great talk “Swift-ly Secure” by<em> </em>Seth Law</a>.</li><li>Follow Moxie Marlinspike and <a href="https://www.google.com.ua/webhp?sourceid=chrome-instant&amp;ion=1&amp;espv=2&amp;ie=UTF-8#q=moxie+marlinspike&amp;tbm=vid">watch all his talks</a> :)</li></ul><p><a href="https://twitter.com/vixentael">Let me know</a> if you care about security as much as I do =)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6e6dcabd871a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/stanfy-engineering-practices/data-protection-for-mobile-client-server-architectures-6e6dcabd871a">Data Protection For Mobile Client-Server Architectures</a> was originally published in <a href="https://medium.com/stanfy-engineering-practices">Stanfy Engineering Practices</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Estimate Mobile Projects 2. Why Estimation Fails and How to Prevent This]]></title>
            <link>https://medium.com/stanfy-engineering-practices/how-to-estimate-mobile-projects-2-why-estimation-fails-and-how-to-prevent-this-e93b06bdb3d3?source=rss----18a296d8704a---4</link>
            <guid isPermaLink="false">https://medium.com/p/e93b06bdb3d3</guid>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[project-management]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[vixentael]]></dc:creator>
            <pubDate>Mon, 30 Nov 2015 10:26:27 GMT</pubDate>
            <atom:updated>2015-12-29T09:33:25.621Z</atom:updated>
            <content:encoded><![CDATA[<p><em>After the project is estimated and engineers start development, everything looks clear. What could possibly go wrong? Read about challenges and pitfalls during estimations.</em></p><p>This is the second part of post series “How to Estimate mobile projects”. Read also <a href="https://medium.com/@vixentael/how-to-estimate-mobile-projects-1-a-step-by-step-guide-8b4c25ba7621#.20movro4u"><strong>Part 1 — A step by step guide</strong></a> where we described the initial process of breaking down features and estimations.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*HeEtOKQ5nRq08R7W.png" /></figure><blockquote>The first 90 percent of the code accounts for the first 90 percent of the development time. The remaining 10 percent of the code accounts for the other 90 percent of the development time.</blockquote><blockquote>— Tom Cargill, Bell Labs</blockquote><h3>Changes and uncertainty</h3><p>Sometimes, a project’s details change during development. Some changes are small (changing fonts or colors), some changes are large (adding an extra page or swapping screens). Changes themselves are not a problem, but they certainly affect the initial estimation. Sometimes, in order to make small changes, you need to rewrite a large piece of the system.</p><p>Read this <a href="https://medium.com/@stanfymobile/developer-horror-story-abf3d8add243">developer horror story</a>, which describes how many steps you need to take in order to change the text in the application that is already published in the AppStore.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ExuQPdYPmxBVLLa9.png" /><figcaption><em>Asking the team to estimate another feature…</em></figcaption></figure><p>The future changes are the things that nobody can estimate at the beginning of the project. Therefore, we must keep in mind that initial estimation becomes irrelevant when the project’s scope changes, which is the case in 90% of all projects.</p><h3>Reinventing the wheel</h3><p>The world of iOS development has lots of libraries that significantly reduce development time. We use libs like AFNetworking/RestKit, ReactiveCocoa, Runes, Themis, SDWebImage, SVProgressHUD, other UI controls, our own libs and so on. We can focus on the really interesting or complex components, and implement more valuable features before release. The more cool problem-solving libraries are in our arsenal, the more accurate our estimation is.</p><p>The mobile world is evolving so fast that we often google before implementing large components of the application, for example, how fast our favourite database is in the new version of iOS. Such research reduces the chance of stumbling upon unexpected problems during development and allows us to be in the know.</p><h3>Some tasks are more time-consuming than they appear</h3><p>Never underestimate the challenges that are associated with the real-world features. Among them are such things as time operations, especially with time zones, and specific hardware capabilities like cameras, GPS, push notifications or Bluetooth. It takes more time because development on a real device is “slightly” slower than on the simulator (although Apple tries to make our life easier every year).</p><p>In the same category we include integration with other physical devices such as an external microphone or smart watch.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*d0y6tpU3aEqKyrLl.png" /><figcaption><em>Augmented reality and working with physical devices: that takes time!</em></figcaption></figure><p>Normally, embedding Apple services such as In-App purchasing and iAd doesn’t take a long time, and most developers think “it’s easy”, but it may take a long time to test, so we usually mark previously mentioned tasks as “time-consuming”.</p><p>In addition, <strong>the application won’t submit itself to the Store.</strong> We add several hours for submission to the overall estimated time. This is especially sad when you have to take lots and lots of screenshots for each localization, but now we can open up the <a href="https://github.com/KrauseFx/fastlane">fastlane</a> tool, and things go much faster. Needless to say that it’s easy to forget something in the pre-release atmosphere, so we have created a ‘<a href="https://medium.com/@stanfymobile/check-list-submit-to-appstore-b0a56f42275a">before submission checklist</a>‘ to keep things in one place.</p><h3>Must-have features that are always forgotten</h3><p>What features are present on 80% of the applications, but are often forgotten during the estimation? Screens with a bunch of texts, such as the FAQ, TOS, license agreement and disclaimer. Alert-reminders asking users to rate an application and leave some comment in the store. A “contact us” button to send an email. These features are ‘easy’, but you should put them on the list, too.</p><p>Gathering usage statistics is very important in order to make the right decisions in the future. The simplest way is to track each screen opening and the pressing of every button. But sometimes you need to collect more complex events to calculate conversion or to understand whether the design works as expected. To do this, you need to think about what kind of events statistics will be useful and to integrate analytics tools (like <a href="http://www.flurry.com/">Flurry</a>, <a href="http://www.google.com/analytics/mobile/">Google Analytics</a> or <a href="https://mixpanel.com/">Mixpanel</a>).</p><h3>Communication and documentation also take time</h3><p>Developers usually estimate only the technical side of the story. Time spent on communication is also important. For example, often it’s necessary to design server-client API before starting the development phase, but sometimes API documentation is being designed on-the-fly. It takes time to coordinate teams, especially if they work remotely. In this case we don’t estimate ‘communication’, but ‘creating/updating API doc’.</p><p>According to the <a href="http://www.agilemanifesto.org/">agile manifesto</a>, working product is more important than comprehensive documentation, but it doesn’t mean that docs should not be created. When we estimate complicated features we don’t forget to add points to create the documentation. Talking about client-server interactions we often create <a href="http://www.tracemodeler.com/articles/a_quick_introduction_to_uml_sequence_diagrams/">sequence diagrams</a>. Reading such diagrams instead of digging through the code trying to figure out what’s going on, saves hours, but creation of the diagram also takes time.</p><h3>Unpredictable team factors</h3><h4>Teams make mistakes.</h4><p>More often the team underestimates the complexity of the task, but sometimes they can overestimate it. A few tips on how to reduce this risk to a minimum.</p><p>Permanently increase the level of the team (gain more Exp!). More projects estimated and done means more XP gained. Besides, it is important to conduct the retrospective team meetings to try to figure out the reasons for inaccurate estimates.</p><p>Also, communicating with other teams, listening to their experience and mistakes, helps. And of course, reading a variety of developer resources daily or weekly to monitor community’s pitfalls and trends is also helpful.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*q1PLdVuzpL5VKRS_.png" /><figcaption><em>Team changes are unpredictable…</em></figcaption></figure><h4>Teams change.</h4><p>Swapping horses when crossing a stream is obviously a bad idea. It’s not a developer’s fault if one team estimated the project, but another one is going to develop it.</p><p>Unfortunately, it happens. In this case, it is necessary to discuss and re-estimate the project with the new/updated team. Well, it seems like a waste of time, but in fact, it makes it easier to navigate in the project timeline and to understand the schedule before it gets too late.</p><h3>Iterate and re-estimate</h3><p>We talked about rough estimates in <a href="https://stanfy.com/blog/how-to-estimate-mobile-projects-a-step-by-step-guide">Part 1</a>. In fact, agile project development involves continuous planning and evaluation sessions every sprint or two. Those features that were rough estimated should be re-estimated in more detail, taking into account the knowledge of the system that has emerged.</p><p>Features estimation, implementation, and estimation analysis are a part of the development cycle. The team gains XP and reduces the risks associated with every new project estimation.</p><h3>Well,</h3><p>in the developers’ world, there are many factors that affect the project’s estimation at the different stages. Unfortunately, it’s impossible to take all of them into account. Fortunately, we know many of these factors and know how to minimize risks.</p><p>On the one hand, it is crucial to improve the team constantly, creating various and complex projects, sharing practices with other teams and absorbing their experience. On the other hand, development should move by small iterations, constantly keeping one’s eye on the ball to see the possible divergences from the plan as early as possible.</p><h3>Read More</h3><p>Part 1 — <a href="http://How%20to%20Estimate%20Mobile%20Projects%201">How to Estimate Mobile Projects. A step by step guide</a></p><h3>P.S.</h3><p>Found useful? Enjoyed my pony sketches? Feel free to like and share post! :)</p><p><em>Originally published on </em><a href="https://stanfy.com/blog/how-to-estimate-mobile-projects-a-step-by-step-guide/"><em>Stanfy’s blog</em></a><em> on October 12, 2015.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e93b06bdb3d3" width="1" height="1" alt=""><hr><p><a href="https://medium.com/stanfy-engineering-practices/how-to-estimate-mobile-projects-2-why-estimation-fails-and-how-to-prevent-this-e93b06bdb3d3">How to Estimate Mobile Projects 2. Why Estimation Fails and How to Prevent This</a> was originally published in <a href="https://medium.com/stanfy-engineering-practices">Stanfy Engineering Practices</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Estimate Mobile Projects 1. A Step by Step Guide]]></title>
            <link>https://medium.com/stanfy-engineering-practices/how-to-estimate-mobile-projects-1-a-step-by-step-guide-8b4c25ba7621?source=rss----18a296d8704a---4</link>
            <guid isPermaLink="false">https://medium.com/p/8b4c25ba7621</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[project-management]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <dc:creator><![CDATA[vixentael]]></dc:creator>
            <pubDate>Mon, 30 Nov 2015 10:26:12 GMT</pubDate>
            <atom:updated>2015-12-07T10:39:14.158Z</atom:updated>
            <content:encoded><![CDATA[<p><em>Read some advice on how to transform the project into achievable tasks and what to keep in mind during estimation.</em></p><p>This is the first part of articles series How to Estimate mobile projects. Read also <a href="https://medium.com/@vixentael/how-to-estimate-mobile-projects-2-why-estimation-fails-and-how-to-prevent-this-e93b06bdb3d3#.sw8n7jshu"><strong>Part 2 — Why Estimation Fails and How to Prevent This</strong></a><strong> </strong>to learn about challenges and pitfalls that may occur.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rlu7UMSZx8GrOoK3U13jtw.png" /></figure><p>If anyone asks two dev teams to estimate one project, most likely we will get <em>two different estimates</em> because each team’s judgement will be based on their experience and expertise.</p><p>In a perfect world, before engineers take off with an estimation,the project is already divided into functional modules, each is well-described, and interactions between them are documented, too. This project is evaluated by a team of experienced developers and they start development instantly. But the real world is not so rosy.</p><h3>Start development from estimation</h3><p>There is a widespread opinion that project estimations are a waste of time because they are very volatile in their nature: projects frequently turn out to be more challenging, new demands arrive, new features are added, members of the team come and go.</p><p>It is especially true in the case of a startup or an innovative project — where lots of things are to be validated or even completely pivoted. It’s hard to argue with harsh reality, but it’s always fun to look back at the end and realize how the project began and how naive we were.</p><blockquote>Estimation of the project is the first step to a successful release.</blockquote><p>The estimation is important: it explains how much time is needed to complete the project and get to release. It also helps to move from deliberation of the idea to the elaboration of the detailed plan; to estimate the complexity of system pieces; and to prioritize them.</p><h3>Dig into the project’s problem domain</h3><p>Here at <a href="https://stanfy.com/">Stanfy</a> we estimate projects at different stages. The first stage is a rough estimation when the project only appears on the horizon. Here we explore the project’s industry (medicine, e-commerce, video streaming), and define users and what functions they may need.</p><p><strong>We really need to understand the underlying domain and the problem we’re trying to solve.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*rbPcugI9e37WHEce.png" /><figcaption><em>Exploring new areas is fun</em></figcaption></figure><p>At the rough estimation stage we devise how the user will work with the app and create the preliminary list of features. In order to make this list more accurate, we design low-fidelity wireframes, which show the user’s flow screen by screen inside the app. Wireframes allow us to put things in perspective: how the app’s features are correlated with the screens, and how the screens are connected to provide an intelligible user experience.</p><p><strong>The next step is picking out the most tricky technological pieces:</strong> for example, whether the application has an offline mode with synchronization or a barcode scanner or live chat or video streaming. It allows us to understand what technological challenges may arise along the way, and what constraints we should keep in mind.</p><p>For example, integration with Spotlight Search is available only starting from iOS9; we should take this into account if we are going to create an app for iOS8, too. The more tricky features an application has, the more the roughly estimated time may differ from the actual one.</p><p>At this stage most customers think carefully about their lives, money and plans, and make a decision about whether they are ready to move forward or want to stop. After that comes Stage 2 of estimation, which we call ‘make it as accurate as you can’.</p><h3>Design detailed screens</h3><p>Having a detailed design is very important during the estimation phase. Steps to detailed screens are simple: low-fidelity wireframes, high-fidelity wireframe, interactive prototypes, designs. Lo-fi wireframes are created in the previous step, and they can be transformed into high-fidelity ones. Hi-fi wireframes show more details on the screen: layout, buttons, content placeholders. They pay respect to the design guidelines for every platform: hi-fi wireframes for iOS look different from those for Android.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*dqbPKKWLIo7_9M2o.png" /><figcaption><em>High-fidelity wireframes vs implemented designs</em></figcaption></figure><p>Hi-fi wireframes can be easily transformed into interactive prototypes. One can open prototypes on mobile phones and interact with them like with real applications. Such prototypes are remarkably helpful for developers during the estimation phase; they help to understand an application’s navigation better and visualize its overall architecture.</p><p>Anyway, <strong>the result of estimating a project which has only wireframes — even interactive ones — is not completely accurate numbers.</strong></p><p>The next stage is to transform wireframes into the set of designed screens. Looking at designs, developers understand the app even better: which components to use and whether it’s necessary to write custom elements or it’s enough to customise native ones.</p><p>A good design corresponds to guides: the <a href="https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/">Apple Human Interface Guidelines</a> and the <a href="https://developer.android.com/design/index.html">Android Design Guide</a>. The sets of native components for the web, desktops and mobiles are each different, so if the designer uses complex or non-native components, it increases the resulting estimates. For example, the radio button is native for Web applications, but it has the analogues for mobile — a <a href="https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/Controls.html">switch</a> or <a href="http://developer.android.com/guide/topics/ui/controls/togglebutton.html">toggle button</a>. Nevertheless, estimating the prototypes is not as accurate as estimating already rendered designs.</p><h3>Create a detailed feature list</h3><p>It is hard to estimate the bare idea, so it’s necessary to create a features list or user stories that make up the project. Features are functional pieces that bring value to the user.</p><p>Describing features is something outside of the scope of the estimation and has to be done by the product owner’s team. Our development team clarifies and supplements the descriptions with the technical details.</p><p>For example, let’s consider a feature such as login via email. It consists of the login screen itself, keyboard behavior (it’s better to send data when the user presses the ‘done’ button on the keyboard than when he needs to hide the keyboard and look for the ‘send’ button behind it), data validation, sending requests to the server, handling responses, showing loading, showing error messages, etc.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*6rH03ymnhtDhix5s.png" /><figcaption><em>Spreadsheet with initial project’s estimation</em></figcaption></figure><p>Even the login feature that seemed so small hides many details, and a project is a set of such features. Usually we create a simple spreadsheet where features are divided into blocks, with less or more detailed descriptions of each.</p><h3>Estimate effort</h3><p>To estimate the feature means to find efforts (time and cost) that are required to get this feature done. There are different <a href="https://en.wikipedia.org/wiki/Estimation_%28project_management%29">methods of estimation</a>, but we use analogy based estimation, correlating the feature with its difficulty: easy, normal, hard, infinity — like game levels!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*erizk_qQzFSxJQFw.png" /><figcaption><em>Imagine that you are choosing the difficulty level during the features’ estimation</em></figcaption></figure><h4>Let’s see examples.</h4><ul><li>Easy: Login, forgot password, FAQ, help screens. Usually, static or dynamic screens, without too complex a design, often without sending requests to the server.</li><li>Normal: Home screen, registration, tables, collections, custom controls. Usual screens with server requests, or custom controls.</li><li>Hard: Third-party API integration, audio/video recording, streaming, chatting, custom gestures, synchronization, offline mode.</li><li>Extreme. Usually they’re unclear and huge features. It’s better to divide them into smaller ones.</li></ul><p>Sometimes it’s hard to define where the line is between groups. The rule is simple: round upward if you have doubts.</p><p>Let’s look at an example. Almost every mobile application uses tableview to show content: like showing tweets or cat photos. In the mobile world, the table is a list of the cells, which contain texts, pictures, dates and so on.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Al8Pania4cDIFjUy.png" /><figcaption><em>Tables everywhere!</em></figcaption></figure><p>A table may look very simple, but from a developer’s perspective a simple table involves:</p><ul><li>Design cells (which can contain a lot of information and extra buttons and have flexible content depending on height).</li><li>Loading data (send requests to the server, parse response, create data models)</li><li>Loading more, pull-down-to-refresh.</li><li>Showing loading, empty, and error states (like connection errors).</li><li>Adding/removing items from the table. In my experience, removing items from the table can be very tricky — many apps crash due to data inconsistency.</li><li>Merging content. Sometimes you will need to merge local content with data from the server.</li><li>User interaction when tapping on the cell itself or on a button on the cell (usually the background changes to indicate the selected state and a new screen opens).</li><li>Image caching for pictures in cells (if any).</li><li>Nice animation when cells appear on the screen while scrolling (image fading or light bouncing, depending on the project style).</li></ul><p>Looks complicated, right? And after all, a table should look nice and be scrolled smoothly.</p><p>But the good thing is that most of these features only need to be written once and can be reused with different tables inside one project or in different projects.</p><p><a href="https://github.com/stanfy/ios-components-bikeshedding">We are working</a> on the list of components that are frequently used in many mobile applications, describing different user scenarios and corner cases. It’s useful to have this list on hand during project estimation to keep in mind unique peculiarities of every component.</p><p><strong>The result of this stage is the list of the estimated features.</strong> The more hard or even ‘extreme’ features there are in the list, the more time the project takes.</p><h3>Sort features by priority</h3><p>Some features are more important than others. Therefore, we divide them into “must have”, “nice to have” and “cool, but later.” “Must-haves” are core features — without them the application won’t serve its purpose.</p><p>This technique is called the <a href="https://en.wikipedia.org/wiki/MoSCoW_method">MoSCoW method</a>; <strong>it allows you to focus on the most important requirements</strong> to provide users a valuable product as soon as possible.</p><p>Prioritizing has to be done by the product owner’s team right after creating the features list. Priorities help developers to focus on the most important features (without spending time on the deep study and evaluation of the features in the bottom of the icebox).</p><p>If we are talking about a chat application, for example, then the chatting itself is a core feature, but stickers’ support and sending audio messages can be added in the next release.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Ghm3WB7uN7Y5K3EB.png" /><figcaption><em>Sorting features by priority allows you to finish more important things first</em></figcaption></figure><p>Often, a list of “cool but later” features is changed right after the first release when users give their feedback. It may turn out they really want a geolocation function to share with friends, and stickers can be postponed.</p><h3>R&amp;D features</h3><p>Of course, there are features that we can’t estimate the value of at first. For such features, we do a little research, google and collect links to understand which way to go and what to expect. <strong>At the end of the estimation phase, we highlight such R&amp;D features and consider that they may increase the overall estimated time.</strong></p><p>For example, the integration with not very popular third-party services could be rather tricky. If a service is well documented, just to integrate it and be sure that it works correctly can make up around 20% of the overall work. But often, ‘correctly’ doesn’t mean ‘good enough’ — and you devote the remaining 80% of the time to customizing, improving or even hacking your app.</p><h3>Do not estimate tech practices!</h3><p>Some things we do not add to the features list even though we do them during development. Among these are engineering practices such as pair programming or writing tests on business logic or backend API. We also “automatically” integrate crash analytics tools (like Crashlytics) and use the continuous integration/continuous delivery services to regularly build and deliver the latest version of the app.</p><p>The time is required to set up such things, but usually this time is generously repaid even before the product is released. For example, first we must spend some time to obtain keys from the crash detecting system and configure your application to use them; but then analyzing the crash reports may save you an unbelievable amount of time in finding and fixing crashes before users notice them.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*J-6VrAQnK-SlylHV.png" /><figcaption><em>Using extreme programming practices should not be estimated as an extra cost</em></figcaption></figure><h3>Solutions instead of the problems</h3><p>During the estimation phase, understanding the challenges ahead is to some extent guesswork, as no problem is a real problem yet, and you have plenty of time to plan, simplify features, reiterate design and proceed on a clear path. If the proposed budget or schedule seems inadequate to do the work, we propose adjusting upward or downward the cost, schedule or features.</p><p>In essence, planning is about trying to understand the challenges ahead beforehand. In good teams, <strong>it is each member’s responsibility to maintain a special tone during estimations</strong> — talk about solutions to ‘possible problems’, not about ‘these monsters ahead’.</p><h3>So,</h3><p>the <strong>estimation process is a team job</strong>: the client describes his own vision, the product owner’s team clarifies the idea and creates and prioritizes the features list. Developers are immersed in the project area, trying to find out as much as possible about the project and the end-users. They estimate features, adding a technical point of view and trying not to forget anything.</p><p>Some features are typical for many applications, so they are easier to estimate (for example, you can like posts in almost every social app). It’s more complicated to estimate unique features that no one else has done before. Of course, much depends on the experience of the team and how many different unique applications they have developed.</p><h3>Read more</h3><p>Part 2 — <a href="https://medium.com/@vixentael/how-to-estimate-mobile-projects-2-why-estimation-fails-and-how-to-prevent-this-e93b06bdb3d3#.sw8n7jshu">Why Estimation Fails and How to Prevent This</a></p><h3>P.S.</h3><p>Found useful? Enjoyed my pony sketches? Feel free to like and share post! :)</p><p><em>Originally published on </em><a href="https://stanfy.com/blog/how-to-estimate-mobile-projects-a-step-by-step-guide/"><em>Stanfy’s blog</em></a><em> on October 12, 2015.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8b4c25ba7621" width="1" height="1" alt=""><hr><p><a href="https://medium.com/stanfy-engineering-practices/how-to-estimate-mobile-projects-1-a-step-by-step-guide-8b4c25ba7621">How to Estimate Mobile Projects 1. A Step by Step Guide</a> was originally published in <a href="https://medium.com/stanfy-engineering-practices">Stanfy Engineering Practices</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Building Profanity Filters: clbuttic sh!t]]></title>
            <link>https://medium.com/stanfy-engineering-practices/building-profanity-filters-clbuttic-sh-t-ef310749cb1?source=rss----18a296d8704a---4</link>
            <guid isPermaLink="false">https://medium.com/p/ef310749cb1</guid>
            <category><![CDATA[development]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[filters]]></category>
            <dc:creator><![CDATA[vixentael]]></dc:creator>
            <pubDate>Sun, 29 Nov 2015 15:11:45 GMT</pubDate>
            <atom:updated>2015-12-29T09:33:54.874Z</atom:updated>
            <content:encoded><![CDATA[<p>The built-in profanity filter is not a popular feature in the mobile apps, however in some cases it plays an important UX role.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Am3JiQgFuVw37p0D0AP4mg.png" /><figcaption>Creating filter based on scanning whole words and substring in the text</figcaption></figure><p>We’re developing an application that cares about users really much: users shouldn’t see any offensive texts there. But checking every post by a live moderator takes a lot of time and reduces the application responsiveness.</p><p>We’ve created a “live” filter inside the app that is completely invisible, as long as the user’s text does not contain offensive words. If the filter finds something rude, it gently hints user about wicked content.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*OvrSs8ZnQfbuZs_uszM7JQ.gif" /><figcaption>Live filtering: avoid false positives</figcaption></figure><p>Of course, every filter can be broken, so, in addition, the app has ‘flag abuse’ feature for users to mark inappropriate content.</p><p>Creating profanity filter is quite interesting and tricky task. We found lots of corner cases and learned many dirty words :)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KiZNHA4ZJiTYXn28k1qXXA.png" /><figcaption>One can use l33t sp34k to bypass the filter</figcaption></figure><p>I’ve described the evolution of the filter rules in my slides with more techy examples :)</p><p>☝️Attention! 18+. Lot of dirty words below :)</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fround-lake.dustinice.workers.dev%3A443%2Fhttps%2Fspeakerdeck.com%2Fplayer%2F88a03fa2533a455297e16f158a7778ea&amp;url=https%3A%2F%2Fround-lake.dustinice.workers.dev%3A443%2Fhttps%2Fspeakerdeck.com%2Fvixentael%2Fbuilding-profanity-filters-on-mobile-clbuttic-sh-t&amp;image=https%3A%2F%2Fround-lake.dustinice.workers.dev%3A443%2Fhttps%2Fspeakerd.s3.amazonaws.com%2Fpresentations%2F88a03fa2533a455297e16f158a7778ea%2Fslide_0.jpg&amp;key=d04bfffea46d4aeda930ec88cc64b87c&amp;type=text%2Fhtml&amp;schema=speakerdeck" width="710" height="596" frameborder="0" scrolling="no"><a href="https://medium.com/media/2987c1d787c43bb88e07335370be2ece/href">https://medium.com/media/2987c1d787c43bb88e07335370be2ece/href</a></iframe><h3>P.S.</h3><p><a href="https://speakerd.s3.amazonaws.com/presentations/88a03fa2533a455297e16f158a7778ea/it-sat-profanity-filters.pdf">Tap on pictures</a> to play demo and find secret content 🤐</p><h3>P.P.S.</h3><p>Originally published on <a href="https://stanfy.com/blog/building-profanity-filters/">Stanfy’s blog</a> on September 10, 2015.</p><p><strong>If you liked the article, hit that heart button below. Would mean a lot to me. :)</strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ef310749cb1" width="1" height="1" alt=""><hr><p><a href="https://medium.com/stanfy-engineering-practices/building-profanity-filters-clbuttic-sh-t-ef310749cb1">Building Profanity Filters: clbuttic sh!t</a> was originally published in <a href="https://medium.com/stanfy-engineering-practices">Stanfy Engineering Practices</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Pros and Cons of Using Embedded Android for a Non-Mobile Device]]></title>
            <link>https://medium.com/stanfy-engineering-practices/pros-and-cons-of-using-embedded-android-for-a-non-mobile-device-4fb3d2634a3b?source=rss----18a296d8704a---4</link>
            <guid isPermaLink="false">https://medium.com/p/4fb3d2634a3b</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[embedded-systems]]></category>
            <category><![CDATA[android-app-development]]></category>
            <dc:creator><![CDATA[Pavlo Bashmakov]]></dc:creator>
            <pubDate>Thu, 12 Nov 2015 10:34:54 GMT</pubDate>
            <atom:updated>2015-12-29T09:34:14.759Z</atom:updated>
            <content:encoded><![CDATA[<p>Earlier this year Google announced Brillo as a platform that extends Android to smaller connected devices with just 64MB of memory. It is not that small compared to the 1MB of flash memory in Particle Photon, the Internet of Things hardware development kit which works directly with the cloud over Wi-FI. But still it is much better than the standard resource heavy Android that requires at least 500 MB of flash memory.</p><p>While we are waiting for Brillo’s release, let’s look at how we can use a standard Android as an embedded operating system for the next generation of devices. Let’s assume that we need to design and manufacture a new hardware device in non-mobile categories like smart photo frames, smart projectors, smart mirrors, smart TV top boxes, etc. The question is: Is it worth selecting Android as the embedded operating system for your next device?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/486/0*azQhQfykya1ReHuI.png" /><figcaption>Android System Architecture</figcaption></figure><h3>Good things about using embedded Android (Pros)</h3><p>There are definitely more good things than bad about using Android as an embedded OS for a custom made device.</p><h4>1. Easy UI customization.</h4><p>Many <a href="https://github.com/wasabeef/awesome-android-ui">graphics libraries</a> are available for a fast <a href="http://android-developers.blogspot.com/2015/05/android-design-support-library.html">UI development</a>.</p><h4>2. A large and growing community of Android developers.</h4><p>Google is pushing Android everywhere (smartphones, smartwatches, cars, tablets, TVs) and encourages developers to create custom apps for each device. Besides having this extended ecosystem, Google also invests in the education and training of Android developers with the Udacity Android Nanodegree.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/357/0*XG21HoNdKzDtRFnP.png" /></figure><p>The Android ecosystem is growing.</p><p>So it is safe to assume that it will not be a problem to find a decent Android developer for your custom app development or even for extending your device to a full featured ecosystem later.</p><h4>3. Linux based.</h4><p>Android is running on top of Linux Kernel. Most drivers for Android devices are actually Linux drivers. It is handy when you need to integrate custom hardware modules and can use Linux drivers for that</p><h4>4. Great developer tools.</h4><p>The Android Studio, fully provided with features, has everything needed, like Code Editors, Graphical Layout Editors, Debuggers. Not everything will work for low level Kernel or NDK developments, but still it is great for the overall ecosystem and custom app developers.</p><h4>5. Reduces time to market.</h4><p>It is easier to start with Android than with a Linux distro because it is easy to customize the UI and to find developers for it. Great tools and community help to move fast and deliver products to market early.</p><h3>Things to keep in mind about embedded Android (Cons)</h3><p>All good things have their price, so there are some issues that may arise when using Android as an embedded OS in non-mobile hardware devices.</p><h4>1. It is resource heavy</h4><p>It requires about 512MB of RAM and a CPU with about 1GHz, so it is definitely not for small and power-efficient devices that should last months on a single battery charge. But Android Wear on smartwatches has shown us that it is moving toward miniaturization as well.</p><h4>2. Hard to update OS to the newest version</h4><p>Usually board vendors don’t provide updates for the new Android and support only a few current versions. It means that you are on your own with the updates to the new OS version release that is not an easy task, especially if you’ve already made changes in the system services and have some manually integrated drivers.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*xORHWaGPy6Sp46El.png" /><figcaption>Android Fragmentation in 2015 — OpenSignal</figcaption></figure><h4>3. No Google products available without an agreement with Google</h4><p>This means that you cannot use automatic platform updates distributed as an APK through the Google Play store. No Google Maps or Google+ services either.</p><h3>Final thoughts</h3><p>Android is a ubiquitous OS that becomes available on more and more devices, from smartphones to smart cars. It has the backing of Google, is used by myriad hardware manufacturers and has the constantly growing Android community.</p><p>Many developer tools and the growing community of Android developers make it easy to build your product quickly and reduce the time to market. And with the release of Brillo later this year we will have even more possibilities for extending Android to even more embedded devices.</p><p>What do you think about using embedded Android in non-mobile devices?</p><p>If you need help with development of your custom Android Firmware — <a href="https://stanfy.com/get-in-touch/">let us know</a>!</p><p><strong>Other useful links:</strong></p><ul><li><a href="https://stanfy.com/blog/fixing-up-a-custom-android-build-pitfalls-and-possibilities/">Fixing up a custom Android build: Pitfalls and possibilities</a></li><li><a href="https://static.googleusercontent.com/media/source.android.com/en//compatibility/android-cdd.pdf">Android Compatibility Definition</a></li></ul><p><em>Originally published at </em><a href="https://stanfy.com/blog/pros-and-cons-of-using-embedded-android-for-a-non-mobile-device/"><em>stanfy.com</em></a><em> on October 15, 2015.</em></p><p><strong>If you liked the article, hit that heart button below. Would mean a lot to me. :)</strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4fb3d2634a3b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/stanfy-engineering-practices/pros-and-cons-of-using-embedded-android-for-a-non-mobile-device-4fb3d2634a3b">Pros and Cons of Using Embedded Android for a Non-Mobile Device</a> was originally published in <a href="https://medium.com/stanfy-engineering-practices">Stanfy Engineering Practices</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Optimistic Models 2 — Handling multiple interactions without server confirmation]]></title>
            <link>https://medium.com/stanfy-engineering-practices/optimistic-models-2-handling-multiple-interactions-without-server-confirmation-24d173510961?source=rss----18a296d8704a---4</link>
            <guid isPermaLink="false">https://medium.com/p/24d173510961</guid>
            <category><![CDATA[programming-tips]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Taykalo Paul]]></dc:creator>
            <pubDate>Thu, 05 Nov 2015 14:11:29 GMT</pubDate>
            <atom:updated>2015-12-29T09:34:48.678Z</atom:updated>
            <content:encoded><![CDATA[<p><a href="https://stanfy.com/about"><em>Paul Taykalo</em></a><em>, Lead iOS Engineer at Stanfy, </em>a <a href="https://stanfy.com">mobile design and development studio</a> based in San Francisco.</p><p>—</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wOfWOoMpLb7JkItLW8ulyw.jpeg" /></figure><p>Hi there. I hope that you’ve already read the <a href="https://medium.com/stanfy-engineering-practices/do-not-let-your-user-see-spinners-35b824c3ce2f">previous post</a> about why you shouldn’t show spinners in your applications, and how you can actually avoid it.</p><p>Let’s recap a few things here. Our main goal is to allow the user to feel that every action she performs in the application happens immediately, blazingly fast, even if some actions are performed slowly. We’ll be working with non-confirmed operations here a lot, so we cannot use this approach if we’re about to work with highly-sensitive data, such as credit card information, payment information, etc.</p><p>Previously we mentioned that in order to make an application look faster, we can predict some operations and show the results to the user without receiving actual confirmation from the server. Despite the fact that there is always a delay when an application communicates with the server, we were able to successfully hide that from the users.</p><p>However, this will work well only for simple situations, when the user doesn’t perform actions too quickly, and when we’re actually able to perform them fast enough and not bother about cases, where multiple concurrent operations are performed on the same object. In case there are multiple operations performed, we’ll need something a bit more complex than a simple optimistic model.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nEwjJxPMwM7D9uLYI5fB6Q.png" /><figcaption>Users can be pretty damn fast</figcaption></figure><p>Let’s consider the following example. The user is working with an object (let’s say a post) and every operation she performs needs to be confirmed by the server.</p><p>So here is a list of actions that the user performs:</p><ul><li>likes the post</li><li>adds a comment to the post</li><li>changes post rating from 2 to 5</li><li>unlikes the post</li><li>updates the title to “Handling multiple interactions without server confirmation”</li><li>changes the post rating from 5 to 2</li><li>changes post rating from 2 to 4</li><li>likes the post</li></ul><p>Let’s say that there’s no such thing as a “Save button” on the screen, and the user expects that every change she makes will be automatically saved at some point. Also, let’s imagine that we cannot wait until the user finishes all his operations (In real life we could probably wait some time before sending a request to the server, then group changes that the user has made, and only then send a request).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/926/1*7YG0v6j6aQPwYMWiBFciiw.png" /><figcaption>One screen — multiple user actions</figcaption></figure><p>Base implementation of this logic can be described like so: Just send the update once the user changes something, and show the results from the server. This implementation often leads to blinking and showing incorrect (from the user perspective, but 100% confirmed on the server side) information to the user.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ln3ukZvyd6-fUGhWLlIo-g.png" /><figcaption>Expectations vs Actual result</figcaption></figure><p>It probably still can work fine… until operations start to fail.</p><p>If we aren’t using an optimistic model, it will be hell; the only thing you can do then is to tell the user “Sorry, something went wrong; please revise all the changes you’ve made in the last four minutes, and check to see if everything looks fine.” Some application decides to show tons of alerts — for each failed operation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/638/1*Tuqqys3qH10GcucaNeuYyQ.jpeg" /><figcaption>Error alert’s hell</figcaption></figure><p>But even using the optimistic model, it’s hard to correctly handle this situation. If there are a lot of operations, we would have a state based on unapproved states and this chain will break. :(</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iyryRoT1jeriSZMVsBFwDw.png" /><figcaption>If we miss one operation in chain…Things will go wrong..</figcaption></figure><h4>Storing confirmed object and updates</h4><p>In order to handle those situations, we could use another trick — first, we need some Model in our application which can calculate the state of the object by giving the model a Starting state and list of operations which should be performed on that object.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vi-Jofermbe5qoGu8AknSA.png" /><figcaption>Predicting value based on list of operations being performed</figcaption></figure><p>Next, when an operation is performed on the object, we add this operation to the list of unconfirmed operations, and recalculate the current object state. Once the operation succeeds, we should update the confirmed object and remove the finished operation from the list, and then recalculate the state again. If the operation fails, we just need to remove this operation from the list and recalculate the visible state.</p><p>That’s all. Just by adding this one simple rule, we can correctly rollback our failed operations.</p><h4>Queueing updates</h4><p>In order to simplify your life, I highly recommend preventing concurrent updates on the object. On one hand it will require having some queue for each object, but on the other hand it will allow you to handle complex cases faster.</p><h4>Grouping and discarding operations</h4><p>When we have list of operations that need to be performed on the object, we can simply run them on the server one by one, and update the visual state correspondingly, using the confirmed object + set of operations which are left.</p><p>If we know that a list of operations can become too big, we could start to use some optimisations in order to decrease it.</p><p>Take a look at the previous example, with the post. What can we change there?</p><ul><li>If our server accepts object updates and we can send the whole object with changes, we would next: {like}, {comment:, rating:4, title:”title”}.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*a2yuADbcs565MX7W3H37Vw.jpeg" /><figcaption>All these operations can be grouped to one server call</figcaption></figure><ul><li>If our server doesn’t accept object updates and works per property basis, we still have some things to optimise.</li></ul><h4>Retrying operations</h4><p>We can add one more thing — if the operation fails, we won’t throw it away immediately. Instead, we would retry it again a few times after some delays (Actually, it’s good to have this optimisation even if we’re not using optimistic models). :)</p><p>We can go even further. Instead of blindly repeating the same operation, upon operation failure, we can check whether or not the result of this operation was already overridden by the next operations. If so, we can throw away the current operation and start the next one.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RNCkBTNUKimxhqKZWG1xlA.png" /><figcaption>We can throw away some operations, since they’re not actual anymore</figcaption></figure><h3>Sum up</h3><p>We’re often bound to the servers in our applications. The server is the king. The server decides what to do, what the current state is, and how to perform complex business logic. Often the connection to that server isn’t fast and not reliable enough. By moving some parts of simple logic on the client side, we shouldn’t often have to wait for confirmations and can go on even without server confirmation.</p><h3>P.S</h3><p>This article was intended to be published long time ago, and since then a lot of things happened. One of them is that Parse has revealed their <a href="https://github.com/ParsePlatform/Parse-SDK-iOS-OSX">SDK source,</a> and there you can find, that <a href="https://github.com/ParsePlatform/Parse-SDK-iOS-OSX/blob/master/Parse/Internal/Object/EstimatedData/PFObjectEstimatedData.m">some operations</a> <a href="https://github.com/ParsePlatform/Parse-SDK-iOS-OSX/blob/61f68e9333206f0eebf15d5adab076a0ae7c4b71/Parse/Internal/Object/Utilities/PFObjectUtilities.h">are performed</a> in the way, similar to described in this article. Still, I decided to publish this article, may be not everyone have looked to the Parse sources yet :))</p><h3>P.P.S</h3><p>This is technically <a href="https://stanfy.com/blog/optimistic-models-%E2%80%8Ahandling-multiple-interactions-without-server-confirmation/">repost of the post</a> that was written on <a href="https://stanfy.com/blog/">Stanfy’s blog</a>. But since there are a lot of people who are following me on Medium, I will repost all my posts here too. :) <em>(I don’t like the idea how Medium works with comments, so better ask me questions in the blog</em>)</p><p><strong>If you liked the article, hit that heart button below. Would mean a lot to me. :)</strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=24d173510961" width="1" height="1" alt=""><hr><p><a href="https://medium.com/stanfy-engineering-practices/optimistic-models-2-handling-multiple-interactions-without-server-confirmation-24d173510961">Optimistic Models 2 — Handling multiple interactions without server confirmation</a> was originally published in <a href="https://medium.com/stanfy-engineering-practices">Stanfy Engineering Practices</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[3 Types of Software Architecture for Connected Devices. A Smart Light Bulb Case]]></title>
            <link>https://medium.com/stanfy-engineering-practices/3-types-of-software-architecture-for-connected-devices-a-smart-light-bulb-case-54dc7727136f?source=rss----18a296d8704a---4</link>
            <guid isPermaLink="false">https://medium.com/p/54dc7727136f</guid>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[internet-of-things]]></category>
            <category><![CDATA[technology]]></category>
            <dc:creator><![CDATA[Pavlo Bashmakov]]></dc:creator>
            <pubDate>Thu, 17 Sep 2015 13:50:10 GMT</pubDate>
            <atom:updated>2015-09-17T13:50:10.595Z</atom:updated>
            <content:encoded><![CDATA[<p>Ubiquitous computing and the latest development in the miniaturization of electronic components for the smartphone industry have made it possible to connect any device to your smartphone and a cloud to integrate it with a myriad of online services. How do consumers decide what kind of connection a device needs?</p><p>Let’s take a regular light bulb — one of the most highly commoditized products on the market. At least it used to be so until LED technology gained traction and now we are looking at forecasts of 45% growth per year through 2020 in LEDs. Markets appear to be moving toward LEDs replacing 100% of existing technology including incandescent bulbs. At the same time, the whole new segment of smart home appliances, especially the smart light bulbs, emerged with the introduction of Philips Hue in 2012.</p><p>Now we are seeing dozens of smart light bulbs on the market with new players launching a crowdfunding campaign on Kickstarter or Indiegogo every other month. Let’s pretend we need to build our own smart light bulb and think about how to connect it to the Internet and to the user.</p><h3>High Level Architecture for a Connected Smart Light Bulb</h3><p>There are <a href="https://stanfy.com/blog/developers-guide-to-iot-standards/">different ways</a> to connect a light bulb to a smartphone and/or the Internet: smartphone dependent or smartphone independent; direct connection over Bluetooth/Wi-Fi; or connection through the hub.</p><h4>1. Smartphone Centric Architecture (with or without cloud)</h4><p>In smartphone-centric architecture a light bulb is connected directly to a smartphone via Bluetooth. Thus the light bulb doesn’t have a direct link to the Internet and depends on the proximity of the smartphone.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/570/0*kBqxH_OKBJLzavRD.png" /><figcaption>Smartphone Centric Architecture for connected device</figcaption></figure><p>In this case the connection of the light bulb to the Internet is possible only through the smartphone. Consequently any smart feature that relies on the Internet is available only in close proximity to the smartphone. It’s like triggering an IFTTT action only when the smartphone is present in a Bluetooth range (up to 100 meters), because without the smartphone there is no connection from IFTTT to the light bulb.</p><p>The definite advantage of this architecture for customers is that they don’t need an additional device or hub for the light bulb to be connected but can control it from the smartphone. Furthermore, the setup process is quite easy and straightforward for the user, but it comes at the cost of dependency on a smartphone in order to connect to the Internet.</p><h4>2. Hub-centric Architecture (with or without cloud)</h4><p>The Hub in hub-centric architecture is working as an intermediary for connecting a bulb to the smartphone and to the Internet, since it usually connects to the home Wi-Fi or Ethernet network. A smart lightbulb is totally independent of a smartphone and could be smart on it’s own.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/617/0*SkjQ0Bt_i0RNoVgr.png" /><figcaption>Hub Centric Architecture for connected device</figcaption></figure><p>With the hub-centric architecture it is easier to organize the grouping and seamless connection of the many light bulbs and other appliances in a house. Every connected device can be controlled from anywhere and at any time. Background smart triggers, from integrations to the third party services (IFTTT, stock market dynamics, etc), are easily achievable, as well as controlling lights from any smartphone belonging to the home owners.</p><p>A device cloud in this architecture is optional because many smart features could be set up without having a dedicated cloud infrastructure. But with a cloud features become more robust and reliable because there is a lot more computational power available in a cloud for complex tasks than on a hub device itself.</p><p>The drawback of hub-centric architecture lies in the need to add another device to the system that needs to be delivered to the customer’s home and installed correctly.</p><p>And this is also the architecture broadly used by Google, Apple and Amazon in approaching the smart home market today. Read more on their hubs below.</p><h4>3. Cloud Centric Architecture (without hub)</h4><p>In the Cloud-centric architecture without hub we have a smart device that is directly connected to the home Wi-Fi network and doesn’t need any additional hub to work. It has a simple setup process for the customer and looks similar to the Smartphone Centric Architecture but with the benefit of a direct and constant connection of the device to the Internet.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/665/0*nejzUyraP-9dhosJ.png" /><figcaption>Cloud Centric Architecture for connected device</figcaption></figure><p>Sometimes this architecture becomes similar to the Hub centric architecture in that there is a Master-Slave relationship organized with similar smart devices. The master device is connected to the internet through the Wi-Fi network and other devices are connected to the master and to one another with the mesh network (802.15.4, 6LoWPAN, etc).</p><p>The good thing about this architecture is that there is no need to buy and install additional devices (like with the Hub) while retaining a constant and independent connection to the Internet.</p><h3>Smart Home Ecosystem Wars: Android Brillo + Weave vs HomeKit vs Amazon Echo</h3><p>There is a constant battle of ecosystem platforms designed to organize and connect our home appliances. Such a platform is a necessary and required step before we can invent and build more services on top of the connected smart home devices.</p><p>Google and Apple are moving towards the Hub centric architecture with OnHub and Apple TV respectively. They both also have their own infrastructure ecosystems (Brillo + Weave from Google and HomeKit from Apple) that are aiming to keep customers locked within their walled gardens. Such an approach will allow Google and Apple to have full control over your home, know everything about you and your family and provide added services to you for an additional cost. This will be a good scenario with a recurring business model for them.</p><p>Amazon is also <a href="http://fortune.com/2015/07/01/amazon-internet-of-things/">trying</a> to build the same ecosystem with Amazon Echo and a fleet of third party connected hardware appliance. Eventually the result will be the same locked ecosystem for the consumer in which she can use content and services and buy her household products from Amazon. Another great concept from Amazon, which is currently tested only with its Prime Members, is the Amazon Dash buttons that allow users to buy products with literally one click of a button that is attached to a wall in the kitchen or bathroom.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/0*yGK7M249X_zcatPL.png" /><figcaption>Amazon Dash Buttons</figcaption></figure><p>As we can see, there is a real race between major players to connect all the appliances in our homes. They want to connect every device to businesses, services and people to provide a real value for us. Of course, this is in exchange for the data and opportunity to subscribe you to the recurring paid services.</p><p><em>UPDATE:</em> While this article was being written, Amazon released the <a href="https://developer.amazon.com/public/binaries/content/assets/html/alexa-lighting-api.html">Lightning API</a> for the Amazon Echo, which lets customers control lights and switches by speaking a command. If you are a smart light bulb developer you can benefit from such integration, which increases interoperability and gives a customer more options when using the device.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/667/0*BB5e2lIkw9HSiXqF.png" /><figcaption>Amazon Ligting Api</figcaption></figure><h3>Final Thoughts about Smart Light Bulb Development</h3><p>Having said everything about connected objects let’s make a final list of thoughts that could help you design and make a decision about a great smart light bulb product and other connected objects.</p><ol><li><strong>Independent connection to the Internet</strong> creates the possibility to connect the outer world with your home. Better not to lock a device into a direct connection with the smartphone, because eventually all devices should be connected the third-party services and businesses to attract customers.</li><li><strong>Integration with big players’ ecosystems</strong> like Google Brillo, Apple HomeKit, Amazon Echo will leverage the power of common infrastructure and unlock interoperability with other smart things.</li><li><strong>Open developer API</strong> from day one and build a community of makers, businesses and people around your smart device product.</li></ol><p>Let’s make the connected world seamlessly integrated with businesses and people.</p><p><em>If you like this article please help to </em><strong><em>spread the word about it and Recommend it.</em></strong><em> Thanks!</em></p><p><strong>Stanfy</strong> is a team of passionate software developers and engineers that works in mobile and IoT and can help you to go through the necessary steps of software engineering, from prototyping and manufacturing to the market. <a href="https://stanfy.com/get-in-touch/">Let’s talk.</a></p><p><em>Originally published at </em><a href="https://stanfy.com/blog/3-types-of-software-architecture-for-connected-devices/"><em>stanfy.com</em></a><em> on September 1, 2015.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=54dc7727136f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/stanfy-engineering-practices/3-types-of-software-architecture-for-connected-devices-a-smart-light-bulb-case-54dc7727136f">3 Types of Software Architecture for Connected Devices. A Smart Light Bulb Case</a> was originally published in <a href="https://medium.com/stanfy-engineering-practices">Stanfy Engineering Practices</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Do not let your user see spinners]]></title>
            <link>https://medium.com/stanfy-engineering-practices/do-not-let-your-user-see-spinners-35b824c3ce2f?source=rss----18a296d8704a---4</link>
            <guid isPermaLink="false">https://medium.com/p/35b824c3ce2f</guid>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[user-experience]]></category>
            <dc:creator><![CDATA[Taykalo Paul]]></dc:creator>
            <pubDate>Thu, 20 Aug 2015 11:44:59 GMT</pubDate>
            <atom:updated>2015-09-04T18:37:34.627Z</atom:updated>
            <content:encoded><![CDATA[<p><a href="https://stanfy.com/about"><em>Paul Taykalo</em></a><em>, Lead iOS Engineer at Stanfy, </em>a <a href="https://stanfy.com">mobile design and development studio </a>based in San Francisco.</p><p>Today, we are writing applications. And each application is connected to the Internet. Let’s just talk about those applications which are connected to the Internet. Often, when users perform some operation in the application, a server response is needed, so while this response is being performed, the user is staring at this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/192/1*V3h-VWthi5lL0QySF6qZPw.gif" /><figcaption>Spinner</figcaption></figure><p>There’s no problem with that if you really need to have a server response, and you need to have 100% correct data only. But the thing is that there are a lot of times when we can easily avoid showing the spinner to the user, and trick the user, showing him what he wants to see rather than showing spinners during every user interaction, even if those spinners are cute.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/64/1*hFQWCMGBlYc_ZzkXhd6Vng.gif" /></figure><h4>Types of user interaction</h4><p>Let’s look at user interactions from the perspective of user expectations. When doing some operations in the application, the user can’t be sure about the result — before a publication is opened, it’s hard to predict its contents. On the other hand, some operations are highly predictable for the user:</p><ul><li>liking a favorite post</li><li>writing a comment</li><li>following/unfollowing another user</li></ul><p>Often all these operations require an internet connection in order to be executed, and in badly designed applications, we often see a spinner after each operation. In very badly designed applications, we see a spinner which locks the whole application screen (and which we don’t have the ability to cancel).</p><h4>Idea</h4><p>Somehow we need to convince the user that these operations are performing immediately. And here we’ll explain how we do that in our applications.</p><p>This approach doesn’t require big architecture solutions from the start and can be implemented at any moment of the application development cycle, without any harm to the original. Still, there are few things which are not required, but highly recommended. These things aren’t new and you can find a lot of information about how to use them correctly and why you need to have them in your application.</p><h3>Requirements</h3><h4>View Layer without logic</h4><p>Taken from <a href="https://en.wikipedia.org/wiki/Model_View_ViewModel">MVVM</a> pattern. The main idea is that the View Layer doesn’t know anything about your business logic. All that this View Layer should care about are simple, plain objects, which have no business logic in them, or at least the View Layer shouldn’t know anything about it:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a854b517e44c5ad0117c983008c02d96/href">https://medium.com/media/a854b517e44c5ad0117c983008c02d96/href</a></iframe><h4>Updateable View Layer</h4><p>The View layer should reflect any data changes that are performed in the data it renders. Let’s say a person’s name was changed. Your view should behave correctly, and be able to update itself when this happens. In our examples UIViewController will be the object which will respond to the changes in the model and will tell View to update itself with new data.</p><h4>Request Manager</h4><p>This is the object that is responsible for network operations in your application. You should have one (I hope you do). Also, it’s even better if your ViewController speaks with the Model layer, and the Model layer itself speaks with Request Manager. Again, this is not required, but this is how it works in our applications.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ae6a2f1a4eab995019dc62d2f2286172/href">https://medium.com/media/ae6a2f1a4eab995019dc62d2f2286172/href</a></iframe><h3>Application Structure</h3><p>Here’s how(probably) your application works now. This is waaay too schematic, but you can update it with your own Structural Units.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*ED5bsflS_fqtzxudydgGWg.png" /></figure><p>So here’s what happens:</p><ul><li>Model gets the data from internet</li><li>ViewController listens to the data from Model and updates View</li><li>User Performs some Action on the View</li><li><strong>Spinner starts</strong></li><li>View Controller tells Model to handle action</li><li>Model goes to the internet(to the server, for example)</li><li>Model gets response from the server</li><li>ViewController’s callback got called</li><li>ViewController updates view</li><li><strong>Spinner stops</strong></li></ul><h4>Let’s add one small thing</h4><p>In order to trick the user we’ll need to have just one simple thing — the Optimistic Model.</p><h4>Optimistic Model</h4><p>The idea behind that is pretty straightforward. When the user changes something, the optimistic model gets the original object, tries to predict the potential result, then calls ViewController’s callback with this updated object, and then performs the actual operation in the background like the default Model. Once the real result is returned from the server, the optimistic model calls callback with the real object, or in case of an error, the Model performs callback with the original object and then calls error callback.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*AL4GpBNDyiG3FV-z_stPQw.png" /></figure><p>If we highlight possible flows, they can look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*d_PrDCVrhRXocq57AgEYwA.png" /></figure><h4>Optimistic Model Implementation</h4><p>Now, let’s look how the Optimistic Model implementation can look like</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3437595e328a36b685892145bf8bff09/href">https://medium.com/media/3437595e328a36b685892145bf8bff09/href</a></iframe><p>With this simple update we were able to perform network operations “immediately” (at least from the user perspective).</p><h4>Let’s Summarize</h4><p>What do we have as the result?</p><ul><li>A happy user who doesn’t need to wait for each operation to finish:)</li><li>A happy user, who thinks that your application is blazingly fast(even if your server is really slow).</li></ul><h4>Notes</h4><ul><li>In the example, we’re copying the object. This is done to prevent some <a href="http://www.objc.io/issues/7-foundation/value-objects/#mutability">unexpected changes,</a> which can occur, for example, when there are other references on this object in the application.</li><li>In the example, in server response, we have a fully updated object. In the real world application, this rarely true. Anyway, even if server responds with partial updates, this approach can work correctly.</li><li>The Optimistic Model can be simply used for independent properties or groups of properties of object.</li><li>Depending on your needs, you probably would need to have Local Storage, which will store data that has not been sent to the server yet.</li><li>In complex case, when user tries to perform different operations quickly on the same object, you will probably need to use Temporary/Shadow Storage, which will decide what to show. An example of the implementation of this object will be covered in next post.</li></ul><h4>P.S.</h4><p>Now, press “recommend” button, and measure how long it takes to perform one simple action. Do you see the spinner there? :) So why would you put spinners in your application?</p><p><em>Stanfy is an </em><a href="https://stanfy.com"><em>agile software development company</em></a><em>. We help others evaluate technology, develop and deploy software systems that tuned to work in mobile and wearable world. </em><a href="https://stanfy.com/get-in-touch/"><em>Drop us a line</em></a><em> if you need a collaboration on your lean technology product or startup.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=35b824c3ce2f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/stanfy-engineering-practices/do-not-let-your-user-see-spinners-35b824c3ce2f">Do not let your user see spinners</a> was originally published in <a href="https://medium.com/stanfy-engineering-practices">Stanfy Engineering Practices</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>