This article is a simple tutorial for those who are transitioning from iOS to Android.
In iOS applications, information such as text posts, images, mp3 files, videos, etc. can be organized in a table view. But how exactly do we create a similar implementation in Android?
iOS Implementation
In iOS a delegate method is called when assigning the number of rows in a section and numbers of section in the table.
Android Implementation
In Android, we may create a table row object and display it depending on how many elements are there in our storage.
In this example, the array above containing strings will be our data source.
Above is an example on how we used our data source to add rows inside a table layout.
We used a For-in loop that creates a String object named sampleString for every element inside our array myStrings.
In every iteration, a new TableRow and TextView object is created.
The sampleString object is set as textView object’s text.
The textView is then added to the tableRow.
The tableRow is added to the tableLayout afterwards.
Your output should be like the image above. Again we created each table row object depending on how many elements inside the array and added them in the table layout we created in the XML.
Pretty easy and fast, right? Try working with the TableLayout and TableRow objects to see different results.
Recently, we were assigned to port an existing iOS prototype to Android. As iOS developers first and foremost, the Android experience is proving to be a challenge. In terms of the user interface, iOS still feels neater... but I’m not gonna lie, it is easier to build your app in an Android device unlike in iOS with all those certificate and private keys needed.
Anyway, those are just my insights at the moment. Now back to porting our prototype. How is this possible, you might ask? Well we used some available tools to port our existing prototype to Android...
Here are the links to the summary for each tool:
Marmalade SDK
MyAppConverter
ObjC2J
Recommendations
What to use depends on what your project needs at the moment. Marmalade SDK, for instance, introduces itself as a game engine that contains different library files and tools required to deploy applications for different mobile devices. If you are developing mobile games with cross compatibility, using Marmalade SDK is recommended.
MyAppConverter can also help you convert your native iOS app to native Android app, and it even supports Objective-C to Swift and SpriteKit to Android. However, since it is not focused on the UI of your app, you might have to consider remaking the look of your app for Android when using MyAppConverter. Also, MyAppConverter coverage for some iOS frameworks is limited (e.g. UIKit has a coverage rate of only 33%).
ObjC2J is somewhat similar to MyAppConverter. I personally do not recommend this yet because it is still under development but since it is a Google product, it is definitely worth knowing about.
This is the third of a three-part trial of iOS to Android conversion tools. More info on that here.
Introduction to ObjC2J
As stated in its documentation, ObjC2J is an “open-source library tool that translates Objective-C (Mac OS X) code to Java for the PC platform. The goal is to translate an app's written in Objective-C with UI code to JVM platform (and Android JVM in future).”
It is still in development stage and can now “nearly translate non-UI Objective-C code into Java classes.”
Read more about it here and here.
Implementing ObjC2J
In our trial, we used the following sample Objective-C code:
We found that although some Objective-C file conversion to Java source was successful...
This is the second of a three-part trial of iOS to Android conversion tools. More info on that here.
Introduction to MyAppConverter
According to its documentation, MyAppConverter “helps you convert native iOS mobile apps instantly to native Android app, it's not focused mainly on the look and feel, and UI interaction of your app.”
Services
iOS to Android
Objective-C to Swift
iOS SpriteKit to Android
Code Block Converter - converts small snippets of code instantly
Testing the Code Block Converter
Here’s a link to the sample converted code.
We tried converting a simple log from Objective-C code to Android code.
The output is as seen below:
A closer look:
This doesn’t seem to be an accurate conversion to native Android/Java language. Instead, methods built-in from the imported libraries had been used, such as
com.myappconverter.java.foundations.NSObjRuntime
com.myappconverter.java.foundations.NSString
Conclusion
MyAppConverter converts code line by line using the Code Block Converter, but it does not fully support all iOS frameworks at this time. For more details, see covered frameworks and coverage rate here.
This is the first of a three-part trial of iOS to Android conversion tools. More info on that here.
Intro to Marmalade
According to Wikipedia, Marmalade SDK is a “cross-platform software development kit and game engine by Marmalade Technologies Limited that contains library files, samples, documentation and tools required to develop, test and deploy applications for mobile devices.”
Based on its documentation, Marmalade Juice “adds Objective-C and iOS framework support to Marmalade, allowing rapid porting of iOS projects to Android and others.”
Read more on Marmalade+Juice and this Introduction+to+Juice.
Implementing Marmalade Juice
We tried converting/porting one of our existing prototypes, created using Objective-C and built on the iOS SDK, to Android. Here’s how to do it:
Right click on Marmalade, then go through Show Package Contents > Contents > Applications.
In Applications, open “hub” (not “hub2”).
Marmalade Hub can offer different things depending on what you want. In our case, we will be using Marmalade Juice to port our iOS app to Android, following the instructions on this link.
We continued porting our iOS prototype to Android and the results are shown below.
The build failed because MultipeerConnectivity.h is not found.
Building Using XCode
We tried opening the Marmalade SDK project using XCode to see if we can build it in the IDE.
Upon using XCode for Building:
The same build failure shows up when it finds the Multipeer Connectivity header file.
Conclusion
Building our existing prototype using Marmalade SDK has not been possible so far because one of the frameworks we used, Multipeer Connectivity framework, is not recognized.
In a previous article, I talked about CSS preprocessors and how they can be more helpful instead of using just plain old CSS. And although I had recommended SASS instead of LESS, I have received requests for tutorials in both as some of our readers want to test each preprocessor out and decide for themselves. So today, I shall be focusing on LESS (I’ll cover SASS in another post in the future).
Okay, let’s get the party.. I mean tutorial started..
LESS INSTALLATION
I used Node.js’ NPM to install LESS. It’s actually very simple.
This will add LESS to your project folder. You can also use NPM to install LESS globally. Just add “sudo” and “-g” on your prompt, easy peasy lemon squeezey.
Once installed, check your project folder (my project is called html5_c) for a folder called “node_modules.” In it you’ll find a “less” folder holding all the needed files for awesomeness.
Take note though: this is only for when you add LESS to a particular project. You won’t find this if you install LESS globally.
PROJECT APPLICATION
Start by creating a file with a “.less” extension.
Next, add your LESS code to the file. Try playing with your code. You can start with color palettes, using variables such as this:
Variables in LESS start with “@”. Instead of using the color hex, use variables for better naming convention.
The general idea with using LESS and other CSS preprocessors is to write cleaner code then compiling these to create the needed CSS files. You will be able to create more readable, easier-to-maintain stylesheets.
Take this CSS file for example:
We have this <div> with an id called sidebar. Under #sidebar, there’s a ul with an li under it, with a “hover” attribute called a.
If we write this in LESS instead of CSS, here’s how it might look:
See the difference? It’s NESTED!!! ...making it way easier to understand.
Another cool thing about CSS Preprocessors is the “MIXIN”. The term itself, “mix”, signifies mixing up classes to acquire certain attributes.
Take this CSS example:
Since some elements have the same attributes, mixins slashes through that, thereby minimizing confusion and lines of code.
Here’s the LESS code for the above CSS:
A class called “top-footer-tab” holds the attribute for an element with an id of “next_meeting” and “span-1″ ...Who needs to copy-paste code when you can reuse?
GENERATING THE CSS FILES
Done writing your LESS files? Here’s how to compile these to CSS...
Whoa, that’s it?? Easy, right?
Nooo. It’s actually a bit tedious if you consider how every change you make in your LESS files will not take effect in your CSS files unless you run this command.
There is a way to solve this weakness though: by using TASK RUNNERS! (will give a separate tutorial on these too, soon!)
But as far as LESS is concerned, I encourage you to try it and I’ll give you a tap on the back *tap tap* for reaching the end of this simple tutorial.
As a mobile developer, it is important to have a basic understanding of how instant messaging can be implemented as this is a prevalent function in social networking sites and social media apps. In a previous article, I mentioned about how the Multipeer Connectivity Framework can be used for creating an instant messaging app in iOS. Well here’s another way of doing this - by using web sockets.
“Sockets? Aren’t these the things where we plug our home appliances?”
Well, close. By definition, sockets are hollows which something fits into. Although in this article we are referring to web sockets.
How Sockets Work
In the above illustration, the message “Hello!” is sent by a mobile client. It will be sent to the server through our socket and back to other clients through our socket again.
HTTP Requests VS Web Sockets
Unlike in the commonly used HTTP where we send a GET or POST request to the server like the snippet below:
Web Sockets automatically send data to all clients connected to the server by having a full-duplex communication. Full-duplex allows both client and server to communicate with each other simultaneously. This is similar to our landline phones and mobile phones where both users can speak and be heard at the same time.
This gives us a real-time conversation using our mobile app or web app.
Here’s a sample snippet using Socket Rocket for iOS.
The first step is to connect to the web socket:
Then, use the delegate methods to handle the result of the connection:
Create a helper method to be used in sending your message:
Finally, a delegate method will be called when a message is received:
Besides Socket Rocket, socket.io may also be a helpful resource when creating your app. Try these out and show off your simple chat application to the world!
This might probably be my last entry as an iOS developer and a member of R&D as I’m soon to be reassigned as a Python developer. I loved being an iOS developer and thankfully I was able to experience one year of iOS development. Although it was a short time, I really enjoyed developing 2 iOS apps and a lot of unfinished prototypes. I learned a lot from my team. I’m thankful to my manager for being patient and understanding but she had no choice except let me go. Hopefully, I won’t forget everything I learned and will do my best to keep updated in iOS development so I won’t forget how it feels to be an IOS developer. Well at least I could learn something new and have a fresh start and two specializations. That would be so cool. Now I could have the best of both worlds. I will surely miss my team. It was fun while it lasted. I guess this is goodbye. As Kobe Bryant said: “This season is all I have left to give. My heart can take the pounding. My mind can handle the grind. But my body knows it’s time to say goodbye.”
Recently I was asked to do a sample dating app and one of its key elements is a page where a user could fill out his or her profile and preferences.
Naturally, there are a lot of fields to fill out...
Having a lot of text fields to fill out is a pain, not just for the user, but for us developers too. Should we validate each text field to ensure correct data? That would cost us a lot of time and require long code which could get really messy.
A quick alternative to this would be to limit users’ options through picker views, such as the UIPickerVIew in iOS. Users can simply choose from pre-defined options that developers have screened beforehand to not contain invalid data.
Hope this tip saves you a lot of time and several lines of code!
In a previous post, we had announced the release of Make Me Calm, which features integration with Apple’s Health app. The road to release hasn’t been without its hiccups though. One might even say getting Make Me Calm to the App Store has made us anything but calm, lol.
Are you in the final stages of developing your own Health app? Well you’re in luck; here’s a quick checklist of items you will need to consider prior to submitting your app binary.
□ Read Apple’s Guidelines for using HealthKit
Seriously, don’t just read them, commit them to heart. These Guidelines are the equivalent of Uncle Ben telling you to take real good care of your users’ Health data. Don’t be this guy:
□ Prepare your privacy policy
A privacy policy needs to be included in-app, and a URL to it should be provided in your app information on iTunes Connect . Setting up a privacy policy webpage and displaying this page in-app through a webview is a good approach if you see the need to update your policy later on (without having to submit a new app version).
□ Indicate integration with the Health app in your marketing info
This includes text on your iTunes Connect app description as well as on the webpage listed in your app’s Marketing URL.
□ Make sure HealthKit has been checked in App Services
...on the App IDs used in generating your provisioning profiles. If it hasn’t, your app will not appear on the iPhone’s Settings/Privacy/Health (see below) after the user gives permission to access Health data. This is considered a major bug and will cause your app to be rejected.
□ Finally, the HealthKit functionality must be clearly identified in your app's user interface
Nobody wants their health info floating out in the void. So when it comes to Health-related apps, a good user experience should include steps to educate through UI how the app utilizes Health data. Be as straightforward as possible, e.g. in your How-To-Use or Tutorial screens, to build users’ trust.
Prior to XCode 7, you could just put any object of type id into collection types such as NSArray, NSDictionary, or NSSet. This was like putting stuff in a box. You’d never know what was in it until you open and see what was inside.
The problem with this is the likelihood of an error to occur when retrieving an object with a different data type than expected, e.g. retrieving an NSString object instead of an NSInteger variable. It’s like sticking your hand into the box and pulling out a cat, when all the while you were simply expecting to pull out a pair of socks.
The obvious solution to this is to create code to do error-checking or typecasting of the objects being retrieved. This takes time to code and test though. Good thing there is now an easier way: using the Objective-C Generics collection. Until recently, this was only available in Swift, and it’s like putting labels on boxes.
With Generics, you can specify what type of object you want your collection types to have. If you want to have an Array of NSString objects, you can do so without worrying about passing or retrieving the wrong type of object. This also makes code more readable and helps your app run faster.
Here’s how to declare the Generics collection
For NSArray/NSMutableArray: NSArray<datatype>
For NSDictionary/NSMutableDictionary: NSDictionary<keyType, objectType>
For NSSet/NSMutableSet: NSSet<dataType>
Generics can also be applied to custom classes
Declaration
Implementation
If we declare with NSString type, the compiler will ask for an NSString type argument to be inserted. Inserting types other than NSString will also generate a warning.
Covariance and Contravariance
The __covariance & __contravariance type constructors are not included in Apple’s documentation, but i saw this implemented in one of the collection classes.
These are constructors that will ensure type-safety. We use _covariant if we want our collection class to be immutable, meaning we cannot change the elements inside the collection. On the other hand, we use _contravariant if we want our collection class to only be written to, meaning we cannot read the elements in the collection class.
This is how we implement a Generics class with __covariant:
Header File
Implementation File
Notice that the method declared in header file is different in our implementation file. Apparently ‘ObjectType’ is just a placeholder; it is not a data type. Therefore you will have an error if you type ‘ObjectType’ as an argument. In order to have a method that takes Generics parameters, id should be used so it can be any type of object. Note that ‘ObjectType’ is just a place holder. You can use any name you want. We simply used the name ‘ObjectType’ to be consistent with Apple’s implementation.
You can also specify what type you want your Generics class to have.
Using other data types will return an error.
Plus we can be more specific in our method. So instead of id, we can use NSArray
And there you have it! Having generics makes our code a lot easier to manage. There’s less worry about retrieving and handling unexpected data types that could cause runtime errors. Generics makes your collection types clearer as to what type of objects they contain. I hope you will be able to use Generics soon in your projects.
We’ve just released Make Me Calm for Apple WatchOS 2!
Get it on the App Store: Make Me Calm for Apple Watch
And check this out: the app has also been included on WatchAware. Donuts for everybody! :D
So the thing about it is… “Make Me Calm” is not just a mantra. It’s a handy app to help you get through difficult moments. Whenever you’re feeling angry, sad, or even afraid, you can use the app to relax by reading inspiring quotes and soothing messages.
We’ve also integrated Make Me Calm with Apple’s Health app, to detect if you are within the average resting heart rate of 60-100 beats per minute. Anything higher than 100 bpm may signify stress or anxiety, but who’s to say a minute of silence and encouraging words can’t change that.
To everyone who attended the 6th Cyscorpions' In-House DevCon on October 21, consider this a slightly-delayed thank-you-note! Does news on our industry’s platform leaders make more sense now? I hope so! I hope “Riding on the Backs of Giants” has given you some ideas on how to D.I.E. (insert collective gasp of those who weren’t able to attend here).
Alright, for those who didn’t get the D.I.E. joke, check out the slides from the talk. It’s not the same though without my brilliant side-comments in the background, lol.
Here at Cyscorpions R&D we continue to strive to deliver the latest technology to our fellow developers. One way to do this is to integrate our research to some of our prototypes.
In my experience as part of the team, I have encountered several obstacles in both research and development phase. One story that I would tell you is about the current prototype I’m working on.
I was assigned to do a prototype application which showcases the Multipeer Connectivity Framework.
“What in the world does that framework do?”
Some introduction to this framework.
Multipeer Connectivity provides discovery and communication with nearby iOS devices by sending message-based data, streaming data and resources like files and images using infrastructures such as Wi-Fi networks, peer-to-peer Wi-Fi, and Bluetooth.
Here comes some technical terms..
Sessions
Session objects manages the communication for peers. It is like a dinner table where friends or families communicate with each other.
Advertisers
This is the guy that tells the other guys “hey I’m ready to chat!”. It tells other peers that you are willing to join a session.
Browsers
Browser objects looks for advertisers and invites them to sessions. It is the host guy of the group.
Heads up to these limitations
Only 8 peers are able to communicate in one session including the host
Communication is really slow especially transferring files when using bluetooth
“How’s your development experience?”
I was assigned to do a prototype where the main feature is to chat within a group using bluetooth.
I encountered two significant problems:
Remove the authentication when joining a session
Eliminate the limit of peers per session (we are trying something different)
I will try to rate these two problems based on how many mugs of coffee I consumed while solving them.
Remove the authentication when joining a session
The first problem is not really complicated.
What I did to solve it is to automatically connect the advertiser to the session when it is found by your browser object.
But be advised that this our prototype’s feature. It is recommended that you add an authentication to increase the security of your application. Here are some related links:
NSHipster Multipeer Connectivity
Multipeer Connectivity Presentation by waynehartman
I rate this problem with 3 mugs of coffee.
Eliminate the limit of peers per session
This one is really tricky and we’re looking at different ways to implement it. We’re trying to eliminate the user limitation or in other words any amount of users should be able to join the group chat.
Unfortunately we haven’t implemented this yet but here are some ways that we’re looking on
Save the state of the messages sent by the users in the session
Automatically disconnect idle peers so that it will free up slots in the session and reconnect peers who are going to be active
Send the saved messages to the newly connected peer
Though we haven’t really solved this one yet, I still rate this problem with 5 mugs of coffee.
So that’s about it. Make sure to utilize this fancy framework introduced by Apple. The best thing about development is having fun while experimenting with new things. Don’t forget to drink your coffee as a booster pack. Go all out and create the next big thing!
It is not common for iOS applications to use peer-to-peer connection nowadays because of the more powerful cellular data and wireless LAN technology. But in cases where you cannot find any Wi-Fi connection or cellular signal on your phone, peer-to-peer connectivity might come in handy.
For instance, we can use peer-to-peer connectivity so users may be able to chat with each other. There are different peer-to-peer approaches, depending on the type of application you are planning.
A peer-to-peer chat application can use the Multipeer Connectivity framework by Apple to exchange messages between iOS devices, irregardless of whether users have a cellular signal or wi-fi connection.
Multipeer Connectivity Framework
Multipeer Connectivity Framework offers reliable communication with iOS devices through Bluetooth, and communication is even more reliable when devices are connected to the same wireless network. If you are developing social networking or dating type apps, I would recommend this framework as it can provide anonymity to the user.
“I want to add a multiplayer feature to my game app, can I use Multipeer Connectivity?”
Although you can use Multipeer Connectivity for your game application, there is a more suitable framework available that focuses on multiplayer features for game applications: the GameKit Framework.
GameKit Framework
GameKit Framework is a higher level framework compared to Multipeer Connectivity Framework. Although they have a lot of similar functionality, GameKit is recommended for game applications as it offers more functionality such as Game Center and in-game voice chat which the Multipeer Connectivity doesn’t have.
“Those two frameworks sound big. I just want a setup where one sends data and the other receives and processes it.”
In this simple case, a framework called Core Bluetooth is available for use.
CoreBluetooth Framework
CoreBluetooth Framework has two profiles: the peripheral and the central. The peripheral usually has the data needed by the central. To accomplish tasks for your app, the central searches and connects to the peripheral, and processes whatever data the peripheral has sent.
If your application is as simple as a reminder app, where a device A sends reminders whenever device B is nearby, then CoreBluetooth Framework is recommended.
In WatchOS 1, the way to communicate to the Parent App (iPhone App) is via openParentApplication method. In Watch OS2, there are now Watch Connectivity sessions. Here’s a quick guide on how to setup using the latest method.
First things first, import WatchConnectivity (for this sample app, I used Swift).
Next, you'll need to setup an app connectivity session before receiving data.
Application Context
Context is passed using transfer queue. When the new context arrives, it will override the current context (e.g add new user or update user data).
To receive data from its counterpart, use the delegate method session:didReceiveApplicationContext:
Messaging
Messaging require devices to be in a reachable state. To check the device’s reachability:
To send data via session:
These methods use NSDictionary representation to send information. If you want to send information in NSData representation, use the sendMessageData:replyHandler:errorHandler: method.
For callbacks on sending data, check out session:didReceiveMessage: and session:didReceiveMessage:replyHandler:
For more info about Watch Connectivity Session, please refer here.
Technically you can send information without checking the device’s reachability just by directly triggering the sendMessage method. However, checking reachability before execution is best practice.
Advanced Techniques for Sharing Data Between Parent and Watch app
Notification
You can use the Darwin Notification Concept to broadcast notification between two processes (via process ID or PID). Darwin Notification runs in a kernel level of application and has a unique process identifier.
Shared Data Container
App Groups is an iOS scheme that allows different apps to share data. If your apps have the right entitlements and proper provisioning profile, they can access data and directories outside your iOS sandbox environment. Check out Apple’s App Groups configuration guide for more info.
For writing a data container, you can use NSUserDefaults or NSFileManager.
To deploy projects or games for web use, developers have long used Unity Web Player on browsers that support the NPAPI plugin. However, with the deprecation of the NPAPI plugin on Chrome (and soon on other browsers), Unity recommends WebGL as an alternative. It is a solution that is still under development, but so far WebGL has shown some potential as a substitute for Web Player.
We thought we’d try it out by doing a test deploy of one of Cyscorpions’ most loved apps, Red’s Revenge. With just a few tweaks, we were able to transform what was originally a Unity game built for the iPhone into a web game, playable on Chrome.
Here are the steps for deployment:
Go to File → Build Settings in Unity. You should see a popup menu like the one below.
Select an Optimization level. You can choose from three options: Slow, Fast, and Fastest.
Selecting Fastest will produce optimized builds but building time will take longer to complete. This is best used for making a final build for production or for release.
Selecting Slow will build your project faster but it will not be as optimized as the Fastest option. This is best used when testing for possible bugs.
Check Development Build. If this is enabled, Unity will provide a build with a non-minified version of Javascript so we can trace errors efficiently.
Click the Build And Run button. This will build and compile your Unity project to WebGL and run it after finishing.
With a running WebGL build, you too can deploy your Unity application to various sites or even setup a site and upload your content. Take note, however, that you may also encounter different errors as Unity WebGL is still under development and has its limitations compared to Unity Web Player.