Android vs iOS Which Platform to Build Your App for

Android vs iOS Which Platform to Build Your App for?

Regina Fox

Regina Fox is a writer and editor with a passion for music, books, and technology that makes daily life just a little bit easier (she'd quite literally be nowhere without her phone GPS).

Android vs iOS Which Platform to Build Your App for

The Android vs iOS battle rages on, even after years of both operating systems going mainstream. When it comes to personal use, it will always be individual preference based on usability, functionality, and compatibility partiality. But when it comes to pursuing a mobile app development project, there are other factors at play. Not only are you concerned with creating the best product on the best platform, but you’ve also got to be conscious about your budgeting when deciding which operating system to build for. So, should you build both an Android and iOS version of your app? If not, what are the consequences? If so, which should you build first and how much will it cost? You’re not going to like this, but the answer to all these questions is: it depends. Let’s unpack the Android vs iOS battle.

Difference Between Android and iOS


There are many difference between the Android operating system and iOS as well as the devices that support them. Because of its world-wide adoptability, Android is the largest operating system in the world. It runs on devices by Samsung, LG, Google, Huawei, Nokia, and more technology hardware companies. It is mainly written in Java, C, and C++. On the other hand, iOS is designed exclusively for Apple devices like iPhone, iPad, and MacBook. It is the world’s second most used mobile operating system after Android. It was developed mostly using Swift.

android vs ios

Android vs iOS: Which is better?


Objectively, there is no better platform when it comes to Android vs iOS. Each present their own unique set of benefits compared to the other. On the other hand, they each have their downfalls. Let’s compare pros and cons of both Android and iOS.

Android Pros

  • Dominant in global market
  • More flexibility to customize app
  • Diverse phone options
  • Can side-load apps from outside the Play Store

Android Cons

  • Takes longer to develop
  • Users are slower to adopt new operating systems
  • Users are less likely to purchase apps
  • More susceptible to malware

android vs ios

iOS Pros

  • Faster, easier, cheaper to develop
  • Apple users more likely to purchase apps
  • Tight security
  • Apple users more likely to update OS

iOS Cons

  • Less popular outside western Europe and North America
  • Less flexibility to customize
  • Apps take longer to be approved in App Store
  • Fewer device options for users

android vs ios

Which Platform to Build Your App on


Now that we’ve compared and contrasted Android vs iOS, it’s time to start unpacking which platform is best suited for your app. This process involves thinking critically about four main concepts: budget, timeline, target audience, monetization strategy. All four of these factors will play a major role in deciding to build for Android or iOS.

Android vs iOS: Budget


Unfortunately, mobile app development companies aren’t going to build you an Android and iOS version of your app for one low price. Rather, there is a price associated with both and Android version of your app and iOS. This is because the app code has to be written twice—once for iOS and once for Android. Of the two, iOS is often the cheaper option for two main reasons:

1. Apple apps are written in Swift which requires less code than Android programming languages

2. iOS has fewer devices (remember the list from above?), components, and software fragmentations to account for compared to Android

The gap between Android cost and iOS cost continues to grow beyond deployment as support and maintenance plans are more rigorous and time-consuming for Android apps. What’s more, Android developers also have to be concerned with fixes bugs for users running older operating systems since Android users are less likely to update their phones—a problem Apple users don’t have to worry much about.

Android vs iOS: Timeline


In addition to generally being more affordable, iOS app development is faster than Android app developmentsome estimates put development time at 30–40% longer for Android. Like mentioned above, less code, fewer device screens to make compatible, and less work after deployment are what save software engineers time during iOS development compared to Android.

android vs ios

Android vs iOS: Target Audience


Keeping the user at the center of your app experience is the most important thing during your app development journey. And so, it is imperative to look at your target audience and consider their geographic and demographic characteristics. If you’re targeting a global audience, Android may be your best bet. But, if your audience is in Western Europe or North America, Apple may be a better choice.

iOS Demographic Fast Facts

-iOS Apple users are more likely to have more education and hold managerial positions
-iOS users tend to be younger, with a greater share of the 18–24-year-old market
Women are more likely to use iPhones than Android

Android Demographic Fast Facts

-Android is dominant in global up-and-coming markets, including in Asia, Africa, and Latin America
-Android users are more likely to work in technical jobs
-Slightly more men prefer Android than iOS

android vs ios

Source: App Annie

Monetization Strategy


Developing a monetization strategy for your app development project should be one of the first items on your to-do list. Some people opt for the investor route, others prefer a subscription program for a solid ROI. Charging users per download is another option you may consider. If you select this monetization strategy, building an iOS app will likely bring you more success over Android. Here’s why:

-iPad & iPhone users earn 40% more than the average Android user
-Apple users tend to spend more on apps
-Android users tend to be less willing to pay for apps than iOS users

Building your Android and/or iOS app


Deciding between building an Android app or an iOS app is not easy. You must consider your budget, timeline, target audience, and monetization strategy before making your decision. Ultimately, there will be tradeoffs if you decide to build either an Android or iOS app. In order to reap the benefits of both operating system, many folks opt to build them both. This is a sure-fire way to make your app available to all users!

Sunflower Lab is an iOS app development company and Android app development company with over 10 years experience. We were early adopters of both operating systems because we knew it would have a great impact on the way we live, work, and play. Our customers come from all shapes, sizes, and backgrounds to discover the power of mobile app development. To start your journey, contact our mobile app specialists today.

Related Posts

10 Essential Real Estate App Features that Enhance Your Business

Employee expense receipt management is the perfect process for RPA because it is logic based and redundant. Let’s

Guide To 7 Best Tech Stack 2023 for Software Development

Employee expense receipt management is the perfect process for RPA because it is logic based and redundant. Let’s


How To Setup CI-CD Pipeline Using Bitrise For Flutter Applications

As we can see in current Mobile Application Development trend, Flutter has gain rapid growth in short span of time compares to any other Mobile application development framework. Earlier when any company or early stage start up pick Flutter for their upcoming Mobile Application Project framework, they tend to rely on readily available features, give their developers to spend some time and provide a space to them so they can get align with this new framework. 

In all cases, from a small start-up group to maintained team of developers, every mobile application industry follows some common software solutions and practices which are beneficial to maintain projects in a good way. Having ready-to-deploy or ready-to-release strategy is one of the best practices that an organization follows. In technical, this is called Continues-Integration & Continues-Deployment (CI-CD). In this article, we’ll be telling you how you can setup CI-CD pipeline on Bitrise for your Flutter Application.  

What actually is Bitrise ?  

Bitrise is the cloud CI/CD tool we use as a Service with main focus on mobile app development (ios, Android, React Native, Flutter, etc..). It is a collection of tools and services to help you with the development and automation of your software projects. 

Whole process of setting up CI-CD pipeline is divided into few sections as below:

  • Configure Flutter Application with different flavours 
  • Configure Flutter Application on Bitrise Web UI 
  • Configure Android & iOS Release Configurations 

In following part of this article, we’ll be covering all these sections one by one. So, let’s begin:  

Part 1 – Configure a Flutter Application with different Flavors

Part 2– Configure Flutter Application on Bitrise Web UI 

There are few steps for initializing your app on Bitrise. Let’s follow the steps in order to configure it. 

Step 1: Add a new application on web UI of Bitrise by clicking on topmost right button (+). 

Step 2: After adding a new app, select if you want the App to be public or private to the organization. 

Step 3: Now add your app from the repository which you want to connect as shown in the picture:

bitrise flutter

Bitrise Scanner automatically detects your git repository which contains a Flutter application and ask you some questions to configure the default Bitrise setup. 

Step 4: In Setup Repository Access, you can select auto-add SSH key or you can add it if you have.  

Step 5: In Branch Select Option, you have to select the branch in which your full code exists. It will then configure and scan it automatically. 

bitrise flutter

Step 6: Select your Schema name inside Project build configuration. 

bitrise flutter

Step 7: Add your app icon and Register a Webhook. When the setup is done, Bitrise automatically triggers a build with the default workflow called primary. 

bitrise flutter

By default, Bitrise creates 2 work flow primary and deploy. The principal difference between two work flow is the build and signing steps in the deploy workflow. 

To observe it in a proper way, go to the workflow tab and then go to the trigger tab. It will show you each workflow triggered by default. 

Get Help On Your Flutter Project

Now, heading towards our changes as a major in Steps through bitrise.yml file. The bitrise.yml tab will allow you to retrive all the configuration of your application on Bitrise. We usually store this file in git repository to have a backup. 

Our need is totally different from the default bitrise.yml file. So, I have created it to fulfil our needs. So, our need is to setup 4 workflow:

  • pull-request: It is used for checking the code quality (tests, code coverage, …) and if the application can be built without bugs. Depending on your needs, you could also make the application available for a functional validation of the new feature. 
  • production: It is used for building the application for the production environment and make it available to POs, testers, stakeholders who need it. 
  • develop: It is used for building the application for the development environment. 
  • unauthorize: It is used for preventing unauthorized actions in our continuous integration kinematics. This workflow throws an error. 

 

Bitrise configuration to meet our needs: 

Step 8: You have to create a bitrise.yml file in your project and refer the below code into your file if you want. 

Note: You would need to change the following things if you paste the below code!!! 

  • custom_export_options_plist_content in xcode-archive 
  • file-downloader/destination ‘key.jks’ to your jks file 
  • flutter-build/ Android and ios additional params 
  • You can also change the branch and schema according to your needs. 

format_version: '6' 

default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git 

project_type: flutter 

trigger_map: 

  - push_branch: develop 

    workflow: develop 

  - push_branch: master 

    workflow: production 

  - pull_request_source_branch: '*' 

    workflow: pull-request 

    pull_request_target_branch: develop 

  - pull_request_source_branch: develop 

    pull_request_target_branch: master 

    workflow: pull-request 

  - pull_request_target_branch: master 

    workflow: unauthorize 

workflows: 

  production: 

    steps: 

      - activate-ssh-key@4.0.3: 

          run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}' 

      - git-clone@4.0.14: {} 

      - script@1.1.5: 

          title: Do anything with Script step 

      - file-downloader@1.0.1: 

          inputs: 

            - destination: "$HOME/keystores/release.jks" 

            #- destination: "$DOWNLOADED_KEYSTORE_PATH" 

            - source: "$BITRISEIO_ANDROID_KEYSTORE_URL" 

      - certificate-and-profile-installer@1.10.1: {} 

      - flutter-installer@0: 

          inputs: 

            - is_update: 'false' 

            - installation_bundle_url: >- 

                https://storage.googleapis.com/flutter_infra/releases/stable/macos/flutter_macos_1.17.5-stable.zip 

      - flutter-analyze@0.1.0: 

          inputs: 

            - project_location: "$BITRISE_FLUTTER_PROJECT_LOCATION" 

      - flutter-build@0.9.2: 

          inputs: 

            - project_location: "$BITRISE_FLUTTER_PROJECT_LOCATION" 

            - android_additional_params: '--release --flavor production -t lib/main.dart' 

            - ios_additional_params: '--release --flavor production -t lib/main.dart' 

            - ios_codesign_identity: '' 

      - xcode-archive@2.4.19: 

          inputs: 

            - project_path: "$BITRISE_PROJECT_PATH" 

            - export_method: "$BITRISE_EXPORT_METHOD" 

            - force_provisioning_profile: '' 

            - force_team_id: '' 

            - force_code_sign_identity: '' 

            - force_provisioning_profile_specifier: '' 

            - custom_export_options_plist_content: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>compileBitcode</key>\n\t<false/>\n\t<key>destination</key>\n\t<string>export</string>\n\t<key>method</key>\n\t<string>development</string>\n\t<key>provisioningProfiles</key>\n\t<dict>\n\t\t<key>com.sfl.sflFlutterFlavorApp</key>\n\t\t<string>SflFlutterFlavorApp_Prod</string>\n\t</dict>\n\t<key>signingCertificate</key>\n\t<string>Apple Development</string>\n\t<key>signingStyle</key>\n\t<string>manual</string>\n\t<key>stripSwiftSymbols</key>\n\t<true/>\n\t<key>teamID</key>\n\t<string>T2D2NVNN89</string>\n\t<key>thinning</key>\n\t<string>&lt;none&gt;</string>\n</dict>\n</plist>" 

            - configuration: Release-production 

      - deploy-to-bitrise-io@1.3.19: {} 

      - github-status@2.2.2: 

          inputs: 

            - auth_token: "$GITHUB_STATUS_TOKEN" 

    envs: 

      - opts: 

          is_expand: false 

        BITRISE_SCHEME: production 

      - opts: 

          is_expand: false 

        BITRISE_EXPORT_METHOD: development 

  pull-request: 

    steps: 

      - activate-ssh-key@4.0.3: 

          run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}' 

      - git-clone@4.0.14: {} 

      - script@1.1.5: 

          title: Do anything with Script step 

      - file-downloader@1.0.1: 

          inputs: 

            - destination: "$HOME/keystores/release.jks" 

            #- destination: "$DOWNLOADED_KEYSTORE_PATH" 

            - source: "$BITRISEIO_ANDROID_KEYSTORE_URL" 

      - certificate-and-profile-installer@1.10.1: {} 

      - flutter-installer@0.9.2: {} 

      - flutter-analyze@0.1.0: 

          inputs: 

            - project_location: "$BITRISE_FLUTTER_PROJECT_LOCATION" 

      - codecov@1.1.5: 

          inputs: 

            - CODECOV_TOKEN: "$CODECOV_TOKEN" 

      - flutter-build@0.9.2: 

          inputs: 

            - project_location: "$BITRISE_FLUTTER_PROJECT_LOCATION" 

            - android_additional_params: '--release --flavor production -t lib/main.dart' 

            - ios_additional_params: '--release --flavor production -t lib/main.dart' 

            - platform: both 

      - xcode-archive@2.4.19: 

          inputs: 

            - project_path: "$BITRISE_PROJECT_PATH" 

            - export_method: "$BITRISE_EXPORT_METHOD" 

            - force_provisioning_profile: '' 

            - force_team_id: '' 

            - force_code_sign_identity: '' 

            - force_provisioning_profile_specifier: '' 

            - custom_export_options_plist_content: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>compileBitcode</key>\n\t<false/>\n\t<key>destination</key>\n\t<string>export</string>\n\t<key>method</key>\n\t<string>development</string>\n\t<key>provisioningProfiles</key>\n\t<dict>\n\t\t<key>com.sfl.sflFlutterFlavorApp</key>\n\t\t<string>SflFlutterFlavorApp_Prod</string>\n\t</dict>\n\t<key>signingCertificate</key>\n\t<string>Apple Development</string>\n\t<key>signingStyle</key>\n\t<string>manual</string>\n\t<key>stripSwiftSymbols</key>\n\t<true/>\n\t<key>teamID</key>\n\t<string>T2D2NVNN89</string>\n\t<key>thinning</key>\n\t<string>&lt;none&gt;</string>\n</dict>\n</plist>" 

            - upload_bitcode: 'no' 

            - configuration: Release-production 

      - github-status@2.2.2: 

          inputs: 

            - auth_token: "$GITHUB_STATUS_TOKEN" 

    envs: 

      - opts: 

          is_expand: false 

        BITRISE_SCHEME: production 

      - opts: 

          is_expand: false 

        BITRISE_EXPORT_METHOD: development 

  develop: 

    steps: 

      - activate-ssh-key@4.0.3: 

          run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}' 

      - git-clone@4.0.14: {} 

      - script@1.1.5: 

          title: Do anything with Script step 

      - file-downloader@1.0.1: 

          inputs: 

            - destination: "$HOME/keystores/release.jks" 

            #- destination: "$DOWNLOADED_KEYSTORE_PATH" 

            - source: "$BITRISEIO_ANDROID_KEYSTORE_URL" 

      - certificate-and-profile-installer@1.10.1: {} 

      - flutter-installer@0: 

          inputs: 

            - is_update: 'false' 

            - installation_bundle_url: >- 

                https://storage.googleapis.com/flutter_infra/releases/stable/macos/flutter_macos_1.17.5-stable.zip 

      - flutter-analyze@0.1.0: 

          inputs: 

            - project_location: "$BITRISE_FLUTTER_PROJECT_LOCATION" 

      - flutter-build@0.9.2: 

          inputs: 

            - project_location: "$BITRISE_FLUTTER_PROJECT_LOCATION" 

            - android_additional_params: '--release --flavor develop -t lib/main.dart' 

            - ios_additional_params: '--release --flavor develop -t lib/main.dart' 

            - ios_codesign_identity: '' 

      - xcode-archive@2.4.19: 

          inputs: 

            - project_path: "$BITRISE_PROJECT_PATH" 

            - export_method: "$BITRISE_EXPORT_METHOD" 

            - force_provisioning_profile: '' 

            - force_team_id: '' 

            - force_code_sign_identity: '' 

            - force_provisioning_profile_specifier: '' 

            - custom_export_options_plist_content: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>compileBitcode</key>\n\t<false/>\n\t<key>destination</key>\n\t<string>export</string>\n\t<key>method</key>\n\t<string>development</string>\n\t<key>provisioningProfiles</key>\n\t<dict>\n\t\t<key>com.sfl.sflFlutterFlavorApp</key>\n\t\t<string>SflFlutterFlavorApp_Prod</string>\n\t</dict>\n\t<key>signingCertificate</key>\n\t<string>Apple Development</string>\n\t<key>signingStyle</key>\n\t<string>manual</string>\n\t<key>stripSwiftSymbols</key>\n\t<true/>\n\t<key>teamID</key>\n\t<string>T2D2NVNN89</string>\n\t<key>thinning</key>\n\t<string>&lt;none&gt;</string>\n</dict>\n</plist>" 

            - configuration: Release-develop 

      - deploy-to-bitrise-io@1.3.19: {} 

      - github-status@2.2.2: 

          inputs: 

            - auth_token: "$GITHUB_STATUS_TOKEN" 

    envs: 

      - opts: 

          is_expand: false 

        BITRISE_SCHEME: develop 

      - opts: 

          is_expand: false 

        BITRISE_EXPORT_METHOD: development 

  unauthorize: 

    steps: 

      - script@1.1.5: 

          title: Do anything with Script step 

          inputs: 

            - content: | 

                #!/usr/bin/env bash 

                # fail if any commands fails 

                set -e 

                # debug log 

                set -x 

 

                # write your script here 

                echo "this script throws an error" 

                exit 1 

    envs: 

      - opts: 

          is_expand: false 

        BITRISE_SCHEME: production 

      - opts: 

          is_expand: false 

        BITRISE_EXPORT_METHOD: development 

app: 

  envs: 

    - opts: 

        is_expand: false 

      BITRISE_FLUTTER_PROJECT_LOCATION: "." 

    - opts: 

        is_expand: false 

      BITRISE_PROJECT_PATH: ios/Runner.xcworkspace

We added the File Downloader, Certificate and profile installer, CodecovXcode Archive & Export for iOS and Github status steps. 

File Downloader: It is used for downloading the Android certificate. 

Certificate and Profile Installer: It is used to get the mobile provision and certificate for iOS signing. 

Xcode Archive & Export for iOS: It is used to build and sign the iOS app 

Github Status: It is used to send Github status checks on each PR. You can configure your repository on Github so that status checks are mandatory to merge a PR. 

Part 3 – Configure Android & iOS Release Configurations 

Android Signing Configuration: 

The Signing config for Android is defined like this in the build.gradle file : 

bitrise flutter

You must generate the Android keystore if you don’t have one. Once you have the keystore, you need to upload it on Bitrise. Go to the Workflow Tab and then in the Code Signing Tab:

bitrise flutter

Note: Keystore Password, Keystore Alias and Private Key Password are mandatory to fill as of your .jks file. 

 IOS configuration: 

You must be having iOS certificate and mobile provision file. 

For this step, you must have an Apple Developer account to create the mobile provisioning and the certificate. Once you have you can upload them in Bitrise, go to the Workflow Tab and then in the Code Signing Tab. 

gitlab flutter

Now Let’s Start the build for the app, The Android and iOS build should not have any error. You can see your file generated inside the Apps and Artifacts Tab.  

gitlab flutter
gitlab flutter

Hence, we’re done with setting up CI-CD pipeline for a Flutter Project on Bitrise. We wish these details are helpful for setting up pipeline for anyone. Stay connected for our upcoming articles.  

Sunflower Lab is an award-winning company now providing result driven android app development services, ios app development services, robotic process automation services with a history of helping clients solve their toughest technology issues, we exist to build a better and brighter tomorrow.

Get a FREE estimate for your project today.

Our team of experts will review your project and give you a quote at no cost.

Get a quote on your project!

Related Posts

10 Essential Real Estate App Features that Enhance Your Business

Employee expense receipt management is the perfect process for RPA because it is logic based and redundant. Let’s

Guide To 7 Best Tech Stack 2023 for Software Development

Employee expense receipt management is the perfect process for RPA because it is logic based and redundant. Let’s


mobile app development company

11 Reasons To Hire A Mobile App Development Company

Regina Fox

Regina Fox is a writer and editor with a passion for music, books, and technology that makes daily life just a little bit easier (she'd quite literally be nowhere without her phone GPS).

mobile app development company

Why You Should Hire A Mobile App Development Company

Mobile apps are all the rage right now. Businesses are growing rapidly by shrinking their businesses to the size of their customers’ palms. From improving customer experiences, to earning more revenue, to beating out the competition, the benefits of mobile applications are plentiful (and quite convincing, if we do say so ourselves). However, it can be time-consuming, expensive, and frustrating to navigate the first steps. So, we’re going to cut right to the chase. With a customized experience from start to finish, beautiful and powerful products, and experience to back their promises, hiring a mobile app development company is the correct and only first step. Don’t believe us? Read on to find out more. 

Offer More Value To Customers With A Mobile App Development Company

The #1 reason to hire a mobile app development company is to offer more value to your customers. Offering a mobile application can greatly expand your visibility. It can also offer a convenient way for your customers to access your business 24/7. But, if you’re going to put your business out in front of more customers, then it ought to be beautiful. 

Stunning Design

The appearance of your app is the first thing customers are going to see. Guarantee a great first impression by hiring a mobile app development team. These folks are up to date on all the latest trends in mobile app design, and are equipped with all the tools necessary to translate your branding into your product. It’s important that your app be an extension of you and your business. Don’t risk muddying the image of the company you worked so hard to create by cutting corners with design. Tantalize your users’ visual senses with a professional and aesthetically-pleasing application! But, beauty is only UI deep. For a truly successful app, it has to be high-performing.

See More Beautiful Apps

Team of Experts

Recruiting your IT team to YouTube their way through app development can lead to a whole slew of issues—wasted money, security breaches, malfunctioning frameworks, weak design to name just a few! Hiring experts to build your mobile app means you are getting a team of well-trained technicians dedicated solely to your project. These highly-skilled professionals undergo rigorous training programs in order to solve your most difficult technical issues. With years and years of combined experience, the technologists at mobile app development companies possess the talent and confidence to get the job done well and on time.

Get Continued Support With A Mobile App Development Company

After teaming up with a mobile app development company, you’ll never have to go through the process alone. Your experienced team of experts will always stand behind you and your business to tweak your app’s performance, massage any kinks in the operating system, and make sure it is offering the best possible experience to your users. Remember: support and maintenance are key to the long-term health of your application. 

Customization

A major benefit of hiring a mobile app development company versus purchasing an off-the-shelf product is customization. From discovery to deployment, a mobile app companies take a personalized approach to your software solution. You have the power to choose an appropriate security package, pick which features you want, and decide on the right framework to suit your specific needs. Don’t sell your business short by going with a one-size-fits-all product. 

Scalability 

Not only can a mobile app development company deliver a beautiful, high-powered, product for your current company, they can design it to suit your future business, as well. Whether downsizing or expanding is in your long-term business plan, development companies have the ability to leverage scalable technology into the build of your application. 

Reputation

When shopping around for the perfect mobile app development company to hire, be keen on customer reviews and recognitions. What are their clients saying about them? Do they publicize their customer satisfaction rate? Have they been recognized for any award or achievement? An established mobile app development company will have a reputation that proceeds them. You will gain confidence in their work before you even contact them.

“Sunflower delivered professional service and quick turnarounds with updates. The team created a very clean responsive iPad app for us. Great work!” - Nationwide Insurance

 

Deciding on a Mobile App Development Company

As you can see, hiring a mobile app development company offers a bevy of benefits. Now, the only decision you’re left to make is who you will partner with. Allow us to narrow it down for you: Sunflower Lab. We have worked with dozens of industries to help solve their unique problems. We have mastered the development life cycle, and offer unmatched customer service along the way. There is only one place to find the top mobile app development New York, New Jersey, and Ohio has to offer, and that’s at Sunflower Lab. Sunflower Lab is now providing result driven android app development services, ios app development services, robotic process automation services with a history of helping clients solve their toughest technology issues, we exist to build a better and brighter tomorrow.Let us turn your app dream into a reality today!

Get a FREE estimate for your project today.

Our team of experts will review your project and give you a quote at no cost.

Get a quote on your project!

Related Posts

10 Essential Real Estate App Features that Enhance Your Business

Employee expense receipt management is the perfect process for RPA because it is logic based and redundant. Let’s

Guide To 7 Best Tech Stack 2023 for Software Development

Employee expense receipt management is the perfect process for RPA because it is logic based and redundant. Let’s


Set Up Ios - Mobile Ap Development News

How to Implement VoIP Voice Call Using Twilio in iOS

Set Up Ios - Mobile Ap Development News

  • Twilio (/ˈtwɪlioʊ/) is an American cloud communications platform as a service (CPaaS) company based in San Francisco, California. Twilio allows software developers to programmatically make and receive phone calls, send and receive text messages, and perform other communication functions using its web service APIs.  
  • In mobile, device to device video call integration is done using VOIP and Video SDK. 
  • Twilio team has developed their SDK based on WebRTC open source library. 
  • In order to have a video call we need to implement VoIP call (Voice over IP), so that direct call can be made to peer device.  
  • Video call provides single to multiple device connection and Realtime Video Chat. 
  • Twilio Dashboard shows all the insights needed to rectify issues and checking up all the required data. 
  • It also provides many SDK’s with respect to platform and language specific. 
  • Twilio provides separate SDKs for VoIP and Video call functionality. So, to notify user that someone wants to have video call with him we have implemented VoIP call functionality. 
  • In Twilio video call SDK, it provides implementation for video call functionality only. Also, VoIP has functionality to call, call disconnection, call disconnection before accepting the call due to this we need VoIP along with Video call. 
  • So, to achieve the functionality of getting notified when one user makes video call to another user, we have used VoIP call SDK and after user picks up the incoming VoIP call, we are switching to video call by using video call SDK provided by Twilio. 

General VOIP flow: 

  • Consider Device A and Device B as mobile devices. Device A will ask for VoIP token from API by submitting identity. Then we have to register VoIP token. 
  • For placing a call to device B, we need to use Voice connection method of Twilio SDK along with its respected identity. 
  • On account of this Twilio server will fire up push notification to Device B. 
  • After accepting the call, we need to convert it into video call (video call flow is explained in later in the document). 

General VIDEO call flow: 

  • When Device A will call over VoIP, using ‘makeCall’ then twillio will fire a push notification to Device B and Device A will get connected to room for video call and will wait for peer participant to get connected. 
  • If Device B accepts the call, then we need to disconnect the VoIP call and then connect to Video Call in the same room in which Device A is connected. 
  • So, when device B accepts the call, we need to disconnect the VoIP call. Call disconnect listener will be called in Device A end and it will look for any participant is added in Video Call room and will wait for 10 sec. Under this 10 second if peer device is getting connected then we can have a normal video call. And if peer device B is not getting connected in 10 second then automatically call will be disconnected. It will also be helpful when receiver (device B) rejects the call, Caller call will be rejected in 10 seconds. 
  • Twillio Video call provides feature like group call, change audio device, camera switch and mute. 
  • Any unique name will work as room name, here we have kept logic for room name like:

IdentityA_IdentityB or userNameA_userNameB. 

Steps to implement VoIP voice call using Twilio in iOS

  • Install the TwilioVoice framework: 
    • To install via Cocoapods add pod ‘TwilioVoice‘, ‘~> 5.5.0’ in Podfile and under the project path, run pod install and let the Cocoapods library create the workspace for you. Also please make sure to use Cocoapods v1.0 and later. 
  • Create a Voice API key: 
  • Configure a server to generate an access token to be used in the app: 
    • Backend team need to follow documentation for configuring server and for configuration they need Twilio Account SID and they also need API_KEY and API_KEY_SECRET that we got from previous step. 

 

  • Create a TwiML application: 
    • TwiML application identifies a public URL for retrieving TwiML call control instructions. 
    • When iOS app makes a call to the Twilio cloud, Twilio will make a webhook request to this URL, your application server will respond with generated TwiML, and Twilio will execute the instructions you’ve provided. 
    • To create a TwiML application, go to the TwiML app page. Create a new TwiML application, and use the public URL of your application server’s /makeCall endpoint as the Voice Request URL (If your app server is written in PHP, then you need .php extension at the end). 
    • Save your TwiML Application configuration, and grab the TwiML Application SID (a long identifier beginning with the characters AP). 
  • Configure Application Server: 
    • TwilML Application SID that we got in previous step needs to put in server configuration and then backend person need to restart the server so it uses the new configuration info. 
    • Now to check whether everything is configured correctly, open up a browser and visit the URL for your application server’s Access Token endpoint: https://{YOUR_SERVER_URL}/accessToken (If your app server is written in PHP, then you need .php extension at the end). 
    • If everything is configured correctly, you should see a long string of letters and numbers, which is a Twilio Access Token. Your iOS app will use a token like this to connect to Twilio. 
  • Run the App: 
    • To get a quick overview of the code and how things work, we can refer to Voice Quickstart for SwiftWe have used this Quickstart project as reference and used its classes in relevant application where we integrated video call functionality. 
    • Please replace baseURLString in voice class with your application server’s public url. 
    • Now if we build quickstart project, if we leave the text field empty and press the call button to start a call. You will hear the congratulatory message. To dial another client we need to do some additional steps which we will look into next. 
  • Create VoIP Service Certificate: 
    • The Programmable Voice SDK uses Apple’s VoIP Services to let your application know when it is receiving an incoming call. If you want your users to receive incoming calls, you’ll need to enable VoIP Services in your application and generate a VoIP Services Certificate. 
    • To generate a VoIP Services Certificate, go to Apple Developer portal and you’ll need to do the following: 
      • An Apple Developer membership to be able to create the certificate. 
      • Make sure your App ID has the “Push Notifications” service enabled. 
      • Create a corresponding Provisioning Profile for your app ID. 
      • Create an Apple VoIP Services Certificate for this app by navigating to Certificates –> Production and clicking the + on the top right to add the new certificate. 
    • Choose VoIP Services Certificate from available options. 
  • Create a Push Credential with your VoIP Service Certificate: 
    • Once you have generated the VoIP Services Certificate using Keychain Access, you will need to upload it to Twilio so that Twilio can send push notifications to your app on your behalf. 
    • Export your VoIP Service Certificate as a .p12 file from Keychain Access. 
    • Extract the certificate and private key from the .p12 file using the openssl command. Follow below commands to get the keys: 
      • $> openssl pkcs12 -in PATH_TO_YOUR_P12 –nokeys -out cert.pem -nodes 
      • $> openssl pkcs12 -in PATH_TO_YOUR_P12 –nocerts -out key.pem -nodes 
      • $> openssl rsa -in key.pem -out key.pem 
    • Go to the Push Credentials page and create a new Push Credential. Paste the certificate and private key extracted from your certificate. You must paste the keys in as plaintext: 
      • For the cert.pem you should paste everything from —–BEGIN CERTIFICATE—– to —–END CERTIFICATE—–. 
      • For the key.pem you should paste everything from —–BEGIN RSA PRIVATE KEY—– to —–END RSA PRIVATE KEY—–. 
    • Remember to check the “Sandbox” option. This is important. The VoIP Service Certificate you generated can be used both in production and with Apple’s sandbox infrastructure. Checking this box tells Twilio to send your pushes to the Apple sandbox infrastructure which is appropriate with your development provisioning profile. 
    • Once the app is ready for store submission, update the plist with “APS Environment: production” and create another Push Credential with the same VoIP Certificate but without checking the sandbox option. 
    • This Push Credential SID need to be added in server configuration. The Push Credential SID will now be embedded in your access token. 
  • Configure Xcode project settings for push notifications: 
    • On the project’s Capabilities tab, enable “Push Notifications”. In Xcode 8 or earlier, enable both “Voice over IP” and “Audio, AirPlay and Picture in Picture” capabilities in the Background Modes. 
    • In Xcode 9+, make sure that the “Audio, AirPlay and Picture in Picture” capability is enabled and a “UIBackgroundModes” dictionary with “audio” and “voip” is in the app’s plist. 
  • Receive an incoming call: 
    • We are now ready to receive incoming calls. Rebuild your app and hit your application server’s /placeCall endpoint: https://{YOUR_SERVER_URL}/placeCall (If your app server is written in PHP, then you need .php extension at the end). This will trigger a Twilio REST API request that will make an inbound call to your mobile app. Once your app accepts the call, you should hear a congratulatory message. 
  • Make client to client call: 
    • To make client to client calls, you need the application running on two devices. 
    • To run the application on an additional device, make sure you use a different identity in your access token when registering the new device. That is both devices must have different identity in order o get call on a specified device. 
    • Twilio generates access token on the basis of identity so it is good to have different identity for each user. 
    • In quickstart project use the text field to specify the identity of the call receiver, then tap the “Call” button to make a call. The TwiML parameters used in TwilioVoice.connect() method should match the name used in the server. This means that name or identity to which we want to call must be exact same as it registered on server. 
    • Whenever we want to make call to any other identity, we must have to register for incoming notifications using VoIP Push Notifications via TwilioVoice.registerWithAccessToken(…) and when we want to stop receiving incoming notifications, we have to unregister for incoming notifications using VoIP Push Notifications via TwilioVoice.unregisterWithAccessToken(…). 

Get Help from the Sunflower Lab Professionals

Steps to implement video call using Twilio in iOS: 

  • Install the TwilioVideo framework: 
    • To install via Cocoapods add pod ‘TwilioVideo‘, ‘~> 3.7’ in Podfile and under the project path, run pod install and let the Cocoapods library create the workspace for you. 
    • To install SDK via Carthage or manually follow this document. 
    • The iOS SDK supports iOS 11.0 or higher. 
    • The TwilioVideo.framework is built with Xcode 11. The framework can be consumed with previous versions of Xcode. However, re-compiling Bitcode when exporting for Ad Hoc or Enterprise distribution requires the use of Xcode 11.x. 
  • Xcode Configuration: 
    • To allow a connection to a Room to be persisted while an application is running in the background, you must select the Audio, AirPlay, and Picture in Picture background mode from the Capabilities project settings page. 

 

  • Get an API Key: 
    • API Keys represent credentials to access the Twilio API. They are used for two purposes: 
      1.  To authenticate to the REST API. 
      2.  To create and revoke Access Tokens 
    • We can create our API Key from the Twilio Console also. 
      • Go to the API Keys section under Tools in the Twilio Console. 
      • Click on “Create a New API Key”, add a friendly name and save your Key and Secret. 
  • Generate an Access Token: 
    • For testing purposes you can use the Testing Tools page in the Twilio Console to generate an Access Token. An Access Token is a short-lived credential used to authenticate your client-side application to Twilio. 
    • In a production application, your back-end server will need to generate an Access Token for every user in your application. 
  • Connect to a Room: 
    • Call TwilioVideo.connect() to connect to a Room from your iOS application. Once connected, you can send and receive audio and video streams with other Participants who are connected to the Room. 

twilio setup

    • You must pass the Access Token when connecting to a Room. You may also optionally pass local audio, video or data tracks, to begin sharing pre-created local media with other Participants in the Room upon connecting. You can also pass a room name, which allows you to dynamically specify the name of the Room you wish to join. 
    • You can also encode the Room name in the Access Token, which will allow the user to connect to only the Room specified in the token. 
    • An ICE transport policy, which allows you to force calls through TURN relay for testing purposes. 
    • The name of the Room specifies which Room you wish to join. If a Room by that name does not already exist, it will be created upon connection. If a Room by that name is already active, you’ll be connected to the Room and receive notifications from any other Participants also connected to the same Room. Room names must be unique within an account. 
    • You can also create a Room using the Rooms REST API. Look at the REST API Rooms resource docs for more details. 
  • Join a Room: 
    • If you’d like to join a Room you know already exists, you handle that exactly the same way as creating a room: just pass the Room name to the connect method. 
    • Once in a Room, you’ll receive a room:participantDidConnect: callback for each Participant that successfully joins. Querying the participants getter will return any existing Participants who have already joined the Room. 

  • Setup Local Media: 
    • You can capture local media from your device’s microphone, camera or screen-share on different platforms in the following ways: 
    • In an iOS application, begin capturing audio data by creating a TVILocalAudioTrack, and begin capturing video by creating a TVILocalVideoTrack with an associated TVIVideoCapturer. The iOS Video SDK provides customizable video capturers for both camera and screen capture. 

  • Specify tracks at connect time: 
    • When the client joins a Room, the client can specify which Tracks they wish to share with other Participants. Imagine we want to share the audio and video Tracks we created earlier. 

Working with Remote Participants: 

  • Handle Connected Participants: 
    • When you join a Room, Participants may already be present. You can check for existing Participants in the roomDidConnect: callback by using the participants getter. 

  • Handle Participant Connection Events: 
    • We can use room(_ room: TVIRoomparticipantDidConnect participant: TVIRemoteParticipant) method to check if any participat connects to the room. Similarly we can use room(_ room: TVIRoomparticipantDidDisconnect participant: TVIRemoteParticipant) to see if any participant disconnects from the room. 
  • Display a Remote Participant’s Video: 
    • To see the Video Tracks being sent by remote Participants, we need to render them to the screen: 

Participating in a Room 

  • Display a Camera Preview: 
    • The iOS SDK provides a means to render a local camera preview outside the context of an active Room: 

  • Disconnect from a Room: 
    • You can disconnect from a Room you’re currently participating in. Other Participants will receive a participantDisconnected event. 

  • Server-side control: 
    • The Programmable Video REST API allows you to control your video applications from your back-end server via HTTP requests. To learn more, check out the Programmable Video REST API docs. 

Get Help from the Sunflower Lab Professionals

How to start video call after making a VoIP call? 

  • Concept to switch from VoIP to video call is that when caller makes call, receiver receives VoIP call notification. 
  • After that when receiver receives VoIP call, disconnect VoIP call from receiver side so the call will get disconnected from caller side also.  
  • After disconnecting call from receiver side, we need to configure video call. 
  • For caller side, when receiver disconnects VoIP call we will get delegate method for call disconnection so we can configure video call for caller side also. 
  • In the case if receiver decline the incoming VoIP call, no video call screen will appear on receiver side but caller will get notified that VoIP call is disconnected so in that case we can’t identify if receiver has answered the call or declined the call because in both the cases we are disconnecting the VoIP call to switch to video call so we are going by regular procedure of configuring video call environment and will wait for 10 seconds to see if anyone joins to the room. If somebody joins that means receiver has answered the call other wise we will disconnect the video call.

  • There are two scenarios: 
    1.  Caller Side 
    2. Receiver Side 
  1. Caller Side Implementation: 
    • After configuring VoIP call code, open video call screen with camera preview window. 
    • Other configuration for video call like creating audio, video tracks, access token configuration these all configuration is done after the other person picks up the call. This is to avoid audio session related issue that can occur because two libraries(TwilioVoice and TwilioVideo) that are using AudioSession. 
    • To know when user disconnects call, there is one method in TVOCallDelegate, call(_ call: TVOCalldidDisconnectWithError error: Error?)This method gets called when VoIP call disconnects. 
    • So at receiver’s end VoIP call needs to get disconnected after answering or declining the call. Logic for how call disconnects at receiver side will be described later. 
    • After call gets disconnected we can start configuration of access token or audio and video track and other necessary configuration for caller side that are described in quickstart guide of video call and in its documentation. 
    • We can identify from roomDidConnect(room: Room) method of RoomDelegate to check if user has successfully connected to the room. 
    • As caller enters in the room for video call, he will wait here for 10 seconds to see if anyone enters the room or not. We can do this by setting a boolean flag that is true if we are getting an event on didSubscribeToAudioTrack(audioTrackRemoteAudioTrack, publication: RemoteAudioTrackPublication, participant: RemoteParticipantor didSubscribeToVideoTrack(videoTrackRemoteVideoTrack, publication: RemoteVideoTrackPublication, participant: RemoteParticipantthat means some user has joined the video call. These methods are from RemoteParticipantDelegate. 
    • Whenever you want to disconnect video call use self.room?.disconnect() method. 

2. Receiver Side Implementation: 

    • When receiver receives the VoIP call, he has two options: 1) Answer 2) Decline 
    • When receiver answers the call performAnswerVoiceCall(uuidUUIDcompletionHandler@escaping (Bool) -> Voidgets called so we can set a boolean flag for call answered to true. We need to set another boolean flag for call disconnected to false in this method only. This call disconnection flag checks if VoIP call disconnected or not. 
    • Whenever user picks up the call after that application will come to the foreground so register a notification UIApplication.didBecomeActiveNotification to implement code for call disconnection when app comes to foreground. 
    • In the method that will get called when app comes to background, check for below three things: 
      • User must be receiver (We can check this by setting a boolean flag when user makes call it is true otherwise its false) 
      • VoIP call must be active. This means call is not yet disconnected. To check this we can use activeCall object already available in quickstart project for VoIP. If this object is not equal to nil means call is not yet disconnected. 
      • We have set one boolean flag in performAnswerVoiceCall method to check for call disconnection. This flag must be false that means call is yet not disconnected. 
    • When all these three condition meets then only we can run the code for call disconnection by calling the method performEndCallAction(uuidactiveCall!.uuid). 
    • When call disconnected successfully, we can start video call configuration. 
    • Now when user declines the call caller will get call disconnection delegate event as we discussed in caller scenario. 

Extra configuration for video call: 

  • Voice related issue in video call: 
    • Problem-1: Sometimes it happens that while switching from VoIP to video call, you will receive voice of other participant from receiver instead of speaker by default even if you have override audio output to speaker in VoIP while configuring audio session. 
    • Solution-1 
      • When participant connects to room we are getting callback method didSubscribeToAudioTrack(audioTrackRemoteAudioTrack, publication: RemoteAudioTrackPublication, participant: RemoteParticipant). 
      • In this method, we can set audio configuration. If current audio output id built in receiver then we should override output audio port to speaker. 

    • Problem-2: If for example headphone or wireless headphone is attached before making the video call then default audio output port will be headphone, in this case if headphone is removed while video call is in progress then it can be possible that output audio port will be built in receiver which should be speaker in normal scenario. 
    • Solution-2:  
      • When we attach or detach audio port from device, we can get notification by registering to AVAudioSession.routeChangeNotificationSo register to this notification so in our scenario whenever user removes headphone, we can check route change reason key to see if device added or removed, if device is removed then we need to check if wired or wireless headphones or any other audio port is attached or not. If not then we can override audio port to speaker to avoid audio route set to built in receiver. 

References: 

  • Flow Diagrams: 
    • For VoIP: 

Related Posts

10 Essential Real Estate App Features that Enhance Your Business

Employee expense receipt management is the perfect process for RPA because it is logic based and redundant. Let’s

Guide To 7 Best Tech Stack 2023 for Software Development

Employee expense receipt management is the perfect process for RPA because it is logic based and redundant. Let’s

Get a FREE estimate for your project today.

Our team of experts will review your project and give you a quote at no cost.

Get a quote on your project!