<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>MentorMate Company Blog</title>
	<atom:link href="http://mentormate.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://mentormate.com/blog</link>
	<description></description>
	<lastBuildDate>Thu, 12 Aug 2010 14:59:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Black Box Testing Tips for Quality Assurance</title>
		<link>http://mentormate.com/blog/black-box-testing-tips-quality-assurance/</link>
		<comments>http://mentormate.com/blog/black-box-testing-tips-quality-assurance/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 14:54:44 +0000</pubDate>
		<dc:creator>Jeni</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[quality assurance]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://mentormate.com/blog/?p=957</guid>
		<description><![CDATA[There are a lot of ways to go about black box testing, but the main purpose of this post is to assist new and junior testers. Here you can read about the main strategies for testing, some terminology used and methods that will help you in the beginning of your career as a tester.]]></description>
			<content:encoded><![CDATA[<h1>Define operating and testing environments</h1>
<p>It is very important to define which operating systems and on which browsers the application should be tested. Once you define the browsers on which the system should work, make sure you check all functionality on all browsers. If there is not enough time/budget, you can check the design and the main functionalities of the site with all browsers. Most of the cosmetic problems generally appear in Internet Explorer 6.0. We like to use IETester (<a href="http://www.my-debugbar.com/wiki/IETester/HomePage">http://www.my-debugbar.com/wiki/IETester/HomePage</a>), the application supports all Internet Explorer versions.</p>
<p>For comparing the design of a site on different browsers, there is one tool named Adobe BrowserLab that works great. With it you can compare a web page in one browser next to a page in another browser or overlay the pages entirely. The tool supports the following browsers:</p>
<ul>
<li>Chrome 3.0 – Windows</li>
<li>Firefox 2.0 – OS X</li>
<li>Firefox 2.0 – windows</li>
<li>Firefox 3.0 – OS X</li>
<li>Firefox 3.0 – Windows</li>
<li>Firefox 3.6 – OS X</li>
<li>Firefox 3.6 – Windows</li>
<li>Internet Explorer 6.0</li>
<li>Internet Explorer 7.0</li>
<li>Internet Explorer 8.0</li>
<li>Safari 3.0 – OS. X</li>
<li>Safari 4.0 – OS X</li>
</ul>
<h1>Make sure that your bug reports are easy to understand</h1>
<p>The best testers have the most bug reports resolved. A good bug report is one that assists in resolving an issue. Ensure that your bug reports can easily be reproduced by making them as clear and concise as possible. Here are several steps that you can follow:</p>
<h4>1. Reproducibility – inform the developers how often the bug appears</h4>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="189" valign="top"><strong>Reproducibility</strong></td>
<td width="374" valign="top"><strong>Definition</strong></td>
</tr>
<tr>
<td width="189" valign="top">Always</td>
<td width="374" valign="top">The defect appears at all   times.</td>
</tr>
<tr>
<td width="189" valign="top">Sometimes</td>
<td width="374" valign="top">The defect does not appear   every time.</td>
</tr>
<tr>
<td width="189" valign="top">Random</td>
<td width="374" valign="top">The defect occurs   sporadically.</td>
</tr>
<tr>
<td width="189" valign="top">Not reproducible</td>
<td width="374" valign="top">The defect cannot be   reproduced again.</td>
</tr>
</tbody>
</table>
<h4 style="margin-top: 20px;">2. Severity – inform the developers of the scale of the bug.</h4>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="189" valign="top"><strong>Severity</strong></td>
<td width="374" valign="top"><strong>Description<br />
</strong></td>
</tr>
<tr>
<td width="189" valign="top">Block</td>
<td width="374" valign="top">When a bug stops the user   from working with some aspect of the system. These bugs have the highest priority.</td>
</tr>
<tr>
<td width="189" valign="top">Crash</td>
<td width="374" valign="top">When an error page appears.   Sometimes this happens when the developers forget instances of the system.</td>
</tr>
<tr>
<td width="189" valign="top">Major</td>
<td width="374" valign="top">When a bug has a major   impact on the functionality of a large aspect of the software.</td>
</tr>
<tr>
<td width="189" valign="top">Minor</td>
<td width="374" valign="top">When a bug causes major   harm to some piece of functionality, but   does not impact many aspects of the software.</td>
</tr>
<tr>
<td width="189" valign="top">Tweak</td>
<td width="374" valign="top">There is no problem with   the feature, but the way it is working should be slightly changed (tweaked).</td>
</tr>
<tr>
<td width="189" valign="top">Text</td>
<td width="374" valign="top">A problem with the text and/or   labels of the software. Usually typing mistakes or labels that don’t match   the specifications.</td>
</tr>
<tr>
<td width="189" valign="top">Feature</td>
<td width="374" valign="top">This is a new feature that   should be implemented, in most cases it is not a bug. The tester can be asked   to add such a report in order to inform the developers about a new feature   that should be added to the software.</td>
</tr>
</tbody>
</table>
<h4 style="margin-top: 20px;">3. Summary – summarize the bug with one sentence – as a title for your report. Be descriptive and concise.</h4>
<h4>4. Bug Description – this is the most important section.</h4>
<p>Be sure to include:</p>
<ul>
<li>Location of bug in the software</li>
<li>URL (if you are testing web pages)</li>
<li>Testing browsers or environment</li>
<li>Information about the bug – here you need to explain the input data you used and the sequence of steps you made to cause the bug. This point is quite important make sure that your instructions are clear and reproducible. Make sure that you use the same terminology as the developers.</li>
<li>Screen shots with comments and explanations. Firefox has one wonderful Add-on “FireShot”, this Add-on can be found also for Internet Explorer.</li>
</ul>
<p>These days, more and more people in the IT business work with clients or have coworkers that are not from their own country and who communicate in another language. No matter how well you learn to understand a language, there still can be misunderstandings that can lead to problems of all types. It helps to have a pre-planned method and agreed terminology to report bugs.</p>
<h1>There must be bugs</h1>
<p>Start to test with the idea that there should be bugs. There is not a system that does not have a few errors. This mindset will help you to be more focused on finding problems.</p>
<h1>Test situations that should not be executed</h1>
<p>Sometimes, due to a variety of reasons, users do not enter something as they are intended to, press buttons out of order, or otherwise misuse the software. It is important to try to account for these situations.<br />
If you have a registration form to test, try doing things OTHER than fill out the form. It was built to accept data, so try not entering anything and pressing the button for registration, enter invalid data such as email that does not have the “@” symbol or very long zip code or name. Use boundary cases (inputs at or just beyond maximum and minimum limits) to attempt to receive errors. There are symbols that can break the database or break the request from the database if they are entered and saved in the system. Such examples are the percentage (%) symbol, inverted commas(“”), and two minuses (&#8211;) together.<br />
If you have a combination of actions that need to be done one after another, change their sequence. Make sure that you have checked all situations that you can think of, according to the system you test.</p>
<h1>Test real situations</h1>
<p>The above tips should not turn the QA process into a highly critical and aggressive testing period. Do not test and report bugs for unrealistic situations. Make sure you have understood the specification for the application and do not tease the developers with unrealistic bugs.</p>
<h1>Test like you are a regular user, a computer illiterate user.</h1>
<p>Think about the users, question yourself. Is this system user friendly? Can you easily navigate the program? Is the text within the system clear and understandable? Are the error messages helpful? There are a lot of examples in your own personal life. Think about when you sit at home on your personal computer &#8211; which sites or programs do you prefer? Why? Which you do not like? Why? Usability is always the answer.</p>
<h1>Keep written reports</h1>
<p>Sometimes bugs are  shared verbally with the developers. This can work against you.  Make sure that you keep written documentation of all your discussions about issues or anything concerning a project.  The best practice is to have reports on every issue you find.  Sometimes when communicating bugs verbally, many testers complain that the developers take the credit for their work or that managers who calculate the productivity of a tester by the number of bugs he/she reports do not give full credit.</p>
<h1>Work to become a Team</h1>
<p>Communication with your team members is just as important as knowing good techniques for testing and is key for the successful achievement of a quality product. You need to be flexible. During your work you will meet junior developers that have never worked with testers or people who will disagree with your findings. Some developers just need to get used the fact that they have bugs in their programs. This is normal. You need to persuade them that a tester for a developer is not like a critic for an author. Help them understand that you are a team and you both want the same thing. Prove your statement with facts and knowledge of the system and specifications.</p>
<h1>Gain new knowledge</h1>
<p>Black box testing uses external descriptions of the software with no knowledge about the internal structure. If you want to become competitive and help further your career, you should take a peak at the source code and ask questions of the developers. For cosmetic issues, you can read and learn about HTML and CSS and report specific CSS styles/areas of a web page that need fixing. Some tools that can help are the Web Developer Toolbar and the Firefox Add-on, Firebug. Some knowledge about Databases also will be helpful, this way you can more clearly understand the processes in the system and the reasons why some bugs appear. With more knowledge of how the software works, you will speed up the developer&#8217;s work and make yourself more efficient in the process.</p>
<p>Approving a high quality product is a hard and complicated process. Learn from your mistakes and from the bugs you found. Keep good communication with your coworkers, defend your position in a positive manner, keep learning, and continue testing.</p>
]]></content:encoded>
			<wfw:commentRss>http://mentormate.com/blog/black-box-testing-tips-quality-assurance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Link Building with the Experts &#8211; Our Link Building Tips &amp; Strategies</title>
		<link>http://mentormate.com/blog/link-building-experts-link-building-tips-strategies/</link>
		<comments>http://mentormate.com/blog/link-building-experts-link-building-tips-strategies/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 20:21:03 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Marketing]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[link building]]></category>
		<category><![CDATA[linkbait]]></category>
		<category><![CDATA[seo]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://mentormate.com/blog/?p=943</guid>
		<description><![CDATA[We answer the 11 questions from Outspoken Media's "Link Building with the Experts - 2010 Edition" questionnaire.]]></description>
			<content:encoded><![CDATA[<p>Outspoken Media just interviewed 11 famous SEO experts to answer <a href="http://outspokenmedia.com/seo/link-building-interview/">11 great questions about link building</a>. We saw that Dori had gone through and answered these <a href="http://www.dorifriend.com/seo-linking-interview/">link building questions</a> on her blog, so we thought we&#8217;d do the same. We hope you find these answers useful to your own link building campaigns.</p>
<blockquote><p>1) What are a few emerging link tactics that you’ve seen in the past 12 months providing tremendous value to sites/pages? Can you give a specific example or two?</p></blockquote>
<p>I haven&#8217;t found any new link tactics in the past 12 months that provide tremendous value. All the great tactics that truly provide tremendous value have been around for a while.</p>
<blockquote><p>2) The SEO industry has become so stingy with linking to quality content to the point that many people who used to share a lot of it simply don’t bother, as it is not worth the cost of doing so. Is this a trend which spreads? Are we canaries in the coal mine, or is this just an issue impacting the SEO niche because it is far too saturated? What can Google do to encourage organic linking on the WWW (outside of nepotism, hype, spin, misinformation &amp; ego-baiting)?</p></blockquote>
<p>We don&#8217;t like to look greedy, so we don&#8217;t perform the stingy acts on our company web site. However the reason we created SpyderMate initially was as a linkbait tool. So for SpyderMate we don&#8217;t freely post external links. We feel it&#8217;s justified there however because we are offering a free and very useful service to the community.</p>
<blockquote><p>3) What are the criteria for the “perfect link”?</p></blockquote>
<p>The perfect link has the following attributes:</p>
<p>a) High authority domain &amp; page<br />
b) Minimal amount of external links on same page<br />
c) Web site is very relevant to yours<br />
d) The anchor text matches a keyword you are battling for<br />
e) It&#8217;s located within the obvious content section of the web page<br />
f) obviously it&#8217;s not tagged rel=&#8221;nofollow&#8221;</p>
<blockquote><p>4) How do you go about creating a link marketing plan that will A:) Get tangible search results in a 6 to 12 month period and B:) Create sustainability for the website you are creating the plan for (i.e. keeping the links clean and adding links with long term value)</p></blockquote>
<p>Well first you find out what keywords they should be targeting. Then you go through all their competitors ranking  for the keyword phrases and scour all their backlinks. Once you make sure you got a link from every backlink they have possible then you move on. Next you target the more lower hanging fruit longtail keywords through your list of standard directories that you submit to. This helps re-enforce your short-tail keywords with long tail variation power. After this you go for the seriously powerful links. These are your premium directory listings, your serious linkbait web sites and your powerful friend&#8217;s web sites. These sites target the more generic short-tail keywords that help raise all your longtails associated around them. The maintain sustainability you consistently create great new content and linkbait to create a consistent flow of natural inbound, quality, relevant links.</p>
<blockquote><p>5) If you could choose a link on a lower authority page that would provide a moderate amount of targeted traffic or a link on a higher authority page that would provide absolutely no traffic – all other attributes being equal – for ranking benefits on the site you’re developing links for, which would you choose and why?</p></blockquote>
<p>This depends entirely on how relevant and how well converting the lower authority page would be. It also depends on current rankings, whether or not there is a keyword I could boost my rankings for that would beat the conversions coming directly from this link. So if i had a site with a low conversion rate that had a high payout I would go with the lower authority link. If I had a site with a high conversion rate and a lower average payout I&#8217;d go with the high authority link.</p>
<blockquote><p>6) Do you feel that you can conserve pagerank or that it’s still worth the effort to sculpt your links, by limiting the number of links on a page, creating them with JavaScript, passing them through a blocked page or using nofollow?</p></blockquote>
<p>I believe you can, but also don&#8217;t believe it&#8217;s worth the effort, especially on a site that you&#8217;re constantly updating. There are other tasks you can spend your valuable time on that provide more value to your web presence.</p>
<blockquote><p>7) Please discuss what link deprecation is and what impact it may have on a link building campaign.</p></blockquote>
<p>I believe link deprecation to be the result of poorly built links primarily. The only reason this should occur is due to the age of the links. Actually losing links only happens to links that were easily attained and therefore easily lost. The best links are very hard to come by and last the test of time.</p>
<blockquote><p>8) Do you think search engines are trying to find a way to depend less on link popularity and more on other algorithmic/social media factors?</p></blockquote>
<p>I believe they are, but I don&#8217;t think it plays much of a role currently. I also think basing searches on social media is not viable for many categories of web sites. The fact that social media sites like Facebook are social make your likes inherently based around your friend&#8217;s general interests as well as your own. Even though I&#8217;m heavily interested in SEO, it does not mean I&#8217;m going to bother liking SEO articles I find interesting left and right because I know it will annoy my friends. I want to share things that I know my friends will also be interested in. This is not a system that a true search engine can be built upon. A search engine can however leverage this information is done on the right level.</p>
<blockquote><p>9) How much do you stress internal linking on your own or clients’ sites? Do you have a quick rule of thumb or strategy to maximize the effectiveness of internal links?</p></blockquote>
<p>I&#8217;ve found that emphasizing your traffic generating pages through inbound links is critical. Using carefully placed inbound links to associate relevant topics and re-emphasize targeted anchor text is extremely helpful, especially for that highest level page in the link scheme. Enough said.</p>
<blockquote><p>10) What’s a successful link development strategy many overlook or dismiss?</p></blockquote>
<p>Linkbait. People tend to dismiss serious linkbait strategies because of the time/costs associated with them. They tend to think other efforts are easier, but nothing generates those truly unique, critical, powerful links like well done linkbait.</p>
<blockquote><p>11)  What have you been most WRONG about over the course of your link building/SEO career?</p></blockquote>
<p>I was most wrong about how effective thousands of links coming from the same authoritative web site, with different anchor text, coming from different pages, linking to different pages were at lifting my rankings. Domain diversity is absolutely crucial. I&#8217;ve learned that one great warrior is better than thousands of mediocre warriors.</p>
]]></content:encoded>
			<wfw:commentRss>http://mentormate.com/blog/link-building-experts-link-building-tips-strategies/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Google Android Application Development Utilizing Background Processes</title>
		<link>http://mentormate.com/blog/google-android-application-development-background-processes/</link>
		<comments>http://mentormate.com/blog/google-android-application-development-background-processes/#comments</comments>
		<pubDate>Fri, 28 May 2010 22:03:03 +0000</pubDate>
		<dc:creator>Eleonora</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[libraries]]></category>

		<guid isPermaLink="false">http://mentormate.com/blog/?p=881</guid>
		<description><![CDATA[These days it is very important to be informed, mobile and connected with the other parts of the world. The future of development is in the applications for mobile devices. One very useful feature of these devices is their GPS module, which provides your current location. In this post I will show you how to use the coordinates from the GPS in a Google Android application running in the background.]]></description>
			<content:encoded><![CDATA[<p>Android is one of the fastest growing operating systems and software stacks for smartphones. OS smartphones ranked second among all smartphone OS handsets sold in the U.S. in the first quarter of 2010. Dell, HTC, Motorola and Samsung are some of the manufacturers using this operating system.</p>
<p>Google opened the source code under an Apache License and now the Android SDK allows developers to write managed code in the Java language, controlling the device via Google-developed Java libraries. The SDK includes a comprehensive set of development tools, such as a debugger, libraries, a handset emulator, documentation, sample code and tutorials.</p>
<p>Applications that run in the background are supported in Android in contrast to iPhone. All of these facts stimulate me to research this interesting technology. I decided to make an application running in the background and receiving the GPS location. The main goal was to inform the user not to write or read text messages while he or she is driving.</p>
<p>It is pretty easy to develop an Android application, especially if you are using Eclipse. You can download the latest version of the Android SDK from the <a href="http://developer.android.com/sdk/index.html">official site</a>. There are a lot of tutorials explaining how to install and use the SDK in Eclipse, if you are a beginner you can take a look at the <a href="http://developer.android.com/guide/tutorials/hello-world.html">developer’s guide</a>.</p>
<p><strong>Utilizing the GPS Module</strong></p>
<p>As you may know smartphones have a gps module which provides the current location. This feature is used in many applications. To implement it you have to modify the<strong> AndroidManifest.xml</strong>, this is the main configuration file.</p>
<pre class="brush: plain;">
&lt;uses-permission android:name=&quot;android.permission.ACCESS_COARSE_LOCATION&quot; /&gt;
&lt;uses-permission android:name=&quot;android.permission.ACCESS_FINE_LOCATION&quot; /&gt;
</pre>
<p>With these permissions you tell to the application that the GPS module will be used and the application is given access to it.</p>
<p><strong>The Activity Class</strong></p>
<p>There is one very important class in an application&#8217;s overall lifecycle – the Activity class. It takes care of creating a window for you in which you can place your UI. But this activity is not enough to create a background process. It should be used in conjunction with another object from the <strong>ContextWrapper </strong>to achieve the behavior of an application component that runs in the background and doesn&#8217;t interact with the user. This functionality is given up by the Service class. Both the activity and the service should be declared in the android manifest file.</p>
<p>My idea is to create a main activity class and in the <strong>onCreate() </strong>method call the service. But when something is started, there needs to be a way to stop it. The best place to stop the service is in the <strong>onDestroy()</strong> method of the main activity. These two methods are overridden because the main activity has to extend the <strong>Activity.java</strong> class. They look like:</p>
<pre class="brush: plain;">
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    try {
        // setup and start MainService
        MainService.setMainActivity(this);
        Intent svc = new Intent(this, MainService.class);
        startService(svc);
    } catch (Exception e) {
    Log.e(&quot;&gt;&gt;&gt;&quot;, &quot;Problem creating the UI&quot;, e);
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();
    // stop MainService
    Intent svc = new Intent(this, MainService.class);
    stopService(svc);
}
</pre>
<p>This is how the activity class looks. The service class will manipulate the GPS module data. It will get the location in a time interval, get the speed or calculate it if it is not available and finally if the speed is more than 10km/h it will inform the user not to use the phone’s features while driving in order to avoid accidents.</p>
<p><strong>The Service Class</strong></p>
<p>As the main activity extends <strong>Activity.java</strong> class, the service should extend the <strong>Service.java</strong> class. The service is started in the overridden method <strong>onCreate()</strong> of the class.</p>
<pre class="brush: plain;">
// service business logic
private void startService() {
    TimerTask timerTask = new TimerTask(){
        public void run() {
            getUpdateLocation();
        }
    };
    timer.scheduleAtFixedRate(timerTask,0,UPDATE_TIME_INTERVAL);
    Log.i(getClass().getSimpleName(), &quot;Timer started!&quot;);
}
</pre>
<p>First a timer object is needed which will take care of calling the service. To schedule the timer you have to prepare a TimerTask instance, which calls your business logic. In the example it is called the <strong>getUpdateLocation()</strong> method, its functionality will be explained later in this post. The timer is scheduled with the timer task and the specified time interval passed as a constant.</p>
<p>Lets take a look at the <strong>getUpdateLocation()</strong> method. As the title says, the method gets the location from the <strong>LocationManager.java</strong> class. The locations are separated by providers, so they are filtered with a criteria. Some GPS providers send the speed of the device. But if the speed is not received, it can easily be calculated as a quotient of the distance between the current and previous location with the subtraction of the two times.</p>
<pre class="brush: plain;">
private void getUpdateLocation() {
    Log.i(getClass().getSimpleName(), &quot;background task - start&quot;);
    // get the system location service
    locationManager = (LocationManager)
                               getSystemService(Context.LOCATION_SERVICE);
    // create criteria to filter the providers
    Criteria criteria = new Criteria();
    bestProvider = locationManager.getBestProvider(criteria, false);
    Location location = locationManager.getLastKnownLocation(bestProvider);

    date = new Date();
    if(currentLocation == null){
        currentLocation = locationManager.getLastKnownLocation(bestProvider);
        currentDate = new Date();
    }

    float speed = calculateSpeed(location);
    // speed &gt; (10km/h = 2.78m/s)
    if(speed &gt; SPEED_LEVEL){
        Looper.prepare();
        Context context = getApplicationContext();
        CharSequence text = MESSAGE;
        int duration = Toast.LENGTH_LONG;
        Toast toast = Toast.makeText(context, text, duration);
        toast.show();
        Looper.loop();
    }
    // set the currentLocation and currentDate with new values
    // for the next iteration
    currentLocation = location;
    currentDate = date;
    Log.i(getClass().getSimpleName(), &quot;background task - end&quot;);
}
</pre>
<p>The user will be informed with a warning message, if the calculated speed is more than a specified value. This is the business logic, but there is one other thing to take care of – the timer. The timer is started in the <strong>onCreate()</strong> method of the service class. It will be stopped in the <strong>onDestroy()</strong> method of the service class. The <strong>cancel()</strong> method will then be called in order to cancel the timer and remove any scheduled tasks.</p>
<pre class="brush: plain;">
if (timer != null) {
    timer.cancel();
}
</pre>
<p>The completed application will run in the background and inform the user with a message that his or her speed is more than 2.78 meters per second.</p>
]]></content:encoded>
			<wfw:commentRss>http://mentormate.com/blog/google-android-application-development-background-processes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>9 Easy Ways to Speed Up Your Website&#8217;s Load Time</title>
		<link>http://mentormate.com/blog/easy-ways-speed-website-load-time/</link>
		<comments>http://mentormate.com/blog/easy-ways-speed-website-load-time/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 21:09:46 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[libraries]]></category>
		<category><![CDATA[optimization]]></category>

		<guid isPermaLink="false">http://mentormate.com/blog/?p=690</guid>
		<description><![CDATA[Load time optimization is important not only to maximize your site's user-friendiness, but also to optimize your web site's search rankings. These nine tips are intended to help webmasters improve efficiency and rank better in order to get the most out of their web presence.]]></description>
			<content:encoded><![CDATA[<p>Google recently <a href="http://googlewebmastercentral.blogspot.com/2010/04/using-site-speed-in-web-search-ranking.html" target="_blank">announced that they began factoring in web site load</a> time into their search engine ranking algorithm. This has brought the importance of a fast load time front and center even though &#8220;fewer than 1% of search queries will change as a result&#8221; of this update. MentorMate.com likely was not impacted very significantly from this change to Google&#8217;s ranking algorithm; however, we still decided to optimize our site&#8217;s load time. We did this because Google showed that &#8220;<a href="http://searchengineland.com/google-now-counts-site-speed-as-ranking-factor-39708" target="_blank">delays of under a half-second impact business metrics</a>.&#8221; It&#8217;s better to be safe than sorry, and besides, it&#8217;s not that difficult to optimize your site. We recommend you do the same with your web site, here are nine easy ways to do just that:</p>
<h2><strong>1. Place scripts near closing body tag</strong></h2>
<p style="padding-left: 30px;">Scripts  block parallel downloads. While a script is downloading, the browser will  wait until it finishes before downloading anything else. This is why it  is recommended that you get everything else out of the way before  having your users download scripts.</p>
<h2><strong>2. Remove any broken links/references</strong></h2>
<p style="padding-left: 30px;">Simply enter your web page URL in <a href="http://tools.pingdom.com/" target="_blank">Pingdom&#8217;s Full Page Test Tool</a>. This tool will color-code any broken links/references in red so you can easily identify them.</p>
<h2><strong>3. Specify image dimensions</strong></h2>
<p style="padding-left: 30px;">When   image dimensions are  not specified in the HTML and/or CSS of a web  page, the web  server must spend resources calculating these  dimensions.  It&#8217;s  particularly important to specify the dimensions of  images being  used  in conjunction with heavy Javascript  image-manipulation libraries.</p>
<h2><strong>4. Localize external file references to minimize DNS requests</strong></h2>
<p style="padding-left: 30px;">This is another spot in which <a href="http://tools.pingdom.com/" target="_blank">Pingdom&#8217;s Full Page Test Tool</a> comes in handy. Enter your URL and look for any file references to external domains. If possible, copy these files onto your own domain and link to them locally to minimize DNS requests.</p>
<h2><strong>5. Minimize slow-loading libraries and external widgets</strong></h2>
<p style="padding-left: 30px;">Libraries  and external widgets need to be chosen carefully. Sometimes it&#8217;s worth  sacrificing load time for particularly engaging/useful libraries and/or  widgets; however, sometimes you can live without the library and/or  widget. For example, on MentorMate.com we felt it was worth sacrificing <a href="http://code.google.com/p/sexybuttons/" target="_blank">Sexybuttons</a> for better load time, but sacrificing load time for <a href="http://www.shadowbox-js.com/" target="_blank">Shadowbox</a>. External widgets can be particularly bad for a site&#8217;s load  time because of their reliance on external servers.</p>
<h2><strong>6. Compress your files using gzip</strong></h2>
<p style="padding-left: 30px;">These days, gzip  comes pre-installed on most web servers. You can check to see  if gzip is running your server quite easily using <a href="http://code.google.com/speed/page-speed/" target="_blank">Google&#8217;s Firebug  &#8220;Speed Test&#8221;</a> extension. Open Firefox, visit the web site you&#8217;d like to optimize, and open Firebug. From there, click &#8220;Analyze Performance&#8221; and select the &#8220;Resources&#8221; tab. Then you can expand any file to view details. If gzip is installed and compressing the element you are viewing, you will see what is highlighted in red in the following screenshot:</p>
<p style="padding-left: 30px;"><img class="alignleft" title="Google's Firebug &quot;Page Speed&quot; extension gzip enabled" src="http://mentormate.com/blog/wp-content/uploads/2010/04/gzip.png" alt="Google's Firebug &quot;Page Speed&quot; extension gzip enabled" width="608" height="375" /></p>
<h2><strong>7. Merge Javascript and CSS files or use Minify</strong></h2>
<p style="padding-left: 30px;">Depending  on the complexity of your site, it can be quite time consuming to merge  all CSS into one file. The same goes for Javascript. This is  why <a href="http://code.google.com/p/minify/" target="_blank">Minify</a> was developed.  Minify &#8220;combines multiple CSS or Javascript  files, removes unnecessary whitespace and comments, and serves them with  gzip encoding and optimal client-side cache headers.&#8221; Then you simply  need to install it on your site, select the files you want it to serve  together, change some references in your header, and you&#8217;re good to go.  This will minimize your site&#8217;s load time by further helping to reduce  HTTP requests.</p>
<h2><strong>8. Load cross-browser compatibility hacks only for necessary browsers</strong></h2>
<p style="padding-left: 30px;">For instance, we use the IE PNG FIX for IE6 PNG transparency compatibility. This script adds an extra second to web site load time. For this reason, we only load the script if the visitor is running IE6 by applying an IE6-specific stylesheet which references the IE PNG FIX. This way the extra load time will only impact IE6 visitors.</p>
<p style="padding-left: 30px;">We simply added the following line of code to our header:</p>
<pre class="brush: plain;">&lt;!--[if IE 6]&gt;&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/ie6.css&quot; /&gt;&lt;![endif]--&gt;</pre>
<h2><strong>9. Use CSS sprites to minimize HTTP Requests</strong></h2>
<p style="padding-left: 30px;">A CSS  sprite is the combination of multiple images into one. Then CSS  is used to reference different aspects of the image where needed. This  reduces load time by minimizing all of these images into only one  HTTP  request. CSS Tricks has a good <a href="http://css-tricks.com/css-sprites/" target="_blank">example of  CSS sprites</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://mentormate.com/blog/easy-ways-speed-website-load-time/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>JFreeChart Bar Chart Tutorial for Dynamic Java Web Applications</title>
		<link>http://mentormate.com/blog/jfreechart-bar-chart-tutorial-dynamic-java-web-applications/</link>
		<comments>http://mentormate.com/blog/jfreechart-bar-chart-tutorial-dynamic-java-web-applications/#comments</comments>
		<pubDate>Tue, 20 Apr 2010 15:24:01 +0000</pubDate>
		<dc:creator>Eleonora</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[charts]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jfreechart]]></category>
		<category><![CDATA[libraries]]></category>
		<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://mentormate.com/blog/?p=717</guid>
		<description><![CDATA[There are a lot of tutorials and posts explaining how to display a chart in a web application and which libraries to use. I am going to show the process from receiving the http request from the client to sending the response back from the server. I will share my real experience with JFreeChart and the servlet technology for creating and displaying dynamic charts in Java based web application.]]></description>
			<content:encoded><![CDATA[<p>JFreeChart is an open-source Java based library which allows the creation of complex charts in a simple way.</p>
<p>Supported chart types include:</p>
<ul>
<li>X-Y charts (line, spline and scatter);</li>
<li>Pie charts;</li>
<li>Gantt charts;</li>
<li>Bar charts (horizontal and vertical, stacked and independent);</li>
<li>Single valued (thermometer, compass, speedometer).</li>
</ul>
<p>I am going to explain how to use the chart library and how to create a bar chart with a custom color. To create a chart with JFreeChart library, first you have to make a <strong>Dataset </strong>object<em>. </em>The chart is generated from this data collection. Next you have to instate the class <strong>DefaultCategoryDataset</strong>, which is passed to the chart object. In the code below as a data source is used ArrayList, which may come from data base.</p>
<pre class="brush: plain;">
// load the data
double[] data = new double[jobTitles.size()];
for (int i = 0; i &amp;lt; jobTitles.size(); i++) {
     data[i] = jobTitles.get(i).getCount();
}
// create the data set
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
for (int i = 0; i &amp;lt; data.length; i++) {
     dataset.setValue(data[i], &quot;Profit1&quot;, jobTitles.get(i).getTitle());
}
</pre>
<p>The next step is to do an object from chart type. The library uses a class named <strong>JFreeChart </strong>to display the chart. This chart object is an instance, which comes from the method <strong>createBarChart </strong>of<strong> </strong>the static class <strong>ChartFactory</strong>. The method takes as a parameter the formed collection (dataset). There are many properties, which you can pass to the constructor, such as labels, orientation, etc. It is possible to change colors, size, scale and many other characteristics.<strong> </strong></p>
<p>You have ready object now and the next step is to send the chart to the web page. For this purpose, the library includes a class named <strong>ChartUtilities</strong> that provides several methods for saving charts to files or writing them out to streams in JPEG or PNG format. The methods from this class can be used for creating JPEG images for static web pages. The goal, however, is not to save the chart in a hard drive; the goal is to pass the graphic to the application. To do that, you can use the servlet technology and display the dynamic data stream in the jsp pages.</p>
<p>Consequently the next step is to generate <strong>BufferedImage</strong> from your chart object and to transfer this stream through the session. You should also write the image in the http response writer.</p>
<pre class="brush: plain;">
// create the chart
final JFreeChart chart = ChartFactory.createBarChart(&quot;Allocation of Duties&quot;,
                 &quot;Values&quot;, dataset, PlotOrientation.VERTICAL, true, true, true);
// set custom color
GradientPaint gradientpaint0 = new GradientPaint(0.0F, 0.0F,
                 new Color(209, 228, 246), 0.0F, 0.0F, new Color(82, 141, 201));
BarRenderer r = (BarRenderer)chart.getCategoryPlot().getRenderer();
r.setSeriesPaint(0, gradientpaint0);
ChartRenderingInfo info = null;
HttpSession session = request.getSession();
try {
     // create RenderingInfo object
     response.setContentType(&quot;text.html&quot;);
     info = new ChartRenderingInfo(new StandardEntityCollection());
     BufferedImage chartImage = chart.createBufferedImage(640, 400, info);
     session.setAttribute(&quot;chartImage&quot;, chartImage);
     PrintWriter writer = new PrintWriter(response.getWriter());
     ChartUtilities.writeImageMap(writer, &quot;imageMap&quot;, info, false);
     writer.flush();
} catch (Exception e) {
     e.printStackTrace();
}
</pre>
<p>Finally you should write the servlet. This is a Java object, which dynamically answers requests and built response to the client. Each servlet has two main methods &#8211; doGet(HttpServletRequest request, HttpServletResponse response) and doPost(HttpServletRequest request, HttpServletResponse response). You need to get the chart stream from the session in the servlet. The image is set to an attribute named <strong>chartImage </strong>in the session. You have to get http session instance from the request and then to retrieve the previously set attribute.</p>
<pre class="brush: plain;">
// Process the HTTP Get request
public void mdoGet(HttpServletRequest request, HttpServletResponse response)
                                       throws ServletException, IOException {
    // get the chart from session
    HttpSession session = request.getSession();
    BufferedImage chartImage = (BufferedImage)session.getAttribute(&quot;chartImage&quot;);
   // set the content type so the browser can see this as a picture
    response.setContentType(&quot;image.png&quot;);
    // send the picture
    PngEncoder encoder = new PngEncoder(chartImage, false, 0, 9);
    response.getOutputStream().write(encoder.pngEncode());
}
// Process the HTTP Post request
public void doPost(HttpServletRequest request, HttpServletResponse response)
                                       throws ServletException, IOException {
    doGet(request, response);
}</pre>
<p>The result is the graphic below:<a href="http://mentormate.com/blog/wp-content/uploads/2010/04/chart_sample.jpg"><img class="aligncenter size-full wp-image-752" src="http://mentormate.com/blog/wp-content/uploads/2010/04/chart_sample.jpg" alt="" width="621" height="400" /></a></p>
<p>JFreeChart is a library for displaying charts and managing their properties with a big palette of options. For more information go to the project <a href="http://www.jfree.org/jfreechart/">official site</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://mentormate.com/blog/jfreechart-bar-chart-tutorial-dynamic-java-web-applications/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mapping XML Document to Object Model Using DOM in iPhone Application</title>
		<link>http://mentormate.com/blog/mapping-xml-document-object-model-dom-iphone-application/</link>
		<comments>http://mentormate.com/blog/mapping-xml-document-object-model-dom-iphone-application/#comments</comments>
		<pubDate>Mon, 12 Apr 2010 18:23:35 +0000</pubDate>
		<dc:creator>Iordan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://mentormate.com/blog/?p=606</guid>
		<description><![CDATA[This tutorial introduces you to the basic concepts of XML and using a Document Object Model (DOM) as a parser for the iPhone to parse XML. The intended audience is XML beginners with knowledge of Objective C.]]></description>
			<content:encoded><![CDATA[<p>The idea here is to parse the XML response from a Wunderground Data Feed Web Service, which provides information for current weather conditions. The conceptual part of target XML follows. More details about XML and available weather API can be found on the <a title="http://wiki.wunderground.com/index.php/API_-_XML" href="http://wiki.wunderground.com/index.php/API_-_XML">Wunderground Data Feed</a> site.</p>
<pre class="brush: plain;">
&lt;current_observation&gt;
  &lt;credit&gt;Weather Underground NOAA Weather Station&lt;/credit&gt;
  &lt;credit_URL&gt;http://wunderground.com/&lt;/credit_URL&gt;
  &lt;image&gt;
    &lt;url&gt;http://icons.wunderground.com/graphics/wu2/logo_130x80.png&lt;/url&gt;
    &lt;title&gt;Weather Underground&lt;/title&gt;
    &lt;link&gt;http://wunderground.com/&lt;/link&gt;
  &lt;/image&gt;
  +&lt;display_location&gt;&lt;/display_location&gt;
  +&lt;observation_location&gt;&lt;/observation_location&gt;
  &lt;station_id&gt;KSFO&lt;/station_id&gt;
  &lt;observation_time&gt;Last Updated on July 14, 9:56 AM PDT&lt;/observation_time&gt;
  ...
  &lt;local_time&gt;July 14, 10:01 AM PDT&lt;/local_time&gt;
  ...
  &lt;local_epoch&gt;1247590877&lt;/local_epoch&gt;
  &lt;weather&gt;fog&lt;/weather&gt;
  &lt;temperature_string&gt;52 F (11 C)&lt;/temperature_string&gt;
  &lt;temp_f&gt;52&lt;/temp_f&gt;
  &lt;temp_c&gt;11&lt;/temp_c&gt;
  &lt;relative_humidity&gt;76%&lt;/relative_humidity&gt;
  ...
  &lt;icon&gt;fog&lt;/icon&gt;
  ...
&lt;/current_observation&gt;
</pre>
<p>For processing this XML we decided to use DOM parser for the following reasons:</p>
<ul>
<li>To save the structure of data      (more flexible usage for presentation and further processing)</li>
<li>To ensure good      maintainability and adaptability (external provider may change XML      structure)</li>
<li>The XML is not so large that it would not cause memory issues.</li>
</ul>
<div id="attachment_610" class="wp-caption aligncenter" style="width: 278px"><a href="http://mentormate.com/blog/wp-content/uploads/2010/03/Fig.1-The-DOM-presents-an-XML-document-as-a-tree-structure.png"><img class="size-medium wp-image-610 " src="http://mentormate.com/blog/wp-content/uploads/2010/03/Fig.1-The-DOM-presents-an-XML-document-as-a-tree-structure-268x300.png" alt="" width="268" height="300" /></a><p class="wp-caption-text">Figure 1 the DOM presents an XML document as a tree-structure</p></div>
<h2><strong>DOM Tree</strong></h2>
<p>The DOM presents an XML document as a tree-structure. The parser creates a tree object out of the document. The user accesses data by traversing the tree. The API allows for constructing, accessing and manipulating the structure and content of XML documents (Figure 2).</p>
<div id="attachment_612" class="wp-caption aligncenter" style="width: 310px"><a href="http://mentormate.com/blog/wp-content/uploads/2010/03/Fig-2-Using-a-DOM-Tree.png"><img class="size-medium wp-image-612" src="http://mentormate.com/blog/wp-content/uploads/2010/03/Fig-2-Using-a-DOM-Tree-300x86.png" alt="" width="300" height="86" /></a><p class="wp-caption-text">Figure 2 Using a DOM Tree.</p></div>
<p>For our implementation we use a very simple and effective parser - <a title="http://osmorphis.blogspot.com/2009/03/enhancing-standard-nsxmlparser-class.html" href="http://osmorphis.blogspot.com/2009/03/enhancing-standard-nsxmlparser-class.html">XMLTreeParser/XMLTreeNode</a>. The implementation consists of two classes: <em>XMLTreeParser</em> and <em>XMLTreeNode</em>. It uses <em>NSXMLParser</em> to read the document and for every one <em>&lt;element&gt;</em> tag creates a <em>XMLTreeNode</em> object. That way, it creates the tree that contains nodes of type <em>XMLTreeNode</em>.</p>
<p>To create a parser, simply instantiate the <em>XMLTreeParser</em> class:</p>
<pre class="brush: plain;">XMLTreeParser* parser = [[XMLTreeParser alloc] init];</pre>
<p><strong> </strong></p>
<p class="MsoNormal">After that start parsing &#8211; call the parse method and provide the XML data:</p>
<p class="MsoNormal"><span> </span></p>
<pre class="brush: plain;">&lt;strong&gt;XMLTreeNode* root = [parser parse:xmlData];</pre>
<p><strong> </strong></p>
<p class="MsoNormal">Now you can traverse through the tree manually looking for things.</p>
<p class="MsoNormal"><strong><span> </span></strong></p>
<p><strong> </strong></p>
<pre class="brush: plain;">NSArray* items = [stuffindChildren:@&quot;icon&quot;];</pre>
<h2><strong>Architecture of an XML application using DOM</strong></h2>
<p class="MsoNormal"><span style="font-weight: normal">The DOM model is easiest to understand. On Figure 3, a basic architecture of an XML application using DOM is presented:</span></p>
<p class="MsoNormal">
<div id="attachment_613" class="wp-caption aligncenter" style="width: 310px"><a href="http://mentormate.com/blog/wp-content/uploads/2010/03/Fig-3-Architecture-of-an-XML-application-using-DOM.png"><img class="size-medium wp-image-613 " src="http://mentormate.com/blog/wp-content/uploads/2010/03/Fig-3-Architecture-of-an-XML-application-using-DOM-300x145.png" alt="" width="300" height="145" /></a><p class="wp-caption-text">Figure 3 Architecture of an XML application using DOM</p></div>
<p class="MsoNormal"><span style="font-weight: normal">So here&#8217;s what happens: A parser reads the XML file and builds a DOM document to match the XML file. From that point until a save is performed, all interaction between the application and XML hits the DOM document rather than the corresponding XML file. It&#8217;s interesting to note that almost all XML parsers use SAX. Before you build a DOM document you must detect events such as the start of an element (start tag encountered), end of an element (end tag encountered) and/or a new attribute (name followed by equal sign followed by quoted string encountered). DOM can be thought of as an extra abstraction to lessen the programmer&#8217;s workload, at the expense of memory usage.</span></p>
<p class="MsoNormal"><span style="font-weight: normal">Modifications are made directly to the DOM document. Elements can be added, deleted, renamed, and rearranged. Text nodes can be added, delete,d or changed. Elements can be moved either within the same level, or promoted or demoted to different levels.</span></p>
<h2><span style="font-weight: normal"> </span><strong>Choose a design pattern for implementation</strong></h2>
<p class="MsoNormal"><span style="font-weight: normal">Choosing the appropriate pattern is a critical step. The Dynamic Document architectural pattern was used in our case. This pattern contains XML not typed by DTD or schema, but follows assessors for underlying program objects. It allows for unlimited extension by multiple, uncoordinated parties at the cost of lack of type-checking, and it&#8217;s simple to implement.</span></p>
<p class="MsoNormal"><span style="font-weight: normal"> </span></p>
<div id="attachment_614" class="wp-caption aligncenter" style="width: 310px"><a href="http://mentormate.com/blog/wp-content/uploads/2010/03/Fig-4-Map-the-XML-document-to-object-model.png"><img class="size-medium wp-image-614 " src="http://mentormate.com/blog/wp-content/uploads/2010/03/Fig-4-Map-the-XML-document-to-object-model-300x210.png" alt="" width="300" height="210" /></a><p class="wp-caption-text">Figure 4 Map the XML document to object model.</p></div>
<p class="MsoNormal"><span style="font-weight: normal">The DOM API is used to read information from an XML document. There is an easier way of getting around using DOM for modifying and saving the XML data &#8212; creating an object model for the information in the document. You can create this object model by giving it a DOM object that holds all the XML document information. That is, the XML document should be mapped to an object model.</span></p>
<p class="MsoNormal"><span style="font-weight: normal">Figure 4 shows how to map the Current Observation XML document to a set of related classes (object model). The &lt;current_observation&gt; element is mapped to the CurrentObservation class; the &lt;display_location&gt; element is mapped to the DisplayLocation class. The &lt;observation_location&gt; element is mapped to the ObservationLocation class. Single elements (without sub elements or others attributes) are mapped to the parent element class properties.  Each class can be instantiated using a method or Factory implementation by providing a part of XML tree, with root – class element. In this the exampleinit method was used -</span><!--[if gte mso 9]&gt; 08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200350037003300360039003900370034000000 &lt;![endif]--><em><span style="font-weight: normal">(id)initWithData:(NSData *)data</span></em><span style="font-weight: normal">;.</span></p>
<p class="MsoNormal"><span style="font-weight: normal">Here is a partial code listing from CurrentObservation.h:</span></p>
<pre class="brush: plain;">
  @interface WUCurrWeather : NSObject {
   NSString *credit;
   ...
   Image *image;
   DisplayLocation *displayLocation;
   ...
   NSString *icon;
  ...
  }

  @property(nonatomic, retain) NSString *credit;
  @property(nonatomic, retain) Image *image;
  @property(nonatomic, retain) DisplayLocation *displayLocation;
  ...
  @property(nonatomic, retain) NSString *icon;
  ...

  - (id)initWithData:(NSData *)data;

  -(NSString *)description;
  @end;
</pre>
<div>and Image.h <span style="font-size: 13.2px">files</span></div>
<div>
<p><span style="font-size: 13.2px"> </span></p>
<div>
<pre class="brush: plain;">@interface Image : NSObject {
NSString *url;
NSString *title;
NSString *link;
}
@property(nonatomic, retain) NSString *url;
@property(nonatomic, retain) NSString *title;
@property(nonatomic, retain) NSString *link;
- (id)initWidthData:(XMLTreeNode *)root;
- (NSString *) description;
@end
</pre>
</div>
<div>Now you can use your object model to manage data as you wish – save it in a database or show it in a GUI for example.</div>
<h2><strong>Example</strong></h2>
<div>
<p class="MsoNormal">Below is an example of a View Based iPhone Application that calls a Wunderground Data Feed Web Service to get current weather conditions. The update button repeats the call and refreshes the screen when new data arrives. The screenshots below visualize the application&#8217;s behavior:</p>
<table width="100%">
<tbody>
<tr>
<td><a href="http://mentormate.com/blog/wp-content/uploads/2010/03/xml2obj.png"><img class="aligncenter size-full wp-image-617" src="http://mentormate.com/blog/wp-content/uploads/2010/03/xml2obj.png" alt="" width="79" height="87" /></a></td>
<td><a href="http://mentormate.com/blog/wp-content/uploads/2010/03/screenshot1.png"><img class="aligncenter size-full wp-image-615" src="http://mentormate.com/blog/wp-content/uploads/2010/03/screenshot1.png" alt="" width="161" height="241" /></a></td>
<td><a href="http://mentormate.com/blog/wp-content/uploads/2010/03/screenshot2.png"><img class="aligncenter size-full wp-image-616" src="http://mentormate.com/blog/wp-content/uploads/2010/03/screenshot2.png" alt="" width="164" height="247" /></a></td>
</tr>
</tbody>
</table>
<p class="MsoNormal">In the provided <a href="http://mentormate.com/blog/wp-content/uploads/2010/03/xml2obj.zip">source code</a> you can find all these steps implemented.</p>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://mentormate.com/blog/mapping-xml-document-object-model-dom-iphone-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPhone Application Development XML Parser/Parsing Libraries</title>
		<link>http://mentormate.com/blog/iphone-application-development-xml-parser-parsing-libraries/</link>
		<comments>http://mentormate.com/blog/iphone-application-development-xml-parser-parsing-libraries/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 14:46:02 +0000</pubDate>
		<dc:creator>Iordan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[libraries]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[sax]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://mentormate.com/blog/?p=552</guid>
		<description><![CDATA[XML (Extensible Markup Language) is a set of rules for encoding documents electronically. It is defined in the XML 1.0 Specification produced by the W3C. XML’s design goals emphasize simplicity, generality, and usability over the Internet. Although XML’s design focuses on documents, it is widely used for the representation of arbitrary data structures, for example in web services. A variety of APIs for accessing XML have been developed and used, and some have been standardized.]]></description>
			<content:encoded><![CDATA[<p>Existing APIs for XML processing fall into two categories:</p>
<ul>
<li><a title="http://en.wikipedia.org/wiki/Simple_API_for_XML" href="http://en.wikipedia.org/wiki/Simple_API_for_XML">SAX (Simple      API for XML)</a> is a serial access parser API for XML. It      provides a mechanism for reading data from an XML document. The quantity      of memory that a SAX parser must use in order to function is typically      much smaller than that of a DOM parser. Unlike DOM, there is no formal      specification for SAX.</li>
<li>The <a title="http://en.wikipedia.org/wiki/Document_Object_Model" href="http://en.wikipedia.org/wiki/Document_Object_Model">Document      Object Model (DOM)</a> is a cross-platform and      language-independent convention for representing and interacting with      objects in HTML, XHTML and XML documents. It represents a tree structure      based API. The Dom parser implements the DOM API and it creates a DOM tree      in memory for a XML document. Because DOM supports navigation in any      direction (e.g., parent and previous sibling) and allows for arbitrary      modifications, an implementation must at least buffer the document that has      been read so far (or some parsed form of it).</li>
</ul>
<p>Cocoa offers a &#8220;complete&#8221; XML parser with the NSXML family of classes.</p>
<ul>
<li><strong>NSXMLParser</strong> is a SAX parser, meaning that it traverses      the XML tree and informs a delegate of events as they happen. This is an      event-driven parser, which calls methods on a delegate to handle      &#8220;events&#8221; as it parses through the XML.</li>
<li><strong>NSXMLDocument</strong> provides tree parser functionality. An      instance of NSXMLDocument represents an XML document as internalized into      a logical tree structure. This tree-based parser is fairly sophisticated      but it is not included in Cocoa-Touch.</li>
</ul>
<p>In the spirit of small and simple, iPhone developers have the NSXMLParser class to use. Because NSXMLParser only generates messages for a delegate, and doesn’t store data about the XML tree, it requires less memory and is better for accessing small pieces of data or parsing large XML documents. The basic operation of the NSXMLParser class will not be covered here. This is well documented in the <a title="http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/XMLParsing/XMLParsing.html" href="http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/XMLParsing/XMLParsing.html">Apple Programming Guide</a>.</p>
<p>For devices like iPhone where memory usage is critical, using tree parser is not recommended. I guess that is why Apple doesn’t provide NSXMLDocument on iPhone/iPod touch. However, the model of event parsing may not be acceptable by your code. NSXMLParser is probably adequate, but it is not going to handle all your XML parsing needs. The biggest problem with this type of streaming parser is that you lose the structure of your data; your call-backs do not provide any context or hierarchy. Because of the above mentioned or by some other reason like often changing XML format [1] you may need to use something like DOM model implementation.</p>
<h2>Available Libraries (DOM model implementations) for iPhone</h2>
<ul>
<li>XPath/XQuery &#8211; used to      navigate through elements and attributes in an XML document.</li>
<li><a title="http://xmlsoft.org/" href="http://xmlsoft.org/">Libxml2</a> &#8211;      XML C parser and toolkit developed for the Gnome project. At Cocoa with      Love, very nice explanation and code sample to write wrapper for the      libxml2 was posted. It has a title, <a title="http://go2.wordpress.com/?id=725X1342&amp;site=jongampark.wordpress.com&amp;url=http%3A%2F%2Fcocoawithlove.com%2F2008%2F10%2Fusing-libxml2-for-parsing-and-xpath.html" href="http://go2.wordpress.com/?id=725X1342&amp;site=jongampark.wordpress.com&amp;url=http%3A%2F%2Fcocoawithlove.com%2F2008%2F10%2Fusing-libxml2-for-parsing-and-xpath.html">“Using      libxml2 for XML parsing and XPath queries in Cocoa”</a>[2]</li>
<li><a title="http://code.google.com/p/kissxml/" href="http://code.google.com/p/kissxml/">KissXML</a>,<a title="http://go2.wordpress.com/?id=725X1342&amp;site=jongampark.wordpress.com&amp;url=http%3A%2F%2Fcode.google.com%2Fp%2Ftouchcode%2Fwiki%2FTouchXML" href="http://go2.wordpress.com/?id=725X1342&amp;site=jongampark.wordpress.com&amp;url=http%3A%2F%2Fcode.google.com%2Fp%2Ftouchcode%2Fwiki%2FTouchXML">TouchXML</a> &#8211;      two tree XML parsers for iPhone.</li>
<li><a title="http://github.com/arashpayan/apxml/" href="http://github.com/arashpayan/apxml/">APXML</a> &#8211; not a perfect      implementation of the W3C XML 1.0 standard, but it’s close enough for a      lot of usage.</li>
<li>XMLTreeParser/XMLTreeNode      -  <a title="http://osmorphis.blogspot.com/2009/03/enhancing-standard-nsxmlparser-class.html" href="http://osmorphis.blogspot.com/2009/03/enhancing-standard-nsxmlparser-class.html">Enhancing      the standard NSXMLParser class</a></li>
</ul>
<h2>Which parser (DOM or SAX) should you use?</h2>
<p>Well, if you’re going to need to parse very large XML documents, then you should probably consider NSXMLParser. What “very large” means depends a lot on the available memory you have to work with? The model of iPhone and the memory already in use by your app may prevent you from being able to use DOM model.</p>
<p>While DOM model usage may seem easier, NSXMLParser really excels in situations where you’re loading in many instances of the same kind of data, such as an address book or twitter feed. However, if memory is not an issue, I would recommend DOM model. It makes it easy to access the data you want and also allows you to manipulate the tree.</p>
<h2>References</h2>
<ol>
<li>Arash Payan(Salman),<a title="http://arashpayan.com/blog/index.php/2009/01/14/apxml-nsxmldocument-substitute-for-iphoneipod-touch/" href="http://arashpayan.com/blog/index.php/2009/01/14/apxml-nsxmldocument-substitute-for-iphoneipod-touch/">APXML: NSXMLDocument ’substitute’ for iPhone/iPod Touch – Arash Payan</a>,Sep 27th, 2009</li>
<li>jongampark, <a title="http://jongampark.wordpress.com/2009/08/23/tree-xml-parser-for-iphone/" href="http://jongampark.wordpress.com/2009/08/23/tree-xml-parser-for-iphone/">Tree XML parser for iPhone</a>, 2009</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://mentormate.com/blog/iphone-application-development-xml-parser-parsing-libraries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Facebook Application Development Tips for the Facebook API</title>
		<link>http://mentormate.com/blog/facebook-application-development-tips-facebook-api/</link>
		<comments>http://mentormate.com/blog/facebook-application-development-tips-facebook-api/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 20:42:40 +0000</pubDate>
		<dc:creator>Iva</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://mentormate.com/blog/?p=505</guid>
		<description><![CDATA[Thinking of developing a Facebook FBML Application? It is certainly a very exciting and inspiring task. Let me make it as fun for you as possible by pointing out a few obstacles you may come across and ways to bypass them. I personally stumbled upon each of the problems listed below in my first steps in Facebook development. Hopefully, this will help those of you who are taking your first steps into Facebook development avoid some headaches along the way. Let’s get started!]]></description>
			<content:encoded><![CDATA[<p><strong>Facebook Application Response Timeout</strong></p>
<p>Have you ever gotten the message <em>The URL [your application url here] did not respond.</em> even when everything seems to be working on your side?<br />
One probable reason is that Facebook has a certain response timeout – approximately 12 seconds. If your page fails to respond in this time, Facebook will leave it and display an error message. I used a few simple tricks and managed to work around this issue. Try them out:</p>
<p><em>Make the Facebook application lighter:</em></p>
<ul>
<li>The basic idea is to make the page as light as possible on the first load. One way to achieve this is to leave the time consuming tasks like database interaction for later, updating the page with AJAX. <a href="http://wiki.developers.facebook.com/index.php/FBJS#AJAX">(more info)</a></li>
</ul>
<p><em>Speed up your Facebook app:</em></p>
<ul>
<li>You can  use &#8220;Preload FQL&#8221;, that is to send your FQL requests along with the first call, thus making one less roundtrip to the server. <a href="http://wiki.developers.facebook.com/index.php/Preload_FQL">(more info)</a></li>
<li>Facebook provides a Batch API. With this API, you can combine multiple API calls and send them together as one call. <a href="http://wiki.developers.facebook.com/index.php/Using_Batching_API"> (more info)</a></li>
<li>You can do the same thing with multiple queries. Wrap, send, and receive them as one using Fql.multiquery. <a href="http://wiki.developers.facebook.com/index.php/Fql.multiquery">(more info)</a></li>
</ul>
<p>AJAX calls have the same timeout issue (although the timeout here is approximately 13 seconds). Additionally all AJAX calls pass through the Facebook server which slows them down. The result is the following JavaScript error: <em>&#8220;error&#8221;:1349011,&#8221;errorSummary&#8221;:&#8221;Failed to fetch app Ajax&#8221;</em> .</p>
<p>I found a simple solution to avoid it: Use FBJS AJAX and a <a href="http://www.w3schools.com/js/js_timing.asp">timer</a> to abort the request when it reaches the time limit and send a new one.</p>
<p><strong>Facebook API Response Time and Error Count</strong></p>
<p>The Facebook API itself sometimes has latency issues causing your app pages to be fetched slower, increasing the risk of reaching the response timeout. Errors in request to their servers are also known to happen. You should always be informed about the <a href="http://developers.facebook.com/live_status.php">Facebook Platform Status</a>.</p>
<p><strong>Syntax Limitations in FQL</strong></p>
<p>The Facebook API allows you to make your own queries using a query language similar to SQL. There is a list of tables you can access (you can only view information; you are not allowed to update the information in any of these tables). You can easily make your own queries, but you should keep in mind that you cannot do a number of normal (for SQL) things such as join tables, use  &#8216;distinct&#8217;, &#8216;limit&#8217;, &#8216;group by&#8217;, etc., or use &#8220;from&#8221; against more than one table. You can easily do these operations in the code, however. Combined with the use of the <a href="http://wiki.developers.facebook.com/index.php/Fql.multiquery#Example_Requests">multiquery</a> functionality, things should work almost as fast as if you were using pure SQL.</p>
<p><strong>Facebook API Changes</strong></p>
<p>As you may guess, the Facebook API still is in development, so you should keep yourself up to date with the constant changes in its platform. Some of these changes are potentially breaking, some features are being deprecated or changed, and some cool new things are being added. It is useful to read the <a href="http://wiki.developers.facebook.com/index.php/Developer_Roadmap">Facebook Developer Roadmap</a> to be informed for the specific changes that have been planned and when to expect them. Here are some of the upcoming ones:</p>
<ul>
<li><em>an open source, faster, slimmer, and more efficient JavaScript Library will be developed</em> &#8211; I am personally looking forward to this. It will be of great help, as right now the FBJS is very limited.</li>
<li>p<em>rofile boxes, application info sections, and the Boxes tab will be removed</em> – If you want to integrate into the user&#8217;s profile, you will be able to do that only with Application tabs.</li>
<li>form<em>atting on canvas pages will be changed to better highlight an application&#8217;s brand</em> – For now, I myself am using fb:dashboard. It not only gives you clean app navigation, but also a great look by positioning the name and icon of your app nicely on every page.</li>
</ul>
<p>Until recently, some of the API changes, even when prepared for them, had unexpected effects on some applications (in some cases, bugs appeared) and there was nothing we could do about it.<br />
In late February, Facebook introduced a tool to help us prepare for the changes – the Migrations tool. When Facebook announces a new feature or fix, you can first do some testing before going to the Migrations tab in your application settings and choosing to enable it (it is disabled by default).</p>
<p>In conclusion, I can assure you that whatever problems you may stumble upon there is a huge community of developers willing to help you out. Just go to the <a href="http://forum.developers.facebook.com/">Facebook Developers Forum</a>. There is also lots of documentation and useful tips in the <a href="http://wiki.developers.facebook.com/">Facebook Developers Wiki</a>. Have fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://mentormate.com/blog/facebook-application-development-tips-facebook-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using iPhone UIWebView Class with local CSS &amp; JavaScript resources</title>
		<link>http://mentormate.com/blog/iphone-uiwebview-class-local-css-javascript-resources/</link>
		<comments>http://mentormate.com/blog/iphone-uiwebview-class-local-css-javascript-resources/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 17:16:50 +0000</pubDate>
		<dc:creator>Iordan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[uiwebview]]></category>

		<guid isPermaLink="false">http://mentormate.com/blog/?p=433</guid>
		<description><![CDATA[With the great significance of the large screen on iPhone / iPod Touch, the graphical user interfaces experience of iPhone applications are more important than on other mobile platforms. One possible approach to make your application more interactive and dynamic is to use the default iPhone Design Resource UIWebView with local style definition (CSS) and JavaScript.]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste">This post will cover the basic setup and creation of an application with web content for iPhone that will load local CSS and some useful JavaScript functions. Most of these hints I found partially in different blogs and forums listed in the reference section. The idea is to collect all them together. You can use the following technique to create a more attractive application design.</div>
<div id="_mcePaste">Creating an application using UIWebView control is not the focus of this post. Here is a helpful beginner’s tutorial for creating an application using UIWebView. We assume that you are already familiar with this topic.</div>
<h3>UIWebView load</h3>
<p>Our work will start with a little change in calling load method of the UIWebView instance. Instead of <em>loadRequest</em></p>
<pre class="brush: plain;">[[webView graphWebView] loadRequest:requestObj];</pre>
<p>we use the <em>loadHTMLString</em> method, providing an NSString object that contains HTML code of our page as a parameter:</p>
<pre class="brush: plain;">[[webView graphWebView] loadHTMLString:htmlPageStr baseURL:baseURL];</pre>
<p>To get this page to load resources and styles correctly, you have to set up the right URL:</p>
<h3>Set baseURL property of UIWebView to refer your bundle&#8217;s resources directory</h3>
<div id="attachment_437" class="wp-caption alignright" style="width: 143px"><a style="float: right;" href="http://mentormate.com/blog/wp-content/uploads/2010/03/screen1.png" target="_blank"><img class="size-medium wp-image-437    " src="http://mentormate.com/blog/wp-content/uploads/2010/03/screen1-208x300.png" alt="MentorMate" width="133" height="192" /></a><p class="wp-caption-text">Initial loading screen with progress indicator</p></div>
<p>On the following reference<sup>[2]</sup> you can find a short and clear revision of the problem of displaying local images in a UIWebView. To use relative paths or files in UIWebView, you have to load the HTML into the view with the correct baseURL parameter. The following example shows how to do this:</p>
<pre class="brush: plain;">NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];</pre>
<p>And then call load method of UIWebView provide above NSURL parameter:</p>
<pre class="brush: plain;">[[webView graphWebView] loadHTMLString:pageStr baseURL:baseURL];</pre>
<p>A short explanation: An <em>NSBundle</em> object represents a location in the file system that groups code and resources that can be used in a program. <em>mainBundle </em>method returns the <em>NSBundle</em>object that corresponds to the directory where the current <em>application executable</em> is located. <em>bundlePath </em>instance method of <em>NSBundle</em> returns the full pathname of the receiver’s bundle directory. <em>NSURL</em> class is used to create an object which will hold the URL information. It provides a way to manipulate URLs and the resources they reference. <em>loadHTMLString</em> method of UIWebView has parameter <em>baseURL</em> that accept an NSURL object instead of a pathname as the file reference. Giving the above baseURL to UIWebView, you can refer to your bundle&#8217;s resources directory like this:</p>
<pre class="brush: plain;">&lt;img src=&quot;myimage.png&quot;&gt;</pre>
<p>Or from within CSS like this:</p>
<pre class="brush: plain;">background-image: url(loading.gif)</pre>
<p>It’s important to note that resources (images, CSS and JavaScript Files) inside your application bundle are at the root of the bundle, even if you place them in an separate group (folder) in your project.</p>
<p>Giving the correct URL to UIWebView will allow you to refer to local resources in your page, but it does not work in all cases. If you want to use JavaScipt, some additional settings have to be done.</p>
<h3>Link a CSS and JavaScript files</h3>
<div id="attachment_438" class="wp-caption alignright" style="width: 140px"><a href="http://mentormate.com/blog/wp-content/uploads/2010/03/screen2.png" target="_blank"><img class="size-medium wp-image-438  " src="http://mentormate.com/blog/wp-content/uploads/2010/03/screen2-204x300.png" alt="MentorMate" width="130" height="192" /></a><p class="wp-caption-text">Second loading screen with progress indicator</p></div>
<p>Now you can use generic HTML technique to add CSS and JavaScript to the web page and displaying in a UIWebView.</p>
<pre class="brush: plain;">&lt;link href=&quot;default.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;
 &lt;script type=&quot;text/javascript&quot; src=&quot;showhide.js&quot;&gt;&lt;/script&gt;</pre>
<p>Do not forget to add your CSS and Javascript files to the xCode project (if you are using external files).</p>
<p>Some additional actions have to be taken before starting your application and using JavaScript functions.<sup>[3]</sup></p>
<p>XCode setup (*.js) javascript as some type of source code needs to be compiled in the application. We would like to include it as a resource so I&#8217;ve solved it by doing two things:</p>
<ol>
<li>Select .js file and in the &#8220;Detail&#8221; view unselect the bullseye column indicating it is compiled code</li>
<li>In the &#8220;Groups &amp; files&#8221; view expand the &#8220;Targets&#8221; tree and expand the application then go to &#8220;Copy Bundle Resources&#8221; and drag the *.js files into it.</li>
</ol>
<p>The Apple dev forums has a posted solution. <sup>[4]</sup> You need to do two things &#8211; select the .js file in your project, and turn off the checkbox that indicates that it is compiled (the &#8220;bullseye&#8221; column). If you don&#8217;t do this, you&#8217;ll get a warning in your build log about being unable to compile the file (which should be your first warning &#8211; always try to figure out and and correct any and all warnings that appear in your build).</p>
<h3>Set transparent background color for UIWebView</h3>
<div id="attachment_436" class="wp-caption alignright" style="width: 139px"><a href="http://mentormate.com/blog/wp-content/uploads/2010/03/screen3.png" target="_blank"><img class="size-medium wp-image-436  " src="http://mentormate.com/blog/wp-content/uploads/2010/03/screen3-201x300.png" alt="MentorMate" width="129" height="192" /></a><p class="wp-caption-text">Final screen with graph representation.</p></div>
<p>In our example we need to figure out a transparent background for UIWebView. On the parent View Container we have additional controls (buttons, labels) and already defined background. The following code will set this:</p>
<pre class="brush: plain;">[[webView graphWebView] setBackgroundColor:[UIColor clearColor]];&lt;/code&gt;

[[webView graphWebView] setOpaque:NO];
</pre>
<h3>Example</h3>
<p>MentorMateDemoJS is a simple application example which uses the settings described above. It is a view-based application that shows a graphical representation of some data. Application behavior consists of a predefined call with formatted data to Vvidget Service<sup>[5]</sup> for graph generation. The service returns an image that is loaded in UIWebView Design Resource. The update button is added to resend the graph request and update view.</p>
<p><span style="text-decoration: underline;">The Problem</span>: Graph image requires some time for loading.</p>
<p><span style="text-decoration: underline;">Our Decision</span>: Notify user of graph loading process by showing a progress bar during load time.</p>
<p>To achieve this, we use UIWebView with local resource of two JavaScript functions. One to show/hide notification messages and the other to visualize a progress bar during loading time. In the provided sources you can find all these steps implemented.</p>
<p><a href="http://mentormate.com/blog/wp-content/uploads/2010/03/MentorMateDemoJS.zip">Sources of the example iPhone application</a></p>
<h3>References</h3>
<ol>
<li>iPhone SDK Articles, <a title="http://www.iphonesdkarticles.com/2008/08/uiwebview-tutorial.html" rel="nofollow" href="http://www.iphonesdkarticles.com/2008/08/uiwebview-tutorial.html" target="_blank">UIWebView Tutorial</a>, August 19, 2008</li>
<li>iPhone Development Blog, <a title="http://iphoneincubator.com/blog/windows-views/uiwebview-revisited" rel="nofollow" href="http://iphoneincubator.com/blog/windows-views/uiwebview-revisited" target="_blank">UIWebView – Loading External Images and CSS</a>, February, 2009</li>
<li>StackOverflow, <a title="http://stackoverflow.com/questions/843820/iphone-uiwebview-local-resources-using-javascript-and-handling-onorientationchang" rel="nofollow" href="http://stackoverflow.com/questions/843820/iphone-uiwebview-local-resources-using-javascript-and-handling-onorientationchang" target="_blank">iPhone UIWebView local resources using Javascript and handling onorientationChange</a></li>
<li>Developer Forum, <a title="https://devforums.apple.com/message/32282#32282" rel="nofollow" href="https://devforums.apple.com/message/32282#32282" target="_blank">UIWebView and JavaScript</a>, 2009</li>
<li>Vvidget, <a title="http://www.vvidget.org/service/manual/index.html" rel="nofollow" href="http://www.vvidget.org/service/manual/index.html" target="_blank">Vvidget Server™ Reference Manual </a>, 2010</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://mentormate.com/blog/iphone-uiwebview-class-local-css-javascript-resources/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>MentorMate&#8217;s Backup Script</title>
		<link>http://mentormate.com/blog/mentormates-backup-process/</link>
		<comments>http://mentormate.com/blog/mentormates-backup-process/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 21:37:04 +0000</pubDate>
		<dc:creator>Doug</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[scripts]]></category>
		<category><![CDATA[version control]]></category>

		<guid isPermaLink="false">http://mentormate.com/blog/?p=256</guid>
		<description><![CDATA[Backups are important and automated backups help reduce error by removing the human component.  Of course it is always good to check in and make sure that everything is working properly, and audit your systems periodically to see if you need to add anything new to your backup.  MentorMate uses a script with a few simple tools to get all important information in one place and make redundant onsite and offsite backups of it.]]></description>
			<content:encoded><![CDATA[<h2>Overview</h2>
<p>The script starts by creating a copy of all of the important information in a staging area.  Keeping the staging area intact will help speed up the backup after it has been run once since rsync is used for most of the copying.  After the staging area is updated, we use rdiff-backup as our incremental backup system.  The rdiff-backup repository can then be copied to other local and offsite locations to increase reduncancy in the backup.  The output is sent by email every time the backup runs, so we are automatically updated on its status, and can correct any errors that may have taken place.</p>
<h2>Relevant Tools</h2>
<p>Following is a description of the tools that are used to back up our data, as well as some of the tools that are holding out data.  Different sets of data must be backed up in different was in order to maximize efficiency and reliability.</p>
<h3>Hardware</h3>
<p>We use a mixture of standard desktop hardware, server hardware, and virtual dedicated servers for our infrastructure.  Services requiring reliability are all run on the virtual dedicated servers providing uptime guarantees.  All of our backups are gathered and stored on two local computers, each with a raid 1 array, and copied to an offsite computer.</p>
<h3>Bash</h3>
<p><a href="http://www.gnu.org/software/bash/manual/bashref.html">http://www.gnu.org/software/bash/manual/bashref.html</a></p>
<p>Bash is an interactive shell and a scripting language that is installed by default on Linux, and can be configured on many other operating system.  We use it for the backup system because it is easy to call other programs that are already designed to do a lot of the work that we need to do for the backup.  This gets us a full backup in less than 100 lines of code.  The small amount of code makes it easy to proof read and test for errors.</p>
<h3>Rsync</h3>
<p><a href="http://samba.anu.edu.au/rsync/">http://samba.anu.edu.au/rsync/</a></p>
<p>Rsync is a very common program for copying data from one location to another when bandwidth can be limited, or when large amounts of data must be copied.  It first checks if the file exists in the destination, and, if it does exist, makes sure that it is that same file.  If the file already exists, and is up to date, the file is not copied.  For our backup, this saves a lot of time since there is generally only a small amount of files that change.</p>
<h3>Rdiff-Backup</h3>
<p><a href="http://rdiff-backup.nongnu.org/">http://rdiff-backup.nongnu.org/</a></p>
<p>After the staging area has been updated, we use rdiff-backup to keep track of 10 days of history.  rdiff-backup copies files from the source to an rdiff-backup repository.  Instead of deleting files that have been removed and overwriting files that have changed, it stores a backup of any changes.  It is possible to go into the repository later and restore any version that has not been removed.</p>
<h3>OpenVZ</h3>
<p><a href="http://wiki.openvz.org/">http://wiki.openvz.org/</a></p>
<p>OpenVZ allows us to quickly and easily set up new virtualized environments, known as containers.  OpenVZ containers are not fully virtualized, so they do not require as many resources as traditional virtual machines.  Our OpenVZ containers are used to quickly and easily set up testing environments, and to provide some of our services within our office that do not have the uptime requirements of the services running on the offsite virtual dedicated servers.</p>
<h3>Logical Volume Management</h3>
<p><a href="http://tldp.org/HOWTO/LVM-HOWTO/">http://tldp.org/HOWTO/LVM-HOWTO/</a></p>
<p>Logical Volume Management (LVM) is an abstraction layer between the hard drive and the partitions and filesystems on that hard drive.  One or more hard drives or partitions, known as physical volumes in LVM language, can be combined into a volume group.  The volume group can then be divided into multiple logical volumes, which behave like partitions and can be formatted like a normal partition would be.  There are many features in LVM that provide an advantage over normal partition management including resizing partitions and volume groups while the filesystems are mounted, moving the logical volumes from one physical drive to another, also while the filesystems are mounted, and many other management tasks.  Our backup script takes advantage of the ability to create a snapshot of a filesystem.  A snapshot creates another logical volume that is an image of the first logical volume frozen in time.  Any changes that are made to the files on the original logical volume will be stored in the extra space at the end of the volume group that is dedicated to the snapshot when the snapshot is created.  Business can continue as normal as we create a backup from a consistent set of files where we no longer need to worry about someone writing to the files while we are backing them up.</p>
<h3>MySQL</h3>
<p><a href="http://www.mysql.com/">http://www.mysql.com/</a></p>
<p>MySQL is a database that comes with it&#8217;s own set of backup tools to ensure that you get a consistent copy of the database.  Mysqldump locks the database when necessary to make sure that it does not make a copy of the database when some other program is in the middle of making a change to the database.</p>
<h3>Subversion</h3>
<p><a href="http://subversion.apache.org/">http://subversion.apache.org/</a></p>
<p>Subversion is a version control system.  We use it for all of our development projects to ensure that each team of developers is working with the most recent version of the code.  Because all of our projects use subversion, we have built up a large collection of code that would take a long time to fully back up each day.  We use subversion tools along with some bash scripting to compare the most recent version of the code in version control with the version that we last backed up, and only back up the changes.</p>
<h3>Grep, Sed, and Others</h3>
<p><a href="http://linuxmanpages.com/">http://linuxmanpages.com/</a></p>
<p>There are many other tools used throughout the script.  The two biggest examples are grep, a regular expression program, and sed, a stream editor which takes some input and changes it as specified.  If you want to know more about any of these tools, you can look them up in the Linux manual pages, or you can find more information on them using your favorite search engine.</p>
<h2>Variables</h2>
<p>﻿Following are the variables that are used in this script.  Some of the values have been changed for security reasons.</p>
<pre class="brush: plain;"># space seperated list of servers that have openvz and lvm set up
CONTAINER_SERVERS=&quot;fox walrus&quot;
# server to put a second copy of the backup on, located in MN
SECONDARY_BACKUP=&quot;walrus&quot;
# offsite server
OFFSITE_BACKUP=&quot;offsite.server.com&quot;
# Location on the openvz servers where the lvm snapshot of the openvz partition is mounted
SRC=&quot;/vzsnap/&quot;
# Location on the main backup server to collect all files
STAGING=&quot;/backup/staging/&quot;
# Location of the rdiff-backup repository
RECENT=&quot;/backup/recent_backup/&quot;
# Location on the second server for a copy of the rdiff-backup repository
SECOND_RECENT=&quot;/backup/recent_backup/&quot;
# Location on the offsite server for a copy of the rdiff-backup repository
OFFSITE_RECENT=&quot;/home/backup/recent_backup/&quot;
# Command locations
LVCREATE=/sbin/lvcreate
LVREMOVE=/sbin/lvremove
VZLIST=/usr/sbin/vzlist
VZCTL=/usr/sbin/vzctl</pre>
<h2>OpenVZ Containers</h2>
<pre class="brush: plain;"># containers
echo &quot;Staging Containers&quot;
for host in $CONTAINER_SERVERS
do
   containerlist=`ssh $host $VZLIST -aH -o veid`
   for container in $containerlist
   do
      echo &quot;Backing up $container from $host&quot;
      ssh $host $LVCREATE -L2G -s -n vzsnap /dev/filestore/vz &gt; /dev/null

      # check if the container is running
      run=&quot;`ssh $host vzlist | grep --only-matching $container`&quot;
      if [ &quot;$run&quot; == &quot;$container&quot; ]
      then
         # check if mysql server is running inside the container
         if [ -f /vz/private/$container/etc/init.d/mysql ]
         then
            ssh $host &quot;vzctl exec $container 'if [ -f /var/run/mysqld/mysqld.pid ]; then echo mysql is running; echo /var/run/mysqld/mysqld.pid &gt; /mysqld.pid; fi'&quot;
            if [ -f /vz/private/$container/mysqld.pid ]
            then
               pass=&quot;`ssh $host cat /vz/private/$container/etc/mysql/debian.cnf | grep --max-count=1 password | sed 's/^password = //'`&quot;
               user=&quot;debian-sys-maint&quot;
               ssh $host vzctl exec $container mysqldump --user=$user -p$pass --all-databases &gt; /backup/staging/$container.dump
               ssh $host vzctl exec $container rm /mysqld.pid
            fi
         fi
      fi

      ssh $host mkdir -p $SRC
      ssh $host mount /dev/filestore/vzsnap $SRC
      rsync -a --delete root@$host:$SRC/private/$container $STAGING/
      rsync -a root@$host:$SRC/etc/vz/conf/$container.conf $STAGING/
      ssh $host umount $SRC
      ssh $host $LVREMOVE /dev/filestore/vzsnap --force &gt; /dev/null
      ssh $host rmdir $SRC
   done
done</pre>
<p>For each server that is running OpenVZ containers, we want to make a full backup of each of the containers.</p>
<ol>
<li>We use LVM to create a snapshot of the filesystem.  This gives us a version of the files that we can copy that is consistent with itself at a given point in time.</li>
<li>In the case that MySQL is running in the container, we want to make sure that we do not get a corrupt copy of the database just in case it was in the middle of a commit when the LVM snapshot was taken.  For this, we will use the standard MySQL backup tool mysqldump.  This will also allow us to easily examine an old version of the database without fully restoring the entire container.</li>
<li>Finally, we copy the configuration for the container, and all of the files within the container.</li>
</ol>
<p>This will give us enough to restore any of our containers to the point at which the backup was taken.</p>
<h2>Version Control (SVN)</h2>
<pre class="brush: plain;">echo &quot;Staging Source Control&quot;
REPOS=`ssh scm.mentormate.com ls /files/repo/svn/`
echo $REPOS
for repo in $REPOS
do
   echo &quot;processing svn repo $repo&quot;
   head=`svn info svn+ssh://scm.mentormate.com/files/repo/svn/$repo/ | grep &quot;^Revision: .*&quot; | sed 's/^Revision: //'`
   curfile=$STAGING/svn.$repo.lastversion
   # check if there is currently a backup of the repo
   if [ -f $curfile ]
   then
      # if yes, read the last saved file
      current=`cat $curfile`
   else
      # if no, start from the beginning
      current=0
   fi
   if [ $current -lt $head ]
   then
      if [ $current -ne 0 ]
      then
         current=$(( $current + 1 ))
      fi
      padcurrent=`printf &quot;%05d&quot; $current`
      padhead=`printf &quot;%05d&quot; $head`
      # take incremental backup
      ssh scm.mentormate.com svnadmin dump -r$current:$head --incremental /files/repo/svn/$repo | gzip --best &gt; $STAGING/svn.$repo.$padcurrent-$padhead.dump.gz
      echo &quot;$head&quot; &gt; $curfile
   else
      echo &quot;$repo does not have any changes&quot;
   fi
done</pre>
<p>We use subversion for version control.   It&#8217;s very easy to dump a full backup of a subversion repository, but when the repositories get large, this can start to take a lot of time and bandwidth.  It is better to only back up the new revisions.</p>
<ol>
<li>Get a list of all subversion repositories</li>
<li>The head is the version that was most recently committed to the repository.  This can be obtained by checking the svn info.</li>
<li>The head that we backed up the last time that we made a backup was saved to a file.  This will give us a range for the last backup that we made to the current head.</li>
<li>An incremental backup is taken of only the new revisions, and the current head is written to a file.  The filename will tell us which revisions were backed up.</li>
</ol>
<p>When restoring this, the files can be combined and loaded into a new repository, or they can be loaded into a new repository one after the other.  If you decide that there are too many files for one repository, you can simply delete all of the files for that repository, including the last revision file, from the staging area, and a full backup will be taken the next time the backup script runs.</p>
<h2>Backup Router Configuration</h2>
<pre class="brush: plain;">wget -q https://192.168.1.1/diag_backup.php --post-data 'Submit=Download' --no-check-certificate --http-user=admin --http-password=&quot;**********&quot; --output-document=$STAGING/pfsense.xml</pre>
<p>We use pfSense for our router software.  This allows us great flexibility at a very low cost.  pfSense has a web page with a button for downloading the configuration file.  Wget can be set to send the appropriate information to request the configuration file.  In the event that the router hardware fails, we can quickly install pfSense on new hardware, and load the configuration.</p>
<h2>Crontab from the Backup Server</h2>
<pre class="brush: plain;">crontab -l &gt; $STAGING/crontab.`hostname`</pre>
<p>If our main backup server goes down, we want to make sure that we know everything that it was doing.  All of our important backups jobs run as a single user, so we only need to get one crontab here.</p>
<h2>Staging to Incremental Backup</h2>
<pre class="brush: plain;">rdiff-backup $STAGING/ $RECENT/
rdiff-backup --remove-older-than 10B $RECENT/</pre>
<p>Now that we have everything in the staging area, we want to copy it to a more long term location.  We will do this using rdiff-backup, which will store multiple revisions of our files without making a full copy of each one.  We then need to remove old revisions of the files so that the repository does not get too large.  In this case, we keep 10 versions of the files.</p>
<h2>Offsite Backup</h2>
<pre class="brush: plain;">rsync -azq --delete $RECENT/ $SECONDARY_BACKUP:$SECOND_RECENT/
rsync -azq --delete --bwlimit=10 $RECENT/ user@$OFFSITE_BACKUP:$OFFSITE_RECENT/</pre>
<p>The final step is to make sure that we have multiple copies of our big backup.  The rdiff-backup repository is copied to a second onsite server, for easy restore in the event of hardware failure on the backup machine, and an offsite server.</p>
<h2>Conclusion</h2>
<p>By gathering all of our information into one place, then taking an incremental backup and sending that to remote servers, we have easily created a backup script that stores incremental versions of all of our important data in one place.</p>
]]></content:encoded>
			<wfw:commentRss>http://mentormate.com/blog/mentormates-backup-process/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
