Sigurd Snørteland



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;
        }
	}
}

About these ads

Trackbacks & Pingbacks

  1. Media coverage « Sigurd Snørteland pingbacked on 3 years, 10 months ago
  2. Tweet search – one code, three mobile platforms (wp7, monodroid, monotouch) (via Sigurd Snørteland) « TechTrends pingbacked on 3 years, 10 months ago
  3. ひとつのC#ソースを使ってWP7・iPhone・Androidアプリを作る - ななふぉ pingbacked on 3 years, 10 months ago
  4. For Developers: Write Once, Run Everywhere pingbacked on 3 years, 10 months ago
  5. Use .NET to build Windows Phone, iPhone, iPad and Droid Apps | Mike Hacker pingbacked on 3 years, 9 months ago
  6. Tweet Search | AllGraphicsOnline.com pingbacked on 3 years, 5 months ago

Comments

  1. * Greg Kerr says:

    I’ve been writing Windows apps for nearly 25 years, make a living now doing WPF work, and do some iPhone/iPad and WP7 work on the side (but haven’t taken the MonoTouch plunge completely yet), and all I can say is “This just rocks.” Truly, .NET everywhere. Thanks!

    | Reply Posted 3 years, 10 months ago
  2. * Sølve Heggem says:

    Very interesting, cool if you can do the talk in Oslo as well :)

    | Reply Posted 3 years, 10 months ago
  3. * Corneliu says:

    Hi,
    Great job and a great proof of the strengths of .Net.

    However, I’d be surprised but this app would pass the AppStore submission. It looks to WP7 and not enough iPhone(ish) to be accepted.
    We do something relatively similar for WP7/iPhone but we do code the UI specific to each platform and try to share the controllers (as much as possible)
    WP7: Silverlight
    iPhone: Interface Builder + custom view layer.
    – Haven’t tried Android yet.
    It’s a bit more work but it allows you to make the app feel ‘native’ on each platform instead of strangely different.

    Anyway, fantastic work.
    Corneliu.

    | Reply Posted 3 years, 10 months ago
  4. * Colin E. says:

    Very very cool.

    I am very interested in cross-platform XAML (http://www.scottlogic.co.uk/blog/colin/2010/10/white-paper-silverlight-wpf-and-windows-phone-7-cross-platform-development/), however, you example here adds another dimension!

    Regards, Colin E.

    | Reply Posted 3 years, 10 months ago
  5. Nice! I came across this post on Twitter. Just yesterday I gave a presentation with two of my colleagues about the exact same topic! We looked at how we could share Controller and Model logic, communication with web services and how to deal with differences in handling UI, async operations, etc.

    Got lots of skepticism from a bunch of Objective-C purists, haha. But MonoTouch is an awesome product! MonoDroid still has a long way to go, but is promising.

    | Reply Posted 3 years, 10 months ago
  6. * tim says:

    How are you managing this code? Do you have it in three separate projects?

    | Reply Posted 3 years, 10 months ago
  7. * Melanie says:

    Hello! This post couldn’t be written any better! Reading through this post reminds me of my good old room mate! He always kept chatting about this. I will forward this article to him. Fairly certain he will have a good read. Thanks for sharing!

    | Reply Posted 1 year, 11 months ago
  8. * Wyatt says:

    Hey! Someone in my Facebook group shared this website
    with us so I came to check it out. I’m definitely enjoying the information. I’m
    bookmarking and will be tweeting this to my followers!
    Superb blog and great style and design.

    | Reply Posted 1 year, 10 months ago
  9. Thanks for finally talking about >tweet search – one code, three mobile
    platforms (wp7, monodroid, monotouch) |
    Sigurd Snørteland <Liked it!

    | Reply Posted 1 year, 6 months ago
  10. * geo news says:

    At this time I am going away to do my breakfast, when having my breakfast coming yet again to read more news.

    | Reply Posted 1 year, 5 months ago
  11. * Janine says:

    Can it be okay to be able to put a percentage
    with this on my own private web page easily publish a blueprint to this particular web-site?

    I would like to convey our adoration for the generosity pertaining to folks who have the necessity
    for assistance on this condition. Your very own devotion in order to transferring the content over turned into exceptionally powerful and it has helped individuals just like me to reach their dreams.
    The crucial tips and hints signifies a lot in my opinion as
    well as even more to our peers. Cheers; coming from
    all all of us.

    | Reply Posted 1 year, 3 months ago
  12. What you composed was actually very logical.
    But, think on this, what if you added a little information?
    I am not saying your content isn’t good, but suppose you added a post title that grabbed folk’s
    attention? I mean tweet search – one code, three mobile platforms (wp7, monodroid, monotouch) | Sigurd Snørteland is kinda boring.
    You ought to peek at Yahoo’s front page and see how they create article titles to get viewers to click. You might try adding a video or a pic or two to get people excited about everything’ve got to say.
    In my opinion, it could bring your blog a
    little bit more interesting.

    | Reply Posted 1 year, 2 months ago
  13. Hi there to all, the contents present at this web page are actually amazing
    for people experience, well, keep up the nice
    work fellows.

    | Reply Posted 1 year, 1 month ago
  14. Consider the look and style of the piano bench If you want it to match the piano, select a look for the bench that complements that of the piano.
    The key part of double piano benches is to let the piano learners achieve the training practice
    easily while boosting their own skills. Several bench organizations acquired their commence
    in the early 1900s by contracting with the piano suppliers to supply benches in numerous designs that would match the actual complete
    and leg type of the piano getting purchased and marketed.

    | Reply Posted 1 year ago
  15. hey there and thank you for your information – I have certainly picked up anything new
    from right here. I did however expertise some technical points using this web site, since I experienced to reload the site many times previous to I could get it to load properly.
    I had been wondering if your hosting is OK?
    Not that I’m complaining, but sluggish loading instances times will
    very frequently affect your placement in google and can damage your high quality score if ads and marketing with Adwords.
    Well I am adding this RSS to my e-mail and
    could look out for a lot more of your respective fascinating
    content. Ensure that you update this again soon.

    | Reply Posted 1 year ago
  16. * Vile Sinaia says:

    Hotel Monaco Bucuresti

    bookmarked!!, I love your site!

    | Reply Posted 4 months ago


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: