So I've announced to unpublish Podcatcher from the Windows Phone marketplace. Podcatcher has been a dear project to me for many reasons and I've noticed it also had some satisfied users. In this blog post I try to open up some of the reasons for unpublishing it.
Podcatcher was (one of the other) projects that I used to teach myself how to do Windows Phone programming. Or even C# programming for that matter. When you start a new project in a completely new environment and language you tend to make a lot of mistakes. And then you fix them. That's how you learn, right.
But some things are more fundamental than others. One of the things that I couldn't fix anymore - a thing that was so fundamental - and a thing that I today for sure would have done differently is how to model the state data using Linq-to-SQL DataContext. It sits at the bottom of every other model that I have. I already once redid the DataContext functionality by properly disposing them inside using() statements. But at this point of time to go forward I would need to redesign how I lay out my data in multiple DataContexts to handle concurrency better and make it easier to update just the correct pieces of data. Some of the bugs that I've now faced were DataContext.ChangeConflictExceptions which are especially nasty to debug and fix. But basically they mean that the data models are not holding up anymore.
Another major pain point has been how the UI components are being updated from UI events that are being fired and updating the data models. This is related to the previous point about the need to do major data model changes. Nowadays I would never have used the Events like I did in the beginning. First they felt like the signals and slots from Qt, which I am very familiar with. So I used them like Qt's signals and slots to update the models that were tied to the UI. But in the long run this became somewhat messy and uncontrolled. This, too, would have required some major changes to fundamental functionalities of how the UI is being updated. Today I would have probably used something along the lines of Rx to handle the events in the system.
async and await
Boy, if I would have been able to use async and await from the beginning instead of BackgroundWorker as my threading model, the code would have been so much cleaner and more maintanable. But because Podcatcher originally targeted Windows Phone 7.5, it wasn't available at the time. The application was then moved over to Windows Phone 8.0, but all the critical threading code and model handling had already been implemented. This is also one of the teaching that I got along the way and I am glad I first did it "the wrong way" because now I can appreciate async/await so much more.
Windows Phone 8.1
Microsoft announced Windows Phone 8.1 at the Build conference. It's a great step forwards for Microsoft but also to all Windows Phone users. Windows Phone 8.1 will bring even nicer applications to end users with more fluent animations and good looking UIs.
Why does this matter for Podcatcher? Well, Podcatcher has never been really a poster boy for good looking UIs. I am not a designer so the UI is what I call a "developer graphics UI". So for Podcatcher to meet the demands of what a Windows Phone 8.1 app should look like would require big efforts. First of all, it should be a Windows Phone 8.1 XAML application (as opposed to a Windows Phone 8.1 Silverlight application. Confusing, I know) because not all of the animations for Windows Phone 8.1 are available for Silverlight applications. I could probably try to convert the application from a Windows Phone 8.0 application to a Windows Phone 8.1 XAML application, but I have my doubts about this since my upgrade from Windows Phone 7.5 to Windows Phone 8.0 was not successfull. Yes, the Windows Phone 8.0 variant of Podcatcher is an application that I started from scratch in Visual Studio.
So first I would need to make the Podcatcher a Windows Phone 8.1 XAML app to be able to utilize the new animations and other fancy stuff available in the new platform. Then I would need to make Podcatcher look even more appealing by probably doing some major UI design updates along the lines of adding new animations. With all the stuff I descirbed above, this is somewhat of a big hurdle.
The Podcast app
Microsoft is adding an app called "Podcast" that comes preinstalled on every Windows Phone 8.1 device that is bought from a retail store. How the heck am I going to compete against Microsoft in this space? This is probably the reason why I don't have the energy to fix the issues that I've described earlier. After all, yes, the issues are "just code" related and you can always write new code, right. But with Microsoft having their own podcast app in the app list preinstalled does not really add any extra motivation to make the necessary changes.
So why did I unpublish the application in the end, instead of keeping it as it was? I guess it boils down to two things: pride and time.
Pride because I am not proud of Podcatcher anymore as it is now and as we enter the Windows Phone 8.1 era. It should be so much better, nicer looking and coded in a different way. I know I can do it now, but not with the problems it carries on its shoulders.
Time, because I don't really have the time to do the necessary changes but also because I do get feedback (positive, but also complaints and bug fix requests) that I feel bad about. I don't have the time to fix the issues or add the feature requests. So in the end it feels like the application is not complete anymore and its just easier to let it go.
All of Podcatcher's code is open sourced on GitHub with the GPL license (except for the Telerik components that the Windows Phone 8.0 version depends on). Go get the code from here: https://github.com/kypeli/Podcatcher.
As for me, I will now code something else Yep, I've installed the Windows Phone 8.1 SDK so I will probably do something else for Windows Phone in the future. No idea yet what. Starting from scratch and to be able target the more mature Windows Phone platform feels great. But one thing is certain: I've learned so much from coding Podcatcher that the project has not been in vain. And now that the code is out there, I hope it will help someone else too.
Let me start by saying that of course does Windows Phone 8 support HTTPS in the browser, but it seems some HTTP related APIs do not.
As I am developing my podcast client for Windows Phone, I occasionally get bug reports from Windows Phone 8 users that I can't reproduce on my Windows Phone 7 device. This is one of those.
I use BackgroundFileTransfer and BackgroundAudioPlayer components in my podcast client. Both of them operate on HTTP(S) endpoints as clients. But I got a bug report the other day say saying that the download failed on a file and the same (audio) file cannot be played in the player. I had to start digging deeper, as the same media file does work without issues on my Windows Phone 7 device. It turns out that the file in question is behind a HTTPS endpoint. I don't know if it matters, but the server returns HTTP code 301 (Permanently moved) which means that the server requests the client to go look for the content from another location that it specifies.
I looked at the network traffic using Wireshark. It turns out, as you can see below, that Windows Phone 8 terminates the connection after the initial SSL handshake by sending TCP package with [FIN, ACK]. Windows Phone 8 just throws in the towel and gives up.
On the other hand Windows Phone 7 responds at the same location with a TCP [SYN] package which means it wants to continue the communication. It gets the HTTP code 301 as response and moves happily on.
So why doesn't Windows Phone 8 support HTTPS?
I have made Microsoft aware of this issue by posting on to their forum a question: http://social.msdn.microsoft.com/Forums/en-US/wpdevelop/thread/f4cc446d-534c-496f-86e2-d21e72001177. I have not yet received a response.
Update: So I got a response to the forums from Microsoft saying they are indeed investigating this issue, which is very nice! Thanks And it also turns out that very likely, this is related to the HTTPS -> HTTP change in the connection. As you can see from the WP7 traces, it's WP7 doing the first HTTP request which means it already got the HTTP 301 response from the server - over HTTPS. Hence it's not visible in the trace.
So I think Microsoft tried to do something to enhance the security, but broke the experience. And I really hope they find this a bug, as this would be unexpected behavior from a browser, so why would these HTTP APIs behave differently and break things? At least give me an option to use this "insecure" way of communication.
I have been developing a podcast client for Windows Phone for the past few months - just for my own pleasure, to learn Windows Phone development and to have a decent podcast client for Windows Phone. Because it is a podcast client, I need the ability to play MP3 files and lucky for me, Window Phone 7.5 provides a mechanism for this called BackgroundAudioPlayer. It's a bit clunky to set up, but in the end quite straightforward thanks to some pretty good instructions. I got all the pieces of the software working together and I was pretty happy of how it all worked out for me in the end. Including the audio player was working fine.
Until I submitted the app for publishing to the Windows Phone Marketplace, that is. The certification failed because "starting to play any podcast episode resulted in a crash". I was quite baffled. I had, after all, been using my own podcast client to listen to my own podcasts for quite some time, including playing them of course. And I mean playing a lot, since I had been using the app for quite some time before I did the submission to Marketplace. This was driving me nuts because I just couldn't reproduce the issue (ok, to be frank I had other issues I had to fix too, but the root cause I couldn't reproduce). Thanks to a brave and kind beta-tester I managed to finally get closer to the truth, because he could reproduce the crash on his device and the version that was downloaded from the Marketplace through the beta-program.
If you want to contribute to the Nemo Mobile apps, you might feel like me in the beginning: a bit lost about where to start and what's needed in order to set up a development environment. Nemo has already quite a detailed wiki page, but I felt like something was missing for a n00b like me. But thanks to w00t I managed to set up a development environment on my Ubuntu desktop so that I can compile and run the Nemo QmlContacts application. This blog post will hopefully clarify what's needed in order to contribute to Nemo apps in general. Oh, and this is for Ubuntu Linux.
In this blog post I will only go through installing the QmlContacts application. But I imagine the other Nemo apps requiring similar steps.
I am pretty sure I could run my script last week, but I cannot anymore today.
kypeli@ubuntu:~$ sudo ./myscript.sh
[sudo] password for kypeli:
sudo: ./myscript: command not found
Obviously this was very strange to me because the script was in the current working directory, all permissions looked fine and I could run the script just fine without sudo, which indicated that the shebang was ok.
kypeli@ubuntu:~$ ls -la ./script.sh
-rwxr-xr-x 1 root root 568 2012-02-13 05:49 ./script.sh
Usage: ./script.sh [foobar] Give 'foobar' to do Baz
So what has happened? Apparently Ubuntu changed something in some update (I am still to verify this) which prevents me from running scripts as sudoer from other than sudo compile time predefined paths. You can verify this by looking at the flags that were used to compile sudo and look for the --with-secure-path option. sudo will not run any script (or command for that matter) outside of these paths. Including .
kypeli@ubuntu:~$ cat /usr/share/doc/sudo/OPTIONS
Give a reasonable default path for commands run as root via sudo.
Well - this was a bit annoying to me for two reasons. I am pretty sure this worked for me last week on my Ubuntu, but suddenly it doesn't work anymore. And secondly, I am not running any public server and I want to run my own scripts with root privileges (why I want to do that is a different topic :)) if I so choose. I must stress that I can see the reasons for doing this and security is always a trade off between security and usability. I would not do this on any public server, but for Ubuntu to not allow me to run my own commands as root is a bit annoying.
Luckily I found this tip from Björn Wijers' blog: http://www.burobjorn.nl/blog/2012/01/04/fix-sudo-and-path-environment-variable-on-ubuntu/
Update: Seem Björn's blog is down, so I'll post the solution here. Put the following line to your $HOME/.bashrc file:
alias sudo='sudo env PATH=$PATH $@'
And the run source $HOME/.bashrc (this will not be necessary on subsequent boots or starts of the terminal). You should again be bale to run your scripts with sudo.
This will enable the fix only for me, as I put the alias in my .bashrc file, so it's not even a terrible security risk. And that's fine.
I would also like to thank @anidel for pointing out initially this possibility.