Using .NET web services and dataset objects in your iphone app
iPhone XML SOAP or .NET Web Services
can seem overwhelming at first but its actually not too hard to do, you can even download a .NET dataset and query it on the iPhone!
Being a complete n00b to iphone’s cocoa touch api / objective C and then jumping in feet first to iphone programming is like being swallowed by an enormous whale. Its very dark, you can see the blow hole, but you know the only way of reaching it is to be blown out by a mucous-infused geisure of hot and sticky whale snot. (if you have ever tried to obtain help on irc or various forums you know what I am talking about) not to mention the endless sea of apple docs that may or may not contain any information that you actually need depending on your luck.
That being said after much hair pulling reading docs forums and some examples from everywhere I have put together a simple solution to connect to a .NET web service over https and return a dataset object back to the iphone that can be queried and used accordingly.
Download This: iPhone .NET Dataset Framework.zip
In the attached file you will find 6 documents:
DataSet.h
DataSet.m
XMLDataSetParser.h
XMLDataSetParser.m
WebServiceHelper.h
WebServiceHelper.m
These files are pretty much self explanatory. DataSet.h/.m contain code for creating your DataSet Object and contain methods for querying the dataset.
WebServiceHelper contains the code to connect to the appropriate web service with the appropriate methods and parameters
XMLDataSetParser will take the data received from the webservice and pipe it into your DataSet Object.
To use an XML .NET Web service all you need to do is include these files in your project and then call the following procedures.
//First import the relevant files to your viewcontroller class (XMLDataSetParser is
//included by the DataSet class so there is no need to import it here)
#import "WebServiceHelper.h"
#import "DataSet.h"
// Create a connection to the web service
WebServiceHelper *DataCon = [[WebServiceHelper alloc] init];
//set up service method and urls please visit the webservice address in a browser to
//get the exact strings the service expects
DataCon.XMLNameSpace = @"https://myurl.com/WebService";
DataCon.XMLURLAddress = @"https://myurl.com/WebService/service.asmx";
DataCon.MethodName = @"getDataSetFromServer";
//add parameters **PARAMETERS ARE CASE SENSITIVE MAKE SURE THEY ARE TYPED CORRECTLY
//AS THE SERVICE EXPECTS THEM**
DataCon.MethodParameters = [[NSMutableDictionary alloc] init];
[DataCon.MethodParameters setObject:@"Parameter1" forKey:@"P1"];
[DataCon.MethodParameters setObject:@"Parameter2" forKey:@"P2"];
//Connect to the service and retrieve the xml raw data into a NSMutableDataObject
//be sure to include a NSMutableData object called "data" or whatever you wish in
//your viewcontroller
self.data = [DataCon initiateConnection];
//Create a dataset object using the new raw data we received from the service
DataSet *dsMyDataSet = [[DataSet alloc] initWithXMLData:self.data];
//Now we have a dataset filled with data from the initWithXMLData command lets
//query some data from it!
//Set up a dictionary object to hold our query data from the dataset
NSMutableDictionary *mydata= [[NSMutableDictionary alloc] init];
//retrieve all rows from the selected table and column
mydata = [dsMyDataSet getRowsForTableAndColumn:@"Table1" col:@"Username" ];
//mydata should contain all rows from column "Username"
//retrieve all rows from the selected table and column where the CURRENT column
//matches a string
mydata = [dsMyDataSet
getRowsForTableAndColumnWhereEqualsString:@"Table1" col:@"username" where:@"bob"];
//mydata should contain all rows from column username containing the exact match "bob"
//retrieve all rows from the selected table and column where a DIFFERENT column
//matches a string
mydata = [dsMyDataSet
getRowsForTableAndColumnWhereColumnEqualsString:@"Table1"
col:@"username" whereColumn:@"email" whereValue:@"bob@microsoft.com"];
//mydata should contain all rows from column "username" where the column "email"
//contains the exact match "bob@microsoft.com"
//you can do what you want with the data at this point like a simple iteration
NSEnumerator *userIterator= [mydata objectEnumerator];
NSString *username;
while(username = [userIterator nextObject])
{
NSLog(@"Username: %@", username);
}
[mydata release];
Thats it!!! Hope this helps someone else save as much time as it is now saving me!
Dynamic Iframe height using javascript
Welp another challenge another day. My good pal Scott (also at Imperium.ca) gets the credit for this one. We found while using a dotnetnuke back end it was far easier and far less limited to create our custom applications separately and include them in iframes and simply inherit the permissions from the dotnetnuke namespace in .NET. So while this worked great we had a huge draw back, the iframes were static height and although there was an “auto” setting in dotnetnuke, it did not appear to be functional in any of the browsers we tested.
Enter the dynamic iframe height.
We scoured much code for working examples but were hard pressed to find any that were cross browser compatible. We found some code at dynamicdrive.com while it did work resizing the iframes it was still missing a few things. One problem is we were not writing the “<iframe>” tag manually so we could not follow part two of the instructions, also part 3 instructs to place the resize call in an <a href> tag. Again we needed the script to automatically resize any and all iframes on the page once the child page was loaded. Scott tinkered until… in firefox IE7 and safari browsers we could add iframes and when the page fully loaded it would automatically adjust the iframe height by including one javascript file in the parent page and one javascript file in the child page.
I hope this helps someone else as much as it has helped us.
There are 2 js files that we will use the first js file goes in the parent page head block and loads the script for the parent page.
<!– BEGIN CODE –>
<script type=”text/javascript”>
/***********************************************
* IFrame SSI script II- © Dynamic Drive DHTML code library (http://www.dynamicdrive.com)
* Visit DynamicDrive.com for hundreds of original DHTML scripts
* This notice must stay intact for legal use
***********************************************/
//Input the IDs of the IFRAMES you wish to dynamically resize to match its content height:
//Separate each ID with a comma. Examples: ["myframe1", "myframe2"] or ["myframe"] or [] for none:
var iframeids=[];
//Should script hide iframe from browsers that don’t support this script (non IE5+/NS6+ browsers. Recommended):
var iframehide=”yes”
var getFFVersion=navigator.userAgent.substring(navigator.userAgent.indexOf(“Firefox”)).split(“/”)[1]
var FFextraHeight=parseFloat(getFFVersion)>=0.1? 16 : 0 //extra height in px to add to iframe in FireFox 1.0+ browsers
function resizeCaller() {
var dyniframe=new Array()
for (i=0; i<iframeids.length; i++){
if (document.getElementById)
resizeIframe(iframeids[i])
//reveal iframe for lower end browsers? (see var above):
if ((document.all || document.getElementById) && iframehide==”no”){
var tempobj=document.all? document.all[iframeids[i]] : document.getElementById(iframeids[i])
tempobj.style.display=”block”
tempobj.style.overflow=”visible”
}
}
}
function resizeIframe(frameid){
var buffer = 10;
var currentfr=document.getElementById(frameid)
currentfr.style.overflow=”hidden”
currentfr.scrolling=”no”
if (currentfr && !window.opera){
currentfr.style.display=”block”
if (currentfr.contentDocument && currentfr.contentDocument.body.offsetHeight) //ns6 syntax
currentfr.height = currentfr.contentDocument.body.offsetHeight+FFextraHeight + buffer;
else if (currentfr.Document && currentfr.Document.body.scrollHeight) //ie5+ syntax
currentfr.height = currentfr.Document.body.scrollHeight + buffer;
if (currentfr.addEventListener)
currentfr.addEventListener(“load”, readjustIframe, false)
else if (currentfr.attachEvent){
currentfr.detachEvent(“onload”, readjustIframe) // Bug fix line
currentfr.attachEvent(“onload”, readjustIframe)
}
}
}
function readjustIframe(loadevt) {
var crossevt=(window.event)? event : loadevt
var iframeroot=(crossevt.currentTarget)? crossevt.currentTarget : crossevt.srcElement
if (iframeroot)
resizeIframe(iframeroot.id);
}
function loadintoIframe(iframeid, url){
if (document.getElementById)
document.getElementById(iframeid).src=url
}
function stretchAllIframes() {
var objs = document.getElementsByTagName(“iframe”);
for(var i=0; i < objs.length; i++) {
iframeids[iframeids.length] = objs[i].id;
}
resizeCaller();
}
</script>
<!– END CODE –>
The second code is for the page that will be loaded into an iframe
<!– BEGIN CODE –>
<script type=”text/javascript”>
function addOnloadEvent(fnc){
if ( typeof window.addEventListener != “undefined” )
window.addEventListener( “load”, fnc, false );
else if ( typeof window.attachEvent != “undefined” ) {
window.attachEvent( “onload”, fnc );
}
else {
if ( window.onload != null ) {
var oldOnload = window.onload;
window.onload = function ( e ) {
oldOnload( e );
window[fnc]();
};
}
else
window.onload = fnc;
}
}
addOnloadEvent(parent.stretchAllIframes);
</script>
<!– END CODE–>
Centering the scrollbar horizontally using javascript
So normally when we develop a website template we make it liquid layout to fit in most browsers however in some cases we want the minimum width to be set with an optional overflow image. Kind of hard to picture… at any rate we wanted the browser to scroll horizontally but be centered on the page in lower resolutions without having to mess with the template.
I did a lot of searching and even found some people saying it was not possible. Well I tell you it is. Here is a script that will work for you. Just copy to your own autoscroll.js file and include it, or you can copy paste this into a script block.
function setScroll()
{
var docWidth;
var docMinWidth = 1182; //min width in pixels any browser size smaller then this will cause the scrollbar to appear and center
docWidth = getDocWidth();
if( typeof( window.pageYOffset ) == ‘number’ ) {
//Netscape compliant
scrOfY = window.pageYOffset;
scrOfX = window.pageXOffset;
if (docWidth < docMinWidth ) { window.scroll((docMinWidth - docWidth) / 2, scrOfY);}
} else if( document.body && ( document.body.scrollLeft != ‘undefined’ || document.body.scrollTop != ‘undefined’ ) ) {
//DOM compliant
scrOfY = document.body.scrollTop;
scrOfX = document.body.scrollLeft;
if (docWidth < docMinWidth ) { window.scroll((docMinWidth - docWidth) / 2, scrOfY);}
} else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
//IE6 standards compliant mode
scrOfY = document.documentElement.scrollTop;
scrOfX = document.documentElement.scrollLeft;
if (docWidth < docMinWidth ) { window.scroll((docMinWidth - docWidth) / 2, scrOfY);}
}
}
function getDocWidth()
{
if (document.body.scrollWidth)
return document.body.scrollWidth;
var w = document.documentElement.offsetWidth;
if (window.scrollMaxX)
w += window.scrollMaxX;
return w;
}
function addOnloadEvent(fnc){
if ( typeof window.addEventListener != “undefined” )
window.addEventListener( “load”, fnc, false );
else if ( typeof window.attachEvent != “undefined” ) {
window.attachEvent( “onload”, fnc );
}
else {
if ( window.onload != null ) {
var oldOnload = window.onload;
window.onload = function ( e ) {
oldOnload( e );
window[fnc]();
};
}
else
window.onload = fnc;
}
}
addOnloadEvent(setScroll);
Exporting Contacts from Outlook to Windows Live Messenger
Well it seems I had a little issue crop up this week and I thought I would share it with you. I began getting messages from some friends on Windows Live Messenger stating that I had been asking them to purchase diet pills! I thought “how can I have a virus? I don’t click on anything strange” Well turns out somehow they had gotten my password for live messenger/hotmail. I still have no idea how they were able to do it, I do not browse shady sites or use the same password of anything that is “risky” my password was also 12 digits containing numbers and letters and capital letters. I really am not sure if it was brute force or what.
At any rate… I changed my password the messages stopped everything was ok again. (although i did start receiving 5 spam messages a day from other bots thereafter). I signed off msn and when i tried signing back in my new password didn’t work. now whether this is because the account was again hijacked using the forgot password or I just couldn’t remember my new password in its entirety I couldn’t and can no longer use my account.
So I signed up a brand new account and realized ugh all my contacts are of course gone. Luckily I had previously been using the hotmail outlook add in that lets you sync outlook with hotmail, all my contacts were still in outlook with all the IM addresses. “Hooray!” I said to myself.
I quickly began looking for a way to get these contacts out of outlook and into messenger again. I tried various things like dragging from outlook to messenger. Windows Live Messengers import options only allowed one file type “CTT”. Oddly enough Microsoft has not included a CTT export option for Outlook. So after sobbing for a few minutes about how long it was going to take me to get these contacts into live messenger one by one, I decided to write a small application to search outlook folders and export a CTT file. (A CTT file is simply an XML file under the hood in case you were wondering)
Anyway here is a link at Imperium Inc. to the export application should you need to export your contacts from outlook into windows live messenger! Enjoy! you will need the Microsoft .NET 2.0 Framework installed first. (I think most people have this already)
Nirf.NET 1.0.3 Released
Well I am happy to release NiRF.NET 1.0.3 Currently tested in IE7 Safari and Firefox 3, NiRF now supports css background images.
This means you can pick a custom font and give the class a background-image. This will overlay your custom font over top of the background-image.
Nirf actually reads the background image and creates a new image using that as the background. To position the text on the background image you simply use top and left padding (in px) in the css class, this will push the text where you want it to go on the background.
Now there are many uses for this feature one is simply having images with Captions on them, Another might be Dynamic tabs on a web page with custom fonts on those tabs.
To see a demo of the new custom font background-image and hover options check out http://nirfserv.getnirf.com or head over to the downloads page then download the hosted or the NiRF.NET version. Remember to use the hosted version you need a free account and you need to generate a user key.
Open Source NiRF First Release
The First NiRF
Well its been an extremely busy weekend coding, with a few 3am coding sessions and a multitude of Motivational Liquids (aka Beer) we have finally reached our first release of both the .NET and PHP NiRF server versions. If your just tuning in, NiRF is a new dynamic text replacement method to use custom fonts on web pages. You can now download them from the Downloads Page at http://getnirf.com As this is a first release we encourage the community to report any bugs found or problems encountered in the Forums. Or you may contribute your code and upload it to our code repository found in the downloads section once logged in.
Thanks for your support we hope this is the first step toward creating an easy to implement standard we can all use to enjoy custom fonts on websites.
Whats Next?
We are currently working on a way to use NiRF in Blogspot, WordPress, Myspace, Forums and other such places that do not allow you to upload code or use javascript. Stay tuned as we hope to have this ready for this coming weekend.
No Space for spaceX
So I heard on twitter some commotion about a rocket launching, I went to the live webcast to see what was happening, well it was an exciting launch (the second attempt) right up to the point the camera went dead and we were informed an anomaly had taken place on the vehicle. With no further updates I logged off the site and went back to business as usual. I found out later the stage 1 engine did not seperate… That is really too bad, it doesn’t seem to phase the spacex team though and they are going full on with the next rocket. Kudos to the whole team. Even though it was a failure it was still an amazing thing to watch. Seeing the rocket soar high into the clouds and the ground become a small spec in the rear of the camera was really something. Makes you realize how small this planet really is.