,

Storing Deals in the Wallet

Deals are redeemable offers that the user can save to the Wallet and later present to a vendor for redemption.

To add a deal to the Wallet, create a new Deal object and call its SaveAsync method, as demonstrated:

Deal deal = new Deal(coupon.Id)
    {
        DisplayName = "10% off!",
        Description = "Get 10% any item purchased.",
        IssuerName = "Unleashed",
        IssuerWebsite = new Uri("http://example.com"),
        IsUsed = false,
        MerchantName = "Unleashed",
        TermsAndConditions = "Valid at participating locations only.",
        Code = "123454321",
        ExpirationDate = DateTime.Now.AddMonths(3)
    };

await deal.SaveAsync();


Note

The DisplayName property must be set to a non-empty string before calling SaveAsync, or an exception is raised.


The sample app for this section retrieves a list of available coupons from a WCF service and displays them on a page. The user may select one of the coupons to view it in greater detail and to save it to the Wallet’s Deals area.

The source code for this section is located in the WalletDealsAndMembership directory of the downloadable sample code.

The sample uses a custom class named Coupon. The CouponsViewModel retrieves the list of available coupons from the DealsAndMembership WCF service using the service’s GetCoupons method.

For the sake of simplicity, the service declares a list of dummy coupons, like so:

readonly List<Coupon> coupons = new List<Coupon>
    {
        new Coupon
            {
                Id = "1",
                Title = "$25 Off!",
                Description = "$25 off your next purchase!",
                ExpirationDate = new DateTime(2013, 8, 1),
                Terms = "Valid at participating locations only.",
                Code = "3425167",
                Base64Image = GetBase64ImageCoupon()
            },        new Coupon { ... },
        new Coupon { ... },
        new Coupon { ... },
    };

The service retrieves a sample barcode image for each coupon from within the assembly. The service then converts the image to a base-64 encoded string (see Listing 25.11).

Base-64 encoding is a way of taking binary data and turning it into text so that it is easier to transmit. Sending the image encoded in Base-64 prevents the data from being misinterpreted during transmission because raw binary data may contain special control characters.

LISTING 25.11. DealsAndMembershipService.GetBase64CouponImage Method


static string GetBase64CouponImage()
{
    Assembly assembly = Assembly.GetExecutingAssembly();

    using (Stream stream = assembly.GetManifestResourceStream(
        "DanielVaughan.WPUnleashed.DealsAndMembershipService.Barcode.bmp"))
    {
        BinaryReader br = new BinaryReader(stream);
        byte[] bytes = br.ReadBytes((int)stream.Length);
        string result = Convert.ToBase64String(bytes);
        return result;
    }
}


The CouponsViewModel retrieves the list of available coupons from the service. The CouponsViewModel.Load method populates an ObservableList with the Coupon objects returned from the DealsAndMembershipService, as shown in the following excerpt:

public async void Load()
{
    var service = (IDealsAndMembershipService)new DealsAndMembershipServiceClient();

    try
    {
        Coupons = await Task<ObservableCollection<Coupon>>.Factory.FromAsync(
            service.BeginGetCoupons, service.EndGetCoupons, null);
    }
    catch (Exception ex)
    {
        Debug.WriteLine("Unable to retrieve coupons." + ex);
    }
}

The CouponsViewModel contains a DelegateCommand<Coupon> named ViewCouponCommand that uses the base class’s INavigationService to navigate to the CouponView.xaml page, as shown:

void ViewCoupon(Coupon coupon)
{
    ArgumentValidator.AssertNotNull(coupon, "coupon");

    Navigate("/CouponView/CouponView.xaml?CouponId=" + coupon.Id);
}

The Deals pivot item on the MainPage.xaml displays each coupon within a ListBox. Tapping an item in the ListBox executes the viewmodel’s ViewCouponCommand via the custom commanding infrastructure, as shown:

<phone:PivotItem Header="Deals"
                    DataContext="{StaticResource couponsViewModel}">
    <ListBox ItemsSource="{Binding Coupons}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Margin="12,20,0,0"
                    c:Commanding.Command="{Binding ViewCouponCommand,
                        Source={StaticResource couponsViewModel}}"
                    c:Commanding.CommandParameter="{Binding}">
                    <TextBlock Text="{Binding Title}"
                           Style="{StaticResource PhoneTextLargeStyle}" />
                    <TextBlock Text="{Binding Description}"
                           Style="{StaticResource PhoneTextSmallStyle}"
                           Foreground="{StaticResource PhoneSubtleBrush}" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</phone:PivotItem>

The CouponView.xaml OnNavigatedTo method passes the query string dictionary containing the coupon ID to the CouponViewModel. The viewmodel’s Load method retrieves the ID from the query string dictionary and uses it to retrieve the Coupon object from the WCF service. See the following excerpt:

public async void Load(IDictionary<string, string> parameters)
{
    string couponId;

    if (!parameters.TryGetValue("CouponId", out couponId))
    {
        return;
    }

    var service = (IDealsAndMembershipService)
                    new DealsAndMembershipServiceClient();

    try
    {
        Coupon = await Task<Coupon>.Factory.FromAsync(
            service.BeginGetCoupon, service.EndGetCoupon, couponId, null);
    }
    catch (Exception ex)
    {
        Debug.WriteLine("Unable to retrieve coupon." + ex);
        MessageService.ShowError("Unable to retrieve coupon.");
    }

    Refresh();
}

The viewmodel converts the coupon’s Base-64 image string to a BitmapImage and assigns it to the Deal object’s BarcodeImage property. The CouponViewModel.AddToWallet method uses the Base64ToImageConverter to perform the conversion (see Listing 25.12). You look at this conversion process in more detail in a moment.

The AddToWallet method copies the coupon properties over to a new Deal object and saves it to the Wallet using the Deal class’s SaveAsync method.

LISTING 25.12. CouponViewModel.AddToWallet Method


async Task AddToWallet()
{
    bool successful = true;

    try
    {
        BitmapImage barcodeImage
            = Base64ToImageConverter.ConvertToBitmapImage(
                        coupon.Base64Image);

        Deal deal = new Deal(coupon.Id)
            {
                BarcodeImage = barcodeImage,
                DisplayName = coupon.Title,
                Description = coupon.Description,
                IssuerName = "Unleashed",
                IssuerWebsite = new Uri("http://example.com"),
                IsUsed = false,
                MerchantName = "Unleashed",
                TermsAndConditions = coupon.Terms,
                Code = coupon.Code,
                ExpirationDate = coupon.ExpirationDate
            };

        await deal.SaveAsync();
    }
    catch (Exception ex)
    {
        successful = false;
        Debug.WriteLine(ex.ToString());
        MessageService.ShowError("Unable to add deal to wallet.");
    }

    if (successful)
    {
        MessageService.ShowMessage("Deal added to wallet.");
    }
}


The coupon’s Base64Image is converted to a BitmapImage using the custom Base64ToImageConverter class (see Listing 25.13). The static ConvertToBitmapImage method accepts a string and converts it to a byte array, which is then used to create a Stream to initialize a new BitmapImage object.

The Base64ToImageConverter is an IValueConverter, which the view also uses to display the coupon’s barcode image.

LISTING 25.13. Base64ToImageConverter Class


public class Base64ToImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null)
        {
            return null;
        }

        string base64String = value.ToString();
        return ConvertToBitmapImage(base64String);
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    public static BitmapImage ConvertToBitmapImage(string base64EncodedImage)
    {
        byte[] imageBytes = System.Convert.FromBase64String(base64EncodedImage);
        using (MemoryStream stream
                        = new MemoryStream(imageBytes, 0, imageBytes.Length))
        {
            BitmapImage bitmapImage = new BitmapImage();
            bitmapImage.SetSource(stream);
            return bitmapImage;
        }
    }
}


Figure 25.6 shows a deal displayed in the Wallet. The Wallet retains the barcode image and displays it whenever the user navigates to the deal.

Image

FIGURE 25.6 Viewing a Deal in the Wallet Hub.

You remove a Deal from the Wallet in the same way as for other Wallet items: by calling the Wallet class’s static Remove method with the string ID of the Wallet item, as shown:

Wallet.Remove(coupon.Id);

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.79.241