Who is Ali Özgür?

RecentComments

Comment RSS

Here is a stackoverflow question which describes the issue very well

I have some code that needs to run after the a UIWebView finishes loading a document. For that I've set the UIWebView's delegate to my controller, and implemented the webViewDidFinishLoading method.

This gets called multiple times, depending on the type of page to load. I'm not sure if it's because of ajax requests, requests for images, or maybe even iframes.

Is there a way to tell that the main request has finished, meaning the HTML is completely loaded?

Or perhaps delay my code from firing until all of those events are done firing?

Some people say that "UIWebView must die". Yes I actually agree with them. UIWebView loads slower than Safari, it is hard to use and it does not expose some core methods. For example you can not get source of the loaded HTML page or the document title with a regular method call. But it has its strenghts like the stringByEvaluatingJavaScriptFromString (MonoTouch equivalent is EvaluateJavascript) method. With this method you can perform some of the missing core functions.

The idea to solve the mentioned problem goes on like this

 

  1. Inject javascript to the loaded (or still loading) document
  2. With the enjected javascript check the document ready state
  3. If document is already loaded inject  a hidden input indicating the document is loaded
  4. If document is not loaded yet inject another javascrip which simply binds an anonymous function to window.onload so that we can inject the hidden document loaded indicator input when window.onload is called
  5. As the last step each time didFinishLoading is called/fired try to find the injected document loaded indicator input element by evaluating another javascript
  6. If document loaded indicator input element is in place we can be sure that the whole document is loaded and we can continue with the execution
Here is the injected javascript script code mentiond through steps 1-4
 
if(document.readyState == 'complete')
{
	var element = document.createElement('input'); 
	element.setAttribute('type','hidden'); 
	element.setAttribute('id','moodlez_documentloaded'); 
	document.body.appendChild(element);
}
else
{
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.setAttribute('id','moodlez_windowload');
  script.text = "window.onload = function(){var element = document.createElement('input'); element.setAttribute('type','hidden'); element.setAttribute('id','moodlez_documentloaded'); document.body.appendChild(element);}";
  document.body.appendChild(script);
}

In the above JavaScript code the if(document.readyState == 'complete') block is needed so that we can handle the case when didFinishLoading fires only one time because the HTML page does not contain any frames and other stuff causing multiple  calls to didFinishLoading.

Here is the MonoTouch (C#) code which implements the steps mentioned above

 

public void LoadCompleted ()
{
	// Your code here......
	
	// check if the hidden document loaded indicator input is present
	jsResult = this.WebView.EvaluateJavascript ("document.getElementById('moodlez_windowload').toString();");
	
	// hidden element is not present so evaluate the javascript which has the potential to add the element
	if (String.IsNullOrWhiteSpace (jsResult)) 
	{
		string eval = "if(document.readyState == 'complete'){" + Helper.LoadCompleteJs + "}else{" + "var script = document.createElement('script');" + " script.type = 'text/javascript';" + " script.setAttribute('id','moodlez_windowload');" + " script.text = \"window.onload = function(){" + Helper.LoadCompleteJs + "}\";" + " document.body.appendChild(script);" + "}";				
		this.WebView.EvaluateJavascript (eval);
	}
	
	
	// Lets check again if the hidden document loaded indicator input is present
	jsResult = this.WebView.EvaluateJavascript ("document.getElementById('moodlez_documentloaded').toString();");
	
        // document loaded indicator input is not present so this means document did not complete loading	
	if (string.IsNullOrWhiteSpace (jsResult)) 
		return;
			
	// Your code here, which you want to be executed after document loading si really completed
			
}

Note: Helper.LoadCompleteJs static variable holds the following javascript code string which in turn is loaded from a resource file on application startup

 

var element = document.createElement('input'); 
element.setAttribute('type','hidden'); 
element.setAttribute('id','moodlez_documentloaded'); 
document.body.appendChild(element);

This method can be used from Objective-C, just translate the code of LoadComplete method to Objective-C and you are ready to go.

 


Posted in: MonoTouch  Tags:
aliozgur posted on February 22, 2010 10:01

We have been busy developing our new baby JiraTouch for the last 3 months. It has been a tough journey with lots of unknowns and new things. Platform was new, development tools were new and the team was new. The only knowns were Jira and the C# language. I would like to share some of my observations in this blog post.

What is JiraTouch?

You can read JiraTouch features to learn more about JiraTouch.

You can watch video tutorials to see JiraTouch in action.

You can buy JiraTouch from AppStore.

Jira and SOAP API

No need to talk about the quality of Jira software on its own. But I'm sorry that Jira SOAP API is not as complete as the product itself. The most serious problem is the versioning dilemma of the SOAP API. SOAP API is introduced since Jira version 3.0 but over the time (Recent version is Jira 4.01) there have been lots of changes with the API. Change is normal and we do not expect all aspects shall be covered at once, since the product itself matures and changes so does the SOAP API. But I would be more happy if Jira guys developed a good API versioning strategy with good API change documentation. For example with no specific versioning information included in the wsdl you get different properties for the same Type. One perfect example is RemoteComment type, this type has changed dramatically through Jira versions. Here are examples of the WSDL for different jira versions

This snippet is from the wsdl of a Jira 3.6 installation

More...


Posted in: IPhone , MonoTouch  Tags: