Added a new async sample for LazyTableImages

The sample uses the new async feature to download the application
images.
This commit is contained in:
Ryan Alford 2013-11-02 10:13:42 -04:00
Родитель d140cd357f
Коммит 97669e1576
32 изменённых файлов: 1026 добавлений и 0 удалений

Просмотреть файл

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

Просмотреть файл

@ -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 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 GzipWebClient ();
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: " + e.Error.Message);
} 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 ();
}
}
}

Просмотреть файл

@ -0,0 +1,17 @@
using System;
using System.Net;
namespace LazyTableImages
{
public class GzipWebClient : WebClient
{
protected override WebRequest GetWebRequest (Uri address)
{
var request = base.GetWebRequest (address);
if (request is HttpWebRequest)
((HttpWebRequest) request).AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
return request;
}
}
}

Двоичные данные
LazyTableImagesAsync/Images/Placeholder.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 711 B

Просмотреть файл

@ -0,0 +1,23 @@
<?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>CFBundleIconFiles</key>
<array>
<string>Resources/icon-57.png</string>
<string>Resources/icon-114.png</string>
<string>Resources/icon-72.png</string>
<string>Resources/icon-144.png</string>
<string>Resources/icon-29.png</string>
<string>Resources/icon-58.png</string>
<string>Resources/icon-50.png</string>
<string>Resources/icon-100.png</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

Просмотреть файл

@ -0,0 +1,110 @@
<?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" />
<Compile Include="GzipWebClient.cs" />
</ItemGroup>
<ItemGroup>
<InterfaceDefinition Include="RootViewController.xib" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<Folder Include="Images\" />
<Folder Include="Resources\" />
</ItemGroup>
<ItemGroup>
<Content Include="Images\Placeholder.png" />
</ItemGroup>
<ItemGroup>
<BundleResource Include="Resources\icon-72.png" />
<BundleResource Include="Resources\icon-29.png" />
<BundleResource Include="Resources\icon-50.png" />
<BundleResource Include="Resources\icon-58.png" />
<BundleResource Include="Resources\icon-100.png" />
<BundleResource Include="Resources\iTunesArtwork%402x.png" />
<BundleResource Include="Resources\Default-568h%402x.png" />
<BundleResource Include="Resources\Default-Landscape%402x~ipad.png" />
<BundleResource Include="Resources\Default-Landscape~ipad.png" />
<BundleResource Include="Resources\Default-Portrait%402x~ipad.png" />
<BundleResource Include="Resources\Default-Portrait~ipad.png" />
<BundleResource Include="Resources\Default.png" />
<BundleResource Include="Resources\Default%402x.png" />
<BundleResource Include="Resources\icon-57.png" />
<BundleResource Include="Resources\icon-114.png" />
<BundleResource Include="Resources\icon-144.png" />
</ItemGroup>
<ItemGroup>
<ITunesArtwork Include="Resources\iTunesArtwork.png" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LazyTableImages", "LazyTableImages.csproj", "{4D3A8E8A-53D4-4CF5-97D6-9E6199DDB582}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|iPhoneSimulator = Debug|iPhoneSimulator
Release|iPhoneSimulator = Release|iPhoneSimulator
Debug|iPhone = Debug|iPhone
Release|iPhone = Release|iPhone
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4D3A8E8A-53D4-4CF5-97D6-9E6199DDB582}.Debug|iPhone.ActiveCfg = Debug|iPhone
{4D3A8E8A-53D4-4CF5-97D6-9E6199DDB582}.Debug|iPhone.Build.0 = Debug|iPhone
{4D3A8E8A-53D4-4CF5-97D6-9E6199DDB582}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{4D3A8E8A-53D4-4CF5-97D6-9E6199DDB582}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{4D3A8E8A-53D4-4CF5-97D6-9E6199DDB582}.Release|iPhone.ActiveCfg = Release|iPhone
{4D3A8E8A-53D4-4CF5-97D6-9E6199DDB582}.Release|iPhone.Build.0 = Release|iPhone
{4D3A8E8A-53D4-4CF5-97D6-9E6199DDB582}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{4D3A8E8A-53D4-4CF5-97D6-9E6199DDB582}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = LazyTableImages.csproj
EndGlobalSection
EndGlobal

Просмотреть файл

@ -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");
}
}
}

Просмотреть файл

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<SampleMetadata>
<ID>4912a5a3-7b98-4886-9d50-1b0c417f6037</ID>
<IsFullApplication>false</IsFullApplication>
<Level>Beginning</Level>
<Tags>User Interface, Web, Graphics</Tags>
</SampleMetadata>

Просмотреть файл

@ -0,0 +1,4 @@
Lazy Table Images
=================
This sample demonstrates how to lazily download images and add them to a prepopulated table.

Двоичные данные
LazyTableImagesAsync/Resources/Default-568h@2x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 12 KiB

Двоичные данные
LazyTableImagesAsync/Resources/Default-Landscape@2x~ipad.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 24 KiB

Двоичные данные
LazyTableImagesAsync/Resources/Default-Landscape~ipad.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 9.4 KiB

Двоичные данные
LazyTableImagesAsync/Resources/Default-Portrait@2x~ipad.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 25 KiB

Двоичные данные
LazyTableImagesAsync/Resources/Default-Portrait~ipad.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 9.8 KiB

Двоичные данные
LazyTableImagesAsync/Resources/Default.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.2 KiB

Двоичные данные
LazyTableImagesAsync/Resources/Default@2x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 12 KiB

Двоичные данные
LazyTableImagesAsync/Resources/iTunesArtwork.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 106 KiB

Двоичные данные
LazyTableImagesAsync/Resources/iTunesArtwork@2x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 273 KiB

Двоичные данные
LazyTableImagesAsync/Resources/icon-100.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 11 KiB

Двоичные данные
LazyTableImagesAsync/Resources/icon-114.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 14 KiB

Двоичные данные
LazyTableImagesAsync/Resources/icon-144.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 18 KiB

Двоичные данные
LazyTableImagesAsync/Resources/icon-29.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.0 KiB

Двоичные данные
LazyTableImagesAsync/Resources/icon-50.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.2 KiB

Двоичные данные
LazyTableImagesAsync/Resources/icon-57.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.1 KiB

Двоичные данные
LazyTableImagesAsync/Resources/icon-58.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.2 KiB

Двоичные данные
LazyTableImagesAsync/Resources/icon-72.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.6 KiB

Просмотреть файл

@ -0,0 +1,180 @@
//
// 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;
}
async 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;
data = await GetImageData (app);
app.Image = UIImage.LoadFromData (NSData.FromArray (data));
InvokeOnMainThread (() => {
var cell = Controller.TableView.VisibleCells.Where (c => c.Tag == Controller.Apps.IndexOf (app)).FirstOrDefault ();
if (cell != null)
cell.ImageView.Image = app.Image;
});
}
async Task<byte[]> GetImageData(App app)
{
byte[] data = null;
try {
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = true;
using (var c = new GzipWebClient ())
data = await c.DownloadDataTaskAsync (app.ImageUrl);
} finally {
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = false;
}
return data;
}
}
}
}

14
LazyTableImagesAsync/RootViewController.designer.cs сгенерированный Normal file
Просмотреть файл

@ -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 {
}
}

Просмотреть файл

@ -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>

Просмотреть файл

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

Двоичные данные
LazyTableImagesAsync/Screenshots/LazyTableImages.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 192 KiB