Posts Tagged ‘Twitter’
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;
}
}
}


















