Apple developing home media server

Last week, just when I thought I had looked into every option available for a home media server the rumor is posted that Apple might be creating one. Better just wait for the keynote which will be held Tuesday at 9 am PST or 18 CET.

Image from MacRumors forums.

Virtualisation with VirtualBox

Whenever you look around for virtualisation solutions on the Mac platform you get two answers: VMware Fusion and Parallels. One you don’t hear so much about however is VirtualBox from Sun. I haven’t used the first two since VirtualBox is open source and free of charge. I first installed it two months ago and although it worked it was extremely slow. This was not so much due to the software rather my machine only had 1 GB of RAM available and running two operating systems is rather intensive. A few weeks ago I upgraded to 4 GB and tried out VirtualBox again, I’ve been using it almost daily since then. It works great!

Most of the time I’m a .Net developer so I need Visual Studio and Windows to get my work done and apart from the fact that some keys don’t work, or I haven’t figured out how to get them working, like the function keys, I don’t feel any difference compared to working on a native Windows box. You don’t loose any responsiveness.

Copy Pasting text is supported, so I can copy text from i.e. Safari into Notepad. While skimming through the manual there was a mention on how to share files between the two operating systems but I haven’t really looked into that. It works with shared folders to achieve this functionality, the two other virtualisation options support drag and drop I think.

You can run VirtualBox as any other window but most of the time I run it in seamless mode. This means that the applications you start in Windows can be placed next to your running OS X applications, seamlessly. This is illustrated by the attached screenshots, the first one shows the Windows applications locked on the Windows desktop and the second one shows the same applications but now running in seamless mode.

I first used spaces to keep my OS X and Windows applications separated but found that not comfortably to work in. I would look something up in Safari then switch to Visual Studio and saw all the applications fly from left to right, a few minutes later I’d receive a mail and everything flew back again. If there would be one school example on why to use spaces I thought it would be virtualisation but now I’m not convinced of the entire idea any more. Why on earth would you use it except for adding more icons on your desktop.

So, to sum it up, if you need to run Windows on OS X and don’t want to reboot everytime for BootCamp, go download VirtualBox!

Since a video says so much more on how everything works, here is a movie I found on YouTube:

Using Fluent NHibernate in Spring.Net

In order to load the mappings you’ve written using Fluent NHibernate you need to call the extension method “AddMappingsFromAssembly” on the configuration. The “LocalSessionFactoryObject” defined in Spring.Net supports out of the box the loading of .hbm files from an assembly or a location in the file system. Luckily this class can be extended with ease. The code below is all you need to use Fluent NHibernate with Spring.Net, any suggestions for a better name are welcome.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Spring.Data.NHibernate;
using FluentNHibernate;
using System.Reflection;
using NHibernate.Cfg;
 
namespace SessionFactories
{
    public class FluentNhibernateLocalSessionFactoryObject
	: LocalSessionFactoryObject
    {
        /// <summary>
        /// Sets the assemblies to load that contain fluent nhibernate mappings.
        /// </summary>
        /// <value>The mapping assemblies.</value>
        public string[] FluentNhibernateMappingAssemblies
        {
            get;
            set;
        }
 
        protected override void PostProcessConfiguration(Configuration config)
        {
            base.PostProcessConfiguration(config);
            if(FluentNhibernateMappingAssemblies != null)
            {
                foreach(string assemblyName in FluentNhibernateMappingAssemblies)
                {
                    config.AddMappingsFromAssembly(Assembly.Load(assemblyName));
                }
            }
        }
    }
}

Update 29 June: please check the comments since a new version brought some changes to this blog post.

Blog Intentions for 2009

The last three months my activity here has dwindled down, but I’m going to try to pick up the pace again. Still need to get through the final chapters of Cocoa Programming for Mac OS X , talk about and implement single sign on in a desktop application, try out some new technology in the todo application, build a mediaserver,…

In the meanwhile, happy new year ;).

In search of a mediaserver

I’ve been looking into ways to move my media library to a safer and more accessible medium than the external hard disk I use at the moment. I also plan to rip all my CDs since more and more of them are starting to have scratches, even though I’m careful with those silver discs. My home network consists of Windows PC’s (desktop, media center) and Apple products (MacBook, iPhone) so I need something that works for both environments and can be expanded to other audio devices.

The first mediaserver I looked into was SqueezeCenter. The server is opensource and has the backing of an established company, in this case Logitech. They have several commercial products which can listen to your server and play the music or send the stream to your hifi installation. The stream can be opened in iTunes or WMP, just like you’d do with any internet radio. The downside of this is that you can’t browse your collection through these players though I’m sure that you can find a plugin for WMP to do this since there are iPhone applications (iPeng, Squidgy) available to control a SqueezeCenter.

I first tried their recent 7.3 release but that didn’t want to run, the previous version 7.2 ran like a breeze. The only out of the box way to control what songs are played is through the web interface.

The second one I installed was Firefly Media Server, since this one is based on a proprietary Apple protocol it works great in iTunes. Your collection is recognized as a shared iTunes library so you can choose what you want to hear in the same way you do when the mp3’s would be stored locally. The downside of this is that I can’t run this in my media center and that I need iTunes on my other windows machines. Also if I’d want to play music on a stereo I’d need to keep a PC running since the server can’t stream directly to AirTunes.

The third one I tried was TwonkyMedia, installation was no problem but I couldn’t connect with any player and the posts on their forum didn’t seem that promissing, customers who don’t get support is no good advertisement. The server however is based on the UPnP protocol, which is kind of the standard in the industry. WMP 11 can connect to such a server, as can the Playstation 3 and a lot of other players.

Searching for UPnP servers led me to TVersity, which blew me away. I can connect with my iPhone, my Vista Media Center, WMP, any browser,… It’s much more than just an audio server I suggest you look at their website and try it out. The only downside, iTunes doesn’t support UPnP.

So far my search for a media server, I haven’t decided which way to go.

Replace MacBook memory

Today I upgraded my MacBook (early 2008) from 2×512 MB RAM to 2×2 GB RAM. The entire process took me 5 minutes, including the time to search for a fitting screw driver. It was far easier than expected.

  • First turn over your MacBook, so the top is facing the table. Make sure you have a clean and soft surface to avoid any scratches.
  • Use a 10 cent piece to turn the lock next to the battery to the unlocked position. The battery will pop out.
  • Remove the battery.
  • Use a cross screwdriver to remove the three screws of the plate protecting the memory and the hard disk. They are very small so use your smallest screwdriver you can find. Next pull the plate away, you now have access to the memory.
  • By using the lever per memory slot the ram sticks will pop out making place for the new ones. Gently push them in until you hear a click.

Done ;).

iPhone Tech Talk Amsterdam

In October I read about the iPhone Tech Talk tour and immediately registered for the event. I’m still teaching myself Cocoa so I thought this could be helpful. Only a week before the actual start time people got their registration confirmations and I was one of the lucky few. While I can’t go into detail about the content of the event, since I’m bound by the NDA. Which is strange to say the least, wouldn’t you want people who take the time to go to your event to talk about it with others?

Anyway, the actual agenda varied from the one posted on the website. The presentations I saw were:

  • iPhone Development Overview
  • iPhone User Interface Design
  • iPhone Development Tools Overview and Programming Concepts
  • Introduction to Objective-C and Cocoa Touch
  • Developing iPhone Applications with UIKit
  • Maximizing Your Application’s Performance on iPhone
  • Submitting to the App Store using iTunes Connect

If you compare this with their original list, you see that there were a lot more sessions than originally planned and as a result the speaker had a lot of trouble fitting it all in his schedule. Which is disappointing, removing two or three topics would have been better especially since there was a lot of overlap between some of them. User Interface Design for instance explained all the different controls available and this was repeated again in the UIKit presentation. What would have been better was explaining the concepts behind it in the first session and then actually implementing a sample application using the UIKit. Model View Controller was also explained three times, why not explain it once and show code the second time. Knowing the theory behind it is good, but actually showing us why some things are in place would have been better.

Did all this make it a useless event? Certainly not, if there is one in the future I hope I will be able to attend again and because this was the first time Apple organized something like this they probably still have to learn what content fits and what not.

And ow yeah, catering was excellent! 😉

Dutch alt.net

If you’re into alt.net and speak dutch, though it’s not really required, you might be interested in the dutch alt.net group. The plan is to have regular meetings “with like minded people to discuss and demonstrate the merits and drawbacks of different approaches in .net development”. For the next meeting we’re trying not to have an agenda, let’s see where that goes.

Adding transactions and exploring the BindingList

I stopped working on my todo sample after all the frameworks were playing nicely together and my todo list was displayed. Next up was adding edit capabilities.

At work I normally use Spring.Aop to inject an INotifyPropertyChanged implementation into the objects I pass to the view, but since I’m trying out new stuff here I turned to the default .Net BindingList to support change notification. I’m actually quite happy with the capabilities that are provided, for now at least. The BindingList has a ListChanged event which gets fired if either a property of an object in the list gets changed or the list itself is modified. For my basic sample here this is more then enough. Something I struggled with however, was how to turn off notifications while the list is being populated with data which improves responsiveness of the UI. After some googling I found that you had to call ResetBindings, strange that I didn’t find anything on MSDN that told me how to work in this scenario. I might need to pick up a book on Windows Forms development though, professionally I work with WinForms 99% of the time when I need to create a UI, who knows what other ‘goodies’ I’m missing out on.

public void SetDatasource(List<TodoDto> todos)
{
    todoDtoBindingSource.RaiseListChangedEvents = false;
    todoDtoBindingSource.DataSource = todos;
    todoDtoBindingSource.RaiseListChangedEvents = true;
    todoDtoBindingSource.ResetBindings(false);
}

With the UI now raising events when the user makes changes, the presenter that is listening had to keep track of the changes and forward them to the webservice when the user wants to save his work. The code I’ve written for that isn’t rocket science or hard to grasp. It boils down to what is transferred between the client and the server.

public enum ChangeType
{
    Added = 0,
    Changed,
    Deleted
}
 
public class TodoEditDto
{
    public virtual Guid EditId { get; set; }
    public virtual TodoDto EditedTodo { get; set; }
    public virtual ChangeType ChangeType { get; set; }
}

The ChangeType indicates what has happened, the item was added, changed or deleted. The TodoEditDto wraps the edited dto, adds a ChangeType and EditId property. The EditId is generated on the client and used to identify newly saved objects when the server sends back the Id’s that were generated when the todo was persisted. That way a new created todo can be edited right away after saving it.

// saved data to server
foreach (var persistedEdit in response.PersistedEdits)
{
    var foundEdit = (from edt in editedTodos
                     where edt.Value.EditId.Equals(persistedEdit.EditId)
                     select edt.Value).First();
    foundEdit.EditedTodo.Id = persistedEdit.EditedTodo.Id;
}

With some basic editing now in place, some work is still needed in the UI, let’s now add transactional support to our save method. Spring.Net allows you to add this capability declarative or programmatic and even within these two approaches there are several ways to achieve your result. At work I’ve always used the declarative way using AutoProxy and the [Transaction()] attribute. To make that work you need to add a reference to Spring.Data, add the attribute to the methods that need to be transactional and add the following object definitions to your configuration.

<object id="AutoProxyCreator" 
		type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator, Spring.Aop"/>
 
<object id="TransactionAdvisor"
		type="Spring.Transaction.Interceptor.TransactionAttributeSourceAdvisor, Spring.Data">
		<property name="TransactionInterceptor" ref="TransactionInterceptor"/>
</object>
 
<!-- Transaction Interceptor -->
<object id="TransactionInterceptor"
		type="Spring.Transaction.Interceptor.TransactionInterceptor, Spring.Data">
		<property name="TransactionManager" ref="TransactionManager"/>
		<property name="TransactionAttributeSource" ref="AttributeTransactionAttributeSource"/>
</object>
 
<object id="AttributeTransactionAttributeSource"
	type="Spring.Transaction.Interceptor.AttributesTransactionAttributeSource, Spring.Data">
</object>
[Transaction(TransactionPropagation.Required)]
public SaveEditedTodosResponse SaveTodos(SaveEditedTodosRequest request)
{
    // do stuff
}

At runtime, Spring.Net will create a proxy for each service that has the tranascation attribute declared on its methods and manage the transaction from in that generated class. Everything you’ve written will be transactional from that point until the method that is being called is completed. For now however, let’s use the TransactionProxyFactoryObject. To use this approach I only need to change my service definition. Through the transaction attributes property I can define which methods need to be transactional, in this case any method that starts with Save. The target property can be any object in your context.

<object id="TodoService" 
		type="Spring.Transaction.Interceptor.TransactionProxyFactoryObject, Spring.Data">
	<property name="PlatformTransactionManager" ref="TransactionManager"/>
	<property name="TransactionAttributes">
		<name-values>
			<add key="Save*" value="PROPAGATION_REQUIRED"/>
		</name-values>
	</property>
	<property name="Target">
		<object type="TodoCore.AppService.TodoService, TodoCore">
			<property name="TodoRepository" ref="NhnTodoRepository"/>
		</object>
	</property>
</object>

With this in place we now have a basic application which is workable in a test environment. Speaking about tests, I really need to add them to the project. I’m not a very good TDD’er myself, though I’m convinced it is the way to go. I should start applying it.

SampleApplication04092008.rar (2.95 mb)