Sigurd Snørteland


viu² touch – one of the norwegian wp7 app contest winners

More info:
http://www.vs2010.no
http://blogs.msdn.com/b/dpenorway/archive/2011/01/27/3-vinner-av-wp7-app-konkurransen-er-k-229-ret.aspx

viu² touch is a WP7 based version of my silverlight mediacenter app viu² (www.viu2.com).
More information about viu² touch will be published soon!!

Advertisements

tweet search – one code, three mobile platforms (wp7, monodroid, monotouch)

Here is the presentation and the source code from the speech I held at the Norwegian .Net User Group last wednesday.

tweet search
‘tweet search’ is a mobile twitter search app written in c# for Windows Phone 7, iPhone and Android. All three apps share the same twitter search code, but they have custom gui code (WP7=Silverlight, iPhone=MonoTouch, Android=MonoDroid).

Go to the bottom of this article to find links to the source code & presentation.

Shared twitter-code:

public class Twitter
    {
        public event EventHandler twitteSearchCompleted;

        public Twitter()
        {
        }

        public void search(string searchText)
        {
            if (searchText != "")
            {
                WebClient client = new WebClient();
                client.DownloadStringAsync(new Uri("http://search.twitter.com/search.atom?q=" + searchText));
                client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            }
        }

        private void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                List twitteList = new List();

                XDocument xml = XDocument.Parse(e.Result);
                XNamespace atomNS = "http://www.w3.org/2005/Atom";

                var tempList = (from entry in xml.Descendants(atomNS + "entry")
                                select new TwitterObject()
                                {
                                    ID = entry.Element(atomNS + "id").Value,
                                    Title = entry.Element(atomNS + "title").Value,
                                    Date = DateTime.Parse(entry.Element(atomNS + "published").Value),
                                    AuthorName = entry.Descendants(atomNS + "author").Elements(atomNS + "name").FirstOrDefault().Value,
                                    AuthorUri = entry.Descendants(atomNS + "author").Elements(atomNS + "uri").FirstOrDefault().Value,
                                    AuthorImage = (from imgElement in entry.Elements(atomNS + "link")
                                                   where imgElement.Attribute("rel") != null
                                                   && imgElement.Attribute("rel").Value.Contains("image")
                                                   && imgElement.Attribute("href") != null
                                                   select imgElement.Attribute("href").Value).FirstOrDefault()
                                }).ToList();

                twitteList = tempList.ToList();
                twitteSearchCompleted(twitteList, null);
            }
        }
    }

    public class TwitterObject
    {
        public string ID { get; set; }
        public string Title { get; set; }
        public DateTime Date { get; set; }
        public string AuthorName { get; set; }
        public string AuthorUri { get; set; }
        public string AuthorImage { get; set; }
    }

WP7 code:

namespace tweet_search_wp7
{
    public partial class MainPage : PhoneApplicationPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        #region UI

        private void txtSearch_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                this.Focus();
            }
        }

        private void txtSearch_LostFocus(object sender, RoutedEventArgs e)
        {
            search();
        }

        private void lboTwitte_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            lboTwitte.SelectedIndex = -1;
        }

        private void imgSearch_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            search();
        }

        #endregion

        #region Twitter

        private void search()
        {
            lblLoading.Visibility = Visibility.Visible;
            lboTwitte.Opacity = 0.3;

            Twitter twitter = new Twitter();
            twitter.twitteSearchCompleted += new EventHandler(twitter_downloadCompleted);
            twitter.search(txtSearch.Text);
        }

        private void twitter_downloadCompleted(object sender, EventArgs e)
        {
            List list = (List)sender;
            lboTwitte.ItemsSource = list;

            lblLoading.Visibility = Visibility.Collapsed;
            lboTwitte.Opacity = 1;
        }

        #endregion
    }
}

MonoTouch code:

namespace tweetsearchiphone
{
	public partial class MainPage : UIViewController
	{
		#region Constructors

		// The IntPtr and initWithCoder constructors are required for items that need
		// to be able to be created from a xib rather than from managed code

		public MainPage (IntPtr handle) : base(handle)
		{
			Initialize ();
		}

		[Export("initWithCoder:")]
		public MainPage (NSCoder coder) : base(coder)
		{
			Initialize ();
		}

		public MainPage () : base("MainPage", null)
		{
			Initialize ();
		}

		void Initialize ()
		{
		}

		#endregion

		#region UI

		public override void ViewDidLoad()
		{
			base.ViewDidLoad();

			lblTwitter.Text = "";
			txtSearch.ShouldReturn = delegate
			{
				txtSearch.ResignFirstResponder();
				search();

				return true;
			};

			imgSearch.TouchUpInside += HandleImgSearchTouchUpInside;
		}

		void HandleImgSearchTouchUpInside (object sender, EventArgs e)
		{
			search();
		}

		#endregion

		#region Twitter

		private void search()
		{
			Twitter twitter = new Twitter();
			twitter.twitteSearchCompleted += twitter_downloadCompleted;
			twitter.search(txtSearch.Text);
		}

		void twitter_downloadCompleted (object sender, EventArgs e)
		{
			List list = (List) sender;
			BeginInvokeOnMainThread (delegate {

				foreach(TwitterObject tweet in list)
				{
		        	lblTwitter.Text += tweet.Date.ToString() + Environment.NewLine + tweet.Title + Environment.NewLine + Environment.NewLine;
				}

		    });
		}

		#endregion
	}
}

MonoDroid code:

namespace tweet_search_android
{
	[Activity (Label = "tweet search", MainLauncher = true)]
	public class ButtonActivity : Activity
	{
        List list = new List();
        Android.Widget.Button btnSearch;
        TextView lblTwitter;
        EditText txtSearch;

        private List photo_ids = new List() { Resource.drawable.bird };

		protected override void OnCreate (Bundle bundle)
		{
			base.OnCreate (bundle);
            SetContentView(Resource.layout.main);

            ImageView btnSearch = FindViewById(Resource.id.btnSearch);
            btnSearch.SetImageResource(photo_ids[0]);
            btnSearch.Click += new EventHandler(btnSearch_Click);

            txtSearch = FindViewById(Resource.id.txtSearch);
            lblTwitter = FindViewById(Resource.id.lblTwitter);
		}

        void btnSearch_Click(object sender, EventArgs e)
        {
            if (list.Count == 0)
            {
                Twitter twitter = new Twitter();
                twitter.twitteSearchCompleted += new EventHandler(twitter_twitteSearchCompleted);
                twitter.search("nnug");
            }
            else
            {
                foreach (TwitterObject twitter in list)
                {
                    lblTwitter.Text += twitter.Date.ToString() + System.Environment.NewLine + twitter.Title + System.Environment.NewLine + System.Environment.NewLine;
                }

                list = new List();
            }
        }

        void twitter_twitteSearchCompleted(object sender, EventArgs e)
        {
            list = (List)sender;
        }
	}
}


WP7 – Silverlight på mobilen

Click here to find RTM-version of the source code.

Mix10 konferansen som Microsoft arrangerte i midten av mars var i år spekket med mange spennende  nyheter, deriblant RC versjon av Silverlight 4. Det som likevel fikk mest oppmerksomhet var Microsoft’s neste mobile os ‘Windows Phone 7 (WP7)’ hvor man utvikler applikasjoner i XNA og Silverlight. Helt siden versjon 2 av silverlight har utviklere etterlyst muligheten for å kjøre silverlight på bærbare enheter og med WP7 blir dette mulig. Nedenfor ser du et skjermbildet av hovedmenyen i WP7. Det nye os’et har fått masse kule effekter i brukergrensesnittet og Microsoft har utviklet ett eget gui-konsept, Metro, som det anbefales å følge når man utvikler applikasjoner for WP7.

For å gjøre det klart med en gang: silverlight-utvikling på WP7 er utrolig enkelt og morsomt. Dersom du har kodet litt silverlight fra før så er du produktiv fra starten av. Stort sett eneste forskjell fra vanlig silverlight-utvikling er at man benytter noen andre visual studio templates, samt at man får tilgang til noen nye api’er som f.eks. gps, accelerometer, kamera, osv. Når du utvikler har du tilgang til en wp7-emulator i visual studio som applikasjonene kjører i.

WP7 er forventet å bli lansert i 4 kvartal 2010 og kommer da med en applikasjons-butikk tilsvarende iPhone’s AppStore, så det blir muligheter for å tjene penger på WP7-applikasjonen. Jeg anbefaler derfor alle til å gå til http://developer.windowsphone.com og laste ned software og test ut silverlight mobilutvikling slik at vi alle er forberedt på WP7!

Jeg holdt et foredrag om mobil Silverlight-utvikling på NNUG Stavanger i april og anbefaler derfor de som er interessert i mer info om dette temaet til å lese powerpoint’en nedenfor.

.

myWeather
Nedenfor ser du en WP7 silverlight applikasjon for å displaye værvarsel på mobilen. Link til kildekoden finner du rett under bilden.

I forbindelse med foredraget hos NNUG Stavanger konverterte jeg en del kjente “gamle/vanlige” silverlight-applikasjoner, som jeg fant på ‘silverlight.net’, over til å kjøre på WP7. Konverteringsprosessen er utrolig enkelt og i hovedsak innebærer det å kopiere over koden i en nyopprettet WP7-solution i visual studio.

.

wp7clock

Nedenfor vises den opprinnelige applikasjonen i vanlig webbrowser-mode:

Her er en linken til den opprinnelige kildekoden:
http://www.silverlight.net/community/samples/silverlight-samples/silverlight-analogclock–enhancing-the-view

Her er en link til det nye WP7-prosjektet:

.

wp7coverflow

Nedenfor vises den opprinnelige applikasjonen i vanlig webbrowser-mode:

Her er en linken til den opprinnelige kildekoden:
http://www.silverlight.net/community/samples/silverlight-samples/collectionflow

Her er en link til det nye WP7-prosjektet:

.

wp7solitarie

Nedenfor vises den opprinnelige applikasjonen i vanlig webbrowser-mode:

Her er en linken til den opprinnelige kildekoden:
http://www.silverlight.net/community/samples/silverlight-samples/klondike-solitaire

Her er en link til det nye WP7-prosjektet:

.

PS: Til informasjon så er det nå også mulig å teste ut silverlight-utvikling på Nokia’s Symbian-plattform. Sjekk ut denne linken: http://www.silverlight.net/getstarted/devices/symbian.