Introducing timeago: A jQuery library to update fuzzy timestamps automatically

You may have seen at least one of these timestamps in websites especially social networks:

time1

time3

These timestamps are very important and useful in all websites that time matters. But you may have wondered how to implement such a thing in your own web applications.

There are a couple of ways to do so. The first one is to implement this functionality server side. I’ve implemented a server side C# function to do it; but, there would be a very big issue: As the time goes on, the timestamp won’t update! The whole page needs to be refreshed! You may have use ajax to refresh the time but this method also costs lots of resources. The best place to do such a thing is client and that’s exactly what timeago does!

What is timego?

Timeago is a jQuery plugin that makes it easy to support automatically updating fuzzy timestamps (e.g. “4 minutes ago” or “about 1 day ago”).

Timeago has lots of advantages over server side implementation I’ve mentioned above. Here are some:

  • It is very lightweight (About 8KB when not minified and about 4KB when minified and GZiped)
  • Runs on user’s browser; consequently, it won’t cost any server resources.
  • It can be used alongside caching techniques while it runs on client.
  • The timestamps’ values will update live so there’s no need to refresh the whole page or make ajax requests to update them.
  • It’s free and open-source!

How to use timeago?

Using timeago it very simple. Imagine you have a span element in your web page and you want to update the value of this field using timeago. The very first step is to use jquery.timeago.js file in your page’s head element. You also need jQuery library as well; so, add it too if you haven’t:


After that place your ‘span’ as following:

July 17, 2008

As you may have noticed that we put the real datetime we want to calculate from in the ‘title’ attribute. The final step is to add the following piece of javascript in your page:

$(document).ready(function() {
  $("span.timeago").timeago();
});

You’re done! The javascript code above converts all span elements which has “timeago” class.

How to download timeago

Since timeago is an open-source project, it can be found by its GitHub repository or its official website at: http://timeago.yarp.com/. Don’t forget to check out its website for more examples.

This library was very useful for me. Hope it does the same for you.

Quick post: Testing in-app purchases in iOS 8

I love quick posts, they’re short and handy. Some topics should be explained as short as possible. I name these quick posts. In this (quick) post, I want to talk about significant changes to iOS 8 simulator when testing in-app purchases; so, here you go:

iOS simulator - Photo taken from http://www.ralfebert.de/ios/ueberblick-ios-xcode/icon_simulator.pngTesting in-app purchases is one of the most important tasks to do in your applications; because, it’s the way you can make money from your app. In-app purchases were one of those features which had to be tested on a real device only.

Prior to iOS 8, developers had to have at least one real device (an iPod Touch for example) to test their apps’ in-app purchases. But in iOS 8, Apple has made significant changes to its iOS simulator. Now developers can do much more as it’s possible to test in-app purchase functionality right in the simulator even if no real device is available!

This is a very important improvement especially for me as a developer who is working with iOS 8 new feautres. If this feature was not available, I had to install iOS 8 beta on my iPhone which I prefer not to.

There might be more improvements in iOS simulator which I haven’t faced yet. If you know any of them, let the world know them as well by commenting down below.

Have a nice coding ;-)

 

Essential tools everyone should have at home

In less than two month from now, we’ll celebrate our wedding party. Regarding this, we are preparing our new home. This is one of the hardest things to do because, they’re lots of tasks I haven’t ever thought about and I must get all of them done before the wedding party. Before this, I preferred to give all tasks to their professionals; but, after a while, I realized it’s not possible to give them to someone else because there are lots of small tasks that need to be done immediately.

My father is a handyman. He’s doing all of his house’s tasks by himself. He thinks that everyone knows about his own problems better than anyone else. I didn’t understand the meaning of this until now.

YOU NEED TO BE ABLE TO DO SOME OF CRITICAL TASKS YOURSELF. IF YOU DON’T KNOW HOW TO GET THEM DONE, LEARN THEN!

As a result, I decided to fix our new home’s small tasks myself. accordingly, I started to figure out what tools I need. I asked a few repairmen and handymen including my father about the essential tools I should have to get our home issues done and I decided to share them with you here.

Note that these tools is essential for everyone no matter what are their profession. I’m a programmer and I need these tools as well. Also, if you’re not going to do your home tasks yourself, you may want to skip this post. In addition, this post is all about my own opinion and I’m not advertising any brand here.

1. ToolBox

A large toolboxThe very first thing you need is a toolbox. This will help you gather all of your tools into one package; consequently, you won’t lose any of them. Also, it will be possible to carry them all with ease. toolboxes have different sizes and shapes. To get started, it’s not necessary to buy a large toolbox but a very small one is also enough. Moreover, a small bag can be used if you don’t want to buy one. I preferred to buy a small toolbox while I don’t have a lot of tools by the time.

2. Screwdriver

screwdriverAlmost anything including devices, gadgets, electronics, etc. have some screws today. So, it’s obvious you need some screwdrivers to fix them in the case of emergency.

There are plenty of screwdriver types out there but I believe you’ll need just two of them: Slot and Phillips

You’ll need at least two types of screwdrivers to get most of your tasks done. But, if you want you can purchase a power screwdrivers!  Most power screwdrivers have at least two built-in heads and you can extend it whenever you want. Using a power screw driver makes your work much easier and faster. The following is a photo of automatic screwdriver with more 10 heads:

3209014159_25d91e567c_b

3. Pliers

plierPilers are very important when want to hold objects firmly. Actually, it’s very handy tool because can be used in variety of cases but it’s main functionality is holding objects. I use pliers to bend small objects, pull objects out of the wall, hold wires when working with electricity and many many more.

Pliers are not limited to just one type. There plenty of types out there are I’m using some of those as well.

4. Locking pliers

locking plierLocking pliers, Mole grips (Mole wrench) or Vise-Grips are pliers that can be locked into position, using an over-center action. One side of the handle includes a bolt that is used to adjust the spacing of the jaws, the other side of the handle (especially in larger models) often includes a lever to push the two sides of the handles apart to unlock the pliers.

5. Needle-nose pliers

Needle-nose pliersNeedle-nose pliers (also known as long-nose pliers, pinch-nose pliers or snipe-nose pliers) are both cutting and holding pliers used by artisans, jewelry designers, electricians and other tradesmen to bend, reposition and cut wire. Their namesake long nose gives excellent control while the cutting edge near the pliers’ joint provides “one-tool” convenience. Because of their long shape they are useful for reaching into small areas where cables or other materials have become stuck or unreachable with fingers or other means.

6. Pipe wrench

PipeThe pipe wrench (US), Stillson wrench or Stillsons (UK) is an adjustable wrench used for turning soft iron pipes and fittings with a rounded surface. The design of the adjustable jaw allows it to lock in the frame, such that any forward pressure on the handle tends to pull the jaws tighter together. Teeth angled in the direction of turn dig into the soft pipe. They are not intended for use on hardened steel hex nuts or other fittings because they would ruin the head; however, if a hex nut is soft enough that it becomes rounded beyond use with standard wrenches, a pipe wrench is sometimes used to break the bolt or nut free.

7. Utility knife

utility knifeWhen we were bringing furnitures everything was packed so we needed something to unpack them. The utility knife is exactly what we wanted. It’s one of the most handy tools all the time especially while moving to a new place. It has a very sharp blade which helped us unpack all or our packages. In some cases that scissors are not usable, utility knife is the best choice.

8. Self Retractable Metric Ruler

meterFitting everything in its right place is a very important especially for women. Before we start moving to this house, we needed to measure every single part of the house in order to buy right furnitures such as curtains. A metric ruler was essential for us. Without it, we weren’t be able to fit stuff to their places.

9. Hammer

Hammer is a critical tool everyone should have. It comes very handy when want to install something. For example, we used hammer to install our photos and mirrors on the wall. Hammer has a lot of usage and I think it’s one of the first things you should buy.

hammerI believe everyone should have these essential tools to get small tasks done. Someday you will need at least one of them. I think I won’t be able to set things up without these. If you know any other essential tool I forgot to mention, please tell me by commenting down below.

Hope it helps :-)

 

Configure and manage VPN connections programmatically in iOS 8

Update 2: The beta 5 issue has been fixed in the GM release. Everything is currently working just fine.

Update: This solution does not work on iOS 8 beta 5 due to a weird “Missing name” issue; however, it works find on iOS 8 beta 1 to 4. If you know anything new about managing the VPN connections in iOS 8, let me know by commenting down below.

Connecting to VPN servers programmatically had been always an impossible task to do for developers because of Apple’s limitations.

In my previous post I’ve described that Apple introduced a brand-new Network Extension framework which gives developers the opportunity to configure VPN preferences programmatically but I didn’t describe how!

This post is a guide to manage VPN configurations in iOS 8 and OS X (10.10) Yosemite while there’s no official documentation published yet. I Also have to thank quellish who helped me a lot in this.

Requirements

  1. The very first and the most critical things you need is an actual device with iOS 8 beta 1 or above to test the app on! This tutorial cannot be tested on iPhone simulator. If you’re going to write a Mac application, OS X Yosemite Preview 3 or above has to be installed.
  2. Since this test doesn’t work on simulator, you have to be a member of iOS/Mac developer program. Also, you need to make some changes to your provisioning profile. You cannot use your iOS 7 provisioning profiles to develop iOS 8 VPN applications.
  3. Xcode 6 beta. By the time of this post (August 2nd, 2014), Xcode 6 is in beta 4 and just like I’ve mentioned in my previous post, you need to to a member of iOS/Mac program to have access to beta tools.
  4. Last but absolutely not least, you need a Mac since Xcode cannot be run on Windows or Linux machines.

Getting Started

The first thing you need to do before actually start writing any codes is to update your provisioning profiles. If you haven’t created any profiles yet, you need to create one now! To do this, login to your developer account, then click on “Certificate, Identifiers & Profiles”:

Provisioning profile update

Select Identifiers, then select the application you want to update its provisioning profile. If you don’t have any, you can create one using the plus sign. By selecting an app, a list will be appeared. This is a list of features the app is going to use, for example if you want to have iCloud functionality in your application, you have to turn iCloud feature on; otherwise, you won’t be able to test and deploy your iCloud based apps. The following is showing that list:

Identifiers list

By the introduction of iOS 8, a new item has been added to this list which is “VPN Configuration & Control”. This is exactly what we’re looking for! So enable this feature by clicking on it and then ticking its checkbox. When you turn this feature on a modal window will be displayed which describes its functionality:

Enable VPN Config

Enable VPN Configuration & Control feature and click “Done”. Then, download the provisioning profile again and replace it with the old one. We’re done here, now lets get back to Xcode.

Note: In this post I assume that you’re familiar with iOS development and Objective-C. If you’ve never developed any app in for iOS or Mac, you may need to learn some basic concepts and then return to this post.

Open Xcode and create a new iOS 8 single view application project. Then, place a button in the middle of screen and then connect it to your ViewController.

What we’re going to do is to setup VPN preferences on viewDidLoad: method and then connect to our specified VPN server when the button is tapped.

Before getting started, you have to know how all this work! If you understand the structure of Network Extension framework, then it will be much easier to develop apps based on it.

NetworkExtension.framework

Apple has done a brilliant job developing this framework. Every app can access system preferences but in its own sandbox; which means you cannot access other apps’ sandboxes.

First of all, saved preferences have to be loaded from OS to be able to be accessed. Once they’re loaded, it’s possible to make your changes. After changes have been made, they need to be saved. Unsaved preferences won’t be applied. Your app’s preferences can also be removed if you no longer need them. As a result, to create a VPN configuration we need to do the following:

  • Load our app’s preferences
  • Make our changes
  • Save preferences

Note that you need to load your app’s preferences even if you haven’t set any configuration yet.

After VPN connection is created we can connect to or disconnect from it.

Network extension contains three major classes:

  • NEVPNManager
  • NEVPNProtocol
  • NEVPNConnection

NEVPNManager is the most important class in this framework. It’s responsible for load, save and remove preferences. In fact, all VPN tasks have to be done through this class.

Create a new VPN connection

To get started a new instance of this class has to be created:

NEVPNManager *manager = [NEVPNManager sharedManager];

After NEVPNManager is initialized, system preferences can be loaded using loadFromPreferencesWithCompletionHandler: method:

[manager loadFromPreferencesWithCompletionHandler:^(NSError *error) {
    // Put your codes here...
}];

As I’ve mentioned in above code, the load method accepts a compilation handler block. This block is fired whenever the load process is completed. This block also has a parameter which is an NSError. the NSError parameter will be nil if the loading operation completed; otherwise, it will be non-nil. Accordingly:

[manager loadFromPreferencesWithCompletionHandler:^(NSError *error) {
    if(error) {
        NSLog(@"Load error: %@", error);
    } else {
        // No errors! The rest of your codes goes here...
    }
}];

After loading process is completed, It’s time to set up our VPN connection.

iOS 8 supports two major protocols. IPSec and IKEv2. It’s the first time that Apple offers IKEv2 protocol in its operating systems. This protocol is supported by all major operating systems including Android, Windows Phone, Windows Desktop, Linux and now iOS and Mac. In this post I’m going to talk about IPSec and in my next posts I’ll talk about IKEv2 as well. In addition to these protocols, Apple gives you the ability to create your own protocol if needed! This feature is a very important features for those who have implemented their own protocol; because now it’s possible to implement that protocol on iOS and Mac as well. OK, lets set up our IPSec protocol:

NEVPNProtocolIPSec *p = [[NEVPNProtocolIPSec alloc] init];
p.username = @"[Your username]";
p.passwordReference = [VPN user password from keychain];
p.serverAddress = @"[Your server address]";
p.authenticationMethod = NEVPNIKEAuthenticationMethodSharedSecret;
p.sharedSecretReference = [VPN server shared secret from keychain];
p.localIdentifier = @"[VPN local identifier]";
p.remoteIdentifier = @"[VPN remote identifier]";
p.useExtendedAuthentication = YES;
p.disconnectOnSleep = NO;

In the first line, I’ve created a new instance of NEVPNProtocolIPSec. This class is inherited from NEVPNProtocol class. NEVPNProtocol class is an abstract class you can use to create your own protocols.

Then, we specified our username and password in the second and third line. Notice that the password is a reference from Keychain; so, you need to store your password in Keychain first and then retrieve it.

The fourth line is our server address. Server address can be an IP, a host name or a URL.

Next is authentication method. iOS 8 supports three authentication methods

  • NEVPNIKEAuthenticationMethodNone: Do not authenticate with IPSec server.
  • NEVPNIKEAuthenticationMethodCertificate: Use a certificate and private key as the authentication credential.
  • NEVPNIKEAuthenticationMethodSharedSecret: Use a shared secret as the authentication credential.

As you can see, I’ve used Shared Secret method; but, you can use whatever method you want.

The next line is Shared Secret reference. Again it’s reference from Keychain; so, you need to get Shared secret from there. If you’re going to use certificate rather than shared secret. There’s no need to fill sharedSecretReference property; instead, you have to fill identityData property. Identity data is the PKCS12 data for the VPN authentication identity. The value for this property must be a NSData in PKCS12 format:

p.identityData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"clientCert" ofType:@"p12"]];

The next two lines are local and remote identifiers. These two are strings identifying the local and remote IPSec endpoints for authentication purposes.

The next property we need to set is useExtendedAuthetication. This is a flag indicating if extended authentication will be negotiated. This authentication is in addition to the IKE authentication used to authenticate the endpoints of the IKE session. For IKE version 1, when this flag is set X-Auth authentication will be negotiated as part of the IKE session, using the username and password properties as the credential. For IKE version 2, when this flag is set EAP authentication will be negotiated as part of the IKE session, using the username, password, and/or identity properties as the credential depending on which EAP method the server requires.

The last property to set is disconnectOnSleep. This boolean indicates whether the VPN connection must be disconnected when the device goes to sleep or not.

OK that’s enough for protocol. The next thing we have to do is to assign the protocol we’ve just created to the VPN manager. To do so, the setProtocol: method can be used.

[manager setProtocol:p];

IPSec and IKEv2 protocols have a very cool feature called On-demand. This feature enable connect to connect automatically whenever user attempted to connect to the internet. In iOS 8, it’s possible to enable on-demand on the connection. But, I’m going to cover this feature in another post; therefore, lets leave it for now and set the onDemandEnabled property to NO for now.

[manager setOnDemandEnabled:p];

The last thing we must set is the description of VPN preference we’re going to create. To do so, just set its localized description property by using setLocalizedDescription: method

[manager setLocalizedDescription:@"[You VPN configuration name]"];

We’re almost done. We’ve set up the configuration but haven’t saved it yet. To save the configuration simply call the saveToPreferencesWithCompletionHandler: method:

[manager saveToPreferencesWithCompletionHandler:^(NSError *error) {
    if(error) {
        NSLog(@"Save error: %@", error);
    }
    else {
        NSLog(@"Saved!");
    }
}];

This method simply saves your specified configuration to the system settings.

Connect to the VPN connection we’ve just created

Now that you’ve saved your settings to system’s preferences, it’s time to connect to it. NEVPNManager has a property called connection. This property is an object of NEVPNConnection class. It hold information which is responsible for VPN connection. To connect to VPN server you’ve just created, simply call startVPNTunnelAndReturnError: method of NEVPNConnection class just like below:
Run the application on your device and you’ll see and new connection will be create and you can connect to it by tapping the button. Also, you can disconnect from VPN server programmatically as well by calling stopVPNTunnel method of NEVPNConnection:

- (IBAction)buttonPressed:(id)sender {
    NSError *startError;
    [[NEVPNManager sharedManager].connection startVPNTunnelAndReturnError:&startError];
    
    if(startError) {
        NSLog(@"Start error: %@", startError.localizedDescription);
    } else {
        NSLog(@"Connection established!");
    }
    
}

If you have any idea, suggestion or anything else regarding this post, please leave your comments down below. I’ll blog about IKEv2 and On-demand features in the near future. Stay tuned.

Storyboards are now available on OS X Cocoa development

One of the coolest things I love to work with when develop iOS applications is using storyboards. They’re definitely one of the best ways to develop application in my opinion because, they’re very simple and simplify a lot of development tasks, cover most application scenarios and easy to understand as most iOS developers tend to use them.

In recent Apple WWDC (2014), a new version of Xcode (6) has been introduced. This version has a lot of cool features not only for iOS 8 but OS X as well! One of the most surprising features in this version is the support of storyboards for OS X Cocoa development! Using Xcode 6, Mac developers can take advantage of storyboards! Let’s take a look:

Download Xcode 6 from Apple’s developer website. (By the time, Xcode 6 is in beta; consequently, you must be a member of Mac/iOS developer program to be able to download it)

Create a new OS X Cocoa Application. The following window will be appeared:

osx-app-create

As you can see in the above screenshot, you now have the ability to create an OS X Cocoa application and use storyboards.

But, you may ask this question: Why this option is disabled here?

Well, the answer is clear! This feature is only available in the latest version of OS X which is by the time OS X 10.10 Yosemite; as a result, you must install it to use storyboards in your applications.

I believe this improvement to Cocoa development, will courage more developers to release the Mac version of their apps. Most iOS developers today have not worked with older technologies such as nib files because when they started iOS development, storyboards were existed and they didn’t need anything else. But now they can do the same thing in Mac applications as they do in iOS.

Hope it helps

Introducing Network Extension in iOS 8 and OS X 10.10

It’s about a year I’m working on an iOS VPN project which enables users to access the web and its contents without any kind of restrictions. By the time, all VPN applications need to install a configuration profile on clients’ devices to apply their VPN configuration on them; because, Apple forbids applications to access iOS system configurations. After the installation of configuration profile, users have to open iOS settings application to enable that VPN service manually; consequently, client applications are act as a profile installer or statistics viewer only!iOS-8-App-Extensions-icon-200x200

The story is completely different on Android devices since restrictions are much fewer than iOS. Android developers can implement a connect/disconnect button to let their users connect and disconnect from VPN servers right from the app.

By introduction of iOS 8, Apple revealed lots of new developer tools and APIs including App Extensions, Handoff, HealthKit, HomeKit, Swift programming language and many many more. But, one of the most useful stuff specially for VPN providers is NetworkExtension which is first introduced in iOS 8 and OS X 10.10!

Network Extension enables developers to manage VPN preferences on their users’ devices. By using this framework, you will have access to almost all iOS VPN preferences. In addition to letting developers access VPN settings, Apple also introduced a new IKEv2 protocol which wasn’t available on iOS or OS X before. This is a standard protocol which is supported by all major mobile and desktop operating systems such as Windows Phone 8.1, Android and now iOS!

I plan to publish more posts about new stuff in both iOS 8 and OS X 10.10. Unfortunately, by now, Apple hasn’t released any documentations regarding Network Extension; but, I’ve done some researches and I’ll share them with you in near future. Until then, please share your idea and information about network extension with me so I can provide a better post to publish :)

 

Set default sharing accounts in Buffer

I love Buffer services. It comes very handy when you want to share some posts with your friends on social networks. Some people are always have their social network websites’ tabs open in their browsers, whereas others (like me) specified a limited time to check their social networks.

I have added some of my favorite blogs and websites to my Feedly account which I read almost everyday and I like to share them if I find something interesting. Buffer helps me not to share all of them as a same time. It’s Buffer’s job:

Buffer is a great tool that will help you in two main ways. First, you can write a bunch of posts at one time, and choose which social profiles to send them to, and then Buffer will spread them out throughout the day or week so that you don’t have to be at a computer all the time in order to have a social media presence. Second, since we shorten your links for you, we are able to provide more analytics than if you just were to post to Twitter or Facebook directly. For example, we can tell you exactly how many folks clicked on each of your links.

Buffer has extension for all main browsers including Firefox and Google Chrome so it’s much easier to share links you like.

The problem comes to life when you press the share button. The following window will be displayed:

Buffer Share Sheet

As you can see in the above picture, I’ve added three of my social accounts; Facebook, Twitter and LinkedIn. I can click on each one if I wanted to disable sharing for that specified link; but, sometimes you I forget to do so. In most cases, I want to just share the link to my Twitter page. I don’t want to send technical posts to my Facebook page because most of my family and friends which are not developers don’t link them at all.

You click “Add To Queue” without choosing which social network you want to share that link to; Accordingly, it will automatically add that link to all your specified social networks. However, you can remove a link from a specific social network anytBuffer Dashboard Pageime by going to your Buffer account, there’s a very simple way I’ve found on my Buffer account today which can be used to set the default enabled social networks!

To so so, just go to your Buffer account page. All of your linked account are listed there as shown in the picture at right. As you may have noticed, There are check marks on the left side of each account which are all checked by default. These are default sharing accounts’ indicators. You can simply uncheck the accounts you don’t want to be enabled by default in the Buffer’s share sheet. Simple, huh!?

I highly encourage you to try buffer if you use social networks and share links with your friends. Buffer is free but you can upgrade to awesome to get the most of your Buffer.

Recordium is now on AppStore top charts!

Recordium is one of the apps we’re working on at Pichak. It’s getting more and more popular everyday, because users love its unique features. Yesterday we’ve celebrated its first birthday. One year ago, the Recordium released to help users record their moments. It makes it easier to record your voice memos and annotate them at the same time.
10359030_774857019211516_3250373144789554679_oSince it’s Recordium’s first anniversary, we decided to make it Free for a very limited time (It’s still free as I’m writing this post). Hurry!

From the first hours of this promotion, the app rocked the store! We hit number 1 (in productivity and business categories) in some countries including Australia, Germany, and more! Yeah this is pretty impressive!
The following is the latest top charts from the App Store:
14 - 1
I think it’s a good time to say that I am proud of working with such talented people. The team at Pichak spent months to develop something lovely for the users.
Lots of new cool stuff are about to happen in Recordium including lots of new features and improvements. By the time, we’ve released Recordium Mini, a compact version of Recordium Pro for those users who just want to highlight their voices. Lots of good news are coming soon. Stay tuned ;-)

Why don’t you enable comments!?

One of the best tasks I’ve done last week was to revise my Feedly feeds. I removed some feeds which hadn’t been upgraded recently and also added some new feeds. I also came across some Persian bloggers and added their feeds as well.

Yesterday I was reading a post by a blogger about technical matters. I thought I can complete the blogger’s idea by adding a comment. When I wanted to do so, I realized that the comments are closed! When checked other post by that person, I found out that there’s no comment capabilities at all! Why?

One of the biggest purpose of blogging is to share your experience with others. No one in the universe is complete enough; consequently, there might be other thought that can complete your ideas which are posted on your blog. Some of the times, I find my solutions in the comments rather than the post itself.

I know there might be some S P A M M E R s out there which can bother you; but, lot of blog extensions and plugins are available today to reduce them. Comments could also be moderated to avoid inappropriate contexts. There are also other options which can be used like Disqus. It’s a very powerful comment system which can be installed very easily on your blog. It manages all comments on your blog. I also used Disqus on my blog too.

If your blog comments are disabled, please re-enable it to improve your knowledge.

Thank you :-)

How to create installation DMG files in OS X

One of the coolest features of Mac OS in comparison with Windows is the simplicity of apps’ installation. In Windows, in most cases, there should be an installation package; otherwise, the app won’t run correctly. On the contrary, Mac apps installations are much simpler. All you need to do is to copy the app bundle to the Applications folder; so, no installation is needed. The installation process of Skype for Mac is a very good example. To install Skype you just need to drag the app icon into the Applications folder. by doing this, you’re copying the Skype app bundle to your Applications folder. The following is the Skype installation page for OS X:

skype_installation_dms

Now how can you create such installation page for your own app?

First of all, look at the picture above. The installation page contains three major sections:

  • The First is the application bundle (in this case, Skype.app).
  • The second is the OS X Applications folder.
  • The third one is the background image of the installation page.

These three things are the requirements to create a DMG installation file. However, you can ignore the background image and let it be just a solid white color background, it’s much better to have a custom background color or image for your installation page. It make your installer more friendly and of course more beautiful. In addition, there is one more requirement (which is obvious of course): You will need a Mac machine to build DMG installation files. As far as I know, you cannot create DMG installation files in Windows.

Getting Started

After all of three requirements I’ve mentioned above were present, you can get started. I decide to break this tutorial into steps so it’s much easier to understand:

The very first thing to do is to create an empty DMG file so we can put our custom files in it. To do so, OS X has a built-in tool named Disk Utility. You can simply search for it in spotlight search box (On the top right of your screen).

disk_utility_home

In the Disk Utility home page click New Image button on the top of screen. When New Image button is clicked, a window will be appeared like the following:

disk_utility_new_image

There are some settings in the New Image window which need your consideration. The first field is the path of your DMG file that is going to be created. The second field is name. It is recommended to set this field as the name of your application because users will see this name when they mount your DMG file on their machine. The third field is size of disk image. Unfortunately, disk images’ file sizes could not be dynamically allocated so you need to pick a size which is right for your application’s size. It’s recommended to choose a size which is a little larger than your application bundle (The minimum size of disk image is 21MB in OS X). The forth field is image format. This field’s value is set to Mac OS extended by default and there’s no need to change it; so, leave it as it is. Encryption and Partitions fields are fifth and sixth fields in the New Image window which should be left as the default value. We don’t need any encryption or partitioning for now. The last field, Image Format, is sightly important here. You have to set this field’s value to read/write disk image. You won’t be able to create the installation DMG if you select anything else! After setting all fields, click “Create” to create the disk image.

By clicking “Create” your disk image will be created and will be automatically mounted. Close Disk Utility, go to Desktop and double-click on the mounted image to see its content. You can see the disk image is empty as you expected. In the next section we need to fill it by adding our custom files. The reason we’re able to add files to our disk image is because we set the image format field to “read/write disk image”.

It’s time to add our custom-designed background image to our installation (If you don’t want to add an image to your installation page, you can skip this section).
You can simply drag your custom background image to the mounted disk. As you can see the file has been copied to the disk image but has not set as disk image background. To do so, right click on the mounted image on your mac desktop and select Show View Options.

myapp_show_view_optionsThere are two things that need to be taken care of in the Show View Options page. The first one is Icon Size and the second is Background.

Icon Size indicates the size of our two main icons in the installer page (Our two icons are your app bundle icon and the Applications icon). Icon size is completely up to you. In the Skype example I’ve mentioned earlier, the icon size is set to the maximum which is 128*128 pixels. I myself prefer to use the maximum as well; because, it makes it easier for users to do the drag-drop action.

After setting the icon size, it’s now time to set the background image. Just select picture item from background radio button group and then DRAG the image you’ve just copied into the disk image (not from other paths of your hard drive) to the “Drag image here” section. As soon as you drop the image, the background will be set. There’s no Save button. All changes will be saved automatically; so, you can close Show View Options window. You can also resize the disk image window by its corners (as same as what you do when want to resize other windows in OS X) to fit your window size with the background image.

The interesting part is that all of your actions will be kept and the next time you open your disk image, background image, icon size and window size is saved.

Note: DO NOT CLICK ON “USE AS DEFAULT” BUTTON. IT WILL SET YOUR SPECIFIED CONFIGURATION INCLUDING BACKGROUND IMAGE TO ALL FOLDERS ON YOUR MAC.

As you may have noticed, The image file is in the middle of disk image window. We need to make it hidden so users can’t see it. There are plenty of ways to make a file hidden but one of the coolest ways is to add a “.” to the first of file name. In Unix systems like Mac, files which are started by a “.” are hidden by default. You can’t change the file name in the finder. You need to rename the file in terminal. So open a terminal window and do the following:

cd /Volumes/[YOUR DISK IMAGE NAME]
mv [YOUR BACKGROUND FILE NAME] .[YOUR BACKGROUND FILE NAME]

As you can see the file is now hidden!
The next step is to copy our app bundle. To do it just copy the app bundle to your disk image. You can also change the location of app bundle to any place of disk image we want. After the bundle has been copied, We need to make an Application icon so use can drag the app to it. To do so, go to you Macintosh HD, click on Applications, hold Command and Option key, and dray it to the disk image window. By holding Command+Option it will make an alias of that folder. Note that we’re not copying the Applications folder, we’re just making an alias from it. Place the two icons near each other so it’s easier for users to install the app.

We’re almost done. Your installation DMG file is ready; but, there is something. By publishing this DMG file, all users can change its background image, icon size, window size, and etc. In fact, they can do whatever you can! To prevent this, we need to make this disk image read-only.
Eject the disk image by right-clicking on disk image icon and selecting “Eject”. Re-open the Disk Utility tool again. On the left side of Disk Utility home pas select the DMG file we’ve created, then, select Convert. The convert window will show up. select a unique name for it and from Image Format select read-only. Click save to create a new disk image from your selected one. The new DMG file we’ve just created is read-only can be safely published and others cannot make changes to it.

If you have any question, don’t hesitate a moment; just ask it on the comments down below :-)
Hope it helps.