Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials - Cross-Platform Mobile Development

96 Articles
article-image-configuring-your-operating-system
Packt
18 Aug 2014
3 min read
Save for later

Configuring Your Operating System

Packt
18 Aug 2014
3 min read
In this article by William Smith, author of Learning Xamarin Studio, we will configure our operating system. (For more resources related to this topic, see here.) Configuring your Mac To configure your Mac, perform the following steps: From the Apple menu, open System Preferences. Open the Personal group. Select the Security and Privacy item. Open the Firewall tab, and ensure the Firewall is turned off. Configuring your Windows machine To configure your Windows machine, download and install the Xamarin Unified Installer. This installer includes a tool called Xamarin Bonjour Service, which runs Apple's network discovery protocol. Xamarin Bonjour Service requires administrator rights, so you may want to just run the installer as an administrator. Configuring a Windows VM within Mac There is really no difference between using the Visual Studio plugin from a Windows machine or from a VM using software, such as Parallels or VMware. However, if you are running Xamarin Studio on a Retina Macbook Pro, it is advisable to adjust the hardware video settings. Otherwise, some of the elements within Xamarin Studio will render poorly making them difficult to use. The following screenshot contains the recommended video settings: To adjust the settings in Parallels, follow these steps: If your Windows VM is running, shut it down. With your VM shut down, go to Virtual Machine | Configure…. Choose the Hardware tab. Select the Video group. Under Resolution, choose Scaled. Final installation steps Now that the necessary tools are installed and the settings have been enabled, you still need to link to your Xamarin account in Visual Studio, as well as connect Visual Studio to your Mac build machine. To connect to your Xamarin account, follow these steps: In Visual Studio, go to Tools | Xamarin Account…. Click Login to your Xamarin Account and enter your credentials. Once your credentials are verified, you will receive a confirmation message. To connect to your Mac build machine, follow these steps: On your Mac, open Spotlight and type Xamarin build host. Choose Xamarin.iOS Build Host under the Applications results group. After the Build Host utility dialog opens click the Pair button to continue. You will be provided with a PIN. Write this down. On your PC, open Xamarin Studio. Go to Tools | Options | Xamarin | iOS Settings. After the Build Host utility opens, click the Continue button. If your Mac and network are correctly configured, you will see your Mac in the list of available build machines. Choose your build machine and click the Continue button. You will be prompted to enter the PIN. Do so, then click the Pair button. Once the machines are paired, you can build, test, and deploy applications using the networked Mac. If for whatever reason you want to unpair these two machines, open the Xamarin.iOS Build Host on your Mac again, and click the Invalidate PIN button. When prompted, complete the process by clicking the Unpair button. Summary In this article, we learned how to configure our operating system. We also learned how to connect to your Mac build machine. Resources for Article: Further resources on this subject: Updating data in the background [Article] Gesture [Article] Making POIApp Location Aware [Article]
Read more
  • 0
  • 0
  • 2911

article-image-so-what-forgedui
Packt
17 Apr 2013
2 min read
Save for later

So, what is ForgedUI?

Packt
17 Apr 2013
2 min read
(For more resources related to this topic, see here.) ForgedUI is a Titanium Studio third-party WYSIWYG (what you see is what you get) module created with the aim to make cross-platform app development quicker and easier, by providing a visual environment and a drag-and-drop style interface. Even though Titanium generates multiple platform apps with a single codebase and facilitates the maintenance and management of mobile projects, it still lacks a design interface tool, and for this reason, ForgedUI comes to the market with the aim to improve what has been holding back a large portion of productivity gains on Titanium SDK. With a steep learning curve and a straightforward interface, Titanium developers are able to reduce app development time by visually designing their apps and get more time to concentrate on other aspects of the project. It doesn't matter if you choose to go with iOS or Android, ForgedUI will give you a hand on screen design, and alongside Titanium Studio, generate the cross-platform code with one click. The ForgedUI interface has common UI elements of the Android and iOS platforms and allows you to design with a simple drag-and-drop process instead of hand written code. This is how ForgedUI looks within Titanium Studio: Once you are happy with your UI design, you can generate the Titanium JavaScript code through ForgedUI with just one click, and this code can be integrated into new or old projects. The generated code is stored in a separate resource file within the current Titanium project. ForgedUI allows you to specify parent-child relationships between compatible components and intelligently generates code that conforms to the required layout and relationship rules. The key features of ForgedUI are as follows: Visual graphical user interface (GUI) designer Supports iPhone and Android (no Tablets) platform projects One-click code generation Seamless integration with Titanium Studio Summary This article has thus explained what ForgedUI is and how it makes cross-platform app development easier. Resources for Article : Further resources on this subject: Animating Properties and Tweening Pages in Android 3-0 [Article] Securely Encrypt Removable Media with Ubuntu [Article] Appcelerator Titanium: Creating Animations, Transformations, and Understanding Drag-and-drop [Article]
Read more
  • 0
  • 0
  • 2900

article-image-rhomobile-faqs
Packt
21 Jul 2011
3 min read
Save for later

Rhomobile FAQs

Packt
21 Jul 2011
3 min read
  Rhomobile Beginner's Guide Step-by-step instructions to build an enterprise mobile web application from scratch         Read more about this book       (For more resources on this topic, see here.) Q: Does Rhomobile create a pure Native Application? A: Yes. Rhomobile creates a pure Native Application. This Application is similar to an Application available in i-store. This application can use device capabilities such as GPS, PIM contacts and calendar, camera, native mapping, push, barcode, signature capture, and Bluetooth. These are much faster than Browser-based applications.   Q: I am new to Ruby should I use Rhomobile? A: Although you need to know Ruby to write Rhodes applications, we realize that many folks learn both Ruby and Rhomobile at the same time. As Rhomobile products require an elementary level of Ruby knowledge, this will not affect your learning curve. But I recommend that you go to any Ruby tutorial online.   Q: Is Rhomobile Free? A: Rhodes is free and open source under MIT Licence. To use RhoSync, you must purchase a commercial license when development commences or you must open source your app under the GPL license. The pricing and details can be found at www.rhomobile.com.   Q: Is support available for Rhomobile? A: Yes. However, you have to purchase a Rhodes Enterprise License and the Rhodes Commercial License to get commercial support. Apart from the Rhomobile support, there are various webinars and tutorials available on www.rhomobile.com. Another good support resource is the Rhomobile Google group, where Rhomobile experts are there to help you.   Q: What about Rhomobile security? A: Both Rhodes and RhoSync support use of https as a transport. In fact it is easier with Rhodes than with native code. You just list the https URL and Rhodes will connect to the backend appropriately. This is simple in contrast to underlying SDKs where significantly different code is written to connect to an https URL.   Q: Does Rhomobile support HTML5? A: Yes, Rhomobile supports HTML5 tags provided the device you are targeting also supports them.   Q: Can we write unit test case for the code? A: Yes, we can write unit test case in Rhodes.   Q: Can we use Ruby gems with Rhodes? A: Yes, we can use Ruby gems with Rhodes. We have to include them in the Rhodes configuration file.   Q: Do we need to have knowledge of different device databases? A: No, we don't need to have prior knowledge of those databases, Rhodes will take care of this. We write our query using Object-relational mapping (ORM) called Rhom and it is the work of ORM to shape the query.   Summary In this article we saw some of the most frequently asked questions on Rhomobile. Further resources on this subject: An Introduction to Rhomobile [Article] Getting Started with Internet Explorer Mobile [Article] jQuery Mobile: Organizing Information with List Views [Article] jQuery Mobile: Collapsible Blocks and Theming Content [Article] Fundamentals of XHTML MP in Mobile Web Development [Article]
Read more
  • 0
  • 0
  • 2570

article-image-implementing-data-model
Packt
06 Mar 2013
13 min read
Save for later

Implementing the data model

Packt
06 Mar 2013
13 min read
(For more resources related to this topic, see here.) Getting on with it Before we define our model, let's define a namespace where it will live. This is an important habit to establish since it relieves us of having to worry about whether or not we'll collide with another function, object, or variable of the same name. While there are various methods used to create a namespace, we're going to do it simply using the following code snippet: // quizQuestion.js var QQ = QQ || {}; Now that our namespace is defined, we can create our question object as follows: QQ.Question = function ( theQuestion ) { var self = this; Note the use of self: this will allow us to refer to the object using self rather than using this. (Javascript's this is a bit nuts, so it's always better to refer to a variable that we know will always refer to the object.) Next, we'll set up the properties based on the diagram we created from step two using the following code snippet: self.question = theQuestion; self.answers = Array(); self.correctAnswer = -1; We've set the self.correctAnswer value to -1 to indicate that, at the moment, any answer provided by the player is considered correct. This means you can ask questions where all of the answers are right. Our next step is to define the methods or interactions the object will have. Let's start with determining if an answer is correct. In the following code, we will take an incoming answer and compare it to the self.correctAnswer value. If it matches, or if the self.correctAnswer value is -1, we'll indicate that the answer is correct: self.testAnswer = function( theAnswerGiven ) { if ((theAnswerGiven == self.correctAnswer) || (self.correctAnswer == -1)) { return true; } else { return false; } } We're going to need a way to access a specific answer, so we'll define the answerAtIndex function as follows: self.answerAtIndex = function ( theIndex ) { return self.answers[ theIndex ]; } To be a well-defined model, we should always have a way of determining the number of items in the model as shown in the following code snippet: self.answerCount = function () { return self.answers.length; } Next, we need to define a method that allows an answer to be added to our object. Note that with the help of the return value, we return ourselves to permitting daisy-chaining in our code: self.addAnswer = function( theAnswer ) { self.answers.push ( theAnswer ); return self; } In theory we could display the answers to a question in the order they were given to the object. In practice, that would turn out to be a pretty boring game: the answers would always be in the same order, and chances would be pretty good that the first answer would be the correct answer. So let's give ourselves a randomized list using the following code snippet: self.getRandomizedAnswers = function () { var randomizedArray = Array(); var theRandomNumber; var theNumberExists; // go through each item in the answers array for (var i=0; i<self.answers.length; i++) { // always do this at least once do { // generate a random number less than the // count of answers theRandomNumber = Math.floor ( Math.random() * self.answers.length ); theNumberExists = false; // check to see if it is already in the array for (var j=0; j<randomizedArray.length; j++) { if (randomizedArray[j] == theRandomNumber) { theNumberExists = true; } } // If it exists, we repeat the loop. } while ( theNumberExists ); // We have a random number that is unique in the // array; add it to it. randomizedArray.push ( theRandomNumber ); } return randomizedArray; } The randomized list is just an array of numbers that indexes into the answers[] array. To get the actual answer, we'll have to use the answerAtIndex() method. Our model still needs a way to set the correct answer. Again, notice the return value in the following code snippet permitting us to daisy-chain later on: self.setCorrectAnswer = function ( theIndex ) { self.correctAnswer = theIndex; return self; } Now that we've properly set the correct answer, what if we need to ask the object what the correct answer is? For this let's define a getCorrectAnswer function using the following code snippet: self.getCorrectAnswer = function () { return self.correctAnswer; } Of course, our object also needs to return the question given to it whenever it was created; this can be done using the following code snippet: self.getQuestion = function() { return self.question; } } That's it for the question object. Next we'll create the container that will hold all of our questions using the following code line: QQ.questions = Array(); We could go the regular object-oriented approach and make the container an object as well, but in this game we have only one list of questions, so it's easier to do it this way. Next, we need to have the ability to add a question to the container, this can be done using the following code snippet: QQ.addQuestion = function (theQuestion) { QQ.questions.push ( theQuestion ); } Like any good data model, we need to know how many questions we have; we can know this using the following code snippet: QQ.count = function () { return QQ.questions.length; } Finally, we need to be able to get a random question out of the list so that we can show it to the player; this can be done using the following code snippet: QQ.getRandomQuestion = function () { var theQuestion = Math.floor (Math.random() * QQ.count()); return QQ.questions[theQuestion]; } Our data model is officially complete. Let's define some questions using the following code snippet: // quizQuestions.js // // QUESTION 1 // QQ.addQuestion ( new QQ.Question ( "WHAT_IS_THE_COLOR_OF_THE_SUN?" ) .addAnswer( "YELLOW" ) .addAnswer( "WHITE" ) .addAnswer( "GREEN" ) .setCorrectAnswer ( 0 ) ); Notice how we attach the addAnswer and setCorrectAnswer methods to the new question object. This is what is meant by daisy-chaining: it helps us write just a little bit less code. You may be wondering why we're using upper-case text for the questions and answers. This is due to how we'll localize the text, which is next: PKLOC.addTranslation ( "en", "WHAT_IS_THE_COLOR_OF_THE_SUN?", "What is the color of the Sun?" ); PKLOC.addTranslation ( "en", "YELLOW", "Yellow" ); PKLOC.addTranslation ( "en", "WHITE", "White" ); PKLOC.addTranslation ( "en", "GREEN", "Green" ); PKLOC.addTranslation ( "es", "WHAT_IS_THE_COLOR_OF_THE_SUN?", "¿Cuál es el color del Sol?" ); PKLOC.addTranslation ( "es", "YELLOW", "Amarillo" ); PKLOC.addTranslation ( "es", "WHITE", "Blanco" ); PKLOC.addTranslation ( "es", "GREEN", "Verde" ); The questions and answers themselves serve as keys to the actual translation. This serves two purposes: it makes the keys obvious in our code, so we know that the text will be replaced later on, and should we forget to include a translation for one of the keys, it'll show up in uppercase letters. PKLOC as used in the earlier code snippet is the namespace we're using for our localization library. It's defined in www/framework/localization.js. The addTranslation method is a method that adds a translation to a specific locale. The first parameter is the locale for which we're defining the translation, the second parameter is the key, and the third parameter is the translated text. The PKLOC.addTranslation function looks like the following code snippet: PKLOC.addTranslation = function (locale, key, value) { if (PKLOC.localizedText[locale]) { PKLOC.localizedText[locale][key] = value; } else { PKLOC.localizedText[locale] = {}; PKLOC.localizedText[locale][key] = value; } } The addTranslation method first checks to see if an array is defined under the PKLOC.localizedText array for the desired locale. If it is there, it just adds the key/value pair. If it isn't, it creates the array first and then adds the key/value pair. You may be wondering how the PKLOC.localizedText array gets defined in the first place. The answer is that it is defined when the script is loaded, a little higher in the file: PKLOC.localizedText = {}; Continue adding questions in this fashion until you've created all the questions you want. The quizQuestions.js file contains ten questions. You could, of course, add as many as you want. What did we do? In this task, we created our data model and created some data for the model. We also showed how translations are added to each locale. What else do I need to know? Before we move on to the next task, let's cover a little more of the localization library we'll be using. Our localization efforts are split into two parts: translation and data formatting . For the translation effort , we're using our own simple translation framework, literally just an array of keys and values based on locale. Whenever code asks for the translation for a key, we'll look it up in the array and return whatever translation we find, if any. But first, we need to determine the actual locale of the player, using the following code snippet: // www/framework/localization.js PKLOC.currentUserLocale = ""; PKLOC.getUserLocale = function() { Determining the locale isn't hard, but neither is it as easy as you would initially think. There is a property (navigator.language) under WebKit browsers that is technically supposed to return the locale, but it has a bug under Android, so we have to use the userAgent. For WP7, we have to use one of three properties to determine the value. Because that takes some work, we'll check to see if we've defined it before; if we have, we'll return that value instead: if (PKLOC.currentUserLocale) { return PKLOC.currentUserLocale; } Next, we determine the current device we're on by using the device object provided by Cordova. We'll check for it first, and if it doesn't exist, we'll assume we can access it using one of the four properties attached to the navigator object using the following code snippet: var currentPlatform = "unknown"; if (typeof device != 'undefined') { currentPlatform = device.platform; } We'll also provide a suitable default locale if we can't determine the user's locale at all as seen in the following code snippet: var userLocale = "en-US"; Next, we handle parsing the user agent if we're on an Android platform. The following code is heavily inspired by an answer given online at http://stackoverflow.com/a/7728507/741043. if (currentPlatform == "Android") { var userAgent = navigator.userAgent; var tempLocale = userAgent.match(/Android.*([a-zA-Z]{2}-[a-zA-Z] {2})/); if (tempLocale) { userLocale = tempLocale[1]; } } If we're on any other platform, we'll use the navigator object to retrieve the locale as follows: else { userLocale = navigator.language || navigator.browserLanguage || navigator.systemLanguage || navigator.userLanguage; } Once we have the locale, we return it as follows: PKLOC.currentUserLocale = userLocale; return PKLOC.currentUserLocale; } This method is called over and over by all of our translation codes, which means it needs to be efficient. This is why we've defined the PKLOC.currentUserLocale property. Once it is set, the preceding code won't try to calculate it out again. This also introduces another benefit: we can easily test our translation code by overwriting this property. While it is always important to test that the code properly localizes when the device is set to a specific language and region, it often takes considerable time to switch between these settings. Having the ability to set the specific locale helps us save time in the initial testing by bypassing the time it takes to switch device settings. It also permits us to focus on a specific locale, especially when testing. Translation of text is accomplished by a convenience function named __T() . The convenience functions are going to be our only functions outside of any specific namespace simply because we are aiming for easy-to-type and easy-to-remember names that aren't arduous to add to our code. This is especially important since they'll wrap every string, number, date, or percentage in our code. The __T() function depends on two functions: substituteVariables and lookupTranslation. The first function is de fined as follows: PKLOC.substituteVariables = function ( theString, theParms ) { var currentValue = theString; // handle replacement variables if (theParms) { for (var i=1; i<=theParms.length; i++) { currentValue = currentValue.replace("%" + i, theParms[i-1]); } } return currentValue; } All this function does is handle the substitution variables. This means we can define a translation with %1 in the text and we will be able to replace %1 with some value passed into the function. The next function, lookupTranslation, is defined as follows: PKLOC.lookupTranslation = function ( key, theLocale ) { var userLocale = theLocale || PKLOC.getUserLocale(); if ( PKLOC.localizedText[userLocale] ) { if ( PKLOC.localizedText[userLocale][key.toUpperCase()] ) { return PKLOC.localizedText[userLocale][key.toUpperCase()]; } } return null; } Essentially, we're checking to see if a specific translation exists for the given key and locale. If it does, we'll return the translation, but if it doesn't, we'll return null. Note that the key is always converted to uppercase, so case doesn't matter when looking up a translation. Our __T() function looks as follows: function __T(key, parms, locale) { var userLocale = locale || PKLOC.getUserLocale(); var currentValue = ""; First, we determine if the translation requested can be found in the locale, whatever that may be. Note that it can be passed in, therefore overriding the current locale. This can be done using the following code snippet: if (! (currentValue=PKLOC.lookupTranslation(key, userLocale)) ) { Locales are often of the form xx-YY, where xx is a two-character language code and YY is a two-character character code. My locale is defined as en-US. Another player's might be defined as es-ES. If you recall, we defined our translations only for the language. This presents a problem: the preceding code will not return any translation unless we defined the translation for the language and the country. Sometimes it is critical to define a translation specific to a language and a country. While various regions may speak the same language from a technical perspective, idioms often differ. If you use an idiom in your translation, you'll need to localize them to the specific region that uses them, or you could generate potential confusion. Therefore, we chop off the country code, and try again as follows: userLocale = userLocale.substr(0,2); if (! (currentValue=PKLOC.lookupTranslation(key, userLocale)) ) { But we've only defined translations for English (en) and Spanish(es)! What if the player's locale is fr-FR (French)? The preceding code will fail, because we've not defined any translation for the fr language (French). Therefore, we'll check for a suitable default, which we've defined to be en-US, American English: userLocale = "en-US"; if (! (currentValue=PKLOC.lookupTranslation(key, userLocale)) ) { Of course, we are now in the same boat as before: there are no translations defined for en-US in our game. So we need to fall back to en as follows: userLocale = "en"; if (! (currentValue=PKLOC.lookupTranslation(key, userLocale)) ) { But what happens if we can't find a translation at all? We could be mean and throw a nasty error, and perhaps you might want to do exactly that, but in our example, we're just returning the incoming key. If the convention of capitalizing the key is always followed, we'll still be able to see that something hasn't been translated. currentValue = key; } } } } Finally, we pass the currentValue parameter to the substituteVariables property in order to process any substitutions that we might need as follows: return PKLOC.substituteVariables( currentValue, parms ); } Summary In this article we saw the file quizQuestion.js which was the actual model: it specified how the data should be formatted and how we can interact with it. We also saw the quizQuestions.js file, which contained our actual question data. Resources for Article : Further resources on this subject: Configuring the ChildBrowser plugin [Article] Adding Geographic Capabilities via the GeoPlaces Theme [Article] iPhone: Issues Related to Calls, SMS, and Contacts [Article]
Read more
  • 0
  • 0
  • 2281

article-image-article-html5-and-the-mobile-web
Packt
31 Jan 2012
16 min read
Save for later

HTML5 and the Mobile Web

Packt
31 Jan 2012
16 min read
(For more resources on this topic, see here.) Introduction Both HTML5 and mobile web are promising technologies. Both have relatively short histories. In this article, most topics we will be covering are relatively basic. This is to help you get started with mobile development quickly and with minimum effort. Both mobile and HTML5 are still evolving in nature and there could be many questions in your mind. We will clear those doubts and set your mind focused on things that matter. The mobile web is growing fast. We now have mobile Safari which is one of the most used apps on the iPhone, allowing developers to build high performance web applications and enhancing users' browsing experience. You do not need a developer account to host and run a mobile site, you don't need to get approval from any app market to launch a mobile website and you can make updates any time you like without the hassle of waiting for approval. All these are benefits of mobile web development, but at the same time, there are challenges such as inconsistencies among browsers, the lack of certain features compared to native apps, and security. We can't tackle them all, but we sure can solve some of them. And we will see, when developing a mobile site, how we can separate the common practices from the best practices. There are literally thousands of smartphones out there; you don't need every single one of them to test your application on. In fact, you may need fewer than 10. If that's still out of your budget, then two devices are good enough. For the rest, you can use simulators/emulators to do the job. This book focuses on six A-grade mobile devices, with focus specifically on iPhone, Android, and Windows Phone: iOS Android Windows Mobile Blackberry v6.0 and above Symbian 60 Palm webOS There are two browsers that are device-independent that will also be covered in this book. They are: Opera Mobile Firefox Mobile Just because other browsers are not in the list does not mean they won't be covered by the issues and techniques we discuss in this book. Identifying your target mobile devices Target browser: all You can't possibly make a mobile site for every single mobile device. No one has the time or energy to do so. Cross-browser mobile web development can be crazy. It's hard to define the scope of the work, as John Resig (creator of jQuery Mobile) pointed out in his presentation slide describing his experience building jQuery Mobile (http://www.slideshare.net/jeresig/testing-mobile-javascript), he asked three questions: Which platforms and browsers are popular? Which browsers are capable of supporting modern scripting? What devices and simulators do I acquire to test with? When you are building a mobile site, you have to ask yourself similar questions, but not the exact same questions, because remember your site should be specifically tailored to your target audience. So your questions should be: Which platforms and browsers are most commonly used by visitors on my website? How many people access my website from a mobile device that is capable of supporting modern scripting? Which devices and simulators do I need for testing? Which platforms and browsers are most commonly used by visitors on my website? Now let's answer the first question. Before building a mobile website, you must first find out who are your target audience, and what mobile devices they use when visiting your site. There are many analytics tools that can help you answer these questions. One of those is Google Analytics. You can sign up for a free Google Analytics account at: http://www.google.com/analytics/. The way to do it is fairly straightforward: most developers are no strangers to Google Analytics. All you have to do is to include the JavaScript snippet from the the Google Analytics site and embed it in your web pages. JavaScript can be rendered in most modern smartphones, so there is really no difference between using it on a desktop site and on a mobile site. How many people access my website from a mobile device that is capable of supporting modern scripting? Now let's answer the second question. One thing you may want to find out is the number of people using mobile browsers to surf your site. And you also want to find out how many people use a relic mobile browser that doesn't support JavaScript at all. This is because if the percentage of people using low-end smartphones is higher than that of people using high-end smartphones, it may not be worthwhile using HTML5 in the first place (although the chance of this is very low). So if your goal is not just to know the number of people using smartphones, but also the number of people who use older versions of mobile phones, Google Analytics for mobile comes to the rescue. You can download the script from: http://code.google.com/mobile/analytics/download.html#Download_the_Google_Analytics_server_side_package Google Analytics for mobile server-side packages currently supports JSP, ASPX, Perl, and PHP. Let's take a look at one of the examples in PHP. All you have to do is to change the ACCOUNT ID GOES HERE with your GA account ID. But remember to replace 'UA-xx' with 'MO-xx'. Unfortunately, when you use the server-side version, you can't use it on pages where you also use the standard JavaScript tracking code, ga.js. Using the server-side version means that you have to give up the JavaScript version. It can be annoying because the JavaScript version provides a lot of dynamic tracking mechanisms that are lacking in the server-side version: <?php  //  Copyright 2009 Google Inc. All Rights Reserved.  $GA_ACCOUNT = "ACCOUNT ID GOES HERE";  $GA_PIXEL = "ga.php";   function googleAnalyticsGetImageUrl() {    global $GA_ACCOUNT, $GA_PIXEL;    $url = "";    $url .= $GA_PIXEL . "?";    $url .= "utmac=" . $GA_ACCOUNT;    $url .= "&utmn=" . rand(0, 0x7fffffff);     $referer = $_SERVER["HTTP_REFERER"];    $query = $_SERVER["QUERY_STRING"];    $path = $_SERVER["REQUEST_URI"];     if (empty($referer)) {      $referer = "-";    }    $url .= "&utmr=" . urlencode($referer);     if (!empty($path)) {      $url .= "&utmp=" . urlencode($path);    }     $url .= "&guid=ON";     return $url;  }?> Alternatives to Google Analytics Google Analytics is not the only mobile analytics service in the market. There are other services providing more specialized services. For example, PercentMobile is a hosted mobile analytics service that makes your mobile audience and opportunities clear. You can find out more about this service at: http://percentmobile.com/ Accuracy of Google Analytics The location reported by mobile devices may not always be accurate; Google Analytics uses IP addresses to determine user location for Map Overlay reports. They are subject to possible inaccuracy, as mobile IPs originate from the wireless carrier gateway which is not necessarily co-located with mobile users. Server loading speed concern Due to the server-side processing, some additional server load may be incurred. Google recommends you first test the snippet on a few of your pages to ensure all is well before rolling out to an entire site. Setting up mobile development tools Target browser: all Now one question still remains unanswered from the previous recipe: which devices and simulators do I need for testing? We will find this out in this article. If you have figured out what major mobile devices you are going to support, now is the time to see how to set them up. Mobile development can be costly if you test on various mobile devices. Although we have all these mobile simulators and emulators available for testing, it's not as good as testing on a real device. Now let's see how we can maximize the testing coverage and minimize the cost. Getting ready We are going to make some assumptions here. Each case is different, but the idea is the same. Let's assume you have a Windows operating system on your desktop, but the top visitors to your site surf using iOS, Android, and Blackberry. How to do it... Your goal is to maximize the coverage and minimize the cost. All three devices have emulators, but not all support different platforms. Name Compatibility iOS simulator Mac Android emulator Windows, Mac, Linux Blackberry simulator Windows As you can see, since iOS simulator only works for Mac, and if you are running a Windows OS, the best and only choice is to purchase an iPhone for testing. For Android and Blackberry, because they both have emulators for Windows, to save budget, you can download the emulators. How it works... List the top mobile devices people use to surf your site. Know the machine OS you are using for the development. Find out the compatibility of each of these device emulators to your development environment. There's more... If you have the budget for more than one mobile device having a different OS, you can think further about screen sizes and the DPI of the mobile device. You may not need to buy two high-end devices. For instance, it's not necessary to own an iPhone4 and an Android Thunderbolt. You can buy a lower-end of Android just to test out how your site would look on a lower-end device. So the idea is to combine your OS, mobile devices, and emulators to maximize the scenarios to cover. Device simulator/emulator download lookup table The following table shows a list of popular mobile device emulators for mobile web design and development testing: Name Type Compatibility URL iOS Simulator Mac https://developer.apple.com/devcenter/ios/index.action#downloads Android Emulator Mac, Win, Linux http://developer.android.com/sdk/index.html HP webOS Virtual Machine Mac, Win, Linux http://developer.palm.com/index.php?option=com_content&view=article&id=1788&Itemid=55 Nokia Symbian Emulator Win http://www.forum.nokia.com/info/sw.nokia.com/id/ec866fab-4b76-49f6-b5a5-af0631419e9c/S60_All_in_One_SDKs.html Blackberry Emulator Win http://us.blackberry.com/developers/resources/simulators.jsp Windows Mobile 7 Emulator Win http://www.microsoft.com/downloads/en/details.aspx?FamilyID=04704acf-a63a-4f97-952c-8b51b34b00ce Browser simulator/emulator download lookup table Apart from device testing tools, we also have tools for platform-independent browsers, notably Opera and Firefox. These are shown in the table below: Name Type Compatibility URL Opera Mobile Emulator Mac, Win, Linux http://www.opera.com/developer/tools/ Opera Mini Simulator Mac, Win, Linux http://www.opera.com/developer/tools/http://www.opera.com/mobile/demo/ Firefox for Mobile Simulator Mac, Win, Linux http://www.mozilla.com/en-US/mobile/download/ Remote testing Apart from emulators and simulators, there are also test frameworks that give you remote access to REAL devices. One of those tools is DeviceAnywhere; one problem is that it is not free. http://www.deviceanywhere.com/ BlackBerry simulator Target Browser: BlackBerry Most mobile device simulators are easy to install and configure if you follow the instructions on their sites, but BlackBerry simulators work differently from other mobile device simulators. For Blackberry device simulators, to connect to Internet, besides downloading the simulators, you also need to download and install BlackBerry Email and MDS Services Simulator. Getting ready Make sure you have chosen a simulator to download from:http://us.blackberry.com/developers/resources/simulators.jsp How to do it... First, go to the page: https://swdownloads.blackberry.com/Downloads/entry.do?code=A8BAA56554F96369AB93E4F3BB068C22&CPID=OTCSOFTWAREDOWNLOADS&cp=OTC-SOFTWAREDOWNLOADS. There you will see a list of products similar to the following screenshot: Now select BlackBerry Email and MDS Services Simulator Package and then click on Next. After downloading and installing the software, you must first launch the service simulator before the Blackberry simulator, in order to allow it to connect to the Internet.The following is a screenshot of a Blackberry simulator: Setting up the mobile development environment Target browser: all Before we start mobile web development, we have to first set up a development environment. Getting ready Set up localhost on your machine. For Windows, Mac, or Linux, the easiest way to set it up is to use the popular and free XAMPP software: (http://www.apachefriends.org/en/index.html). Make sure you have a wireless connection. Also you should have a mobile device with you. Otherwise, use a mobile simulator/emulator. Ensure your mobile device and your desktop are on the same wireless network. How to do it... Create an HTML file and name it ch01r1.html at the root directory of your localhost: Inside ch01r01.html, type in the following: <html>  <head>  <meta name="viewport" content="width=device-width, initial-scale=1.0">  </head>  <body>    <header>    Main Navigation here    </header>  body content here    <footer>    Footer links here    </footer>  </body></html> Now get your IP address. If you are using Windows, you can type the following line in your command prompt: ipconfig Once you have got your IP address, (for example, 192.168.1.16.), enter it in your mobile browser URL address bar. Now you should see the page load with the text displayed: How it works... Within the same network, your mobile device can access your desktop host through your desktop IP address. There's more... If you don't have a mobile device, you can use one of the simulators for testing. But it's recommended to have at least one or two real mobile devices for testing. A simulator could test most things, but not everything, accurately. Testing on a Safari desktop If your main target audience is iPhone mobile Safari users, you can also do testing on a desktop to save time. To do so, open up Safari, go to Preferences, click on the Advanced tab, check Show Develop menu bar as shown next: Now click on the display menu for the current page, choose Develop | User Agent | Mobile Safari 3.1.3 – iPhone: List of community-based collection of emulators/simulators There is a list of emulators and simulators available if you really don't have a Smartphone at hand. You can find the list on a wiki on the Mobile Boilerplate project: https://github.com/h5bp/mobile-boilerplate/wiki/Mobile-Emulators-&-Simulators List of emulators/simulators collection by Firtman Maximiliano Firtman, a mobile and web developer, also an author, maintains a list of emulators on his site at: http://www.mobilexweb.com/emulators Using HTML5 on the mobile web Target browser: all Now we are going to create a simple HTML5 page for your mobile device. If you already have experience with older versions of HTML, HTML5 should be easy to understand. And if you have made a web page for desktop before, it won't be hard for you to make one for a mobile device. Getting ready Create a new file ch01e2.html. How to do it... Save the following code in the file: <!doctype html><html>  <head>  <meta name="viewport" content="width=device-width, initial-scale=1.0">  </head>  <body>    hello to the HTML5 world!  </body></html> Now render this in your mobile browser, and you should see the text render just as expected. How it works... As you can see, the only difference between HTML5 and other HTML pages is the Document Type Definition (DTD) we used: <!doctype html>. You might have seen the code <meta name="viewport" content="width=devicewidth, initial-scale=1.0"> and are wondering what it does. It helps Mobile Safari to know that the page is as wide as the device. Setting initial-scale=1 tells the browser not to zoom in or out. There's more... Here's a little bit of history of HTML5: there are two versions of HTML5 draft, one created by W3C and the other by WHATWG. The W3C is run by a group that is democratic in nature, but super slow in practice. WHATWG is edited by one person, Ian Hickson (who is also working for Google), and a group of people who are not public. As Ian does most of the decision making, it makes WHATWG's version progress faster. HTML5 and version number You might be wondering why HTML5 is being so ambiguous by using a declaration without even a version number. Well there are many reasons to justify this: Version support of HTML doesn't matter much to browsers. What matters is the feature support. In other words, if the browser supports the HTML5 feature you are using, even if you declare the document as HTML4, it will still render the HTML5 element as expected. It's easier to type! Mobile doctypes One question you may ask is whether it is safe to use the HTML5 DTD <!doctype html>. The answer is DTDs were made for validation, not browser rendering. Your next question might be: what about quirks mode? <!doctype html> is the minimum information required to ensure that a browser renders in standards mode. So you are pretty safe to use <!doctype html>. You may have noticed that we use <!doctype html> instead of <!DOCTYPE html>. The reason is HTML5 is not case sensitive, but for consistency with other HTML tags, we will use lowercase throughout the book. Free resources to learn HTML5 There are many excellent and free books, and articles about basic HTML5 tags. If you are unfamiliar with HTML5, you can check out one of the following: HTML5 Doctor: http://html5doctor.com/ Dive Into HTML5: http://diveintohtml5.org/ HTML5 Rocks:http://www.html5rocks.com/ If you are the kind of person who really wants to know every detail about something, you can read the official HTML5 specs. The W3C version of the spec is at: http://dev.w3.org/html5/spec/Overview.html The WHATWG version of HTML Living Standard is at: http://www.whatwg.org/specs/web-apps/current-work/multipage/
Read more
  • 0
  • 0
  • 2233

article-image-article-html5-mobile-setup-and-optimization
Packt
30 Jan 2012
18 min read
Save for later

HTML5: Mobile Setup and Optimization

Packt
30 Jan 2012
18 min read
(For more resources on this topic, see here.) Introduction While there are many operating systems (OS) as well as device makers, inevitably there could be cross-browser issues that cost us a lot of headaches. But on the other hand, we developers love the challenges and set out to tackle them! Throughout this article, we will first focus on cross-browser/browser-specific setup and optimizations you may want to consider. We will then go on to look at a couple of general/ browser-specific features you may want to add at the start of your mobile development. Adding a home screen button icon Target devices: iOS, Android, Symbian On modern smartphones, screens are mostly touch based. The iPhone revolutionized the way we think of mobile by making everything on your device an "app"; even SMS and phone dialing behave like apps with an icon on the home screen. For an HTML web app, things are a bit different; users have to go to a browser app first, type in the address and then launch your site. This can be too much hassle from a user perspective, so on certain smartphones, users can bookmark a home screen icon to a particular web app, so they can launch that particular web app site directly from the icon on their home screen. That sounds cool, right? Yes, it does, but there are also issues associated with it. Not all browsers behave the same way when it comes to touch icons. In this recipe, we will examine the behavior of each browser and how to make home screen icons available to as many mobile browsers as possible. Getting ready First, you have to download the icon sets from the chapter code folder. If you open up the folder, you should be able to see the following:apple-touch-icon.png apple-touch-icon-57x57-precomposed.pngapple-touch-icon-72x72-precomposed.png apple-touch-icon-114x114-precomposed.png apple-touch-icon-precomposed.png These images will be used for different devices. Create an HTML document and name it ch02r01.html. How to do it... In your HTML document, use the following code: <!doctype html><html>  <head>    <title>Mobile Cookbook</title>    <meta charset="utf-8">    <meta name="viewport" content="width= device-width,     initial-scale=1.0">    <link rel="apple-touch-icon-precomposed"     sizes="114x114" href="icons/apple-touch-icon-114x114     -precomposed.png">    <link rel="apple-touch-icon-precomposed"      sizes="72x72" href="icons/apple-touch-icon-72x72     -precomposed.png">    <link rel="apple-touch-icon-precomposed"      href="icons/apple-touch-icon-precomposed.png">    <link rel="shortcut icon" href="     icons/apple-touch-icon.png">  </head>  <body>  </body></html>  How it works... Now let's break down the code: As of iOS 4.2.1, it's possible to specify multiple icons for different device resolutions by using the sizes attribute. <link rel="apple-touch-icon-precomposed" sizes="114x114" href="apple-touch-icon-114x114-precomposed.png"> For high resolution retina displays on iPhone 4, a 114 x 114 icon is used. <link rel="apple-touch-icon-precomposed" sizes="72x72" href="apple-touch-icon-72x72-precomposed.png"> For iPad, a 72 x 72 icon can be used. For non-retina iPhone, Android 2.1+ devices, a 57 x 57 low resolution icon is used. <link rel="apple-touch-icon-precomposed" href="apple-touch-icon-precomposed.png"> For Nokia Symbian 60 devices, a shortcut icon is used in link relation to tell the device about the shortcut icon. <link rel="shortcut icon" href="img/l/apple-touch-icon.png"> Here is what the bookmark looks like on Android: There's more... There must be a couple of questions in your mind after seeing the previous example: Isn't it possible to define more than one value in the rel attribute? So can we combine the last two lines into something as follows? <link rel="shortcut icon apple-touch-icon-precomposed"href="apple-touch-icon-precomposed.png"> It was tested, but somehow mobile browsers couldn't recognize the value. You might have seen people use: <link rel="apple-touch-icon-precomposed" media="screen and (min-resolution: 150dpi)"href="apple-touch-icon-114x114-precomposed.png"> Together with Paul Irish and Divya Manian, we have been working on Mobile Boilerplate (http://www.h5bp.com/mobile) that provides a rock-solid default for frontend mobile development. In Mobile Boilerplate, we have covered all the current scenarios and possible future scenarios: https://github.com/h5bp/mobile-boilerplate/blob/master/index.html#L21 Everything you always wanted to know about touch icons Most ideas presented on this topic are originated from Mathias Bynens. His original article Everything you always wanted to know about touch icons can be found at:http://mathiasbynens.be/notes/touch-icons. Official documentation about Apple touch icons There is a list of official documentation where you can find more information about touch icons for each specific device and browser: Apple touch icon: http://developer.apple.com/library/safari/#documentation/ AppleApplications/Reference/SafariWebContent/ ConfiguringWebApplications/ConfiguringWebApplications.html Official information from WHATWG: http://www.whatwg.org/specs/web-apps/current-work/multipage/ links.html#rel-icon Apple Custom Icon and Image Creation Guidelines Guidelines and articles about how to create a touch icon can be found at the Apple – Custom Icon and Image Creation Guidelines article: http://developer.apple.com/library/ios/#documentation/ userexperience/conceptual/mobilehig/IconsImages/IconsImages html#//apple_ref/doc/uid/TP40006556-CH14-SW11. Preventing text resize Target devices: iOS, Windows Mobile On certain mobile devices like the iPhone and Windows Mobile, browser text may resize when you rotate the device from portrait to landscape mode. This could be problematic to web developers because we want to have full control of the design and rendering of the website. Getting ready Create a new HTML file, and name it ch02r02.html. Enter the following code: <!doctype html><html>  <head>  <meta charset="utf-8">  <meta name="viewport" content="width=device-width,  initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">  <style>    figure, figcaption, header {      display:block;      margin:0 auto;      text-align:center;    }  </style>  </head>  <body>    <header>      HTML5 Logo    </header>    <figure>      <img src="HTML5_Badge_128.png" alt="HTML5 Badge" />      <figcaption>        It stands strong and true, resilient and         universal as the markup you write.         It shines as bright and as bold as the         forward-thinking, dedicated web developers         you are.         It's the standard's standard, a pennant for         progress.         And it certainly doesn't use tables for layout.      </figcaption>    </figure>      </body></html> Now render this page in portrait mode in iPhone, as you can see, it will be rendered normally as follows: Now if you render it in the landscape mode, the font size will suddenly increase. As we can see when the page is changed to landscape mode, the text will get resized. This is not the desired behavior. The following shows how it looks: How to do it... You can follow these steps to fix the issue: You can add the following lines to the CSS, and then render the page in landscape again: html {  -webkit-text-size-adjust: none;} As You can see, the text now appears normal: How it works... To solve this issue, you have to add a CSS property named text-size-adjust in WebKit, and assign the value to none to prevent the auto adjust. Setting text-size-adjust to none solves the problem for mobile-specific websites, but if we render this on a desktop screen or other non-mobile browser, the desktop browser text zoom feature will be disabled. To prevent this accessibility issue, we can set text-size-adjust to 100% instead of none. So we can tweak this example to: html {  -webkit-text-size-adjust: 100%;} There's more... Apart from iPhone, other devices also have ways to add the text size adjust property. Windows Mobile Windows Mobile IE uses a different prefix. They originally added the WebKit prefix. The intent was adding support for the WebKit-specific property to make web developers' lives a bit easier by not having to add yet another vendor-prefixed CSS property to their pages to control how text was scaled. Even more specifically, they intuited that the most common use case for this property was to explicitly set it to none in order to tell the browser not to scale a particular section of the text. After hearing the community's feedback on this issue (and a couple of face-plants when they realized the broader implications of implementing other browser vendors' CSS properties) they've decided that it's best to only implement the -ms- prefixed version and not the -webkit- one. So to make the preceding example more complete, you can add: html {  -webkit-text-size-adjust: 100%;  -ms-text-size-adjust: 100%;} Making it future proof To make things more future proof, you can add one more line without any prefix, as follows: html {  -webkit-text-size-adjust: 100%;  -ms-text-size-adjust: 100%;  text-size-adjust: 100%;} px em, which is better? The common debate about using px versus em is less of a problem on mobile. Originally Yahoo! User Interface used ems for the reason that IE6 doesn't support page zoom with pixels. On mobile, there isn't such an issue, and even if we want the page to render well on desktop browsers, the likelihood of someone using IE6 is getting lower and lower, so in most cases, you can save the trouble of using ems and all the calculation, and choose instead to use pixels. Optimizing viewport width Target device: cross-browser Different mobile devices have different default mobile viewport widths. Refer to Appendix X for a complete list of default viewport widths for all mobile devices. If you leave it unset, in most cases, it will cause an unexpected result. For example, in an iPhone if the viewport width is left unset, it will be rendered as 980 px. Getting ready Let's create an HTML document and name it ch02r03.html. How to do it... Here is what we can do to optimize the viewport width: Add the following code to ch02r03.html and render it in your mobile browser: <!doctype html><html>  <head>  <meta charset="utf-8">    </head>  <body>    <header>      HTML5 Logo    </header>    <div id="main">    <h1>Lorem ipsum</h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitationullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.    </div>      </body></html> Here is how it's rendered by default: If we render this example, we can see that everything becomes extremely small. Now, let's set the viewport width to the device width: <!doctype html><html>  <head>  <meta charset="utf-8">  <meta name="viewport" content="width=device-width">    </head>  <body>    <header>      HTML5 Logo    </header>  <div id="main">  <h1>Lorem ipsum</h1><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>  </div>          </body></html> Now the content width uses the screen width and the text becomes readable: How it works... When we set viewport width to device-width, it will tell the browser not to scale the page to fix the device area. So for iPhone, the device-width is 320 px in portrait mode and 480 px in landscape mode. There's more... For some really old relic mobile browsers, the meta attribute isn't recognized. To deal with these browsers, you need to use: <meta name="HandheldFriendly" content="true"> This is used by older versions of Palm OS, AvantGo, and Blackberry. <meta name="MobileOptimized" content="320"> For Microsoft PocketPC, a MobileOptimized attribute was introduced. So the most complete code should look like: <meta name="HandheldFriendly" content="true"><meta name="MobileOptimized" content="320"><meta name="viewport" content="width=device-width"> IE for Windows Phone viewport blog post On IE for Windows Phone Team Weblog, there is an article about IE Mobile Viewport on Windows Phone 7. In it, the author has explained important information like how Windows Phone 7 implements "device-width", together with much other very useful information in general. You can read the article here: http://blogs.msdn.com/b/iemobile/ archive/2010/11/22/the-ie-mobile-viewport-on-windows-phone-7.aspx Safari documentation Safari has a reference in the developer's library at:http://developer.apple. com/library/safari/#documentation/appleapplications/reference/ SafariHTMLRef/Articles/MetaTags.html Blackberry documentation There is a Blackberry Browser Content Design Guidelines document. It explains Blackberry's use of viewport width: http://docs.blackberry.com/en/developers/ deliverables/4305/BlackBerry_Browser-4.6.0-US.pdf. Fixing Mobile Safari screen re-flow scale Target device: iOS Mobile Safari has an annoying screen re-flow bug: When you rotate the mobile browser from portrait mode to landscape mode, the text will suddenly jump to a bigger size. During the time I was working on building Mobile Boilerplate, Jeremy Keith and I had a long discussion on this issue. The traditional way of fixing this is to add the following scaling attributes to the meta viewport: <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> This solution was first incorporated into Mobile Boilerplate. Jeremy pointed out that this solves the scale jump problem, but at the same time, it causes another issue with accessibility: When you set the values as shown above, you can no longer zoom the page to enlarge it. For people with eyesight problems, the ability to zoom is essential. But if we let the zoom happen, the text jump will annoy the majority of the users. So, for a long time it was an accessibility versus usability debate. I discovered a method that could tackle the issue and we will discuss this next. Getting ready First, let's create an HTML document and name it ch02r04.html, enter the following code in it: <!doctype html><html>  <head>  <meta charset="utf-8">  <meta name="viewport" content="width=device-width,  initial-scale=1.0">  </head>  <body>      <div>  <h1>Lorem ipsum</h1><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitationullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>  </div>  </body></html> This page renders perfectly fine in portrait mode: But when displayed in landscape mode, things change: How to do it... All we need to do to solve this problem is to dynamically reset the scale factors to default when the user zooms in on the page. Now put the following code in your HTML document: <!doctype html><html>  <head>  <meta charset="utf-8">  <meta name="viewport" content="width=device-width,    initial-scale=1.0">  </head>  <body>          <div>  <h1>Lorem ipsum</h1><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>  </div>    <script>      var metas = document.getElementsByTagName      ('meta');      var i;      if (navigator.userAgent.match(/iPhone/i)) {        for (i=0; i<metas.length; i++) {          if (metas[i].name == "viewport") {            metas[i].content = "width=device-width,             minimum-scale=1.0, maximum-scale=1.0";          }        }        document.addEventListener("gesturestart",         gestureStart, false);      }      function gestureStart() {        for (i=0; i<metas.length; i++) {          if (metas[i].name == "viewport") {            metas[i].content = "width=device-width,             minimum-scale=0.25, maximum-scale=1.6";          }        }      }    </script>  </body></html> Now if we rotate the screen from portrait to landscape, the issue should no longer exist, and if we zoom in on the page, it will react as expected: How it works... Let's have a walk through of the code to see how it works. We need to know the default minimum-scale and maximum-scale values. In the iPhone's official documentation, it states that the minimum-scale value is 0.25, and the maximum-scale value is 1.6. So to replace the default value, we need to set: function gestureStart() {  var metas = document.getElementsByTagName ('meta');  var i;  for (i=0; i if (metas[i].name == "viewport") {    metas[i].content = "width=device-width,     minimum-scale=0.25, maximum-scale=1.6";  }} Next, we need to know when to set this. This is very easy: The iPhone has a gesture event listener we can use to target the document body. Here is how to do so: document.addEventListener("gesturestart", gestureStart, false); Finally, we need to make sure this only happens on iPhone. Again this can be easily done using: if (navigator.userAgent.match(/iPhone/i)) {document.addEventListener("gesturestart", gestureStart, false);} There's more... If you are interested to know the whole story and discussion between Jeremy and I, you can read it at http://www.blog.highub.com/mobile-2/a-fix-for-iphone-viewportscale- bug/.Even though this provides a fix for the issue, there are a couple of problems that some people experience: As soon as the user makes a gesture on the document, zooming is enabled again. So if you change the device orientation after that, the zoom bug will still occur. It's reported on iOS4 that users can only effectively start zooming after starting a second gesture. A slightly improved version Mathias Bynens has a revised version with smarter coding. You can see the code at: https://gist.github.com/901295 An even better version John-David Dalton had an even better updated version with smarter and leaner code at:https://gist.github.com/903131 A word for jQuery Mobile Scott Jehl from jQuery Mobile mentioned it might be implemented in jQuery Mobile in the future. Currently, you could see his gist at: https://gist.github.com/1183357
Read more
  • 0
  • 0
  • 1809
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
Modal Close icon
Modal Close icon