Converge updated to use new aggregator service

Converge

TLDR: Get latest app update from store to continue using Converge starting next month.

Converge was built using parse.com, which was great until Facebook bought and decided to shut it down. ūüėĪ Since the announcement last year, I have looked at alternative “back-end as a service” offerings to replace parse.com but couldn’t find anything as good and free. After all, Converge is a free app without any ads so didn’t make any sense to spend $$$ every month.

I finally decided to build my own back-end service to also change the news aggregation infrastructure which can scale to many more news publishers without ongoing additional work, and be almost real time. The initial version was finally complete last week including the app changes required to use the new service. All these changes are now live. Yay!

To continue using Converge once parse.com shuts down at the end of this month, you will need to download the latest version from store.

Now that the app and aggregation service are¬†live, I am hoping to add more publishers and bring Converge to other platforms very soon, starting with Android. Eventually, Converge will need to make money to pay for server costs but that can be figured out later.¬†ūüėä

Cheers!

image credit: wpcentral

Notifying users when app update is available in Windows Phone store

Ensuring that users of your app are on latest version is critically important. I have seen users reporting issues and requesting features which were implemented a few updates ago. With Windows Phone 8.1, users can enable automatic app updates installation but for users who are still on Windows 8 or who do not enable automatic updates, the responsibility is on you, as a developer.

Unfortunately, there is no support in Windows Phone SDK to find out if there is a new version of the current app in store or what version is available in store. For the¬†converge app, I was looking to solve this issue so I traced store app’s network traffic using Fiddler to understand the available APIs. Looking at the network traffic, the API used by store app is fairly obvious. Here is the API request Windows Phone 8 store app sends for app details.

GET http://marketplaceedgeservice.windowsphone.com/v8/catalog/apps/b658425e-ba4c-4478-9af3-791fd0f1abfe?os=8.0.10521.0&cc=US&lang=en-US&hw=520208901&dm=RM-940_nam_att_200&oemId=NOKIA&moId=att-us&cf=99-1
Accept: */*
Accept-Encoding: gzip
User-Agent: ZDM/4.0; Windows Mobile 8.0
X-WP-Client-Config-Version: 107
X-WP-MO-Config-Version: 1224
X-WP-Device-ID: ****
X-WP-ImpressionId: ****:API.BDIGeneric
X-WP-ImpressionK: 5

You don’t need to send all headers or parameters in requests. The response to this call has complete details for your application in the target country/language in xml format. From here on, you can use LINQ to XML to get the data you need to know what version is available in store. Here is slightly modified version of the code I use in the converge app. Feel free to reuse.

//This code has dependency on Microsoft.Net.Http NuGet package.
public async Task CheckUpdate()
{
    const string storeAppDetailsUri = "http://marketplaceedgeservice.windowsphone.com/v8/catalog/apps/b658425e-ba4c-4478-9af3-791fd0f1abfe?os={0}&cc={1}&lang={2}";

    var updatedAvailable = false;

    try
    {
        var osVersion = Environment.OSVersion.Version.ToString(4);
        var lang = CultureInfo.CurrentCulture.Name;
        var countryCode = lang.Length == 5 ? lang.Substring(3) : "US";

        using (var message = new HttpRequestMessage(HttpMethod.Get, string.Format(storeAppDetailsUri, osVersion, countryCode, lang)))
        {
            message.Headers.Add("User-Agent", "Windows Mobile 8.0");

            using (var client = new HttpClient())
            {
                var response = await client.SendAsync(message);
                if (response.StatusCode != HttpStatusCode.OK) return;

                using (var stream = await response.Content.ReadAsStreamAsync())
                {
                    XNamespace atom = "http://www.w3.org/2005/Atom";
                    XNamespace apps = "http://schemas.zune.net/catalog/apps/2008/02";

                    var doc = XDocument.Load(stream);
                    if (doc.Document == null) return;

                    var entry = doc.Document.Descendants(atom + "feed")
                        .Descendants(atom + "entry")
                        .FirstOrDefault();

                    if (entry == null) return;

                    var versionElement = entry.Elements(apps + "version").FirstOrDefault();
                    if (versionElement == null) return;

                    Version storeVersion;

                    if (Version.TryParse(versionElement.Value, out storeVersion))
                    {
                        var currentVersion = new AssemblyName(Assembly.GetExecutingAssembly().FullName).Version;

                        updatedAvailable = storeVersion > currentVersion;
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {
        // HANDLE ERROR HERE. THERE IS NO POINT IN SHOWING USER A MESSAGE. GOOD PLACE TO SEND SILENT ERROR REPORT OR JUST SWALLOW THE EXCEPTION.
        Debug.WriteLine(ex);
    }

    if (updatedAvailable)
    {
        // APP UPDATE IS AVAILABLE. SHOW FIREWORKS IN APP OR JUST OPEN STORE APP TO UPDATE THE APP AFTER USER'S CONSENT.
    }
}

This is definitely not a documented and supported API¬† but considering there are millions of devices using this API, I doubt this will break in foreseeable future. I just don’t understand why Windows Phone team¬†doesn’t make this API public and have folks build stuff on top of it. They have struggled to produce a good store experience since Windows Phone launched anyways. For Windows 8, the APIs are as useless as the store app is so don’t bother trying to do something similar there.

A side note: regardless of how good you think the updates are, don’t update the app too frequently (multiple times in a week) ¬†if you have this notification implemented in the app. This becomes annoying and users start reporting it in reviews. This happened when I had to release multiple updates in a week to resolve content infringement complaints submitted by The Verge.

Hope this help.

Update on The Verge app

Converge

UPDATE: I have not received any further response/complaint from The Verge. Considering I have resolved the complaints they submitted to Microsoft in last app update and received their commitment to support the app previously (as explained below), I have published the app again in store. If The Verge has any feedback or want to discuss anything, I welcome them to reach out to me. You have my commitment to work with you to make this app serve your readers in a way which works for everyone.

The Verge is one of my favorite tech news sites. There are always¬†controversies around who likes which product or tech company but overall, The Verge seems on point most of the¬†time. I read that site so much that I created an app for myself as their mobile site isn’t good. Later when I shared the app in The Verge reader community, a lot of folks liked the app and asked if I could add more features. Now, adding features and making an app worth using takes some serious efforts and commitment.

One thing I learned by watching apps come and go is that one shouldn’t¬†develop an unofficial app unless the service has public APIs or you are partnering with the team who owns the¬†service.

  • First, building a brand and service which people want to use takes your sweat and blood. As a 3rd party developer, you shouldn’t use someone else’s work to succeed.
  • Second, even if you don’t agree with the¬†first point, you can, and you will, be forced to remove the app and your efforts will be wasted.

But if you are partnering, that is really a worthy gig. I absolutely loved working with the amazing team at Khan Academy to develop apps for Windows 8 and Windows Phone

Considering these points, I reached out to the Vox Media (owner of The Verge)¬†engineering team to see if they wanted to partner. They loved the app but after their internal discussion, they chose not to collaborate in any way. Their ask was to not use The Verge branding and they wouldn’t have problem with the app. I was bummed but fully respected their decision and started a thread in The Verge forums to get ideas on a new name.

In this same thread,¬†Nilay confirmed that they love the app and want me to continue improving it. Not only that, this was repeated in their weekly verge cast video. As long as the app didn’t use their branding, they would fully support it. This thread has been removed from the forums now. In fact, The Verge has been removing or locking threads which discuss this app in their forums.

With that confirmation, I started adding features in the app.¬†It took hundreds of hours from my weekends and nights but the results were very satisfying, just look at the reviews posted by users. With the most recent update which includes support for adding comments, app is¬†at par with The Verge’s official apps on other platforms.

Yesterday, I received email from Microsoft Store team that The Verge has submitted content infringement complaint against the app for using their name and logo. This is something I had agreed to fix but didn’t change yet so I unpublished the app from store and updated the app to not use there branding. It seems the feature to include app signature while commenting also caused some frustration for the verge staff but they never reached out to me to resolve that or asked to remove the feature.

Once their reported issues were fixed, I reached out to Vox Media lawyer to make sure they are ok with the fixes I have made. They were happy to know that I had removed their branding but, surprisingly, also mentioned that they don’t want this app to distribute their copyrighted content. I explained that this app is like any other thousands of news reader apps which allow users to read content from sites. I am not taking their content and re-publishing or distributing it. They don’t seem to agree with it even though they mentioned that an app like Feedly is ok. How is my app different from Feddly, they don’t mention that. Why are they doing this, I don’t know. But agreeing to supporting the app and now pulling that support¬†is beyond me. It has definitely caused a lot of stress for me.

I have again reached out to their lawyer as well as other folks in their leadership team. I am hoping to hear from them so that this can be resolved and app can be made available in store again. Technically, I have fixed the issues they complained about and I am free to publish the app until they submit another complaint. There is no point in cat and mouse game though so I want to resolve this issue before making the app available again.

By the way, the update with new name and logo is already visible in the store. You can check it out using the deep link as app is not available in search results or lists.

Feel free to chime-in in comments or on twitter if you have feedback or want to share your support.

The Verge app for Windows Phone

If you are part of the technology world, there is a good chance you read The Verge for getting your fix of news, reviews and their fantastic long reads not only related to technology but also science, art and culture. If want to do that on a Windows Phone though, there are no good options. Until now.

The Verge

Over the last few weekends, I have built a new app for Windows Phone for consuming everything The Verge has to offer. Here are the features it currently supports.

  • Super smooth experience for browsing and reading all the latest news, reviews, features, and exclusives.
  • Read comments posted by The Verge readers.
  • Watch “On The Verge,” “The Vergecast,” “Small Empires,” and more without ever leaving the app.
  • Share news and stories with your friends via Facebook, Twitter, and email.

More features like forums and live tiles are not implemented in the app just yet but I plan to add these over the coming weeks. Feel free to suggest or vote on feature requests on the feedback site. Here is some feedback from the community so far.

Great. The best by far. Great design. Better and more good looking than the android app.

As much as most of The Verge crew don’t like WP, this is a great app to prove how good it can be.

I suddenly feel like we don’t need an official app anymore. Awesome.

Obviously, the app is neither sponsored nor endorsed by The Verge or Vox Media.

Khan Academy on Windows 8: Now Open Source

Khan Academy app launched with Windows 8 last October. A few of us worked together to get the first version developed just in time for Windows 8 launch. Since then, there have been a few minor updates and a big overhaul which was published in store last month. This week is another great milestone: the app is now open source and ready for anyone to contribute.

KhanAcademyInStore

How We Got Here

I developed the initial version with a lot of help from folks over at Khan Academy and an internal Microsoft team. It was really a port of Learning Circle phone app to Windows 8 so naturally, this was developed using C# and XAML.

Later last year, a few more folks from Microsfot and BGC3 stepped up to help and we got some funding. That helped to get Pixel Lab team involved with development and after working on it for a few months,  the next version of the app was published in store last month. This new version was developed in HTML5/JavaScript and this is what we open sourced this week.

Get Involved

If you have experience in developing Windows 8 apps using HTML5 and JavaScript, come join us in making a great Khan Academy app for Windows 8. In addition to HTML5 and JavaScript, having good understanding of WinJS, WinRT, TypeScript and web in general would be great. If you don’t have development experience, you can still help with testing.

Let’s Go!

Learning Circle update is now in Windows Phone Store

Learning circle has been in Windows Phone store for over a year now and it has been very well received with consistent 4+ star rating in many markets. I finally managed to submit an update for the app which cleared store certification today.

Learning Circle Panorama

So, what’s new in this release:

  • Removed ads.¬†When I created the app, I made the decision to host a service to support the app which has costs. I wanted to make sure I don’t end up paying for that out of my pocket as the app is free so ads were really a safety net. For months, cost for hosting the service hasn’t been a problem so I decided to get out of the way of learners and leave them alone with Khan Academy’s legendary content. I’m not a big fan of ads anyways.
  • Updated content library with recent additions at Khan Academy and Channel 9.
  • A few other usability improvements such as multi-select list on downloads page.

If you use learning circle on Windows Phone, you should definitely update to the latest version from store. Let me know if you have any feedback.

Using and Customizing Player Framework in Windows 8 Xaml Apps

If you are creating media apps targeting Xaml frameworks i.e. apps which playback media especially videos, you start with MediaElement control. As you start using it, you’d probably search for properties to enable playback controls (play, pause, seek bar et al) to learn that there¬†are none. That’s right, MediaElement just plays video in a rectangle for an assigned source and you are supposed to build everything else yourself.

Using MediaPlayer from Player Framework

Depending on your requirements, building a video player can be difficult and time consuming. But before you start building one yourself, you should look at Player Framework on codeplex, a set of great player controls for Windows 8, HTML5, Silverlight and Windows Phone. The project is managed by Microsoft and being continuously improved upon. The player controls in this framework have rich set of features and you probably won’t have to build one yourself. To get started, check out the documentation and samples on codeplex to learn more about all the features it supports including IIS smooth streaming, closed captioning, ads and more.

MediaPlayer control in the player framework comes with inbuilt playback controls which are good to start with. Refer the getting started documentation for using player framework in your app. Here is the experience provided by the default controls.

DefaultPlayerControls

Using Windows 8 Style Playback Controls

For Windows 8 apps, you’d want to use playback controls with a modern Windows 8 user experience with full screen overlay controls similar to the the default Video app or Khan Academy app.¬†The MediaPlayer control¬†ships with an entertainment theme for getting better playback controls. To enable entertainment theme, all¬†we need to do is add entertainment theme to our page where we are using MediaPlayer control using Xaml markup as shown below. Checkout the documentation on Applying Theme¬†for more customization options.

<Page.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="ms-appx:///Microsoft.PlayerFramework/themes/EntertainmentTheme.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Page.Resources>

With the entertainment theme, you get solid UI improvement over default playback controls.
EntertainmentThemeControls

Customizing Template of Playback Controls

Now that we have good understanding of using MediaPlayer control and it’s out of the box entertainment theme, let‚Äôs look at the options to customize the playback control UI. The MediaPlayer control is designed using MVVM pattern which means that the views are completely separate from the behavior and the views are template driven. This makes the control extremely flexible for customizations as¬†you can define a completely new template for playback controls and replace the default template. In fact, that’s what we did above by replacing the default template with the one in entertainment theme. Let’s customize the entertainment theme playback controls further and use them in our app. To start, we’ll make a copy of the entertainment theme in our app and customize the template. As an example here, we will use dark red color for the slider pushpin rather than the default color.

  • First, locate the EntertainmentTheme.xaml which is installed with player framework and also gets copied to your app’s output directory during compilation at <approot>\bin\Debug\AppX\Microsoft.PlayerFramework\Themes folder. You can also get it from installation folder located at <drive>:\Program Files (x86)\Microsoft SDKs\Windows\v8.0\ExtensionSDKs\Microsoft.PlayerFramework.Xaml\<version>\ Redist\CommonConfiguration\neutral\Microsoft.PlayerFramework\Themes.
  • Once you have located the file, add it you project in visual studio. If you don’t know how, use either of these options
    • from Visual Studio, use “Add Existing Item” item from context menu in solution explorer, or
    • copy the file to you app folder in file explorer, enable “Show All Files” from the toolbar in solution explorer and use “Include In Project” item from context menu for the file you need to add.
  • Update the Xaml markup of the player page shown above to use the EntertainmentTheme.xaml from project instead of player framework dll.
    <Page.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Common/EntertainmentTheme.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Page.Resources>
    
  • At this point, the control panel UI is rendered using template defined in this file in the project. You can make any changes here to customize the control panel and the changes would reflect in UI. Let’s change the color¬†of the¬†pushpin for our example.
    <Grid>
        <Ellipse Stroke="{StaticResource ButtonForegroundThemeBrush}" Fill="DarkRed" StrokeThickness="2" Width="35" Height="35"/>
        <Path Fill="{StaticResource ButtonForegroundThemeBrush}" Margin="0,0,0,-7" VerticalAlignment="Bottom" HorizontalAlignment="Center" Data="M 0,0 8,0 4,8Z"/>
    </Grid>
    

We changed the Fill value for the Ellipse to dark red in this example. This demonstrates how to make changes in the template.

Let’s take customization to the next level. The behavior and visibility of playback controls are driven by a ViewModel. In the entertainment theme template we changed above, you must have noticed that bindings are used to control visibility. The control panel uses InteractiveViewModel class in player framework which has a number of properties to control visibility of all the elements in playback controls. I highly recommend going through the¬†type definition for InteractiveViewModel to understand the available properties to use in your custom template. Refer API documentation.

If you have full screen¬†video player in your app, you might want to add a Back button to the player screen. This can be added separately to you page but we can take advantage of MediaPlayer’s extensibility. Using this approach, we can also control the visibility of Back button as per playback controls visibility on user interactions. To achieve this, we’ll have to add the Back button to the ControlPanel template in ExtertainmentTheme.xaml we added to the project above.

Another essential requirement might be to show video title for the currently playing video. Again, we can achieve this by putting a TextBlock on the page but then we will have to handle the visibility of the TextBlock ourselves. Instead of doing that, we’ll take advantage of MediaPlayer’s extensibility and add¬†the TextBlock to the template. This has an issue though as we don’t have a property in InteractiveViewModel which can be bound to the Text property of the TextBlock. We definitely don’t want to hard code this.¬†To resolve this, we will create a subclass of InteractiveViewModel and add the additional property in that. In the new ViewModel, we’ll also add a command for binding it to Back button. Once we have the ViewModel, all we’ll have to do is to wire up the custom ViewModel to the MediaPlayer control.

First, let’s go back to the ControlPanel template and add the title TextBlock and Back button to the playback controls template.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <Grid x:Name="HeaderContainer" Background="{StaticResource ItemBackgroundThemeBrush}" Visibility="{Binding IsTimelineVisible, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource VisibleIfConverter}}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Button Command="{Binding GoBackCommand}" Style="{StaticResource BackButtonStyle}" Margin="36,20" VerticalAlignment="Center" />
        <TextBlock Grid.Column="1" TextWrapping="NoWrap" Text="{Binding VideoTitle}" Style="{StaticResource SubheaderTextStyle}"
            Foreground="{StaticResource ApplicationForegroundThemeBrush}" VerticalAlignment="Center" FontSize="40"/>
    </Grid>

    <StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">

Notice we are using bindings to set the Text for TextBlock and Command for Button. Next, let’s create the custom ViewModel with properties we can use for binding.

public class CustomInteractiveViewModel : InteractiveViewModel
{
    public CustomInteractiveViewModel(Action goBack, MediaPlayer player)
        : base(player)
    {
        _goBackCommand = new DelegateCommand(goBack);
    }

    private string _videoTitle;
    public string VideoTitle
    {
        get
        {
            return _videoTitle;
        }
        set
        {
            if (_videoTitle != value)
            {
                _videoTitle = value;
                base.OnPropertyChanged("VideoTitle");
            }
        }
    }

    DelegateCommand _goBackCommand;
    public DelegateCommand GoBackCommand
    {
        get
        {
            return _goBackCommand;
        }
    }
}

In the player page, let’s add the MediaPlayer control to the Xaml markup and assign an instance of the¬†CustomInteractiveViewModel to InteractiveViewModel property of the MediaPlayer control to wire up the custom ViewModel to the MediaPlayer.

<Page x:Class="CustomizingPlayerDemo.PlayerPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CustomizingPlayerDemo"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:mmppf="using:Microsoft.PlayerFramework" mc:Ignorable="d">

    <Page.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Common/EntertainmentTheme.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Page.Resources>
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <mmppf:MediaPlayer x:Name="player" Source="http://download.ted.com/talks/BillGates_2010-480p.mp4?apikey=TEDDOWNLOAD"/>
    </Grid>
</Page>

 

using CustomizingPlayerDemo.Common;
using Windows.UI.Xaml.Controls;

namespace CustomizingPlayerDemo
{
    public sealed partial class PlayerPage : Page
    {
        public PlayerPage()
        {
            this.InitializeComponent();

            player.InteractiveViewModel = new CustomInteractiveViewModel(() => this.Frame.GoBack(), player)
            {
                VideoTitle = "Bill Gates on energy: Innovating to zero!"
            };
        }
    }
}

This gives us a fully customized playback controls UI for player framework MediaPlayer control. This is the same approach I have used in Khan Academy app as well.

CustomizedPlayerControls

The controls we have added to the ControlPanel template are part of the player so we get visibility transitions for these without any extra work. You can download the source code of this sample to see how it works. Please don’t forget to install the player framework using links above before you try to run the sample.

Update:

Hope this helps.