Saturday, July 30, 2011

AirPlay from OS X Lion iTunes to Apple TV 2

One day, shortly after getting a brand new Apple TV 2, I wanted to use Airplay to play music from iTunes on my iMac to both the iMac speakers and through TV via Apple TV. Seems easy enough....start playing some tunes, then select both the iMac and the Apple TV from iTunes' speaker selection menu. Right?.....wrong!

When I selected Apple TV on the speakers menu, I got a popup saying "Connecting to 'Apple TV'...". It stayed up for a few seconds, then went away -- but no music on the TV. What the ? I tried again with no luck...this time noticing that the Apple TV selection in the iTunes speaker selection menu had a lock icon next to it. I assume that means I need to enter the Apple TV's Airplay password...but I haven't been prompted for it.

After googling for awhile I came across this blog post which described how IPv6 settings in OS X affected (i.e. completely freakin' broke) AirPlay from iTunes to Apple TV.  The solution outlined in the blog post was to go into System Preferences » Network, and in the settings for your network connection (i.e. AirPort, Ethernet, etc.) set Configure IPv6 to "Off" in the Advanced... menu.

This solution was going along fairly smoothly right up to the point where there wasn't an "Off" option in the Configure IPv6 menu. The only visible options were "Automatically", "Manually" and "Link-local only".  Uh oh...what now?

Well, it turns out that the OS X Lion update changed things a bit here.  The "Off" option is no longer available. So how do you disable IPv6? You "hack it" of course.  As I found in this forum post, although the "Off" option is no longer visible through the System Preferences user interface, it is still a valid option.  Here's how you get it back (Warning: this involves command line geek stuff...not for the faint of heart):

  1. Open Terminal
  2. Type cd /Library/Preferences/SystemConfiguration
  3. Type sudo vi preferences.plist. This opens the preferences.plist file in an old-school Unix text editor called vi.
  4. Hit the "a" key.  This puts vi in "insert mode".
  5. Using the arrow keys, navigate to the section in the file that looks similar to below for the network connection you're using (i.e. AirPort, Ethernet, etc.), and change whatever value is there to "__INACTIVE__".

    <key>IPv6</key>
    <dict>
        <key>ConfigMethod</key>
        <string>Automatic__INACTIVE__</string>
    </dict>
  6. Hit the "Esc" key.  This gets you out of "insert mode" in vi and back into "command mode".
  7. type "wq" and hit "Enter". This saves your changes and quits vi.
  8. Reboot.
  9. You're IPv6 should now be disabled!


At this point, your iTunes to Apple TV should now work as expected.  When you try to select Apple TV as a "speaker" for AirPlay you will get prompted for the Apple TV's password...which never happened before the fix.

Enjoy, and again thanks to the dudes from these two posts for showing me the light:

Monday, April 19, 2010

Backblaze vs. Mozy – Online Backup for Mac

One day while watching my 4 year old and 2 year old “play” with my iMac’s external hard drives (one for all of our photos, videos and music and the other for Time Machine) the idea struck me that I should maybe start thinking about an online backup solution.

From my extensive initial research (i.e. a couple radio commercials and a quick scan of Google’s sponsored links) it seemed that the two big players were Carbonite and Mozy.  Upon further review, it turned out that Carbonite did not support external hard drives.  What?!?!!  Bu-bye Carbonite.  Hello Mozy.

After a relatively painless install of the Mozy Mac client, I selected about 2GB worth of files to backup (2GB is Mozy’s free version limit) and let it do its thing.  In less time than I expected, all of the files were backed up to Mozy’s online servers.  That’s when things started to unravel.

I went to Mozy.com to see if my files were actually there.  It did show the 2GB of files, but it also said “No backups have been performed”.  What?  I just did a backup…and it says right there that 2GB of my files are there.  I submitted a ticket with Mozy support and they said that it’s a bug and their engineers are working on it.

In spite of the issue on Mozy’s website, the 2GB backup went smoothly enough that I anted up the $5/month and set out to backup the whole enchilada which is around 200GB.  I selected the drives and folders to backup and let it do its thing.  For 5 days I watched as Mozy cranked along at about 10GB a day backing stuff up.  Then, once it got to around 50GB or so it just stopped backing up and started hogging a lot of CPU.  I stopped the backup and restarted, restarted my Mac and tried again.  No love…just stuck at 50GB…and eating up a lot of my CPU.

Well, at this point I wasn’t very happy and decided to see if there were any other options.  I stumbled across David Peterson’s blog post on the subject, and after reading it..wished I would have found it sooner.  Looks like I wasn’t the only one having issues with Mozy.  I took David’s advice and downloaded Backblaze.

Backblaze was easy to install, select what you want to backup, and get going.  My experience was that of Mr. Petersons’….it really wasn’t that much of an experience at all.  I throttled bandwidth usage down during the day, then cranked it at night for the initial upload.  It ended up taking about 2 weeks to backup the full 200GB of content with no issues!

Since the initial backup, I configured Backblaze to only use a low percentage of bandwidth and backup continuously (as opposed to scheduled backups)….and I haven’t noticed it since…the way backup should be.

Winner: Backblaze

Saturday, March 13, 2010

iPhone Stuck On Apple Logo?

Had this problem today where I tried to download an app on to my wife’s iPhone.  The app never finished downloading and showed a “Loading” progress bar of about 50%.  After waiting about 10 minutes or so, with the progress bar still at 50%, I decided to try to reboot the phone.  Power off….power on….Apple logo…..stuck there for an hour.  Uh oh.

Luckily I stumbled across this forum post which contained the instructions below.

WARNING: This will allow you to restore the iPhone…which means that hopefully you have a backup, otherwise this will restore the phone to its out-of-the-box condition (i.e. none of your photos, music, contacts or apps will be on the phone)  If you do have a backup, you’ll be able to restore to the backed-up state. As far as I can tell from what I’ve seen out on the internet, once your phone gets the “stuck on Apple logo” issue, restoring the phone is the only solution.  With that said….here’s how to fix it:

  1. Do a hard reset on the phone, hold the sleep/wake button + the home button until it turns off then release before it turns back on.
  2. Plug the dock into the compute and have iTunes running.
  3. HOLD the home button on the iPhone, while holding it, connect the iPhone onto the dock and CONTINUE to hold the home button until the CONNECT TO ITUNES DISPLAY APPEARS.
  4. iTunes will recognize this and ask if you would like to restore it. Click restore. Then choose to restore from BACKUP! This will take a few minutes. It will fix the problem. Your iPhone will be up and running as normal and all your contacts, sms, bookmarks, settings, etc. will be intact. The only thing that will be erased is the music. But you can easily add that all back right.

Adding Custom SOAP Headers in WCF

Where I work, all of our internal published web services are proxied using IBM’s DataPower SOA Appliances.  One of the requirements for services that want to leverage the infrastructure is that all requests and responses to the service must contain a custom header which contains parameters like “MessageID” for correlation, “SiteID” for location information, etc.  For SOAP based services, this information must be transmitted in the SOAP header.  For the purposes of this article, let’s say we need to include an object like the following into the SOAP header of every service operation.

[DataContract]
public class CustomHeader
{
    public const string Name = "customHeader";
    public const string Namespace = "http://mycompany.com";
    public const string OperationContextKey = "CustomSoapHeader";
    
    [DataMember]
    public string MessageID { get; set; }
    
    [DataMember]
    public string SiteID { get; set; }
}

Back in the ASMX days adding headers like this to a service method was as easy as adding a SoapHeader attribute to your WebMethod. Simple.  In the WCF world, not so simple.

There are 3 issues to be addressed:

  1. We need some way to inject the custom header into the WSDL so the service clients are aware of it and can generate client proxies accordingly. 
  2. We need some method to read and process the custom header from the request.
  3. We need some way to roundtrip the header back to the client.

In our case, we’d like to specify whether the custom header should be included at the service contract level, so an IContractBehavior seems like a good place to start.  We also know that we’ll be processing the request and reply messages, so we’re going to need an IDispatchMessageInspector too. 

Let’s start with the message inspector.  The responsibility of this class is to extract the header from incoming messages, store it in the OperationContext in case the service needs to use it (i.e. for logging purposes), and roundtrip it into the reply message.

/// <summary>
/// Retrieves and stores the custom header from requests and roundtrips it into responses.
/// </summary>
public class CustomHeaderMessageInspector : IDispatchMessageInspector
{
    object IDispatchMessageInspector.AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        // Grab the header from the request
        // TODO: Handle missing or invalid header
        CustomHeader header = header = request.Headers.GetHeader<CustomHeader>(CustomHeader.Name, CustomHeader.Namespace);

        // Stash the header in the OperationContext so the service code can reference it if necessary
        OperationContext.Current.IncomingMessageProperties[CustomHeader.OperationContextKey] = header;

        // The object returned from this method is passed as the "correlationState" parameter to the BeforeSendReply
        // method.  We can use this to "echo" back the header to the caller.
        return header;
    }

    void IDispatchMessageInspector.BeforeSendReply(ref Message reply, object correlationState)
    {
        // correlationState should be the CustomHeader (passed to this method from AfterReceiveRequest)
        // If an exception occured before or during the header processing, this may be null.
        if (correlationState != null)
        {
            // Get the custom header object passed in on the request
            var headerObject = (CustomHeader)correlationState;

            // Build the MessageHeader object from our custom header
            var headerMessage = MessageHeader.CreateHeader(CustomHeader.Name, CustomHeader.Namespace, headerObject);

            // Inject our custom header into the reply.
            reply.Headers.Add(headerMessage);
        }
    }
}

Now that we have the inspector, we’ll need to create an attribute and implement IContractBehavior so we can attach this inspector to the desired service contracts.

/// <summary>
/// Apply this attribute to service contracts to implement CustomHeader processing.
/// </summary>
[AttributeUsage(AttributeTargets.Interface)]
public class CustomMessageHeaderAttribute : Attribute, IContractBehavior, IWsdlExportExtension
{
    void IContractBehavior.ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
    {
        // Attach the message inspector to the endpoint.
        var inspector = new CustomHeaderMessageInspector();
        dispatchRuntime.MessageInspectors.Add(inspector);
    }

    void IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)
    {
        // TODO: Inject the custom header into the WSDL
    }
    
    // All other interface methods are not used and have been omitted for brevity...
}

At this point, the custom header is usable, but with one problem.  It’s not defined in the WSDL, so the service clients might not “know” about it.  To add the header to the wizard, we just need to implement the ExportContract method of the IWsdlExportExtension interface that we left as a “TODO” in the code above.

void IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)
{
   // Build the custom header description
   var headerDescription = new MessageHeaderDescription(CustomHeader.Name, CustomHeader.Namespace);
   headerDescription.Type = typeof(CustomHeader);

   // Loop through all the operations defined for the contract and add custom SOAP header to the WSDL
   foreach (OperationDescription op in context.Contract.Operations)
   {
       foreach (MessageDescription messageDescription in op.Messages)
       {
           messageDescription.Headers.Add(headerDescription);
       }
   }
}

Now we have a fully defined and working header.  To tell a service contract to implement the custom header, we just add our custom attribute to the contract definition.

[ServiceContract]
[CustomMessageHeader]
public interface IMyServiceContract 
{
    // Service definition here....
}

Of course this was a very basic implementation for a specific need, but this approach could be extended to create a more “generic attribute” that you could specify header type as a parameter or allow for updating the header values to return in the reply (similar to how the “old school” SoapHeader attribute worked).

Monday, March 1, 2010

Adding WSDL Documentation to your WCF Services

Back in the good ol’ days of ASMX web service development, adding documentation to the WSDL of your service was as simple as providing the desired info in the Description property of the WebMethod attribute:

[WebMethod(Description="This method always returns 'Hello World!'")]
public string HelloWorld()
{
    return "Hello World!";
}

This injected something like the following into your WSDL which allows web service clients and tools to give the consumer a little more information about a service or method.

<wsdl:operation name="Hello World">
    <wsdl:documentation>This method always returns 'Hello World'!</wsdl:documentation>
    <wsdl:input ... />
    <wsdl:output ... />
</wsdl:operation>

Now fast forward to the new services world of WCF…and its mantra of “I’m uber-powerful, but everything that used to be easy is no longer easy”. There is no out-of-the-box way to inject descriptions into your WSDL in WCF.  Can’t believe it? Neither could I…but there is hope. 

WCF was built to allow extensibility to almost everything, including WSDL generation. For this particular problem, we need to look at contract behaviors (IContractBehavior), operation behaviors (IOperationBehavior), and the IWsdlExportExtension interface.  Armed with these we can develop a behavior which allows you to specify WSDL descriptions for a service or operation in much the same way as the old ASMX days.  Below is the code for a WsdlDocumentation attribute which does just this:

/// <summary>
/// Attribute which injects wsdl:documentation elements into the WSDL.
/// </summary>
/// <remarks>
/// This attribute can be applied to the service contract and it's methods.  
/// </remarks>
[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Method)]
public class WsdlDocumentationAttribute : Attribute, IContractBehavior, IOperationBehavior, IWsdlExportExtension
{
    private ContractDescription _contractDescription;
    private OperationDescription _operationDescription;

    /// <summary>
    /// Initializes a new instance of WsdlDocumentationAttribute.
    /// </summary>
    /// <param name="text">Text to inject into the WSDL.</param>
    public WsdlDocumentationAttribute(string text)
    {
        this.Text = text;
    }

    /// <summary>
    /// Text to inject into the WSDL for the target element.
    /// </summary>
    public string Text { get; set; }

    void IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)
    {
        // This is either for a service contract or operation, so set documentation accordingly.
        if (_contractDescription != null)
        {   
            // Attribute was applied to a contract.
            context.WsdlPortType.Documentation = this.Text;
        }
        else
        {
            // Attribute was applied to an operation.
            Operation operation = context.GetOperation(_operationDescription);
            if (operation != null)
            {
                operation.Documentation = this.Text;
            }
        }
    }
    
    void IContractBehavior.ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
    {
        _contractDescription = contractDescription;
    }
        
    void IOperationBehavior.ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
    {
        _operationDescription = operationDescription;
    }    

   // **** All other interface members are not used and have been removed for brevity
}

To use this new attribute, we just apply it to a service contract and/or method…

[ServiceContract(Name="MyService")]
[WsdlDocumentation("Description of MyService")]
public interface IMyService
{
    [OperationContract]
    [WsdlDocumentation("This method always returns 'Hello World!'")]
    public string HelloWorld()
    {
        return "Hello World!";
    }
}

Voila, the descriptions show up in the WSDL!

Quicken Essentials for Mac – WTF Intuit?!?!!

QuickenEssentialsForMac I downloaded (and paid the $69.99) for Quicken Essentials for Mac yesterday.  My thinking was..”My God, it’s taken them forever to come out with this thing..it must be freakin’ awesome”.

Now I realized that they had not yet integrated Bill Pay into the product….I guess in order to complete the rest of the alleged awesomeness in time for the February 2010 ship date, they deemed it a non-essential feature.  OK….fair enough, I can pay all my bills online at the payees’ sites anyway…so I can live without this feature.

So, after a painless checkout & download process from the Intuit online store, I installed it. I didn’t get past the 2nd step on the “Setup your accounts” wizard before finding out that they don’t support Wells Fargo for transaction downloads.  That’s not a typo…Wells Fargo, the 3rd largest bank in the United States is not supported.  Are you kidding me?  That’s like putting out TurboTax with 1040EZ support missing.  What’s even more perplexing is that they do support Wells Fargo on their (free) Quicken Online product.

So after less than 5 minutes of using the product….I’m uninstalling it and trying to get my money back.

I would expect more from the “leader” in personal finance software products.

WTF Intuit?!?!!