<?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[Mutual Mobile - Medium]]></title>
        <description><![CDATA[We bring digital experiences to life through an integrated approach to design and technology. - Medium]]></description>
        <link>https://medium.com/mutualmobile?source=rss----f5d3225ca8ce---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Mutual Mobile - Medium</title>
            <link>https://medium.com/mutualmobile?source=rss----f5d3225ca8ce---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 13 Nov 2026 08:57:39 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/mutualmobile" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[XCTest: The bane of memory leaks?]]></title>
            <link>https://medium.com/mutualmobile/xctest-the-bane-of-memory-leaks-1924366bc7b7?source=rss----f5d3225ca8ce---4</link>
            <guid isPermaLink="false">https://medium.com/p/1924366bc7b7</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[xcode]]></category>
            <category><![CDATA[xctest]]></category>
            <category><![CDATA[macos]]></category>
            <category><![CDATA[memory-leak]]></category>
            <dc:creator><![CDATA[Mutual Mobile]]></dc:creator>
            <pubDate>Mon, 19 Dec 2022 03:31:44 GMT</pubDate>
            <atom:updated>2022-12-19T03:31:43.859Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eywPXkGAmos70_qoHq-BQw.png" /></figure><p>A software developer, web developer, and mobile app developer enter a bar, and immediately turn around and run for their lives.</p><p>Why?</p><p>Short answer — memory leak</p><p>The long answer? Start scrolling to find out 😆</p><p>Before moving on, you might be wondering <a href="https://www.geeksforgeeks.org/what-is-memory-leak-how-can-we-avoid/">what is memory leak</a>. It is a scenario that occurs when developers or software unintentionally do not free an allocated block of memory when it’s no longer required. In such situations, the performance of the software or application starts decreasing until it fails or becomes extremely slow.</p><p>So, how can this situation be resolved or prevented in the context of <a href="https://mutualmobile.com/blog/developing-mobile-apps-what-you-need-to-know-for-emerging-markets">app development in Apple</a>? Let’s take a look.</p><h3>An apple a day keeps memory leaks away?</h3><p>So, how does app development take place in the context of <a href="https://mutualmobile.com/blog/wwdc-2022-leading-us-to-the-promised-land">Apple’s app development ecosystem</a>, i.e., iOS, macOS, watchOS, and tvOS?</p><p>Across Apple’s ecosystem, app development memory is managed with ARC’s (Automatic Reference Counting) help. ARC helps operating systems track, allocate, and deallocate memory for objects participating in a particular program. However, the OS does require developer’s assistance when it comes to managing the memory footprint.</p><p>The OS knows when to allocate and deallocate memory, but it doesn’t understand the reasoning behind managing the memory. Hence, it falls to the developer to design the interactions of objects in an application to ensure the ARC understands why memory has to be allocated and deallocated.</p><p>ARC manages the memory for an object by injecting retain and release method calls before and after its usage. The ARC keeps an object in memory as long as the object has a reference count of 1 or more. When the reference count falls to 0, the ARC will remove the object from memory. But what happens if the object is not removed from memory? Let’s examine it with an example.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*LYdA8cX54YXbctuL.png" /></figure><p>As you can see in the graph above, several objects hold references to each other. Once ‘App Delegate’ gets deallocated, it removes the reference to ‘View Model’ while deallocating it as well. This similar process also continues with the ‘View Model’ and ‘Department Model’.</p><p>However, as you can see, ‘Department Model’ and ‘Employee Model’ still reference each other, even when no other object is referencing ‘Department Model’. Since they are still referencing each other, they exist in memory, thus causing the infamous memory leak (and giving you the long answer 😉)</p><h3>How to catch memory leaks?</h3><p>Apart from employing ARCs, there are other methods for catching or <a href="https://developer.apple.com/documentation/xcode/making-changes-to-reduce-memory-use">preventing memory leaks</a>; tools and tests are two such ideas that come to mind.</p><p>Xcode has several <a href="https://mutualmobile.com/blog/16-easy-android-developer-tools-for-getting-started">tools that help developers</a> debug and catch memory leaks; however, these primarily come into play after the features and functionalities are developed and can be time-consuming.</p><p>On the other hand, there are tests that can actually catch memory leaks, one of them being the XCTest. So, let’s examine how implementing an XCTest can help detect memory leaks, and here we dive into the practical world of coding.</p><h4>Step 1</h4><p>The first step in this process is creating an Xcode project and a test target. For this example, we’ll be creating four classes — <em>Employee</em>, <em>Department</em>, <em>DepartmentViewModel</em>, and <em>Capture_Memory_Leak_with_XCTestTests</em>, which is an XCTestCase subclass.</p><h4>Step 2</h4><p>Implementing the application’s main target is the next priority</p><pre>import Foundation<br> <br>class DepartmentViewModel {<br>    <br>    var department: Department<br>    <br>    init(_ department: Department) {<br>        self.department = department<br>    }<br>    <br>    func add(_ employee: Employee) {<br>        department.employees.append(employee)<br>    }<br>}<br> <br>class Employee {<br>    var id: Int<br>    var name: String<br>    var department: Department<br>    <br>    init(_ id: Int, name: String, department: Department) {<br>        self.id = id<br>        self.name = name<br>        self.department = department<br>    }<br>}<br> <br>class Department {<br>    var id: Int<br>    var name: String<br>    var employees = [Employee]()<br>    <br>    init(_  id: Int, name: String) {<br>        self.id = id<br>        self.name = name<br>    }<br>}</pre><h4>Step 3</h4><p>The next step is to implement the application’s test target.</p><pre>import XCTest<br>@testable import Capture_Memory_Leak_with_XCTest<br> <br>class Capture_Memory_Leak_with_XCTestTests: XCTestCase {<br>    <br>    /// holds references of instance of each type<br>    /// On deallocation of `viewModel.department` these types will be nil&#39;ed out.<br>    private weak var weakDepartment: Department?<br>    private weak var weakEmployee: Employee?<br>    <br>    override func tearDown() {<br>        super.tearDown()<br>        assertMemoryLeakOnEmployee()<br>        assertMemoryLeakOnDepartment()<br>    }<br>    <br>    private func assertMemoryLeakOnEmployee() {<br>        /// Once `employee` instance is deallocated then `weakEmployee` will also gets deallocated &amp;  below test will success<br>        XCTAssertNil(weakEmployee, &quot;Employee Object is leaking&quot;)<br>    }<br>    private func assertMemoryLeakOnDepartment() {<br>        /// Once `department` instance is deallocated then `weakDepartment` will also gets deallocated &amp; below test will success<br>        XCTAssertNil(weakDepartment, &quot;Department Object is leaking&quot;)<br>    }<br>    <br>    func test_employeeExistsInDepartment() {<br>        let iOSDepartment = Department(1, name: &quot;iOS&quot;)<br>        let abc = Employee(1, name: &quot;ABC&quot;, department: iOSDepartment)<br>        <br>        let viewModel = DepartmentViewModel(iOSDepartment)<br>        viewModel.add(abc)<br>        <br>          /// Entire memory leak magic happens here.<br>        /// By end of this function, If proper object deallocation happens, it is expected that below instance(s) will be nil&#39;lyfied<br>        weakEmployee = abc<br>        weakDepartment = iOSDepartment<br>        <br>        let employeeExist = iOSDepartment.employees.contains {<br>            abc.id == $0.id<br>        }<br>        <br>        XCTAssertTrue(employeeExist)<br>    }<br>}</pre><p>As you can see in the source code in steps 2 and 3, the <em>weakEmployee</em> and the <em>weakDepartment</em> instances in the application’s test target must be weak to ensure the test is carried out seamlessly.</p><p>So how do you find out or catch the memory leak? First, the presence of <em>XCTAssertNil </em>in the application’s main target informs us about the existence of the memory leak.</p><p>However, the leak occurs in the <em>weakEmployee</em> and <em>weakDepartment</em> instances from <em>func test_employeeExistsInDepartment().</em> This function holds the local instance property in the test class scope, so during <em>tearDown() </em>method call asserting the deallocation of instances must be eliminated.</p><p>You can also handle the memory leak by prefixing <em>weak </em>or <em>unowned </em>to property <em>var department: Department </em>from the <em>Employee </em>class.</p><p>This is how you can prevent and catch memory leaks with XCTest, which would also help in attracting the software, web, and mobile developers who ran for their lives 😆</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1924366bc7b7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mutualmobile/xctest-the-bane-of-memory-leaks-1924366bc7b7">XCTest: The bane of memory leaks?</a> was originally published in <a href="https://medium.com/mutualmobile">Mutual Mobile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Jetpack Compose Preview like a pro!]]></title>
            <link>https://medium.com/mutualmobile/jetpack-compose-preview-like-a-pro-780a7cda52df?source=rss----f5d3225ca8ce---4</link>
            <guid isPermaLink="false">https://medium.com/p/780a7cda52df</guid>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[androiddev]]></category>
            <category><![CDATA[jetpack-compose]]></category>
            <category><![CDATA[android]]></category>
            <dc:creator><![CDATA[PRANAY PATEL]]></dc:creator>
            <pubDate>Thu, 15 Dec 2022 10:12:29 GMT</pubDate>
            <atom:updated>2022-12-15T10:12:29.530Z</atom:updated>
            <content:encoded><![CDATA[<p>Let’s discuss a smarter way to use Jetpack Compose Preview while app development!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4i4aC02wU5QBwgAselgznQ.png" /></figure><p>Hey Androiders 👋, this is a blog where we’ll discuss how we can use JetpackCompose @Preview in a different way to make our app development more productive!</p><p>Before starting of JetpackCompose @Preview let&#39;s discuss how we can enable Android projects with required dependencies. We need to add tooling dependencies which will support @Preview annotation in the app:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b147df9ceb059254387e8b48c229500e/href">https://medium.com/media/b147df9ceb059254387e8b48c229500e/href</a></iframe><h4>Simple Composable Preview</h4><p>Create a new Composable using @Composable annotation:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cd2fdb418f0478406e4f9ae0bbdc561e/href">https://medium.com/media/cd2fdb418f0478406e4f9ae0bbdc561e/href</a></iframe><p>and create a preview for the above Composable annotated with @Composable and @Preview to show a preview in the Android studio window:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/68010798e50a65c609d5d2ca3391ce09/href">https://medium.com/media/68010798e50a65c609d5d2ca3391ce09/href</a></iframe><p>Composable preview in the design window:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/560/1*spz32d3ic_8YJ6a9xJ-6qA.png" /></figure><h4>UseCases:</h4><p>Now let’s discuss this differently Preview parameters and use cases where we can update our Preview annotation and make the preview more useful.</p><p><strong>Case 1: </strong>Light/Dark theme preview:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/12b7bcf4be51bc8f21b22ce7eb0f35a9/href">https://medium.com/media/12b7bcf4be51bc8f21b22ce7eb0f35a9/href</a></iframe><p>Output:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/560/1*zG3v6uTq-jg9af5szWkeCg.png" /></figure><p><strong>Case 2: </strong>Preview your entire screen with system UI controls along with different device specifications like in tablets, phones etc:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/83392e107cbca7566b474593ed363efb/href">https://medium.com/media/83392e107cbca7566b474593ed363efb/href</a></iframe><p>specs:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/424/1*_92i-08z5pEGp46TcDNCKA.png" /></figure><p><strong>Case 3: </strong>See preview with enabling background colour for that Composable:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e719b3660c1cefec1838caa0745910c1/href">https://medium.com/media/e719b3660c1cefec1838caa0745910c1/href</a></iframe><p><strong>Case 4: </strong>To test different user locales, you need to add the locale parameter:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6c8ca6bb9044074e066006005293f401/href">https://medium.com/media/6c8ca6bb9044074e066006005293f401/href</a></iframe><h4>MultiPreview Annotations rescue 🔥:</h4><p>Using MultiPreview, we can define multiple @Preview annotations and create a defined annotation that we can reuse instead of writing multiple Preview annotations every time. For example, you can use this annotation to preview multiple devices, font sizes, or themes simultaneously without repeating those definitions for every single composable.</p><p>See the example code below for how I created MultiPreview class to define reusable DevicePreviews annotation that we can reuse every time where we want multiple device preview</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f7265906e83bba27ed43f3f8fc4780c7/href">https://medium.com/media/f7265906e83bba27ed43f3f8fc4780c7/href</a></iframe><p>Using @DevicePreviews class:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5de2f66c138ecf1b7621f4edbc82ce81/href">https://medium.com/media/5de2f66c138ecf1b7621f4edbc82ce81/href</a></iframe><p>Output:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DJW7BS55JI2XvHR_3tbuQg.png" /></figure><p><strong>Spoiler alert </strong>🤯 <strong>!</strong></p><p>You can combine multiple multipreview annotations and normal preview annotations, to create a complete set of previews. Combining multipreview annotations doesn’t mean all the different combinations are shown. Instead, each multipreview annotation acts independently and renders only its variants.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e48f181071fb26caedfd6aa0c999f31f/href">https://medium.com/media/e48f181071fb26caedfd6aa0c999f31f/href</a></iframe><h4>Preview action menus🔥:</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sd4SfVwuLXeZ1NSxfB9-dg.png" /></figure><ol><li><strong>Animation Preview: </strong>Using this menu you can inspect animations defined using Jetpack Compose animation framework frame-by-frame. Currently, limited APIs are supported to view animation previews like updateTransition , AnimatedVisibility , CrossFade etc.</li><li><strong>Interactive Mode: </strong>Using this menu we can make a live preview of gestures like click events and check composable in a different state like the check button in enabled/disable mode:</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Iunfy5E1VZwIbfPae0erBg.gif" /></figure><p>3. <strong>Run Preview: </strong>Using this menu, we run individually composable in isolation mode on the testing device to see how that particular composable looks on a real device/emulator.</p><p><strong>Let’s take a look at the summary of what we have learned:</strong></p><ul><li>How we can enable the Jetpack Compose app for Preview</li><li>How we can use Preview Annotation for composable</li><li>How we can use multi preview to combine multiple Preview and reuse it</li><li>How to use Preview action menus</li></ul><h4>Wrap Up!</h4><p>So, that was pretty cool, right? This is all the stuff related to JetpackCompose Preview.</p><p>More you can learn at Android Studio support for Compose:</p><p><a href="https://developer.android.com/jetpack/compose/tooling">Android Studio support for Compose | Jetpack Compose | Android Developers</a></p><p><strong>Thanks for reading this article. Don’t forget to clap</strong>👏<strong>/recommend as much as you can and also share</strong>📤<strong> with your friends. It means a lot to me.</strong></p><p><strong><em>For more about programming, follow </em></strong><a href="https://medium.com/@pranaypatel"><strong><em>me</em></strong></a><strong><em> and </em></strong><a href="https://medium.com/@mutualmobile"><strong>MutualMobile Engineering</strong></a><strong><em>, so you’ll get notified whenever a new article is posted.</em></strong></p><p><strong>You can find our MutualMobile Engineering best articles </strong><a href="https://medium.com/@mutualmobile"><strong>here</strong></a><strong>.</strong></p><p><strong>Also, Let’s become friends on </strong><a href="https://twitter.com/pranaypatel_"><strong>Twitter</strong></a><strong>, </strong><a href="https://github.com/pranaypatel512"><strong>GitHub</strong></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=780a7cda52df" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mutualmobile/jetpack-compose-preview-like-a-pro-780a7cda52df">Jetpack Compose Preview like a pro!</a> was originally published in <a href="https://medium.com/mutualmobile">Mutual Mobile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Swift III: A beginner’s guide to Swift Charts]]></title>
            <link>https://medium.com/mutualmobile/swift-iii-a-beginners-guide-to-swift-charts-fe270aec36ca?source=rss----f5d3225ca8ce---4</link>
            <guid isPermaLink="false">https://medium.com/p/fe270aec36ca</guid>
            <category><![CDATA[charts]]></category>
            <category><![CDATA[mobile]]></category>
            <category><![CDATA[swift-charts]]></category>
            <category><![CDATA[apps]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Mutual Mobile]]></dc:creator>
            <pubDate>Mon, 12 Dec 2022 13:04:30 GMT</pubDate>
            <atom:updated>2022-12-12T13:04:30.649Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dh2WneVHekIMG-h5edGaEA.png" /></figure><p>What would developers do if Swift never existed? Act like disgruntled pelicans?</p><p>Jokes aside, Swift has become the vital tool of choice for developers for the benefits it brings to the table. And what works even more in Swift’s favor is the regular addition of exciting tools and features. Swift Charts is one such feature that was <a href="https://mutualmobile.com/blog/wwdc-2022-leading-us-to-the-promised-land">introduced at WWDC 2022</a>.</p><p>Data visualization has always helped simplify complex data sets while enhancing presentation. And now, with the help of Swift Charts, developers can implement the same in their apps.</p><h3>Introduction to Swift Charts</h3><p>So, <a href="https://developer.apple.com/documentation/charts">what is Swift Charts</a>? It is a powerful, flexible framework that can create aesthetically pleasing charts using little code. Like SwiftUI, it uses a declarative syntax. Hence, developers familiar with SwiftUI can seamlessly use Swift Charts.</p><p>Earlier, developers had to contend with external libraries for creating charts in their apps, but not anymore.</p><p>Swift Charts also provides out-of-the-box support for dark mode, device screen sizes, dynamic types, voiceover, audio graphs, localization, and multi-platform support. This exciting framework is available for Xcode 14, while also providing support for iOS 16+, macOS 13+, Mac Catalyst 16+, tvOS 16+, and watchOS 9+.</p><h3>Exploring Swift Charts</h3><p>Swift Charts is fun and exciting to use, and it comes with six default chart types called Marks. The six chart types are bar, line, point, area, rule, and rectangle. Additionally, these charts are extensible; hence they can be customized.</p><p>Now, let’s explore these charts with the help of an example.</p><p>Sip n Snacks is an Indian fast food restaurant that serves three types of dishes — dosa, paratha, and chaat. This restaurant is open to customers during morning and evening hours. So, let’s analyze their sales data during the weekdays with the help of charts. This analysis can help the restaurant to plan its staffing and procurement for the week as per the sales trends.</p><p>Let’s start by creating all the <em>enum types</em> that would be required:</p><ul><li><em>FoodItemType</em> enum with cases for dosa, paratha, and chaat as food items for sale.</li><li><em>WeekDaysType</em> enum with a case for each day of the week is created.</li><li><em>TimingType enum with cases for morning and evening hours.</em></li><li><em>ChartType</em> enum with cases for different chart types in Swift Charts.</li></ul><p>So, the image below shows the model code we will be implementing.</p><p><a href="https://gist.github.com/SahilMutualMobile/3b4cb73c87071b0e06a4bc80c3ce0185">https://gist.github.com/SahilMutualMobile/3b4cb73c87071b0e06a4bc80c3ce0185</a></p><p><strong>Code block 1: Model code</strong>‍</p><p>Next, we’ll create two data sets for morning and evening hours. For this, we’ll create two constants — <em>morningSales</em> and <em>eveningSales</em>, which are arrays of <em>RestaurantSales</em>.</p><p>Sample data code for <em>morningSales</em></p><p><a href="https://gist.github.com/SahilMutualMobile/3df034bb8029d9e2f0e6b1d5263eb023">https://gist.github.com/SahilMutualMobile/3df034bb8029d9e2f0e6b1d5263eb023</a></p><p><strong>Code block 2: morningSales sample data</strong>‍</p><p>Sample data code for <em>eveningSales</em></p><p><a href="https://gist.github.com/SahilMutualMobile/fe1912b57d228ecac52d2821380e1681">https://gist.github.com/SahilMutualMobile/fe1912b57d228ecac52d2821380e1681</a></p><p><strong>Code block 3: eveningSales sample data</strong>‍</p><p>So, now let’s explore the various types of charts.</p><h3>Bar charts</h3><p>The process to create a new chart in Swift starts off by defining a chart block. Additionally, you can also pass a data array within the rounded brackets. In this example, it is an array of <em>RestaurantSales</em>. Since we have to loop through the days of the week, we have to define a <em>ForEach</em> block for the <em>itemSales</em>.</p><p>Now, we can create a bar chart with a <em>BarMark</em> block, which will accept x and y coordinates for the graph. In this case, x axis is the days of the week while y axis is the sales numbers.</p><p>Since we need to show sales for the various food items, we’re adding a <em>foregroundStyle</em> modifier to the <em>BarMark</em> block with <em>foodItemName</em>. This will show different colors for each food item and Swift will automatically provide the colors for differentiation.</p><p><a href="https://gist.github.com/SahilMutualMobile/5dd167f747b8ada1b128af7c9ef25c0e">https://gist.github.com/SahilMutualMobile/5dd167f747b8ada1b128af7c9ef25c0e</a></p><p><strong>Code block 4: Bar chart code</strong>‍</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/293/0*ArW6_A6OnTnlEzpx.png" /><figcaption><strong>Image 1: Bar chart iPhone preview</strong></figcaption></figure><h4>Line, point, and rule charts</h4><p>Line charts in Swift are similar to bar charts with the only difference being the code block, which is shown as <em>LineMark</em>.</p><p>There is also an option to superimpose a point chart on a line chart by using a shorthand modifier to the <em>LineMark</em> code block. In this example, we are also superimposing another chart known as the <em>RuleMark</em>, with which we can represent a straight line in the x or y axes. Here, its being used to indicate a breakeven point in sales on the y axis.</p><p><a href="https://gist.github.com/SahilMutualMobile/224893cdb9abe2280e39e83cd9b13296">https://gist.github.com/SahilMutualMobile/224893cdb9abe2280e39e83cd9b13296</a></p><p><strong>Code block 5: Line chart code with symbol modifier and rule chart overlay</strong>‍</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/289/0*RM_dhJIPIZ2wWzXA.png" /><figcaption><strong>Image 2: Line chart with symbol modifier and rule chart overlay in iPhone preview</strong></figcaption></figure><h4>‍Area chart</h4><p>Like the <em>LineMark</em>, we can also create an area chart with an <em>AreaMark</em> block.</p><p><a href="https://gist.github.com/SahilMutualMobile/b70735017baac6601c84d6ad8a0d07a6">https://gist.github.com/SahilMutualMobile/b70735017baac6601c84d6ad8a0d07a6</a></p><p><strong>Code block 6: Area chart code</strong>‍</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/304/0*fiFb4PU_eqwz7h68.png" /><figcaption><strong>Image 3: Area chart iPhone preview</strong></figcaption></figure><h4>Rectangle chart</h4><p>Like the <em>LineMark</em>, we can also create an area chart with an <em>RectangleMark</em> block.</p><p><a href="https://gist.github.com/SahilMutualMobile/aca67f631be20a98be0021c042b25090">https://gist.github.com/SahilMutualMobile/aca67f631be20a98be0021c042b25090</a></p><p><strong>Code block 7: Rectangle chart code</strong>‍</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/307/0*bm-pndqxMRQ4cM94.png" /><figcaption><strong>Image 4: Rectangle chart iPhone preview</strong></figcaption></figure><h4>‍The beauty of Swift Charts</h4><p>Now, lets take a look at all the charts on a single screen. This can make the visual differences between the various charts easy to understand. Swift Charts provides us with automatic animations during chart transitions, but we have implemented a custom <em>easeIn </em>animation in this case.</p><p><a href="https://gist.github.com/SahilMutualMobile/d4e1d4e24444db09133cee2f972853bf">https://gist.github.com/SahilMutualMobile/d4e1d4e24444db09133cee2f972853bf</a></p><p><strong>Code block 8: All charts in one screen code</strong>‍</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/0*VyVGmiAxaVE3SWLH.gif" /><figcaption><strong>Image 5: Preview for all charts on iPhone</strong></figcaption></figure><p>‍As you can see Swift Charts is fun to use and also adds an <a href="https://mutualmobile.com/blog/the-newest-way-to-showcase-your-app-app-clips">interesting feature in iOS apps</a>, which helps enhance user experience.</p><p>And that ends the three-part series of our adventures with Swift. So, if you’re looking for an app to be built for iOS, we’d love to hear from you and bounce ideas off together.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fe270aec36ca" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mutualmobile/swift-iii-a-beginners-guide-to-swift-charts-fe270aec36ca">Swift III: A beginner’s guide to Swift Charts</a> was originally published in <a href="https://medium.com/mutualmobile">Mutual Mobile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Swift II — WWDC 2022 heralding a new dawn for Generics?]]></title>
            <link>https://medium.com/mutualmobile/swift-ii-wwdc-2022-heralding-a-new-dawn-for-generics-518b52f9f152?source=rss----f5d3225ca8ce---4</link>
            <guid isPermaLink="false">https://medium.com/p/518b52f9f152</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[apple]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[generics]]></category>
            <category><![CDATA[wwdc]]></category>
            <dc:creator><![CDATA[Mutual Mobile]]></dc:creator>
            <pubDate>Thu, 08 Dec 2022 16:58:50 GMT</pubDate>
            <atom:updated>2022-12-08T16:58:50.376Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gUB_VaK1CkIXtGAcCseSXQ.png" /></figure><h3>Swift II — WWDC 2022 heralding a new dawn for Generics?</h3><p>Apple doing something new at the WWDC. Well, that shouldn’t come as a surprise at all.</p><p>That being said, Generics got its share of extra attention and shot into the limelight due to WWDC 2022.</p><p>Now, coming back to the <a href="https://mutualmobile.com/blog/wwdc-2022-leading-us-to-the-promised-land">highlights of WWDC 2022</a>, Apple announced exciting new additions to Generics as part of Swift 5.7, leading to it getting its day in the sun.</p><h4>Generics in Swift 5.7</h4><p>So, what are these new additions to Generics in Swift 5.7 that got developers excited?</p><ul><li>The usage of some keywords in parameter position.</li><li>The usage of any keyword with a protocol having associated types.</li><li>The unboxing of underlying concrete types to access type-specific relationships.</li></ul><p>It’s also important to note that these were released with Xcode version 14. So, let’s explore these new additions with our <a href="https://mutualmobile.com/blog/swift-i-is-generics-the-quarterback-of-swift-programming">pizza shop example</a>; you remember that, don’t you?</p><h4>Protocol with associated type</h4><p>An associated type gives a placeholder name to a type that is used as part of the protocol. Using our pizza shop example, we start by creating <em>PizzaTopping</em> enum that will have various pizza toppings.</p><p><a href="https://gist.github.com/SahilMutualMobile/a8ddaca0641834585d90fd296cbaca2c">https://gist.github.com/SahilMutualMobile/a8ddaca0641834585d90fd296cbaca2c</a></p><p>Next, we create a protocol <em>RestaurantItem </em>that will have an <em>associatedtype Message</em>, which has a default type of <em>String</em>. Also, we have defined two methods — <em>acceptOrderItem</em> and <em>prepareOrderItem, </em>and both return <em>Message </em>type.</p><p>We will use this <em>RestaurantItem </em>protocol to create concrete products. For our example, we will also create <em>PizzaType</em>, <em>SideDishType</em>, and <em>DrinkType </em>types that conform to <em>RestaurantItem</em>.</p><p><a href="https://gist.github.com/SahilMutualMobile/dca02c7ad9c31266508cdc56c0a3001d">https://gist.github.com/SahilMutualMobile/dca02c7ad9c31266508cdc56c0a3001d</a></p><h4>Pizza product</h4><p>Here, we’ll create a concrete product for three types of pizza — Margherita, farmhouse, and golden corn. We start by creating an enum <em>PizzaType </em>that conforms to <em>String </em>and <em>RestaurantItem </em>protocol while defining three cases for the three types of pizzas. Additionally, a variable type called <em>toppings </em>is introduced, which will hold an array of <em>PizzaTopping </em>depending on the case of the enum instance.</p><p>We also need to implement the two methods from <em>RestaurantItem </em>protocol, <em>acceptOrderItem</em>, and <em>prepareOrderItem</em>. This is because these functions will form an appropriate string based on the pizza selection and return the <em>String</em>.</p><p><a href="https://gist.github.com/SahilMutualMobile/137f879f55e78bf18ed57d12c8e46409">https://gist.github.com/SahilMutualMobile/137f879f55e78bf18ed57d12c8e46409</a></p><h4>Side dish product</h4><p>Similarly, we also create a <em>SideDishType </em>that conforms to <em>String </em>and <em>RestaurantItem </em>protocol.</p><p>Furthermore, we also define two cases for fries and calzone while implementing the <em>acceptOrderItem </em>and <em>prepareOrderItem </em>methods.</p><p><a href="https://gist.github.com/SahilMutualMobile/f24ed9e30dc8cc66c80efccc6ff38a44">https://gist.github.com/SahilMutualMobile/f24ed9e30dc8cc66c80efccc6ff38a44</a></p><h4>Drinks product</h4><p>Continuing in the same vein, we create <em>DrinkType </em>that conforms to <em>String </em>and <em>RestaurantItem </em>protocol.</p><p>We also define two cases for soda and lemonade while implementing the <em>acceptOrderItem </em>and <em>prepareOrderItem </em>methods.</p><p><a href="https://gist.github.com/SahilMutualMobile/b3e1c5e35d073094e55052c867bf44cf">https://gist.github.com/SahilMutualMobile/b3e1c5e35d073094e55052c867bf44cf</a></p><h4>Implementation of the pizza shop</h4><p>Here, we have created a new class called <em>PizzaShop</em>. To proceed, we also declare a variable <em>orderNumber </em>to keep track of the order number.</p><p>To attract customers to our pizza store, we launch an offer for customers, where they can buy one item and get the second for free. To do this, we create a method called <em>onePlusOneOffer, </em>which accepts <em>some restaurant</em> parameter. Before the <a href="https://www.swift.org/blog/swift-5.7-released/">launch of Swift 5.7</a>, this feature wasn’t available, so let’s thank the Swift gods 😆</p><p>This method will accept any type that conforms to <em>RestaurantItem</em>. Once this is done, we can just print the output of <em>acceptOrderItem </em>and <em>prepareOrderItem </em>twice within a loop. Additionally, we also increase the order number and print the order start and order complete messages.</p><p>The pizza shop also needs another method that can accept a happy meal-like combo that includes a pizza, a side dish, and a drink in one order. It should also be able to create a custom order of any combination of restaurant items. To do this, we create a single method called <em>mealOrder</em>. This method will accept an array of any <em>RestaurantItem</em>. This capability was also not present before Swift 5.7.</p><p>Within this method, we can also loop through the array and print the <em>acceptOrderItem </em>and <em>PrepareOrderItem </em>messages.</p><p>The third new feature in Generics as part of Swift 5.7 allows the compiler to unwrap the concrete type from any abstract type definition and call the correct concrete type implementation. Thus, we can print the start and end of the order while increasing the <em>orderNumber </em>property.</p><p><a href="https://gist.github.com/SahilMutualMobile/970ec5be8e973874854e588131fbbc18">https://gist.github.com/SahilMutualMobile/970ec5be8e973874854e588131fbbc18</a></p><h4>Client usage</h4><p>Now, we’ll create two constants of any <em>RestaurantItem </em>array for the happy meals. We instantiate <em>PizzaShop </em>class and call the <em>mealOrder </em>method and pass the happy meal constants or any custom order array.</p><p>And, when we call the <em>onePlusOneOffer </em>method and pass an order for any item in the parameter, we can get one extra item with each item ordered.</p><p><a href="https://gist.github.com/SahilMutualMobile/c561be825267746e4209a1088ed514bb">https://gist.github.com/SahilMutualMobile/c561be825267746e4209a1088ed514bb</a></p><h4>The bottom line</h4><p>With the aforementioned <a href="https://www.wwdcnotes.com/notes/wwdc22/110352/">updates to Generics in Swift 5.7</a>, quite a few limitations have been lifted, making it more relevant and usable in Swift codebases.</p><p>Now, you can go forth and make Generics prosper in Swift using these features. Just don’t use our pizza shop example 😆</p><p>The story around Swift doesn’t end here, as we conclude the Swift series with an exciting sneak peek into the intriguing world of SwiftUI charts, so stay tuned!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=518b52f9f152" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mutualmobile/swift-ii-wwdc-2022-heralding-a-new-dawn-for-generics-518b52f9f152">Swift II — WWDC 2022 heralding a new dawn for Generics?</a> was originally published in <a href="https://medium.com/mutualmobile">Mutual Mobile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Native vs Hybrid Apps: Who’s the Loser? | Mutual Mobile]]></title>
            <link>https://medium.com/mutualmobile/native-vs-hybrid-apps-whos-the-loser-mutual-mobile-27e83cd09ee?source=rss----f5d3225ca8ce---4</link>
            <guid isPermaLink="false">https://medium.com/p/27e83cd09ee</guid>
            <category><![CDATA[native-app-vs-hybrid-app]]></category>
            <category><![CDATA[web-apps]]></category>
            <category><![CDATA[native-application]]></category>
            <category><![CDATA[hybrid-application]]></category>
            <category><![CDATA[cross-platform-apps]]></category>
            <dc:creator><![CDATA[Mutual Mobile]]></dc:creator>
            <pubDate>Wed, 16 Nov 2022 11:10:26 GMT</pubDate>
            <atom:updated>2022-11-16T11:10:26.086Z</atom:updated>
            <content:encoded><![CDATA[<h3>The good, the bad, the hybrid: Why native apps work</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7fH_fZkMq7-1vriY9WB9sg.png" /></figure><p>One is faster to build but tougher to maintain. The other is slower to build but cheaper to maintain. But which is the best bet for your business?</p><p><a href="https://www.pewresearch.org/internet/fact-sheet/mobile/">Smartphones are the most personal devices</a> we have today.‍</p><p>Double-checking your pocket. Controlling your home with it. Connecting, playing, earning. All roads lead back to that slab of glass and silicon nestled in your pocket.</p><p>On a device that’s so personal, you can’t afford to waste your time with sloppy interfaces and buggy apps. It ruins the idea of smartphones for most users — especially <a href="https://nextbillionusers.google/research/">Google’s next billion users</a> for whom the devices may become unapproachable.</p><p>That’s why designing the right experience for apps installed on a device is so crucial.</p><p>It isn’t just about App Store or Play Store ratings — it’s about setting a direction for the future of every user’s experience.‍</p><p>So when an onus of such magnitude rests on a stressed developer or business owner trying to make the right decisions for their company’s app, the choices among the multiple platforms that await them can get overwhelming.</p><p>That’s exactly what we had in mind when we developed this quick-and-easy guide to understanding the advantages and disadvantages of hybrid and native apps.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*r12HwVd2WvBDdZ8t.png" /></figure><h3>What are native and hybrid apps?</h3><p>Native apps are written in your device’s OS languages: Objective-C/<a href="https://mutualmobile.com/blog/swift-i-is-generics-the-quarterback-of-swift-programming">Swift for iOS</a> and Java/Kotlin for Android. Hybrid apps are websites dressed like apps with quite a few pros and cons. For instance, they work across iOS and Android but suffer in overall build quality and compatibility.‍</p><h3>What are the advantages of hybrid apps?</h3><p>Despite their issues, hybrid apps have a few perks:</p><ul><li>A shared codebase devs can maintain across platforms.</li><li>Larger dev community that contributes to open frameworks.</li><li>HTML-friendly base allows them to handle APIs and the backend better.</li><li>An application developed once is done forever across multiple platforms.‍</li></ul><h3>The disadvantages of hybrid apps over native apps</h3><h4>Design language</h4><p><a href="https://material.io/design">Google’s Material Design</a> changed the game for Android apps. Its clear hierarchies and creative user interface guidelines moved Android away from a one-size-fits-all approach and closer to iOS’s <a href="https://developer.apple.com/design/human-interface-guidelines/guidelines/overview/">Human Interface Guidelines</a> (HIG) system. Moreover, each device uses its own browser to render the hybrid app’s web elements.‍</p><h4>High maintenance costs</h4><p>All hybrid apps still need bridges between native operations and their HTML-based processes. Although there are plug-and-play hooks out there with <a href="https://mutualmobile.com/blog/handbook-for-navigation-in-flutter">programming languages like Flutter</a>, React Native, Xamarin, and Ionic, these usually lag behind native OS releases. This inflates maintenance costs and threatens to capsize the product’s development lifecycle.‍</p><h4>Lack of reliable support</h4><p>Hybrid libraries aren’t the best when it comes to supporting third-party SDKs. And it’s the same the other way round. The HTML elements in hybrid apps power its functionality and interaction within a native wrapper — making regular support updates a complex maneuver. ‍</p><h4>Performance issues</h4><p>Granted hybrid apps have come a long way in looking and working like native apps. But the app gets increasingly more unstable as its feature list grows. Moreover, hybrid apps are hugely dependent on internet connectivity and a web browser. They struggle to live up to performance mandates when offline.‍</p><h3>Hybrid apps in the long run</h3><p>On the whole, <a href="https://clearbridgemobile.com/a-breakdown-of-hybrid-vs-native-mobile-app-development-costs-2/">hybrid apps cost more</a> than custom ones in the long run. And that’s without the native-like responsiveness mobile platform users seek today.</p><p>Lower upfront costs are offset by higher development costs later in the life cycle. Granted, hybrid apps are easier to get off the ground. But they’re just as hard to keep up in the air.</p><p>The fast start and early wins hybrid apps afford devs in the beginning of the lifecycle give way to bottlenecks and development manholes later on.‍</p><h3>What are the advantages of native apps?</h3><p>Designed to fit your device’s OS to the last pixel, native apps offer a huge performance and UX leap over hybrid apps. They also keep costs stable, the life cycle predictable, and updates regular. All to a vastly greater degree than hybrid apps.</p><p>In fact, in the case of most enterprise apps, native apps end up costing less than hybrid apps in the long run, thanks to more <a href="https://mutualmobile.com/blog/3-ways-the-product-lifecycle-has-changed-user-research-2">predictable development lifecycles</a>.</p><p>Largely, their advantages are:‍</p><h4>Richer UX</h4><p>Native apps match the OS down to the last pixel. They run directly on top of the OS. Native apps extract more from the hardware and optimize resources a lot better. The resulting user experience is smooth and cohesive–with apps that feel well integrated with one’s device.‍</p><h4>Maximum hardware performance</h4><p>Native apps also afford users better hardware functionality than hybrid apps. It harnesses a smartphone’s resources more efficiently and rides comfortably atop the OS. This ensures the user’s experience isn’t marred by crashes, connectivity issues, and random errors–all huge factors in boosting user retention.‍</p><h4>Cheaper to maintain</h4><p>OS updates are ridiculously easy to apply to native apps. In fact, most of your native app’s updates can be handled quietly in the backend–making for a seamless user experience. And when businesses factor in the ease of maintenance with native apps, they find them cheaper than hybrid apps in the long run.‍</p><h4>Unbeatable app access</h4><p>Everything from the device’s camera, microphone, calendar, GPS, fingerprint sensors, and motion sensors work perfectly with native apps. Users can hop and skip their way through the app without pausing to let it load and work.‍</p><h3>Verdict: Native apps or hybrid apps?</h3><p>For every business looking to build a user-centric app, there simply is no competition on the hybrid front.</p><p>Native apps offer a smoother experience for both businesses and their customers.</p><p>In fact, you are more likely to spend time fixing and tweaking the app because of user complaints about UI elements and performance driven issues when working with a hybrid app.</p><p>Although native apps have larger upfront costs, they end up saving you more money in the long run while offering an unbeatable user experience and an industry standard app performance.‍</p><p>Our verdict: Native apps win over hybrid apps.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=27e83cd09ee" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mutualmobile/native-vs-hybrid-apps-whos-the-loser-mutual-mobile-27e83cd09ee">Native vs Hybrid Apps: Who’s the Loser? | Mutual Mobile</a> was originally published in <a href="https://medium.com/mutualmobile">Mutual Mobile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Biometric authentication with cryptography in Android | Mutual Mobile]]></title>
            <link>https://medium.com/mutualmobile/biometric-authentication-with-cryptography-in-android-mutual-mobile-be8f29578192?source=rss----f5d3225ca8ce---4</link>
            <guid isPermaLink="false">https://medium.com/p/be8f29578192</guid>
            <category><![CDATA[biometric-authentication]]></category>
            <category><![CDATA[decryption]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[cryptography]]></category>
            <category><![CDATA[encryption]]></category>
            <dc:creator><![CDATA[Mutual Mobile]]></dc:creator>
            <pubDate>Fri, 28 Oct 2022 07:02:21 GMT</pubDate>
            <atom:updated>2022-10-28T07:02:21.188Z</atom:updated>
            <content:encoded><![CDATA[<h3>Biometric authentication in Android II: The cryptographic twist</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RmrY8vRy-AxY4UscmiHIyQ.png" /></figure><p>Remember about the ‘ANARCHIC’ future we discussed recently? You know, where we spoke about developers, app aesthetics, and app security.</p><p>Well, this would prevent you from even imagining that alternate universe (or what if its multiverse scenario?) Okay, enough jokes 😛</p><p>So, how?</p><p>As promised (we didn’t solemnly swear, but still 😛), we’re back with the sequel to the <a href="https://mutualmobile.com/blog/biometric-authentication-in-android-a-primer">biometric authentication in Android</a>.</p><p>And this time, cryptography joins the bandwagon of enhancing app security. <br>‍</p><p>But first, <a href="https://www.digicert.com/support/resources/faq/public-trust-and-certificates/what-is-cryptography-and-a-cryptographic-algorithm--">what is cryptography</a>? It is a technique used to secure sensitive data with algorithms that helps ensure the authenticity of data, which cannot be accessed without a secret key. This helps in preventing unauthorized users from reading the encrypted data.</p><p>So now, since you know what’s cryptography, let’s get our hands dirty with the AndroidX Biometric API and cryptography.</p><p>‍</p><h3>AndroidX Biometric API and Cryptography</h3><p>As we mentioned in the first article of this series, the AndroidX Biometric API is a comprehensive solution for handling biometric authentication in Android applications. This API authenticates users with the help of biometrics and device credentials.</p><p>Another key aspect of this API is that it includes an exciting feature known as CryptoObject, which can be used to <a href="https://developer.android.com/reference/androidx/biometric/BiometricPrompt.CryptoObject">incorporate cryptography in the authentication flow</a>. The AndroidX Biometric API supports cryptographic solutions like Signature, Cipher, and Mac. Here, we’ll be focusing on Cipher.<br>‍</p><p>After successful authentication with the biometric prompt, we can further <a href="https://mutualmobile.com/blog/how-is-block-store-redefining-user-app-security">enhance app security</a> with a cryptographic operation. How, you ask?</p><p>By using a <em>SecretKey</em> object to perform encryption and decryption while authenticating with the Cipher object.</p><p>So, let’s see how biometric authentication and cryptography work together in an Android framework.‍</p><h3>Cryptography and key management</h3><p>As mentioned above, a cryptography-based authentication can be carried out using a Cipher object that enables the encryption and decryption of data. To use Cipher, we have to generate a <em>SecretKey. </em>This key can be used by authorized personnel to protect the data.</p><p>In <a href="https://mutualmobile.com/blog/google-i-o-2022-7-things-you-cant-miss">the Android ecosystem</a>, these keys are stored in the <em>KeyStore</em>. This does the job of storing these keys at secure locations.</p><p>In case, an app requests the <em>SecretKey</em>, the <em>KeyStore</em> provides an alias of the key, instead of the actual <em>SecretKey</em> itself. Only the <em>KeyStore</em> is capable of providing an alias of the <em>SecretKey</em>, which helps in boosting reliability and security.</p><p>When the app wants to encrypt data, the <em>KeyStore</em> does that using the alias while providing us with the ciphertext, which is basically the encrypted data. The same also takes place when the app wants to decrypt the encrypted data.</p><p>Here’s how it takes place:</p><pre>fun generateSecretKey(keyGenParams: KeyGenParameterSpec) {<br>    val keyGenerator = KeyGenerator.getInstance(<br>            KeyProperties.KEY_ALGORITHM_AES, &quot;AndroidKeyStore&quot;)<br>    keyGenerator.init(keyGenParams)<br>    keyGenerator.generateKey()<br>}</pre><pre>fun getSecretKey(): SecretKey {<br>    val keyStore = KeyStore.getInstance(&quot;AndroidKeyStore&quot;)</pre><pre>    // keyStore must be loaded before accessing it.<br>    keyStore.load(null)<br>    return keyStore.getKey(KEY_NAME, null) as SecretKey<br>}</pre><pre>fun getCipher(): Cipher {<br>    return Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + &quot;/&quot;<br>            + KeyProperties.BLOCK_MODE_CBC + &quot;/&quot;<br>            + KeyProperties.ENCRYPTION_PADDING_PKCS7)<br>}</pre><h3>Authenticating using only biometric credentials</h3><p>If an app uses a <em>SecretKey</em> that needs biometric credentials to unlock, users have to authenticate their biometric credentials every time before the app accesses the <em>SecretKey</em>.</p><p>Here’s how to enable this with a few steps.</p><h4>Step 1</h4><p>Generate a key using the <em>KeyGenParameterSpec</em> configuration, we use a builder for that:</p><pre>fun getKeyGenParams(): KeyGenParameterSpec {<br>return KeyGenParameterSpec.Builder(<br>        KEY_NAME,<br>        KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)<br>        .setBlockModes(KeyProperties.BLOCK_MODE_CBC)<br>        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)<br>        .setUserAuthenticationRequired(true)<br>        // Invalidate the keys if the user has registered a new biometric<br>        // credential, such as a new fingerprint.<br>        .setInvalidatedByBiometricEnrollment(true)<br>        .build()<br>}‍</pre><h4>Step 2</h4><p>Start the biometric authentication workflow using a cipher:</p><pre>fun authenticateToEncrypt() {<br>    val cipher = getCipher()<br>    val secretKey = getSecretKey()<br>    cipher.init(Cipher.ENCRYPT_MODE, secretKey)<br>    biometricPrompt.authenticate(promptInfo,<br>            BiometricPrompt.CryptoObject(cipher))<br>}‍</pre><h4>Step 3</h4><p>Use the <em>SecretKey</em> to encrypt the sensitive data inside biometric authentication callbacks:</p><pre>override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {<br>    val cipher = result.cryptoObject?.cipher<br>    val plainText = &quot;Some data to encrypt&quot;<br>    val encryptedInfo: ByteArray =cipher?.doFinal(<br>      plaintext.toByteArray(Charset.defaultCharset())<br>    )<br>    Log.d(&quot;TAG&quot;, &quot;Encrypted information: &quot; +  Arrays.toString(encryptedInfo))<br>}‍</pre><h3>Authenticating using biometric or lock screen credentials</h3><p>If an <a href="https://developer.android.com/reference/javax/crypto/SecretKey">app uses a <em>SecretKey</em></a> that needs biometric or lock screen credentials (password, pattern, or PIN) to unlock, then a validity time period must be specified. This validity allows the app to perform multiple cryptographic operations without re-authenticating the user.</p><p>To use this type of key, we have to add a fallback to non-biometric credentials. Hence, we cannot pass an instance of <em>CryptoObject</em> in the <em>authenticate()</em> function of the <em>BiometricPrompt</em>.</p><p>Here’s how this type of authentication takes place.</p><h4>Step 1</h4><p>Generate a key using the <em>KeyGenParameterSpec</em> configuration:</p><pre>val keyGenParams = KeyGenParameterSpec.Builder(<br>            KEY_NAME,<br>            KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)<br>            .setBlockModes(KeyProperties.BLOCK_MODE_CBC)<br>            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)<br>            .setUserAuthenticationRequired(true)<br>            .setUserAuthenticationParameters(<br>                 VALIDITY_DURATION_IN_SECONDS, ALLOWED_AUTHENTICATORS<br>         )<br>        .build()</pre><p>‍</p><h4>Step 2</h4><p>Encrypt the sensitive information within a time span of <em>VALIDITY_DURATION_SECONDS</em> after the user authenticates successfully:</p><pre>fun encryptSensitiveData() {<br>    val cipher = getCipher()<br>    val secretKey = getSecretKey()<br>    try {<br>        cipher.init(Cipher.ENCRYPT_MODE, secretKey)<br>        val encryptedInfo: ByteArray = cipher.doFinal(<br>                plaintext-string.toByteArray(Charset.defaultCharset()))<br>        Log.d(&quot;TAG&quot;, &quot;Encrypted information: &quot; + Arrays.toString(encryptedInfo))<br>    } catch (e: InvalidKeyException) {<br>        Log.e(&quot;TAG&quot;, &quot;Key is invalid.&quot;)<br>    } catch (e: UserNotAuthenticatedException) {<br>        Log.d(&quot;TAG&quot;, &quot;The key&#39;s validity timed out.&quot;)<br>        biometricPrompt.authenticate(promptInfo)<br>    }</pre><p>To add the aforementioned callback, we can mention that the app supports device credentials by including <em>DEVICE_CREDENTIAL</em> into the set of values passed for <em>setAllowedAuthenticators()</em>.‍</p><h3>Authenticating using auth-per-use keys</h3><p>Users also have the option to integrate auth-per-keys within the instance of the <em>BiometricPrompt</em>. Auth-per-keys are secret keys that are used to perform a single cryptographic operation. For example, if you have to carry out 5 cryptographic operations, you’ll need 5 auth-per-keys.</p><p>Due to its immense security benefits, auth-per-keys offer exciting use cases such as making large payments or updating transaction statement records.</p><p>To incorporate an auth-per-key within the <em>BiometricPrompt</em>, we can generate the following <em>KeyGenParameterSpec</em> configuration:</p><pre>val authPerUseKeyGenParams =<br>        KeyGenParameterSpec.Builder(&quot;myKeystoreAlias&quot;, key-purpose)<br>    // Accept either a device credential or a biometric credential.<br>    // To accept only one type of credential, include only that type as the second argument.<br>    .setUserAuthenticationParameters(0 /* duration */,<br>            KeyProperties.AUTH_BIOMETRIC_STRONG or<br>            KeyProperties.AUTH_DEVICE_CREDENTIAL)<br>    .build()</pre><h3>Authenticating without explicit user interaction</h3><p>In some cases, users might not need to confirm the authentication process. Here, the users can interact with the app more quickly after re-authenticating using face or fingerprint recognition.</p><p>To implement this, pass false into the <em>setConfirmationRequired()</em> function in <em>PromptInfo Builder</em>.</p><pre>fun getBiometricPromptInfo(<br>    title: String = &quot;Biometric login&quot;,<br>    subtitle: String = &quot;Log in using your biometric credential&quot;,<br>    negativeButtonText = &quot;Use account password&quot;,<br>isConfirmationRequired = false<br>): BiometricPrompt.PromptInfo {</pre><pre>  val builder = BiometricPrompt.PromptInfo.Builder()<br>      .setTitle(title)<br>      .setSubtitle(subtitle)<br>      .setNegativeButtonText(negativeButtonText)<br>      .setConfirmationRequired(isConfirmationRequired)<br>  return builder.build()<br>}</pre><p>And that’s how you can build a passwordless secure solution for authentication using <em>BiometricPrompt </em>and cryptography.</p><p>With passwordless solutions getting all the attention in recent times, stay tuned for our take on this exciting and potentially game-changing trend!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=be8f29578192" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mutualmobile/biometric-authentication-with-cryptography-in-android-mutual-mobile-be8f29578192">Biometric authentication with cryptography in Android | Mutual Mobile</a> was originally published in <a href="https://medium.com/mutualmobile">Mutual Mobile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Biometric authentication in Android | Mutual Mobile]]></title>
            <link>https://medium.com/mutualmobile/biometric-authentication-in-android-mutual-mobile-d683c10bbd12?source=rss----f5d3225ca8ce---4</link>
            <guid isPermaLink="false">https://medium.com/p/d683c10bbd12</guid>
            <category><![CDATA[api]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[biometric-authentication]]></category>
            <category><![CDATA[api-development]]></category>
            <dc:creator><![CDATA[Mutual Mobile]]></dc:creator>
            <pubDate>Fri, 14 Oct 2022 11:39:39 GMT</pubDate>
            <atom:updated>2022-10-14T11:39:39.396Z</atom:updated>
            <content:encoded><![CDATA[<h3>Biometric authentication in Android: A primer</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4_46548elJk5M0Xy4zuhyA.png" /></figure><p>How would the future look if app developers only focused on making sure apps were aesthetically pleasing and fun to use, without complete regard for app security?</p><p>ANARCHIC!‍</p><p>Hence, it is crucial for developers to also focus carefully on enhancing app security along with user productivity. One of the most secure manners of boosting app security and safeguarding user data is with the help of biometric authentication, such as <a href="https://mutualmobile.com/blog/in-code-we-trust">facial or fingerprint recognition</a>.‍</p><h3>Biometric authentication with AndroidX Biometric API</h3><p>Biometric authentication allows users to unlock their mobile devices using fingerprint or facial recognition. This helps in ensuring that the right person is accessing the mobile device.</p><p>Now, let’s explore <a href="https://developer.android.com/reference/androidx/biometric/package-summary">biometric authentication in Android</a> using an API (application programming interface).</p><p>AndroidX Biometric API is a comprehensive solution for handling biometric authentication in Android applications. This API authenticates users with the help of biometrics and device credentials, while performing cryptographic operations. This API can be integrated easily into any Android project by adding it as a dependency.</p><p>Here’s how it can be done in the build.gradle file of your app module:</p><pre>dependencies {<br>…<br>    implementation &quot;androidx.biometric:biometric-ktx:1.2.0-alpha04&quot;<br>…<br>}‍</pre><h3>Features of AndroidX Biometric API</h3><ul><li>Analyses if a device possesses biometric authentication capabilities.</li><li>Provides a standard biometric prompt for facial or fingerprint recognition.</li><li>Provides callbacks for failed or successful authentication attempts.</li><li>Provides choices for pins, passwords, or patterns, in case you do not want to opt for biometric credentials.‍</li></ul><h3>AndroidX Biometric API and device capability</h3><p>Since the<a href="https://medium.com/@sifat.oshan/androidx-biometric-overview-3682da73f638"> AndroidX Biometric API</a> is relatively new and not all devices possess biometric capabilities, it becomes necessary to check if a particular device is capable. The following extension function can be used to check biometric authentication capabilities:</p><pre>fun Context.isBiometricCapable() : Int {<br>   val biometricManager = BiometricManager.from(this)<br>   biometricManager.canAuthenticate()<br>}</pre><p>In this above scenario, we created a <em>BiometricManage</em>r using the provided context that would assist <em>canAuthenticate()</em> in determining whether the hardware has biometric authentication capabilities.</p><p>In some cases, devices may possess the requisite hardware for biometric authentication, but this <em>BiometricPrompt</em> can only be employed if users have registered their biometric information in their devices’ security settings.</p><p>Moving on, if the <em>canAuthenticate()</em> is implemented, it will return the following results:</p><ul><li><strong>BIOMETRIC_SUCCESS</strong>: The device is ready to use a biometric prompt, implying the device is compatible with biometric software, and the user has added their biometric data to the device’s settings.</li><li><strong>BIOMETRIC_ERROR_NONE_ENROLLED</strong>: The device supports biometrics, but the user has not added their facial or fingerprint data.</li><li><strong>BIOMETRIC_ERROR_NO_HARDWARE</strong>: The device hardware is not capable of biometric authentication.</li><li><strong>BIOMETRIC_ERROR_HW_UNAVAILABLE</strong>: Biometric features are currently unavailable.‍</li></ul><h3>Types of authentications in AndroidX Biometric API</h3><p>Once you have completed the authentication process, you can check the authentication type by calling <em>getAuthenticationType()</em> to see if the user has authenticated using a device or biometric credential.</p><p>In this case, the <em>getAuthenticationType()</em> will provide the following results:</p><ul><li><strong>AUTHENTICATION_RESULT_TYPE_UNKNOWN</strong>: The authentication type is unknown.</li><li><strong>AUTHENTICATION_RESULT_TYPE_DEVICE_CREDENTIAL</strong>: The user has authenticated using device credentials.</li><li><strong>AUTHENTICATION_RESULT_TYPE_BIOMETRIC</strong>: The user has authenticated using device biometric authentication.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*VvHmN95xiLnKG03K.png" /></figure><h3>Building the biometric login prompt</h3><p>Once we have determined that the user’s device has been authenticated, we can display a default system prompt requesting the user to authenticate using biometric credentials. This system-generated prompt is consistent across the apps that use it, thus <a href="https://mutualmobile.com/blog/ux-design-to-interaction-design-you-can-stand-under-my-umbrella">creating a seamless user experience</a>.</p><p>Here’s how you can show the login prompt:</p><ul><li>First, use <em>PromptInfo</em> to configure the desired messages and actions.</li><li>Then, Activity and Callback Handlers are used to initialize the <em>BiometricPrompt<br>‍</em></li></ul><h4>Step 1</h4><p>The <em>PromptInfo</em> is developed using a builder class, <em>BiometricPrompt.PromptInfo.Builder</em>, which also populates it with the title, subtitle, and description.</p><pre>fun getBiometricPromptInfo(<br>    title: String,<br>    subtitle: String,<br>    description: String<br>): BiometricPrompt.PromptInfo {</pre><pre>  val builder = BiometricPrompt.PromptInfo.Builder()<br>      .setTitle(title)<br>      .setSubtitle(subtitle)<br>      .setDescription(description)</pre><pre>  return builder.build()<br>}‍</pre><h4>Step 2</h4><p>Now, you can initialize the <em>BiometricPrompt</em> and handle the callbacks with a custom listener from the calling activity.</p><pre>fun initBiometricPrompt(<br>    activity: AppCompatActivity,<br>    listener: BiometricAuthListener<br>): BiometricPrompt {<br>  val executor = ContextCompat.getMainExecutor(activity)</pre><pre>  val callback = object : BiometricPrompt.AuthenticationCallback() {<br>    <br>      override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {<br>         super.onAuthenticationError(errorCode, errString)<br>         listener.onBiometricAuthenticationError(errorCode, errString.toString())<br>     }</pre><pre>    override fun onAuthenticationFailed() {<br>      super.onAuthenticationFailed()<br>      Log.w(this.javaClass.simpleName, &quot;Authentication failed for an unknown reason&quot;)<br>    }</pre><pre>    override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {<br>      super.onAuthenticationSucceeded(result)<br>      listener.onBiometricAuthenticationSuccess(result)<br>    }<br>  }</pre><pre>  return BiometricPrompt(activity, executor, callback)<br>}</pre><p>What does the above <a href="https://mutualmobile.com/blog/whats-the-fuss-about-static-code-analysis">code snippet in Android</a> achieve? It creates an executor to handle callback events and the callback object to obtain authentication events on Error, Failed, or Success. Then it updates custom listener methods with results and error messages. Finally, it returns a biometric prompt using the activity instance, executor, and callback reference.</p><p>You might be now wondering how to display the biometric prompt. Here’s how it’s done:</p><ul><li>First, we need to <em>setBiometricPromptInfo()</em> by passing the title, subtitle, and description.</li><li>Then we need to initialize the <em>BiometricPrompt</em> using <em>initBiometricPrompt()</em> by passing calling Activity Instance and custom callback listener instance.</li><li>And finally, we show the prompt using the authenticate method by passing <em>promptInfo biometricPrompt.authenticate(promptInfo)</em>.</li></ul><pre>fun initBiometricPrompt() {</pre><pre>val promptInfo = getBiometricPromptInfo(title, subtitle, description) <br>val biometricPrompt = initBiometricPrompt(this, biometricAuthListener) </pre><pre>biometricPrompt.authenticate(promptInfo)</pre><pre>}</pre><p>And that is how you can build a biometric passwordless solution using <em>BiometricPrompt</em>. Now, isn’t that awesome?</p><p>You also can further boost app security and sensitive data (and yes, we thought it best to surprise you with this 😆). So, now, coming to the question on your mind, <a href="https://mutualmobile.com/blog/how-is-block-store-redefining-user-app-security">how to boost app security</a> even after biometric authentication? Well, the answer is adding cryptography to the biometric authentication workflow. But, good things take time, so keep a lookout for the sequel to biometric authentication in Android!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d683c10bbd12" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mutualmobile/biometric-authentication-in-android-mutual-mobile-d683c10bbd12">Biometric authentication in Android | Mutual Mobile</a> was originally published in <a href="https://medium.com/mutualmobile">Mutual Mobile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What is smart IoT and how it works | Mutual Mobile]]></title>
            <link>https://medium.com/mutualmobile/what-is-smart-iot-and-how-it-works-mutual-mobile-f9c9225b8eb6?source=rss----f5d3225ca8ce---4</link>
            <guid isPermaLink="false">https://medium.com/p/f9c9225b8eb6</guid>
            <dc:creator><![CDATA[Mutual Mobile]]></dc:creator>
            <pubDate>Fri, 14 Oct 2022 11:31:15 GMT</pubDate>
            <atom:updated>2022-10-14T11:31:15.406Z</atom:updated>
            <content:encoded><![CDATA[<h3>What is smart IoT?</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RmAQstctvTvDgSZ8HvVFhw.png" /></figure><p>Can today’s IoT (Internet of Things) devices get any smarter? Probably. Smart IoT is a rapidly growing branch that uses artificial intelligence to mimic human-like decision making. But is it something we really need? We voice our opinion.</p><p>The Internet of Things (IoT) dates its story back to Carnegie Mellon University in 1982. A humble <a href="https://www.cs.cmu.edu/~coke/history_long.txt">Coca-Cola vending machine</a> (which goes on to describe its experience) attained the rare distinction of being the first ever IoT device when it connected to the ARPANET (Advanced Research Projects Agency Network).</p><p>ARPANET was the first ever wide-area packet-switched (a method your local internet provider uses even today) network and one of the first few to implement the TCP/IP protocol. All this was to make sure the poor vending machine reported its inventory and if new drinks were cold or not.</p><p>But IoT came to the fore with the rise of the smartphone after the iPhone debuted in 2007. Cisco reports that the <a href="https://www.cisco.com/c/dam/en_us/about/ac79/docs/innov/IoT_IBSG_0411FINAL.pdf">things/people ratio grew from 0.08 in 2003 to 1.84 by 2010</a>! The technology is so ubiquitous today that most of us don’t even realize we’re using it.</p><p>That begs the question…‍</p><h3>What is the Internet of Things?</h3><p>Let’s start with your home.</p><p>What if your devices could talk to each other through the internet to be a little smarter and make your life a lot easier?</p><p>Garden sprinklers that talk to your weather app and adjust water supply based on its information. Coffee makers that link to your alarm clock and have a piping hot Americano ready by the time you dawdle into the kitchen.</p><p>A connected system of hardworking microcontrollers, actuators, and sensors works in tandem with communication hardware like WiFi and Bluetooth to make an IoT network, well, work.</p><p>Works like a charm, no?</p><p>Not really.‍</p><h3>Why IoT isn’t perfect yet</h3><p>While devices talk to each other and act together with more knowledge, they still lack perception. Their understanding of any situation is confined to a single layer. You can trust them to be mature enough to act with spontaneity when circumstances change rapidly. In other words, today’s IoT enables devices to only <em>perform</em> an action in response to feedback, not <em>modify</em> it.</p><p>Consider a home automation system where your lights, air conditioners, and thermostats track your movement to know they should switch on. Once they notice your lack of activity, they assume that you’re absent and turn themselves off.</p><p>But, even a system as clever as this breaks in the face of something as prosaic as sleep. When you’re asleep, the devices notice your lack of movement, assume it indicates your absence, and promptly turn themselves off. It’s good IoT, but dumb execution.</p><p>Cognitive artificial intelligence (AI) makes such systems smarter by letting them perceive. Cognitive AI would take a few initial inputs from you and keep the system in line with your preferences without bothering you for constant, untimely inputs.</p><p>To paint a clearer picture, let’s step into the office of Microsoft’s Chief Scientist, Eric Horvitz.‍</p><h3>How Eric made his office smarter</h3><p>At the Redmond research lab that houses Microsoft’s AI researchers, Eric built an <a href="https://www.microsoft.com/en-us/research/blog/can-robots-social-intelligence/">IoT system to handle visitors to the office</a>. Strong AI powers his system to enable devices to perceive, learn, and reason. Together, they make it easier for visitors to find him and free up his human assistant to do more productive work.</p><p>Once you enter the ground floor lobby, a camera and computer immediately notice you. They calculate your direction, pace, and distance to make a prediction that ensures you have an elevator waiting for you.</p><p>A robot greets you and asks if you need help locating Eric when you get off. As you reach him, a virtual personal assistant anticipates your arrival, checks Eric’s schedule, and asks if you’d like to be seated until Eric frees up.</p><p>Although this entire chain of smart IoT devices received initial training (Eric built this in 2014, by the way), it used cognitive AI to collect data and learn on its own independent of programmers. For example, it taught itself how to react when you pause in the hallway to answer a phone call or pick up a pen.</p><p>In other words, cognitive AI teaches smart IoT systems to learn from real-time data and optimize themselves for better performance. However…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*i7E4q7EoAFi9w2Ql.png" /></figure><h3>What exactly is cognitive AI?</h3><p>As the <a href="http://www.alanturing.net/turing_archive/pages/Reference%20Articles/What%20is%20AI.html">Turing Archive</a> defines it, traditional AI is <em>the science of making computers do things that require intelligence when done by humans. </em>It augments human capacity. But cognitive AI replicates human capacity.</p><p>It does this by modeling itself on the functioning and decision-making of the human brain. It analyzes and validates data to decide without human intervention. Built-in self-learning methodologies such as data mining and pattern recognition make this system flexible enough to adapt with changes in data.</p><p>An everyday example of this is smart assistants like Siri and Alexa. They use <a href="https://mutualmobile.com/resources/your-definitive-guide-to-natural-language-generation">Natural Language Processing</a> (NLP) as well as cognitive AI to mimic human behavior and make leaps of logic to solve complex problems. Just like a human being, cognitive AI can reason, compare, and decide, which is the closest we can get to programming imagination into them.</p><p>Eric’s case above may come across initially as hyper-niche. But it isn’t. There’s a lot to extrapolate and explore in there, with some of it already in practice within smart buildings and smart cities.‍</p><h3>Windows, roofs, and AI: How smart buildings work</h3><p>Ealy smart buildings used an IoT system to collect data from sensors. The building could then use this to save costs because devices would know when to switch themselves off. But, IoT systems typically rely on a boolean rule to manage devices, which often means they could react in ways that are completely out of sync with the situation.</p><p>Cognitive AI will improve this by collecting equipment data from IoT sensors, tagging it by location or asset type, checking against business rules, and triggering algorithms that detect and respond to anomalies.</p><p>AI is handy with real-time data analytics, drawing inferences, and allowing predictive maintenance. A recent development in the field is AI-powered hotdesking, where the building’s virtual assistant monitors available desk spaces (and even conference rooms) to let you know which ones are free to use.‍</p><h3>Concrete, signals, and AI: How smart cities work</h3><p>A smart city does what it does by collecting data from mass urban settings, like important squares, avenues, and traffic stops. For instance, a smart city could collect real-time air quality data and study it to build improvement models. This would help usher in practical civic action and data-based politics.</p><p>The same logic would extend to tracking water use, energy supplies, supply chain logistics, and empowering cognitive AI-powered IoT systems to gradually optimize the system with each passing day. An example would be Bill Gates’ proposed <a href="https://futurism.com/bill-gates-smart-city-arizona">new smart city in Arizona</a>, where he bought $80 million worth of land to start building.‍</p><h3>Do I need smart IoT?</h3><p>Smart IoT has endless possibilities. From saving costs at home to trimming expenses at workplaces, sites, and factories, smart IoT can do wonders for your business. In fact, you can schedule a free one-on-one consultation with one of our specialists to understand if your business can even benefit from smart IoT.</p><p>So if you’re looking to make your business smarter, <a href="https://mutualmobile.com/contact">hit us up here</a>. Our team would love to brainstorm with you. Perhaps, the next big thing is just one conversation away from you and us?</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f9c9225b8eb6" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mutualmobile/what-is-smart-iot-and-how-it-works-mutual-mobile-f9c9225b8eb6">What is smart IoT and how it works | Mutual Mobile</a> was originally published in <a href="https://medium.com/mutualmobile">Mutual Mobile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The importance of discovery in building a great digital product | Mutual Mobile]]></title>
            <link>https://medium.com/mutualmobile/the-importance-of-discovery-in-building-a-great-digital-product-mutual-mobile-ac74acad6752?source=rss----f5d3225ca8ce---4</link>
            <guid isPermaLink="false">https://medium.com/p/ac74acad6752</guid>
            <category><![CDATA[discovery]]></category>
            <category><![CDATA[product-management]]></category>
            <category><![CDATA[product-development]]></category>
            <dc:creator><![CDATA[Mutual Mobile]]></dc:creator>
            <pubDate>Fri, 14 Oct 2022 11:23:05 GMT</pubDate>
            <atom:updated>2022-10-14T11:23:04.955Z</atom:updated>
            <content:encoded><![CDATA[<h3>Discovery: A key cog in the product development process?</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TI6QqXaFtO4bMu-siLdeHA.png" /></figure><p>Imagine if you were a human. Wait, did we just ask you to ‘imagine if you were a human’ 🤦</p><p>That’s on us, so let’s start this from the top.</p><p>Imagine if you were a vampire, werewolf, dragon, unicorn, mermaid, leprechaun, or even Nessie, the Loch Ness monster. Would you rather shop digitally or go the old-school way?‍</p><p>Okay, fiiiiine, we’ll stop this fun/tedious charade (dealer’s choice), and get to the point.</p><p>Digital purchases are on the rise!‍</p><p>Are you wondering how we came to such a declaration?</p><p>Well, a whopping 86% of buyers (humans, not mythical creatures) prefer social media, metaverse, and <a href="https://www.techrepublic.com/article/86-of-buyers-prefer-virtual-metaverse-and-social-media-purchases/">virtual purchases over face-to-face sales</a>. That’s how 😛‍</p><p>The convenience and efficiency make them attractive to customers since they can acquire items instantly, albeit in a virtual space. To keep up with the cutthroat competition, brands are aggressively expanding their product and service lines in the form of digital products such as online courses, software solutions, and graphic design templates. With this increased cutthroat competition, brands are having to come up with unique methods to make their digital products stand out and attract consumers.‍</p><p>So, the big question here is how can brands do that? And only one answer comes to mind — the <a href="https://mutualmobile.com/blog/how-to-conduct-the-perfect-technical-discovery-session">product discovery process</a>.‍</p><h3>Introduction to the product discovery process</h3><p>The product discovery process is a phase wherein research is conducted to collate and collect detailed insights and information that would be used for <a href="https://mutualmobile.com/blog/3-ways-the-product-lifecycle-has-changed-user-research-2">creating digital products</a>. This phase helps brands develop products that are essential, and not just nice to have.</p><p>In this phase, a product’s usability is ascertained and how consumers would perceive it. Some key aspects of the product discovery process include determining the final objective, setting the target audience, product functionality, and UX/UI design.</p><p>The research conducted in this phase is also vital for determining how to make the product stand out from the competition and whether the market is ready for such a product.‍</p><h3>Importance of the product discovery process</h3><h4>Ensures product launch success and reduces risk</h4><p><a href="https://www.inc.com/elizabeth-walton/use-this-simple-hack-to-make-your-next-product-release-a-success.html">How much do companies spend on R&amp;D</a>? Well, according to Inc Magazine, it’s estimated at 23% of a company’s budget. But, depending on the outcome of a product, this expenditure could prove to be highly successful or a waste of money.</p><p>For example, Quibi was a mobile-focused streaming service launched in 2018. However, it was a massive failure, and the company was dissolved in 2020. Such instances can be avoided with a comprehensive and detailed product discovery process.‍</p><h4>Keeps digital development on track</h4><p>This <a href="https://www.chameleon.io/blog/product-discovery-guide">product discovery</a> process provides insights to companies about how their products can add value to consumers. Research methods such as journey maps and user analysis act as guides in the product development phase. They can also be used during the development process to ensure the product features add value to consumers and are synced with the company objectives. This helps reduce hesitancy towards implementing the product discovery process while keeping the digital development on track for success.‍</p><h3>How to create a successful product discovery process</h3><p>Several key aspects must be carried out to ensure a successful discovery process. The first of them is to <a href="https://mutualmobile.com/blog/kick-starting-the-enhanced-connectivity-revolution-with-5g-and-iot">pay close attention to market trends</a>. This helps the company understand what digital services are in demand, which markets to consider, and how to enter said markets successfully.</p><p>Some of these market trends include data analytics and social media. Observing what people are sharing online and examining posts with high engagement gives an idea about the ongoing trends. You can also conduct polls on social media to understand consumers’ preferences and tastes. You could also shadow the social media platforms of digital product companies like Netflix, Canva, and Salesforce to get an insight into the latest trends.</p><p>Secondly, <a href="https://online.maryville.edu/blog/how-technology-is-changing-business-administration/">data gathered from consumers’ habits</a> can also help anticipate trends. For example, previous purchases can give an insight into what consumers might purchase next. The best tool to carry this out is Google Analytics. It provides you with customer behavior analysis, which can be used to understand how consumers respond to your products and what products they gravitate towards the most.</p><p>Apart from market trends and data, you should regularly <a href="https://mutualmobile.com/blog/mutual-mobile-this-startup-increased-revenue-by-saying-no-to-clients">conduct competitor analysis</a> to stay above them. For instance, in the online education space, Udemy has the edge over Coursera since it gives more importance to skill development rather than accredited programs. And that’s precisely the reason why consumers opt for Udemy over Coursera.</p><p>This shows how valuable the product discovery process can be in your armor if used correctly, and we can help you pull it off with our award-winning team.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ac74acad6752" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mutualmobile/the-importance-of-discovery-in-building-a-great-digital-product-mutual-mobile-ac74acad6752">The importance of discovery in building a great digital product | Mutual Mobile</a> was originally published in <a href="https://medium.com/mutualmobile">Mutual Mobile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Flutter for startups: What you should know | Mutual Mobile]]></title>
            <link>https://medium.com/mutualmobile/flutter-for-startups-what-you-should-know-mutual-mobile-d084195b6b53?source=rss----f5d3225ca8ce---4</link>
            <guid isPermaLink="false">https://medium.com/p/d084195b6b53</guid>
            <category><![CDATA[flutter]]></category>
            <category><![CDATA[app-development]]></category>
            <category><![CDATA[flutter-app-development]]></category>
            <category><![CDATA[andoid-app-development]]></category>
            <category><![CDATA[android]]></category>
            <dc:creator><![CDATA[Mutual Mobile]]></dc:creator>
            <pubDate>Fri, 14 Oct 2022 06:29:57 GMT</pubDate>
            <atom:updated>2022-10-14T06:29:57.676Z</atom:updated>
            <content:encoded><![CDATA[<h3>Why is Flutter the best fit for startups?</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LuWMNxPxfPyfFyFvoUN_CA.png" /></figure><p>What if mobile apps never existed? Can you even fathom such a reality?</p><p>Thankfully, we don’t even have to imagine such an alternate reality (*shivers*), since, today, there is an app for every possible requirement. Running out of groceries? Now, there are apps that deliver those directly to your doorstep in 15 minutes flat. Want a fresh set of prescription medicines? Put your feet up and relax at home while those are delivered to you. And of course, then there’s Amazon, that’s got you covered for technology, furniture, books, clothes, and more.</p><p>This growing dependency and the necessity of apps have led to massive <a href="https://www.goodfirms.co/blog/app-development-trends-2022">growth in the app development industry</a>. In fact, global revenue from mobile apps is expected to rise to $613 billion by 2025, up from $318 billion in 2020. This has also increased the competition to develop engaging, robust, and successful applications.</p><p>Keeping this increased competition in mind, there are numerous factors that you must consider when developing your app. One such key factor is the app development framework, which becomes even more critical for startups. Flutter is an app development framework that is considered to be an excellent choice for startups to drive business growth.</p><p>Here, we will delve deeper into the world of Flutter and why it is the <a href="https://mutualmobile.com/work/dribe">best option for startups</a>.‍</p><h3>What is Flutter?</h3><p>Flutter is an <a href="https://mutualmobile.com/blog/handbook-for-navigation-in-flutter">open-source app development framework</a> used for building beautiful cross-platform applications. It’s written in Dart and launched in 2017 by Google. As mentioned, it offers cross-platform development and can be used to create robust apps for Android, iOS, Linux, macOS, Windows, and the web using a single codebase. Furthermore, points continue to stack up in favor of Flutter, since it is the most <a href="https://www.statista.com/statistics/869224/worldwide-software-developer-working-hours/">popular cross-platform app development framework</a>.‍</p><h3>Why is Flutter the ideal framework for startups?</h3><h4>Easy to learn</h4><p>Flutter became the toast of the town within a short time of its launch. Why, you ask? Due to its benefits of ease of learning and effortless accessibility.</p><p>Flutter provides developers with excellent in-depth documentation on the best practices for using it. Moreover, Flutter includes video tutorials on its website, which makes it easier for novices to understand the basics of the app development framework.‍</p><h4>Cross-platform development</h4><p>One of the most striking features of Flutter is that it allows you to <a href="https://mutualmobile.com/blog/the-business-owners-guide-to-react-native">create cross-platform apps</a> for multiple platforms from a single codebase. Unlike other app development frameworks, it doesn’t require separate codebases for different operating systems.</p><p>Writing separate codebases for apps across different operating systems can be cumbersome and tedious. Here’s where Flutter provides a significant advantage while helping save time and money, and reducing developers’ workloads.‍</p><h4>Hot reload</h4><p><a href="https://docs.flutter.dev/development/tools/hot-reload">Hot reload in Flutter</a> is a handy and quick function that allows developers to fix bugs, create UIs, add features, and apply code changes instantly. Hence, developers can update codes at any point and view the changes instantly without restarting the entire program. Moreover, developers get to use this feature in Flutter since it’s written in Dart, which allows them to experiment with unique user interfaces.‍</p><h4>Better performance</h4><p>Apps built using Flutter are considered to perform better than those built using other frameworks, making it ideal for startups. The ahead-of-time compilation feature allows programmers to compile their Dart code into machine language ahead of time, i.e., in build time instead of run time, thus making the app feel native.</p><p>Usually, in other cross-platform frameworks, the <a href="https://mutualmobile.com/blog/your-definitive-guide-to-natural-language-generation">compilation of codebase to machine language</a> is done in run-time, which takes a significant amount of time, thus reducing performance.‍</p><h4>Budget-friendly and free-to-use plugins</h4><p>Flutter is open-sourced and free-to-use, thus not requiring licensing fees. In addition, it also provides plugins and packages. One of them being Firebase Cloud Messaging (FCM). FCM is a free cross-platform plugin and messaging solution for notifications and messages on Android, iOS, and the web.‍</p><h3>Wrapping up</h3><p>Considering the benefits mentioned above, it’s no surprise that Flutter has become developers’ go-to cross-platform app development framework. This also applies to startups since they have limited funds and resources, and Flutter provides them with the tools and services necessary to succeed in a cutthroat <a href="https://mutualmobile.com/blog/how-to-conduct-the-perfect-technical-discovery-session">app development environment</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d084195b6b53" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mutualmobile/flutter-for-startups-what-you-should-know-mutual-mobile-d084195b6b53">Flutter for startups: What you should know | Mutual Mobile</a> was originally published in <a href="https://medium.com/mutualmobile">Mutual Mobile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>