Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add the LazyTableImage example

  • Loading branch information...
commit 35efcf23253f2be43ad8b44b7d3212779be2d938 1 parent 53fa4bb
@alanmcgovern alanmcgovern authored
View
44 LazyTableImages/App.cs
@@ -0,0 +1,44 @@
+//
+// App.cs
+//
+// Author:
+// Alan McGovern <alan@xamarin.com>
+//
+// Copyright 2011, Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using MonoTouch.UIKit;
+
+namespace LazyTableImages {
+
+ public class App {
+
+ public string Artist { get; set; }
+
+ public UIImage Image { get; set; }
+
+ public Uri ImageUrl { get; set; }
+
+ public string Name { get; set; }
+
+ public Uri Url { get; set; }
+ }
+}
View
117 LazyTableImages/AppDelegate.cs
@@ -0,0 +1,117 @@
+//
+// AppDelegate.cs
+//
+// Author:
+// Alan McGovern <alan@xamarin.com>
+//
+// Copyright 2011, Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+using System.Net;
+using System.Collections.ObjectModel;
+
+namespace LazyTableImages {
+ /// <summary>
+ /// The UIApplicationDelegate for the application. This class is responsible for launching the
+ /// User Interface of the application, as well as listening (and optionally responding) to
+ /// application events from iOS.
+ /// </summary>
+
+ [Register ("AppDelegate")]
+ public partial class AppDelegate : UIApplicationDelegate {
+
+ static readonly Uri RssFeedUrl = new Uri ("http://phobos.apple.com/WebObjects/MZStoreServices.woa/ws/RSS/toppaidapplications/limit=75/xml");
+
+ UINavigationController NavigationController { get; set; }
+
+ RootViewController RootController { get; set; }
+
+ public override UIWindow Window { get; set; }
+
+
+ /// <summary>
+ /// This method is invoked when the application has loaded and is ready to run. In this
+ /// method you should instantiate the window, load the UI into it and then make the window
+ /// visible.
+ /// </summary>
+ /// <remarks>
+ /// You have 5 seconds to return from this method, or iOS will terminate your application.
+ /// </remarks>
+ public override bool FinishedLaunching (UIApplication app, NSDictionary options)
+ {
+ Window = new UIWindow (UIScreen.MainScreen.Bounds);
+ RootController = new RootViewController ("RootViewController", null);
+ NavigationController = new UINavigationController (RootController);
+ Window.RootViewController = NavigationController;
+
+ // make the window visible
+ Window.MakeKeyAndVisible ();
+
+ BeginDownloading ();
+ return true;
+ }
+
+ void BeginDownloading ()
+ {
+ // Show the user that data is about to be downloaded
+ UIApplication.SharedApplication.NetworkActivityIndicatorVisible = true;
+
+ // Retrieve the rss feed from the server
+ var downloader = new WebClient ();
+ downloader.DownloadStringCompleted += DownloadCompleted;
+ downloader.DownloadStringAsync (RssFeedUrl);
+ }
+
+ void DownloadCompleted (object sender, DownloadStringCompletedEventArgs e)
+ {
+ // The WebClient will invoke the DownloadStringCompleted event on a
+ // background thread. We want to do UI updates with the result, so process
+ // the result on the main thread.
+ UIApplication.SharedApplication.BeginInvokeOnMainThread (() => {
+ // First disable the download indicator
+ UIApplication.SharedApplication.NetworkActivityIndicatorVisible = false;
+
+ // Now handle the result from the WebClient
+ if (e.Error != null) {
+ DisplayError ("Warning", "The rss feed could not be downloaded");
+ } else {
+ try {
+ RootController.Apps.Clear ();
+ foreach (var v in RssParser.Parse (e.Result))
+ RootController.Apps.Add (v);
+ } catch {
+ DisplayError ("Warning", "Malformed Xml was found in the Rss Feed.");
+ }
+ }
+ });
+ }
+
+ void DisplayError (string title, string errorMessage, params object[] formatting)
+ {
+ var alert = new UIAlertView (title, string.Format (errorMessage, formatting), null, "ok", null);
+ alert.Show ();
+ }
+ }
+}
View
BIN  LazyTableImages/Images/Placeholder.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
12 LazyTableImages/Info.plist
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+</dict>
+</plist>
View
87 LazyTableImages/LazyTableImages.csproj
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
+ <ProductVersion>10.0.0</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{4D3A8E8A-53D4-4CF5-97D6-9E6199DDB582}</ProjectGuid>
+ <ProjectTypeGuids>{6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <OutputType>Exe</OutputType>
+ <RootNamespace>LazyTableImages</RootNamespace>
+ <AssemblyName>LazyTableImages</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
+ <DefineConstants>DEBUG</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <ConsolePause>false</ConsolePause>
+ <MtouchLink>None</MtouchLink>
+ <MtouchDebug>true</MtouchDebug>
+ <MtouchI18n />
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
+ <DebugType>none</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\iPhoneSimulator\Release</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <ConsolePause>false</ConsolePause>
+ <MtouchLink>None</MtouchLink>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\iPhone\Debug</OutputPath>
+ <DefineConstants>DEBUG</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <ConsolePause>false</ConsolePause>
+ <MtouchDebug>true</MtouchDebug>
+ <CodesignKey>iPhone Developer</CodesignKey>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
+ <DebugType>none</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\iPhone\Release</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <ConsolePause>false</ConsolePause>
+ <CodesignKey>iPhone Developer</CodesignKey>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Core" />
+ <Reference Include="monotouch" />
+ <Reference Include="System.Xml.Linq" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Info.plist" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Main.cs" />
+ <Compile Include="AppDelegate.cs" />
+ <Compile Include="RootViewController.cs" />
+ <Compile Include="RootViewController.designer.cs">
+ <DependentUpon>RootViewController.cs</DependentUpon>
+ </Compile>
+ <Compile Include="App.cs" />
+ <Compile Include="RssParser.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <InterfaceDefinition Include="RootViewController.xib" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <ItemGroup>
+ <Folder Include="Images\" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Images\Placeholder.png" />
+ </ItemGroup>
+</Project>
View
20 LazyTableImages/Main.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+
+namespace LazyTableImages {
+
+ public class Application {
+ /// <summary>
+ /// This is the main entry point of the application.
+ /// </summary>
+ static void Main (string[] args)
+ {
+ // if you want to use a different Application Delegate class from "AppDelegate"
+ // you can specify it here.
+ UIApplication.Main (args, null, "AppDelegate");
+ }
+ }
+}
View
181 LazyTableImages/RootViewController.cs
@@ -0,0 +1,181 @@
+//
+// RootViewController.cs
+//
+// Author:
+// Alan McGovern <alan@xamarin.com>
+//
+// Copyright 2011, Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Drawing;
+using System.Linq;
+using MonoTouch.UIKit;
+using MonoTouch.Foundation;
+using System.Collections.ObjectModel;
+using System.Threading.Tasks;
+using System.Net;
+using System.Threading;
+
+namespace LazyTableImages {
+
+ public partial class RootViewController : UITableViewController {
+
+ public ObservableCollection<App> Apps { get; private set; }
+
+ public RootViewController (string nibName, NSBundle bundle) : base (nibName, bundle)
+ {
+ Apps = new ObservableCollection<App> ();
+ Title = NSBundle.MainBundle.LocalizedString ("Top 75 Apps", "Master");
+ }
+
+ public override void ViewDidLoad ()
+ {
+ base.ViewDidLoad ();
+
+ TableView.Source = new DataSource (this);
+ }
+
+ public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
+ {
+ return (toInterfaceOrientation != UIInterfaceOrientation.PortraitUpsideDown);
+ }
+
+ public override void DidReceiveMemoryWarning ()
+ {
+ // Release all cached images. This will cause them to be redownloaded
+ // later as they're displayed.
+ foreach (var v in Apps)
+ v.Image = null;
+ }
+
+ class DataSource : UITableViewSource {
+
+ RootViewController Controller { get; set; }
+ Task DownloadTask { get; set; }
+ UIImage PlaceholderImage { get; set; }
+
+ public DataSource (RootViewController controller)
+ {
+ Controller = controller;
+
+ // Listen for changes to the Apps collection so the TableView can be updated
+ Controller.Apps.CollectionChanged += HandleAppsCollectionChanged;
+ // Initialise DownloadTask with an empty and complete task
+ DownloadTask = Task.Factory.StartNew (() => { });
+ // Load the Placeholder image so it's ready to be used immediately
+ PlaceholderImage = UIImage.FromFile ("Images/Placeholder.png");
+
+ // If either a download fails or the image we download is corrupt, ignore the problem.
+ TaskScheduler.UnobservedTaskException += delegate(object sender, UnobservedTaskExceptionEventArgs e) {
+ e.SetObserved ();
+ };
+ }
+
+ void HandleAppsCollectionChanged (object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
+ {
+ // Whenever the Items change, reload the data.
+ Controller.TableView.ReloadData ();
+ }
+
+ public override int NumberOfSections (UITableView tableView)
+ {
+ return 1;
+ }
+
+ public override int RowsInSection (UITableView tableview, int section)
+ {
+ return Controller.Apps.Count;
+ }
+
+ // Customize the appearance of table view cells.
+ public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
+ {
+ UITableViewCell cell;
+ // If the list is empty, put in a 'loading' entry
+ if (Controller.Apps.Count == 0 && indexPath.Row == 0) {
+ cell = tableView.DequeueReusableCell ("Placeholder");
+ if (cell == null) {
+ cell = new UITableViewCell (UITableViewCellStyle.Subtitle, "Placeholder");
+ cell.DetailTextLabel.TextAlignment = UITextAlignment.Center;
+ cell.SelectionStyle = UITableViewCellSelectionStyle.None;
+ cell.DetailTextLabel.Text = "Loading";
+ }
+ return cell;
+ }
+
+ cell = tableView.DequeueReusableCell ("Cell");
+ if (cell == null) {
+ cell = new UITableViewCell (UITableViewCellStyle.Subtitle, "Cell");
+ cell.SelectionStyle = UITableViewCellSelectionStyle.None;
+ }
+
+ // Set the tag of each cell to the index of the App that
+ // it's displaying. This allows us to directly match a cell
+ // with an item when we're updating the Image
+ var app = Controller.Apps [indexPath.Row];
+ cell.Tag = indexPath.Row;
+ cell.TextLabel.Text = app.Name;
+ cell.DetailTextLabel.Text = app.Artist;
+
+ // If the Image for this App has not been downloaded,
+ // use the Placeholder image while we try to download
+ // the real image from the web.
+ if (app.Image == null) {
+ app.Image = PlaceholderImage;
+ BeginDownloadingImage (app, indexPath);
+ }
+ cell.ImageView.Image = app.Image;
+ return cell;
+ }
+
+ void BeginDownloadingImage (App app, NSIndexPath path)
+ {
+ // Queue the image to be downloaded. This task will execute
+ // as soon as the existing ones have finished.
+ byte[] data = null;
+ DownloadTask = DownloadTask.ContinueWith (prevTask => {
+ try {
+ UIApplication.SharedApplication.NetworkActivityIndicatorVisible = true;
+ using (var c = new WebClient ())
+ data = c.DownloadData (app.ImageUrl);
+ } finally {
+ UIApplication.SharedApplication.NetworkActivityIndicatorVisible = false;
+ }
+ });
+
+ // When the download task is finished, queue another task to update the UI.
+ // Note that this task will run only if the download is successful and it
+ // uses the CurrentSyncronisationContext, which on MonoTouch causes the task
+ // to be run on the main UI thread. This allows us to safely access the UI.
+ DownloadTask = DownloadTask.ContinueWith (t => {
+ // Load the image from the byte array.
+ app.Image = UIImage.LoadFromData (NSData.FromArray (data));
+
+ // Retrieve the cell which corresponds to the current App. If the cell is null, it means the user
+ // has already scrolled that app off-screen.
+ var cell = Controller.TableView.VisibleCells.Where (c => c.Tag == Controller.Apps.IndexOf (app)).FirstOrDefault ();
+ if (cell != null)
+ cell.ImageView.Image = app.Image;
+ }, CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.FromCurrentSynchronizationContext ());
+ }
+ }
+ }
+}
View
14 LazyTableImages/RootViewController.designer.cs
@@ -0,0 +1,14 @@
+// WARNING
+//
+// This file has been generated automatically by MonoDevelop to store outlets and
+// actions made in the Xcode designer. If it is removed, they will be lost.
+// Manual changes to this file may not be handled correctly.
+//
+using MonoTouch.Foundation;
+
+namespace LazyTableImages {
+
+ [Register ("RootViewController")]
+ partial class RootViewController {
+ }
+}
View
384 LazyTableImages/RootViewController.xib
@@ -0,0 +1,384 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">784</int>
+ <string key="IBDocument.SystemVersion">10D541</string>
+ <string key="IBDocument.InterfaceBuilderVersion">760</string>
+ <string key="IBDocument.AppKitVersion">1038.29</string>
+ <string key="IBDocument.HIToolboxVersion">460.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">81</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="2"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="841351856">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBProxyObject" id="371349661">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUITableView" id="709618507">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrameSize">{320, 247}</string>
+ <reference key="NSSuperview"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <bool key="IBUIBouncesZoom">NO</bool>
+ <int key="IBUISeparatorStyle">1</int>
+ <int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
+ <bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
+ <float key="IBUIRowHeight">44</float>
+ <float key="IBUISectionHeaderHeight">22</float>
+ <float key="IBUISectionFooterHeight">22</float>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="709618507"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">dataSource</string>
+ <reference key="source" ref="709618507"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">4</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="709618507"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">5</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <reference key="object" ref="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="841351856"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="371349661"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">2</int>
+ <reference key="object" ref="709618507"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>2.IBEditorWindowLastContentRect</string>
+ <string>2.IBPluginDependency</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>RootViewController</string>
+ <string>UIResponder</string>
+ <string>{{144, 609}, {320, 247}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">5</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">RootViewController</string>
+ <string key="superclassName">UITableViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">RootViewController.h</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSNetServices.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSPort.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSStream.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSXMLParser.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="654420027">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIResponder</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="654420027"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIScrollView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIScrollView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchDisplayController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableView</string>
+ <string key="superclassName">UIScrollView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITableView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITableViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <integer value="784" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3100" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <string key="IBDocument.LastKnownRelativeProjectPath">MasterDetailIPhone.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <string key="IBCocoaTouchPluginVersion">81</string>
+ </data>
+</archive>
View
80 LazyTableImages/RssParser.cs
@@ -0,0 +1,80 @@
+//
+// RssParser.cs
+//
+// Author:
+// Alan McGovern <alan@xamarin.com>
+//
+// Copyright 2011, Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Linq;
+using System.Xml.Linq;
+using System.Collections.Generic;
+
+namespace LazyTableImages {
+
+ public static class RssParser {
+
+ // These are used to select the correct nodes and attributes from the Rss feed
+ static readonly XName FeedElement = XName.Get ("feed", "http://www.w3.org/2005/Atom");
+ static readonly XName EntryElement = XName.Get ("entry", "http://www.w3.org/2005/Atom");
+ static readonly XName AppUrlElement = XName.Get ("id", "http://www.w3.org/2005/Atom");
+
+ static readonly XName AppNameElement = XName.Get ("name", "http://itunes.apple.com/rss");
+ static readonly XName ArtistElement = XName.Get ("artist", "http://itunes.apple.com/rss");
+ static readonly XName ImageUrlElement = XName.Get ("image", "http://itunes.apple.com/rss");
+
+ static readonly XName HeightAttribute = XName.Get ("height", "");
+
+ public static List<App> Parse (string xml)
+ {
+ // Open the xml
+ var doc = XDocument.Parse (xml);
+
+ // We want to convert all the raw Xml nodes called 'entry' which
+ // are in that namespace into instances of the 'App' class so they
+ // can be displayed easily in the table.
+ return doc.Element (FeedElement) // Select the 'feed' node.
+ .Elements (EntryElement) // Select all children with the name 'entry'.
+ .Select (XmlElementToApp) // Convert the 'entry' nodes to instances of the App class.
+ .ToList (); // Return as a List<App>.
+ }
+
+ static App XmlElementToApp (XElement entry)
+ {
+ // The document may contain many image nodes. Select the one with
+ // the largest resolution.
+ var imageUrlNode = entry.Elements (ImageUrlElement)
+ .Where (n => n.Attribute (HeightAttribute) != null)
+ .OrderBy (node => int.Parse (node.Attribute (HeightAttribute).Value))
+ .LastOrDefault ();
+
+ // Parse the rest of the apps information from the XElement and
+ // return the App instance.
+ return new App {
+ Name = entry.Element (AppNameElement).Value,
+ Url = new Uri (entry.Element (AppUrlElement).Value),
+ Artist = entry.Element (ArtistElement).Value,
+ ImageUrl = new Uri (imageUrlNode.Value)
+ };
+ }
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.