Pages

Wednesday, February 1, 2012

[Code Snippet] Read application bundle identificator from plist.

Hi mates!!

A lot of work, so as usually we have not time to update the blog as we want, but today's we've get 5 free minutes to post a new code snippet.

I know, because I just tried to do it, that most of you have tried to read application bundle Id from the plist asi usual, getting the path to the plist file, obtaining its values and getting the correct key.

There's a shorter way to accomplish that, just using NSBundle infoDictionary property that returns us the values stored in our Project-Info.plist.


        NSString* appID = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];

I hope this will be useful for everyone, but now I may continue developing. Turning back to my XCode!

Regards!

Thursday, January 12, 2012

New iphone apps

We have released to app store two new apps based on geolocated photography and oriented to hunting and fishing fans.

First of both was Hunting Log, in which you can store geolocated photos of your hunted pieces and share it with your friends via Twitter and Facebook.

Fisherman's Log has the same functionallity but oriented to fishing lovers.

You can find more info about these apps and our complete portfolio for iOS, Android and Windows Phone in our website: www.fiveflamesmobile.com

Aborting performSelectorInBackgroud:withEvent

First of all, happy 2012. Our best wishes to all of our readers in this new year.

Once again we have to apologize our readers for the lack of updates, but we have a lot of work, maybe there will be some changes in our work and we don't have so much time to update the blog.

Today's entry is not a code snippet as usual, is a little trick for when we are performing any task in background and we want to cancel it. For example, I want to accomplish it when a user taps back button during an array data loading performing in background.

The only way to abort a background task is to define a class boolean variable accesible for any method.

BOOL cancelBackgroundTask

set it to NO when you lauch the task

cancelBackgroundTask = NO;
[self performSelectorInBackground:@selector(bgTask) withObject:nil];

If the user makes any action that should abort the background task, just change the boolean value

cancelBackgroundTask = NO;

And at last, in background task you have to check this variable periodically with an NSTimer or a worse approach but maybe usefull is to check it before perform any action.

if (!cancelBackgroundTask)
    [self loadData];

if (!cancelBackgroundTaks)
    [self presentData];

In this easy way you could abort a background task. This derived of the lack of a function to abort or cancel directly a thread.

I hope this help, enjoy it!

Thursday, December 15, 2011

[Code Snippet] Rounded corners for UIView

We are very sorry about the lack of updates for the block, but now we are overloaded of projects and have no much time to write new posts :(

Here is a little and useful code snippet to round the corners of any UIView (UIWebView, UIImageView, etc...)

You have just to link your binaries with QuartzCore library and import it in the .h file.

#import <QuartzCore/QuartzCore.h>

And in .m file, you have to use this code snippet to round the corners. In the examble I've did it with a UIImageView

[imgView.layer setBorderColor:[UIColor blackColor].CGColor];
[imgView.layer setBorderWidth:1.0f];
                    
[imgView.layer setCornerRadius:10];
[imgView setClipsToBounds:YES];

With this four lines of code, you'll give your app a better look and feel.

Enjoy it!!

P.S. Don't forget to visit our web to see a complete catalogue of our apps.

Monday, December 5, 2011

New web site

We are proud to present you our new official web site: http://www.fiveflamesmobile.com in which you can see all of our developments for iOS, Android and Windows Phone.

This was the cause of the lack of updates of the blog, but don't worry because this blog will continue publishing articles for iOS and Windows Phone developers in blogspot.

We hope that you like our new web site and continue visiting this blog.

Regards!

Five Flames Mobile Team

Wednesday, November 16, 2011

[Code Snippet] Accesing to SSL server trust web services

This code snippet completes the two previous post that says how to connect to a REST service and consume it synchronous and asynchronously.

When we have to access a HTTPS web service first thing that we should think is how to store the trusted root certificate in our iPhone or iPad. Our device has installed some of the most used certificates (you can check the list here) and for this snippet we asume that the server uses Verisign, GoDaddy or any other common SSL certificate, so we have yet installed it.

To accomplish this task you should implement the next functions of NSURLConnection delegate:


- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection
{
    return TRUE;}
-(void)connection:(NSURLConnection *)connection didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    NSLog(@"Challenge cancelled");}
-(BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
   // Server Trust authentication method
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
  
    //Here we told the OS that validate the server certificate against our credential storage.
    [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];       
    NSLog(@"Reto superado");}

If we just want to bypass the authentication, instead of useCredential, we should use continueWithoutCredential method in didReceiveAuthenticationChallenge.

    //Bypass without credentials
    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];

I hope this code snippet could be useful for you, enjoy it!

NOTE: This can be used only with NSURLConnection, just for asynchronous request.

Working in progress...

Hello everyone.

We're sorry for the lack of updates of the last weeks but J.A.Gallego was travelling round Spain with Windows Phone Roadshow and I was also very busy with a suite of nature oriented new iPhone (and maybe iPad optimized in the future) apps.

We're also creating a new web site, exclusively for our apps and games with the help of Virginia, our graphics designer, we'll keep this blog only for code snippets and geek stuff at blogspot for those who has it in their bookmarks and create a separately web for apps and projects to give them more visibility.

At last we are in the way to port Vinos de Cigales and Car Charge to Windows Phone and Android OS, so it's possibly that in the next days two new guys will be added to Five Flames Mobile staff...

These are the causes of the lack of updates, Twitter has been updated frequently but the blog wasn't so we apologize and will try to recover our weekly updates.

Thanks to all of our followers!

Wednesday, October 19, 2011

Windows Phone Roadshow 2011 (Valladolid, Spain)

Yesterday I left my MacBook Pro and the new XCode 4.2 to refresh my .Net for Windows Phone 7, which I'm alternating with Objective-C now, for going to the event organized by Microsoft Innovation Center Mobility Solutions (AKA CIM): Windows Phone Mango Roadshow 2011.

The even took place at Boecillo (Valladolid) and there was more than a hundred people to hear about this new mobile operating system by Eduardo Ortega, Jose Antonio Gallego (our Five Flames blog mate expert in WP7) from CIM and Isabel Gomez from Microsoft Ibérica.

This event is oriented to developers (obviously) and UI/UX designers too, excepting the Key Note and the Introduction to Windows Phone session that was oriented for all publics.

The keynote was presented by Isabel and Eduardo and talks about Windows Phone, its evolution to Mango, and the main improvements that this new version of the OS bring us.

After key note, Eduardo and Jose Antonio gives an introduction about programming for Windows Phone 7 both Silverlight Applications and XNA Games technologies with a little demo for each one. The use of Microsoft Blend studio for designing a rich UI/UX interface like a Flash app and how it's integrated with Visual Studio was awesome for most of the people who saw that create rich visual experiences was easier in Windows Phone 7 than other platforms.

Next session, also by Eduardo and Jose Antonio, talks about data access with SQL Server CE, accesing to web services and the new feature of WP7: Live Tiles. A "widget" like tile attached to an application in which you can show updated content.

In the break after this session the event organizers give us a free brunch for our hungry stomach and afterwards Eduardo Ortega talk us about Windows Phone advanced capabilities included in Mango: gyroscope, compass, accelerometer, camera and augmented reality with GART which could be used or implemented in a Windows Phone app/game with only a few lines of code.

After lunch Eduardo's session talks about multitasking in Windows Phone and the features asociated to this functionality: Tombstoning, dormant, background Agents and Fast Application Switch and how to use it from code.

Next to a little break that prepared us to final sessions Jose Antonio developed from start to end a complete app named "ZombSquare" in which was included every features seem in this event: Silverlight, XNA, 3D Models, Sensors, Data Access and Augmented Reality. The code of this app will be uploaded to codeplex after the Roadshow in order that atendees could experiment by themselves.

The final session, by Jose Antonio and Isabel, talks about uploading apps to Microsoft Marketplace, ROI, promoting apps and everthing useful to obtain cash for publishing our apps and games.

At last, there was a little contest in which Microsoft gives 5 Silverlight books by JosuĂ© Yeray and 5 Windows Phone mobile devices.

Globaly this event was very dinamic and the speakers answer people's questions at every moment. I highly recommended you this event for every developer/designer but expecially if you have previous knowledge in .Net technologies there will be very easy that you could begin programming for mobile phones.

The next places and dates that Windows Phone Roadshow 2001 will take place are:

I hope there will be new devices by Nokia and other manufactures for this Chrismats so this technology could grow up.

Monday, October 17, 2011

[How To] Get Device Unique Id in Windows Phone

To Get the device unique ID you need to first declare in the WMAppManifest.xml file this capability ID_CAP_IDENTITY_DEVICE.

You can use this ID to indentify one device (count unique users, send custom notifications, etc)

In code to get this Id you only need to do this:

public static byte[] GetDeviceUniqueID()
{
byte[] res = null;
object uniqueId;
if (DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out uniqueId))
{
res = (byte[])uniqueId;
}
return res;
}

Enjoy it!

Thursday, October 13, 2011

[Code Snippet] Geolocating photos with reverse geocoding.

Sometimes you have an app which takes a photo, and you want to geolocate it obtaining current latitude, longitude and altitude from the GPS, but generally for the user this info is not useful, it has not a Reverse Geocoder in its brain so the user should prefer to see a name than three numbers.

In this code snippet we're going to se how to accomplish this.

First thing to do is to add the required frameworks to our app.

CoreLocation Framework
MapKit Framework

Next, in your .h file you have to import these frameworks and implement the protocols that we need.

#import <corelocation corelocation.h>
#import <mapkit mapkit.h>

@interface geolocatingPhotoViewController : UIViewController <UIImagePickerControllerDelegate,  CLLocationManagerDelegate, MKReverseGeocoderDelegate>

Let's take the photo with UIImagePickerController and when we've token it, we call CLLocationManager to get our position.

UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init]; imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:imagePicker animated:YES];
[imagePicker release]; 

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
self.imageViewCaptura.image = image;
[picker dismissModalViewControllerAnimated:YES];
CLLocationManager * locationManager = [[CLLocationManager alloc] init]; locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; [locationManager startUpdatingLocation];
}

Once we have our image stored in a UIImageView and we have to wait the CLLocationManager to get our position coordinates. When we have it, we stop the location and call the reverse geocoding to start getting the location name.

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
[locationManager stopUpdatingLocation];
[locationManager release];
capture.longitude = newLocation.coordinate.longitude;
capture.latitude = newLocation.coordinate.latitude;
capture.altitude = newLocation.altitude;

CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(capture.latitude, capture.longitude);
MKReverseGeoCoder *reverserGeoCoder = [[MKReverseGeocoder alloc] initWithCoordinate:coordinate];
reverserGeoCoder.delegate = self; 
[reverserGeoCoder start];
}

At last, if MKReverseGeoCoder was able to get the coordinates info, we only has to get the data and show it.
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {
if (placemark)
{
NSString *strLocation = [NSString stringWithFormat:@"%@, %@ (%@)", placemark.locality, placemark.administrativeArea, placemark.country]; self.textFieldLocation.text = strLocation;
}
NSLog(@"Location info: %@", strLocation );
}

We should control if GKReverseGeocoder wasn't able to retrieve our position information implementing didFailWithError function.

And that's all, now you know how to present location info to the user when it takes a photo.

Enjoy it!

Monday, October 10, 2011

[How to] Share links and status in Twitter, Facebook, linkedIN…

This post do not need any explanation :)

Microsoft.Phone.Tasks.ShareLinkTask shareLinks = new
Microsoft.Phone.Tasks.ShareLinkTask();
shareLinks.LinkUri = new Uri("http://www.fiveflamesmobile.com");
shareLinks.Message = "Try ShareLinkTask in Windows Phone";
shareLinks.Title = "Share Link Task Sample";
shareLinks.Show();


To update your status:
Microsoft.Phone.Task.ShareStatusTask status = Microsoft.Phone.Task.ShareStatusTask();
status.Status = Try ShareStatusTask in Windows Phone";
status.Show();

enjoy it!

Thursday, October 6, 2011

[Code Snippet] Send GET and POST data to web services asynchronously.

Last post talks about sending post and get values to a web service synchronously using NSURLConnection sendSynchronousRequest:(NSURLRequest)request method. Today we'll explain how to do the same request but asynchronously in background.

Firstly, we have to declare some instance variables:


    NSURLConnection *urlConnection;
    NSURL *loginURL;
    NSMutableData *responseData;


The initial code is like synchronous method, we have to prepare the NSURL object, and load the NSMutableURL object with the URL, the parameters and setting the correct headers value.

NSURL *url = [NSURL urlWithString:@"http://www.fiveflamesmobile.com/login.php?from=mobile"];
NSString *formValues = [NSString stringWithFormat:@"name=%@&device=%@", @"FiveFlames", @"iPhone"];
NSData *formData = [formValues dataUsingEncoding:NSUTF8StringEncoding];
[urlRequest setHttpBody:formData];

And now, instead of invoke sendSynchronousRequest method, we have just to initialize the NSURLConnection object with our request and set the delegate to the class that implements the delegate methods, in this case, our class.


urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

And now we've just to implement the delegate methods. You haven't to put any protocol declaration in .h file.

Basic methdos to implement are:

Will send request is invoked just before to send the request, and we keep the "real" URL stored in our class variable.

- (NSURLRequest *)connection:(NSURLConnection *)connection
             willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse
{
    [urlConnection release];
    urlConnection =  [[request URL] retain];
    
    NSLog(@"URL Recibida: %@:", [[request URL] absoluteString]);
    
    return request;
}

If we have store some data into NSURLRequest HttpBody property, this method will be invoked just after have sent them.

- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
    NSLog(@"PeticiĂłn enviada");
}


The method didFailWithError is invoked when the NSURLConnection fails so is time to check the error.

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"Error: %@", [error description]);    
}

The method didReceiveResponse is invoked when the server and the client establish the connection, so we have to initialize here the container in which the response will be saved.

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    responseData = [[NSMutableData alloc] init];
    [responseData setLength:0];   
}

This method is invoked when data is received (obviously). If the amount of data is small, it will be invoked once, but if the amount of data is big, this method will be invoked repeatedly. We just to add the received data to the container.

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [responseData appendData:data];
    NSLog(@"Data sin decodificar: %@", data);
}


At last, connectionDidFinishLoading is invoked when the response is totally stored in our variable, so now it's time to log it, parse it or do whatever you want to do with it.

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{
    //Log de la respuesta para depuraciĂłn
    
    NSString *strResponse = [[NSString alloc] initWithBytes:[responseData bytes]
                                                     length:[responseData length] 
                                                   encoding:NSUTF8StringEncoding];
    NSLog(@"\n--------- Received Response ---------\n");
    NSLog(@"%@", strResponse);
    NSLog(@"\n--------- End of received response ---------\n");
    
    [strResponse release];
    
}

This is a very basic implementation of an asynchronous request.  We'll try to show you how to make SSL asynchronous connections, but we reserve it for another post.

Enjoy the code!

Friday, September 23, 2011

[Code Snippet] Send GET and POST data to web services.

It has been two weeks with a lot of work and a seriously lack of time to update the blog, but we are back again.

This week code snippet is about sending data to web services, XML and JSON are most used technologies used today but maybe some of your has to send data to an older php web page that receives data from a form by GET, POST or both of them. How could we accomplish that?

Let's see a code snippet to do it synchronously, later we'll publish a new entry with the asynchronous method.

First thig to do is to create the NSURL object which we are going to make the request to. If it has any GET parameters we should put them in the URL String.

NSURL *url = [NSURL urlWithString:@"http://www.fiveflamesmobile.com/login.php?from=mobile"];

After that we have to create a NSMutableURLRequest in order to put the post parameter.

NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
[urlRequest setHttpMethod:@"POST"];

And now we only have to put in the HTTPBody the form variables as URL encoding like "key1=value1&key2=value2..." as a NSData object.

NSString *formValues = [NSString stringWithFormat:@"name=%@&device=%@", @"FiveFlames", @"iPhone"];
NSData *formData = [formValues dataUsingEncoding:NSUTF8StringEncoding];
[urlRequest setHttpBody:formData];

And now, we only just to make the request and save the response.

NSURLResponse *response;
NSError *error;

NSData *responseData = [NSURLConnection sendSynchronousRequest:urlRequest response:&response error:&error];

NSLog (@"Response: %@", responseData);

That's all, with this code snippet you could keep your older php or asp pages and reuse it to develop a server-client iOS app.

Enjoy it!

Thursday, September 8, 2011

[iOS2WP7] From iOS to Windows Phone. Introduction

From now we're going to alternate the blog's updates between Code Snippets and iOS to Windows Phone migration tips for whose that want to migrate this iOS applications and games to this new mobile OS.

iOS is a huge and very stable platform and iPhone is most sold device from all over the times, so there are thousands and thousand of applications and games in the AppStore. A lot of these games and applications are very useful or adictive (see Angry Birds for example) and Windows Phone users are waiting to have it in their phones so it's a good idea to migrate them, and now it could be a good moment to start.

Windows Phone is a very young OS for mobile devices, and being realistic there aren't so much available devices in the market so you could think "Why should I have to migrate my apps/games for that little potencial market?" Let's see a few good answers.

- Growing trend. Now there aren't a lot of devices running Windows Phone, but for Christmas campaign some manufacturers like Nokia (waiting for them...) HTC (Radar and Titan last ones) Samsung... are going to launch their last models including Windows Phone 7 Mango, so it seems that the potential number of users of your apps/games is going to growht.

- Positioning. Your app/games uploaded to Marketplace have less competence that another platforms like Android Market or AppStore so it's easier to have a better rating and visibility. If your app is the first to do something it will be a reference for Windows Phone users.

- Knowledgment: Maybe there are not much market to attack, but if you adquire the knowledment to migrate iOS apps/games to Windows Phone now, you will be one step beyond the competence if this platform begins to growth.

- Easy to develop: If you are a iOS developer, programming for windows phone is much easier than do it for iOS. I'm doing both things and believe me, it's easier.

- Facilities: Visual Studio for Mobile Development is free for developers, Microsoft developer license for one year has the same cost as iOS one...

- Lack of fragmentation. Like iOS, Windows Phone has fixed characteristics so you haven't to get crazy with differentes screen resolutions, different ROMs, different OS...

If after reading this article, you are convinced to migrate your apps, don't forgot this blog. We're going to publish coding tips, examples with both C# and Objective-C code for comparing, and a serie of articles to help you to accomplish this task.

For fist reading have a look to this guide published by Microsoft: Windows Phone 7 Guide for iPhone Application Developers

And the first link to have under Five Flames Mobile Blog ;) :Windows Phone Interoperability Bridges

Enjoy it!

Monday, September 5, 2011

[HOW TO] Intercept javascript events with Windows Phone WebBrower control

If you need intercept javascript events in Windows Phone web browser control, you must use the ScriptNotify event. This event is launched when the window.external.Notify() function is called from javascript code.

First you must enable IsScriptEnabled property.

IsScriptEnabled

Second, you must handle the ScriptNotify event, you could make this from xaml code or from code behind, as you prefer.

webBrowser1.ScriptNotify+=new EventHandler<NotifyEventArgs>(webBrowser1_ScriptNotify);

EventScript

HTML Example:

<html>
<head> 
    <title>Demo Windows Phone</title>
    <script type="text/javascript">
function SendNotify() { window.external.Notify(‘demo’); }
</script>
</head>
<body>
    <div>
        <input type="button" value="Notify" onClick="SendNotify()"/>
    </div>
</body>
</html>

You can load this html code with NavigateToString function from WebBrowser control.

private void webBrowser_ScriptNotify(object sender, NotifyEventArgs e)
{
    if (e.Value == "demo")
    {
        MessageBox.Show(e.Value);
    }
}

Note: You can call javascritp functions from c# code, using InvokeScript method.

Monday, August 29, 2011

[How To] Disable Pivot swipe gesture in Windows Phone

If you need to disable Pivot gestures in WP7 you only need use the IsHitTestVisible  property. This property gets or sets a value that declares whether this element can possibly be returned as a hit test result from some portion of its rendered content.

If you set to true the contained area of this control can be used for hit-testing,
If set this property to false the control will not report any event when the user manipulate it.

In code, you only need mark the IsHitTestVisible property to false.

pivotControl1.IsHitTestVisible = false;

Remember that this action is not a recomended practice in Windows Phone.

Wednesday, August 24, 2011

[Code Snippet] Custom UINavigationBar back button

Back from my holidays, I come back with my weekly wednesday's code snippet.

Sometimes when we work with UINavigationcontroller we want to custom the back button for a more visual image, or just an arrow. Today let's see how to create a custom back button with our own image for the UINavigationBar.

First of all, you have to implement in viewDidLoad the next piece of code

    if ([self.navigationController.viewControllers count] > 1)
    {
        //Creating our custom back button
        UIButton *home = [UIButton buttonWithType:UIButtonTypeCustom];
        [home setTitle:@"Volver" forState:UIControlStateNormal];
       
        UIImage *homeImage = [UIImage imageNamed:@"backbutton.png"];
       
        [home setBackgroundImage:homeImage forState:UIControlStateNormal];
        home.frame = CGRectMake(0, 0, 80, 30);
       
        [home addTarget:self action:@selector(cancel:) forControlEvents:UIControlEventTouchUpInside];
       
        UIBarButtonItem *cancelButton = [[[UIBarButtonItem alloc]
                                          initWithCustomView:home] autorelease];
        self.navigationItem.leftBarButtonItem = cancelButton;
    }
After that, we just have to implement the selector to pop the view controller and back to the previous one:

-(IBAction)cancel:(id)sender{
    [self.navigationController popViewControllerAnimated:YES];
}
And that's all. Now you can improve your UI with a custom back button. Enjoy it

Tuesday, August 23, 2011

Windows Phone SDK 7.1 Release Candidate

The Windows Phone Software Development Kit (SDK) 7.1 provides you with all of the tools that you need to develop applications and games for both Windows Phone 7.0 and Windows Phone 7.5 devices. This download is the Release Candidate (RC) and provides a ‘Go Live’ license that enables you to develop and publish applications to the Windows Phone Marketplace.

The Windows Phone SDK includes the following

  • Windows Phone SDK 7.1 (RC)
  • Windows Phone Emulator (RC)
  • Windows Phone SDK 7.1 Assemblies (RC)
  • Silverlight 4 SDK and DRT
  • Windows Phone SDK 7.1 Extensions for XNA Game Studio 4.0
  • Microsoft Expression Blend SDK for Windows Phone 7
  • Microsoft Expression Blend SDK for Windows Phone OS 7.1
  • WCF Data Services Client for Window Phone
  • Microsoft Advertising SDK for Windows Phone

 

You can download this tools here: Windows Phone SDK 7.1 RC

Monday, August 22, 2011

[How To] Scroll a ListView from code

Scroll a ListView from code, sometimes could be a headache, but you only need do this in the next way.

public MainPage()
{
    InitializeComponent();
    miListBox.Loaded += new RoutedEventHandler(miListBox_Loaded);
}

void miListBox_Loaded(object sender, RoutedEventArgs e)
{
    miListBox.SelectedIndex = 14;

    miListBox.ScrollIntoView(miListBox.SelectedItem);
}

The key of this Tip is that you must call ScrollIntoView Metod after loading ListView control.

 

Regards!

Monday, August 15, 2011

[How to] Discover User Agent in Windows Phone

As you know, we can recover the UserAgent from web browser using javascript, specifically using the navigator object. With this object we can see the platform version, user agent and other properties of our browser, in this case we will use the navigator.userAgent property.

Windows Phone do not allow us exec javascript in native mode, but we can do this inside a WebBrowser control, for this, you can follow these setps:

1) Add a WebBrowser control to our PhoneApplication page.
2) Using the function NavigateToString to load the script,  you can see the script in the example showed below.
3) Finally we intercept the ScriptNotify event from WebBowser control and we will process and store the value in the IsolatedStorage for when we need.

Declare a WebBroser control.

private WebBrowser webBrowserControl;

In the constructor of our PhoneApplicationPage, instance and add the control.

        public ManiPage()
        { 
            (…) 
            control.Loaded += new RoutedEventHandler(webBrowserControl_Loaded);

            webBrowserControl = new WebBrowser();
            webBrowserControl.IsScriptEnabled = true;
            webBrowserControl.Visibility = System.Windows.Visibility.Collapsed;
            webBrowserControl.ScriptNotify += new EventHandler<NotifyEventArgs>(webBrowserControl_ScriptNotify);
            contentPanel.Children.Add(webBrowserControl);
        }

When the WebBrowser control is loaded completely, we will load the scritp using NavigateToString function.

        void webBrowserControl_Loaded(object sender, RoutedEventArgs e)
        {
            string html = @"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.01 Transitional//EN"">
                <html>
                <head>
                <script language=""JavaScript"" type=""text/JavaScript"">
                function getUserAgent() {
                    window.external.notify(navigator.userAgent);
                }
                </script>
                </head>
                <body onload=""getUserAgent();""></body>
                </html>";

            webBrowserControl.NavigateToString(html);
        }

Finally process the ScriptNotifi event and recover the UserAgent value. The format of UserAgent looks like this (in this case the User Agent of a Windows Phone Emulator)

Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; Microsoft; XDeviceEmulator)

void webBrowserControl_ScriptNotify(object sender, NotifyEventArgs e)
{ 
    _userAgent = e.Value;  
    System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings["UserAgent"] = _userAgent;

    if (UserAgentChanged != null)
    {
        UserAgentChanged(e.Value, new EventArgs());
    }
}

NOTE: If you want to recover this value later, you can do this:

string userAgent;
System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings.TryGetValue<string>("UserAgent", out userAgent);