Tag Archives: App

How to built a Control Center layout with 25 lines of Swift code

Control Center using GridLayout

Recreating a layout similar to Control Center is easy with GridLayout, a library that uses AutoLayout to organize view in a grid like layout.

The key to building this layout is seing it as a grid with 4 equal columns and 6 equal rows. Placing items on the grid is then a matter of picking the right column and row and the right column span and row span.

    func buildControlCenter() -> UIView {
        var items = [GridItem]()
        items.append(GridItem(buildPanel(), position: Position(rowSpan: 2, columnSpan: 2), margin: 8).stretched())
        items.append(GridItem(buildButton(), margin: 12).stretched())
        items.append(GridItem(buildButton(), row: 1, margin: 12).stretched())
        items.append(GridItem(buildButton(), column: 1, margin: 12).stretched())
        items.append(GridItem(buildButton(), row: 1, column: 1, margin: 12).stretched())
        items.append(GridItem(buildButton(), row: 2, margin: 12).stretched())
        items.append(GridItem(buildButton(), row: 2, column: 1, margin: 12).stretched())
        items.append(GridItem(buildButton(), position: Position(row: 3, columnSpan: 2), margin: 12).stretched())
        items.append(GridItem(buildButton(), row: 4, margin: 12).stretched())
        items.append(GridItem(buildButton(), row: 4, column: 1, margin: 12).stretched())
        items.append(GridItem(buildButton(), row: 5, margin: 12).stretched())
        items.append(GridItem(buildButton(), row: 5, column: 1, margin: 12).stretched())
        items.append(GridItem(buildPanel(), position: Position(column: 2, rowSpan: 2, columnSpan: 2), margin: 8).stretched())
        items.append(GridItem(buildButton(), position: Position(row: 2, column: 2, rowSpan: 2), margin: 8).stretched())
        items.append(GridItem(buildButton(), position: Position(row: 2, column: 3, rowSpan: 2, columnSpan: 2), margin: 8).stretched())
        items.append(GridItem(buildButton(), row: 4, column: 2, margin: 8).stretched())
        items.append(GridItem(buildButton(), row: 4, column: 3, margin: 8).stretched())

        return UIView.gridLayoutView(items: items,
                                     rows: [.fill, .fill, .fill, .fill, .fill, .fill],
                                     columns: [.fill, .fill, .fill, .fill])
    }

You can find the entire sample on GitHub.

If you haven’t already, give GridLayout a try, it can save you time when building complex layouts.

I use GridLayout in several of my games. If you would like to check them out, visit my website.

5 Rules for Creating App Screenshots

Screenshots are one of the crucial ingredients contributing to the success of your app.
Great apps have great screenshots and Store assets. The purpose of the screenshots is to communicate the strong points of your app. Imagine having a pitch your idea in person to someone in person. The sentences you use to describe your app should be the inspiration for your screenshots.

1. Screenshots should surface your content using a compelling narrative

The screenshots should be accompanied by short 3 to 5 words sentences. These sentences should either summarise the focus of the screenshots or tell part of the app story.
Remember: users are motivated by stories and convinced by compelling graphics.

2. Use your best screenshot first

First impressions matter so make good use of the first screenshot slot. Ask yourself If the user only looks at one screenshot, what screenshot should that be? Assume you have only one chance to convince the user and focus on capturing the essence of the app in the first screenshot.

3. Avoid using screenshots of the user interface

Screenshots of settings, options, about us or similar supporting views should not be captured in screenshots. If possible you can even remove elements of the user interface from the screenshots to avoid distracting the user attention. (E.g. remove a distracting back button if it sits on top of aesthetically pleasing content before taking the screenshot). Feel free to break this rule if the user interface is award winning or designed by a renowned artist.

4. Use all available screenshots slots in the Store

If the app does not offer a lot of content use the screenshots for telling a story instead.

E.g.

  • A weather app that only has only a view that displays the weather in your current location, and does not allow seeing the forecast or the weather in other locations: take screenshots during different time of the day and in differ physical locations. Use 3 to 5 screenshots to show the main view with different content while explaining to the user the ideal use case for the app.

  • A note taking app with only one view should focus on how the app can be used instead of enumerating features. The main features of the app should be obvious from the usage scenario.

5. The last screenshot should either be memorable or contain a call to action

Use one of the most attractive screenshots as the last screenshot along with your tag line. Alternatively, use a call to action to instruct the user what to do next.

Rules can only get you so far. To really stand out, feel free to take creative liberties. After all, if your are doing what everyone else is doing, you won’t be any better than the rest.

Follow these rules to improve your Store conversion rate and to make users understand your app faster.

I have used these rules successfully on several of my games that I published in the Microsoft Store and in the App Store. You can find links to all the games that I built on my website: frenzygames.net

Listen to your users, they know what they want

While developing Puzzle Frenzy, I took tons of wrong decision. On multiple occasions I assumed what my game players want and I implemented several features which were never used, or used by very few users.

However, over time I started to listen to what the users were asking for. By putting together all the communication channels I was able to come up with totally different features that I originally had in mind. And guess what?! by implementing those features suddenly I got more user engagement, better ratings and more downloads.

Being an game or app developer is not easy and surely poses a lot of challenges. For me, one of the biggest problem was that I was putting my judgement ahead of my users feature requests.

I soon as I realized that 50.000 voices are stronger than 1 (my own) the game development started to flourish.

For anyone out there interested in satisfying their users I have one golden advice:

Listen to your users, they know what they want!

Quiz for Geeks is now available on Windows Phone!

I’m pleased to announce Quiz for Geeks is now available on Windows Phone.

You can now get the same set of questions and the same challenging gameplay at your fingertips!

Give it a try and let me know what your think!

Download link: http://www.windowsphone.com/en-us/store/app/quiz-for-geeks/2a79d5ca-c1a0-4f19-b044-6073c41953b7

Constructive feedback and good ratings are encouraged 🙂

Quiz for Geeks for Windows Phone

Quiz for Geeks for Windows Phone

How much code can you really place in your Portable Library?

Recently, Jevgeni asked me how much code I was able to share between my projects by using a Portable Library. He is contemplating building a Windows Phone and a Windows Store app and wants to create a Portable Library for sharing common code.

So I decided to get some numbers based on my new app code which is going to (hopefully) reach Windows Store soon.

Code Sharing between a Portable Library and a Windows Store app

Code sharing between a Portable Library and a Windows Store app

The app is not 100% ready yet, so I might add few lines of code but at the moment it turns out I placed more than 70% of my code in a Portable Library.

However, I invested quite a lot into having such a structure as I plan to release a Windows Phone app around the same core.

While you are waiting for my new app to be released :), go ahead and try my other apps already in the Windows Store: Puzzle Frenzy (download link) and Puzzle Frenzy Kids (download link).

Ask for User Rating: The Story of How I Doubled My Daily App Downloads

I currently have two apps in the Windows Store: Puzzle Frenzy and Puzzle Frenzy Kids. I’ve been closely monitoring user rating, feedback and request from day one and tried at the same time to tweak and improve the apps.

However, one thing I noticed quite fast was that my app was not getting too many ratings. Even if rating an app is possible in Windows 8 for all apps without extra work (bring up right side bar -> Settings -> Rate and review), my users were simply not doing that. On top of that, I noticed that my competitors’ apps and all the top apps in the same category had hundreds, thousands, even tens of thousands of ratings.

I also realized that the more ratings an app has, the higher it is placed in the Windows Store. It goes without saying that user ratings have a significant contribution to the ranking of the app.

Therefore, I decided to ask for user rating inside the apps, to see if the users will respond and rate my apps more frequently.

However, I found what I think is the sweet spot for getting users to rate the app:

  • I will ask users to rate the app only after they have engaged in (and hopefully enjoyed) the app, that is after they already played 3 puzzle games. By doing so, the users will most likely give it a good rating because they appear to have enjoyed the app enough to stay in the app and play all the 3 games.
  • I offer the user the choice not to rate it and ask again later. I tried not to be too annoying with these requests so I only display it after 3, 7, 15 or 30 games. If even after the fifth prompt the user hasn’t rated the app, I won’t bother him again because he most likely isn’t going to rate the app anyway.
  • I don’t bother the user again once he rated the app, but I still display a “Rate app” button on the home page, in case he changes his mind or wants to update his rating.
Puzzle Frenzy User Rating Prompt

Puzzle Frenzy User Rating Prompt

After introducing these changes, the number of ratings I was getting increased quite a lot.  In around one week I started to get the same number of ratings which before I was getting in one month.

As a consequence, (there were other factors for sure, but the user rating prompt was most likely the most important) the apps got ranked higher and higher, and they started getting more downloads.

On average, now I get around twice as many downloads as I did before.

I highly recommend adding such prompt to anyone developing apps on any platform.

Be ready however, with more ratings and feedback comes more responsibility.

Take user feedback into account and react to it as it will help you improve your app.

Good luck!

Ensuring Data Integrity Using Digital Signatures in WinRT

The data stored in Windows Storage  for Win8 Apps (equivalent of IsolatedStorage for WP8) can be accessed by users directly, even by using Windows Explorer.

The files are stored under C:\Users\<User>\AppData\Local\Packages\<AppName>\LocalState and even if <AppName> is actually a combination of publisher name, app name and another sequence of letters, it is pretty easy to tell which app is which.

If you are going to store data and you want to keep your users from modifying it, you have to make sure you have the right mechanisms in place for doing so.

Luckily, WinRT has some useful libraries for helping you accomplish file signing in Windows.Security.Cryptography namespace.

The classes in this namespace can help you ensure the integrity of a file by creating a digital signature whenever you save it, and by verifying the signature whenever you read the file.

Wikipedia is a good starting point for finding out more about Digital Signatures and RSA.

Here is how you initialize the all the variables needed for signing and signature verification:

var hashAlgorithmName = HashAlgorithmNames.Sha1;
var asymmetricKeyAlgorithmName = AsymmetricAlgorithmNames.RsaPkcs1;

hashAlgorithm = HashAlgorithmProvider.OpenAlgorithm(hashAlgorithmName);
asymmetricKeyAlgorithm = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(asymmetricKeyAlgorithmName);

var privateKeyBuffer = Convert.FromBase64String(privateKeyString).AsBuffer();
privateKey = asymmetricKeyAlgorithm.ImportKeyPair(privateKeyBuffer, CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey);

Here is how you create a signature:

public IBuffer Sign(IBuffer byteArrayBuffer)
{
var hashBuffer = hashAlgorithm.HashData(byteArrayBuffer);
var encryptedBuffer = CryptographicEngine.Encrypt(privateKey, hashBuffer, null);

var hashString = CryptographicBuffer.EncodeToBase64String(hashBuffer);
Debug.WriteLine("This is the hash:" + hashString);

var encryptedHashString = CryptographicBuffer.EncodeToBase64String(encryptedBuffer);
Debug.WriteLine("This is the encrypted hash:" + encryptedHashString);

return encryptedBuffer;
}

Here is how you verify a signature:

public bool VerifySign(IBuffer originalBuffer, IBuffer encodedHashBuffer)
{
var originalHashBuffer = hashAlgorithm.HashData(originalBuffer);
var decriptedHashBuffer = CryptographicEngine.Decrypt(privateKey, encodedHashBuffer, null);

byte[] originalHashArray;
byte[] decriptedHashArray;

CryptographicBuffer.CopyToByteArray(originalHashBuffer, out originalHashArray);
var originalHashString = Convert.ToBase64String(originalHashArray);
Debug.WriteLine("Original hash:" + originalHashString);

CryptographicBuffer.CopyToByteArray(decriptedHashBuffer, out decriptedHashArray);
var decryptedHashString = Convert.ToBase64String(decriptedHashArray);
Debug.WriteLine("Decrypted hash:" + decryptedHashString);

return originalHashString == decryptedHashString;
}

Notes:

  • In order to make it work, you need a private key which you can generate using:
var key = asym.CreateKeyPair(512);
  • For the sake of simplicity, I keep the private file as a resource inside the app, which is not necessarily a good idea. The only reason I do it in this way is because I want to prevent anyone from easily changing the content of the saved files. However, this approach can easily be improved by storing the private key into a secure location and retrieving it over a secure channel.

Remember! Signing a file won’t keep your users from seeing its content, it will only prevent them from modifying it, or let you know if they they did.

Good luck!