Android Vs iOS: What Platform Should You Build Your Mobile App For?
Now that we live in a society that’s heavily reliant on mobile technology, mobile app development has seen a boom over the last few years. As smartphones get an upgrade with each brand’s release of their flagship device, apps become more advanced. They dish out more features that not only help users but also businesses to expand their operations through this platform. Apple has even trademarked the catchphrase “there’s an app for that” to let users know there is one that can actually help with just about any particular task.
According to an App Annie report, the mobile app industry earned a whopping US$41.1 billion in gross annual revenue and according to Statista, it’s projected to hit US$101.1 billion by 2020. With the population of smartphone users growing each year, the market is far from saturated.
Internet on-the-go is clearly a necessity for many users, and there’s nowhere to go but up. More companies are starting to jump into the mobile app arena after regarding smartphones as a catalyst that can grow their business. The mobile app platform has become a channel to boost sales, increase brand awareness and deliver content through branded apps.
But how do you jump into the fray? Like all things technical, there’s a process you need to go through. Here’s how it currently goes:
Choose an initial platform for the app
There are two giants that dominate the current smartphone market: Android and iOS. To find out which one has more users, a study by Gartner found that 87.8% of smartphones sold in Q3 of 2016 globally were Android. In contrast, Apple only had 11.5%. While there is a huge difference, that doesn’t mean going for Android is the better choice.
Test and get feedback
Once you’ve developed your app on your preferred platform, you will need to beta test it to an intended audience and collect feedback on how it works. During this process, you will know if everything about how the app is designed works perfectly. You will also find out if there are bugs you need to fix and improvements that would make your app better.
Make iterations and expand features
After zeroing in on the bugs and identifying what you need to improve on, you can release new versions packed with all the new features. This is a continuous process; as your business improves, so does your app to deliver the best user experience you can offer.
Build and release the app on the other platform
You will eventually be able to figure out how everything works on your initial operating system. The next step is to widen your reach, so your next move is to release your app on the other platform.
But for your initial development, testing, and optimization processes, you should be able to address the question: Which platform should you go for? Let’s weigh up the differences.
Android
The Pros: With its open-source software, Android offers app developers a low barrier of entry and allows the use of crowd-created frameworks and plugins. This results in a platform that’s more flexible, which gives developers the freedom to play around with their app’s features and functionalities. This kind of technical environment enables them to modify apps to make the necessary improvements.
As mentioned earlier, Android operating systems have a huge monopoly over the smartphone market. Although this makes Android look like the obvious first choice, there are many other factors that come into play.
The Cons: Although Android’s open-source nature is favorable for developers, it’s a double-edged sword. Android app development is more complex, taking more time to master. And while the OS covers a wide variety of devices and iterations, this benefit causes a large amount of fragmentation. This results in varied user experiences across all devices.
With its highly-fragmented platform, developers are faced with a real challenge as apps need to be optimized for various screen sizes and operating systems. This leads to a lot of compatibility and testing required, ultimately increasing development costs. For this reason, app development takes longer than those on iOS.
iOS
The Pros: iOS offers a more stable and exclusive platform for developers, making the apps easier to use. Apple designed it to be a closed platform, so the company can design all of their own hardware and software around it. This gives them the authority to impose strict guidelines, resulting to a quick and responsive platform where apps are designed well with less piracy involved.
Since 2016, over 25% of iOS developers earned over US$5,000 in monthly revenue, while only 16% of Android developers generated the same amount. And when it comes to monthly revenues earned by mobile operating systems, a Statista study estimates iOS earns US$8,100 on average per month, bumping Android to second place with US$4,900. But despite these numbers favoring iOS, a third of developers prefer Android.
Compared to the thousands of devices using Android, iOS runs on a mere 20 devices. And with both resolution and screen size playing a smaller role in the app development process, it’s quicker and easier. This results in significantly less device fragmentation.
To put things into perspective, developing an app compatible with three of the latest iOS version covers about 97% of all iOS users. This makes it a fitting choice for first-timers in app development.
The Cons: Due to its restrictive nature, developer guidelines offer a fixed set of tools to build an app, making customization limited. And with the frameworks used to build an app, many of them licensed, development costs could increase.
Additionally, iOS is widely regarded as a more mature operating system than Android, with established rules and standards. These can make approval from the App Store more difficult, taking 4-5 days for an app to be granted one.
Cross-Platform App Development
The Pros: Essentially, cross-platform app development allows you to develop two apps---both for Android and iOS---at the same time. The tools you can use reduces the time and costs related to app development on both platforms. One of the most influential frameworks currently out there is React Native.
React Native is the brainchild of Facebook with the goal of having a framework for smooth and easy cross-platform mobile development. This means no more creating apps separately for Android and iOS. All it takes is one codebase and you’ll be able to create awesome apps that work on both platforms without compromising user experience or interface.
Since cross-platform app development has a ‘write once, run everywhere’ approach, it greatly reduces costs and development time. This means there is no need to learn multiple technologies; all you need is to master a few and you can set things in motion. Initial deployment for your app will move along much faster due to its single codebase nature.
Additionally, any changes needed to be done on the app can be implemented simultaneously without making separate changes on each platform. In terms of business, it’s ideal to develop cross-platform apps to reach a wider audience, which would ultimately lead to higher revenues.
The Cons: Compared to Android and iOS, cross-platform apps do not perfectly integrate into their target operating systems. This results in some apps failing to perform at an optimal level due to erratic communication between cross-platform code and the device’s Android or iOS components. This may also result in failure when it comes to delivering optimized user experiences.
Conclusion
Your choice will entirely depend on your business goals and budget. Each of these platforms has its strengths and weaknesses, but to help you decide, you should know what’s going to work for your business. After careful consideration of your costing, the time of release, and the reach/target audience you’re aiming for, you may have a clearer picture as to where you would want to build your app.
Looking for a pro to help with your mobile app development project? Contact our seasoned experts at Intelligent Bee to learn what we can do for your business!
How to Build an Android Login Screen
Many applications require users to login in order to access all the available features. In this tutorial we will secure an Android activity by requiring users to enter their username and password.
We will start by creating a new blank activity with fragment, LoginActivity.
We will use the following layout for the login fragment (2 edit texts for username & password, 1 button to submit the login form and one text view to show any errors that could happen):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context="com.sendgrid.android.sendgrid.app.LoginActivity$PlaceholderFragment"> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType="textEmailAddress" android:ems="10" android:id="@+id/username" android:hint="Username" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType="textPassword" android:ems="10" android:id="@+id/password" android:layout_below="@+id/username" android:layout_alignLeft="@+id/editText" android:layout_alignStart="@+id/editText" android:hint="Password" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Login" android:id="@+id/button" android:layout_below="@+id/password" android:layout_alignLeft="@+id/editText2" android:layout_alignStart="@+id/editText2" android:layout_alignRight="@+id/editText2" android:layout_alignEnd="@+id/editText2" android:onClick="tryLogin"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" android:id="@+id/error" android:layout_above="@+id/username" android:layout_centerHorizontal="true" android:textColor="#ffff0000" /> </RelativeLayout>
Before writing the actual login code, we will create a helper class to read & save related values to Android's SharedPreferences:
public class Utility { public static Boolean isUserLoggedIn(Context context) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); return prefs.getBoolean("isUserLoggedIn", false); } public static void setUserLoggedIn(Context context, Boolean isLoggedIn) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences.Editor editor = prefs.edit(); editor.putBoolean("isUserLoggedIn", isLoggedIn); editor.commit(); } public static void logout(Context context) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences.Editor editor = prefs.edit(); editor.putBoolean("isUserLoggedIn", false); editor.commit(); } public static void saveUsernameAndPassword(Context context, String username, String password) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences.Editor editor = prefs.edit(); editor.putString("username", username); editor.putString("password", password); editor.commit(); } }
Now let's see the actual login code:
public class LoginActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(R.id.container, new LoginFragment()) .commit(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { return false; } public void tryLogin(View view) { LoginFragment fragment = (LoginFragment) getSupportFragmentManager().findFragmentById(R.id.container); fragment.tryLogin(view); } /** * A placeholder fragment containing a simple view. */ public static class LoginFragment extends Fragment { public LoginFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_login, container, false); return rootView; } public void login(Boolean result) { Utility.setUserLoggedIn(getActivity(), result); if(result) { EditText user = (EditText)getActivity().findViewById(R.id.username); EditText pass = (EditText)getActivity().findViewById(R.id.password); String username = user.getText().toString(); String password = pass.getText().toString(); Utility.saveUsernameAndPassword(getActivity(), username, password); getActivity().finish(); } else { Utility.saveUsernameAndPassword(getActivity(), null, null); TextView error = (TextView)getActivity().findViewById(R.id.error); error.setText("Login failed! Please try again."); } } public void tryLogin(View view) { EditText user = (EditText)getActivity().findViewById(R.id.username); EditText pass = (EditText)getActivity().findViewById(R.id.password); String username = username.getText().toString(); String password = password.getText().toString(); if(!username.isEmpty() && !password.isEmpty()) { TextView error = (TextView)getActivity().findViewById(R.id.error); error.setText(""); CheckLoginTask loginTask = new CheckLoginTask(); loginTask.execute(username, password); } } // we will use an AsyncTask to connect to an API service to check the username and the password // the doInBackground method will return true if the login succeeds public class CheckLoginTask extends AsyncTask<String, Void, Boolean> { @Override protected Boolean doInBackground(String... params) { HttpsURLConnection urlConnection = null; BufferedReader reader = null; String responseJsonStr = null; try { // Construct the URL for the get User query final String GET_PROFILE_BASE_URL ="https://api.domain.com/user?"; Uri builtUri = Uri.parse(GET_PROFILE_BASE_URL).buildUpon().build(); URL url = new URL(builtUri.toString()); // Create the request to server and open the connection urlConnection = (HttpsURLConnection) url.openConnection(); // Create the SSL connection SSLContext sc; sc = SSLContext.getInstance("TLS"); sc.init(null, null, new SecureRandom()); urlConnection.setSSLSocketFactory(sc.getSocketFactory()); // Add API credentials String user = params[0]; String password = params[1]; String userpass = user + ":" + password; // Create the Authentication Token String basicAuth = "Basic " + Base64.encodeToString(userpass.getBytes(), Base64.DEFAULT); // Add the required Headers. urlConnection.addRequestProperty("Authorization", basicAuth); urlConnection.addRequestProperty("Content-Type", "application/json"); urlConnection.setRequestProperty("accept", "application/json"); // Method urlConnection.setRequestMethod("GET"); // Connect urlConnection.connect(); int status = urlConnection.getResponseCode(); String reason = urlConnection.getResponseMessage(); Log.v("LOGIN", status + reason); // Read the input stream into a String InputStream inputStream = urlConnection.getInputStream(); StringBuffer buffer = new StringBuffer(); if (inputStream == null) { // Nothing to do here return null; } reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { // Since it's JSON, adding a newline isn't necessary (it won't affect parsing) // But it does make debugging a *lot* easier if you print out the completed // buffer for debugging. buffer.append(line + "\n"); } if (buffer.length() == 0) { // Stream was empty. No point in parsing. return null; } responseJsonStr = buffer.toString(); getNameDataFromJson(responseJsonStr); } catch (IOException | NoSuchAlgorithmException | JSONException | KeyManagementException e) { Log.e("LOGIN", "Error", e); return false; } finally { if (urlConnection != null) { urlConnection.disconnect(); } if (reader != null) { try { reader.close(); } catch (final IOException e) { } } } // if we reach here it means we successfully logged in return true; } @Override protected void onPostExecute(Boolean result) { super.onPostExecute(result); login(result); } } } }
In the end, all that's left is to start this activity whenever we need the user to login:
public class MainActivity extends Activity { // ... @Override protected void onResume() { super.onResume(); if(!Utility.isUserLoggedIn(this)){ startActivity(new Intent(this, LoginActivity.class)); } } // ... }
iOS vs. Android - Which One Should You Choose?
Six users, six questions. After a (very) long research about which mobile OS is better between the two, I realized that the simplest way to find that out is by actually talking to people that use them. As you might expect, everyone has its own requirements and tastes, but in the end, one of the two OSs clearly stands out.