Saturday, November 18, 2017

Getting started with a private Ethereum Blockchain and Solidity Contract Development on geth 1.6 or higher

In order to take this tutorial it is assumed that you have set up your development environment as explained in the first part Installing a Solidity Development Environment for Ethereum Contract programming.

In the second part of our Ethereum programming tutorial we will set up a private Ethereum development network, and implement our first smart contract.

This tutorial is based on a geth version later than 1.6, namely 1.7.2. What makes worth mentioning it is the fact that in version 1.6 the inline Solidity compiler support was removed from geth. For whatever reason. But by the time of writing these lines (end of 2017) there is no ramp-up tutorial to be found out there which reflects this fact. Even the official Ethereum "Hello world" tutorial still refers to the Solidity compiler being included with geth!

But no worry: I'll do that for you! Here comes the first rookie walkthrough for creating, compiling, deploying, and running a Solidity Ethereum contract utilizing the command line Solidity compiler!

1. Setup the private Ethereum Development Node

First create a new data directory for your private blockchain. We do this right beneath our home directory:

$ mkdir ~/privatechain

Then start a geth development network pointing to this data directory:

$ geth --rpc --rpcaddr 127.0.0.1 --rpcport 8545 --dev --datadir ~/privatechain

If everything went right the last terminal output should read something like:

IPC endpoint opened: /Users/as/privatechain/geth.ipc 

HTTP endpoint opened: http://127.0.0.1:8545 

But what do these options mean:
  • rpc: Enable remote procedure calls via http on this geth instance, so we can connect to it from another node (i.e. terminal window)
  • rpcaddr: The IP address where RPC shall be accessible. In this case it's the local host since we are on the same machine.
  • rpcport: The port to access RPC. As 8545 is the standard port, we also could have left out this option.
  • dev: This flag creates a development network, so we do not connect to the "real" Ethereum network where we would have to spend real Ether (meaning real money) to execute our contracts. It also conveniently preconfigures the first block (the Genesis) of our network. We will cover creating our own Genesis Block in a later tutorial.
  • datadir: Guess what? It points to our private chain's data directory just created!
Just take a look into your privatechain directory. You should find the subdirs geth and keystore there!

2. Connect a geth console to the Development Node

You will have recognized that our running geth node is quite busy with its own affairs. It's not being impressed by typing commands into its terminal window. Not even by poems! So we have to get in contact:

Open another macOS terminal window. I'd suggest using a different color for it so you never mix up the terminals later on. We will use the grass style terminal throughout this tutorial - as it comes preconfigured with macOS - to reference the remote command line interface (CLI) geth console.

So just execute this in the new console window replacing the "as" with your user name:

geth attach ipc://Users/as/privatechain/geth.ipc 

Congratulations! You just opened a remote console to our Ethereum node!

But what about the "ipc" thing when we where talking about "rpc" earlier? Just that simple: IPC or Inter Process Communication can be used when separate processes need to interact on the same machine while RPC must be used when the processes run on different machines.

3. Create the first account

Now we have to create an external account on our Ethereum network. An account enables us to perform transactions on the network (i.e. make use of it). To do so we utilize geth's Management API:

personal.newAccount('password')

'password' literarily is the password here. So feel free to use your own! This command will output the address of the account created. It's a good idea to write it down somewhere!

Now check the account really exists:

personal.listAccounts

This should output an array containing the account just created. So in my case it's:
["0x839d4ed149062e6e2e7ab772167f366282c600ce"]

This first account automatically is set as the coinbase in our network. This is where all the mining rewards will got to. You can check it using the web3 API:

eth.coinbase

This should output the same account just created.

4. Create the Contract Source Code

Now it's time to write our first Ethereum contract definition. If you are familiar with object oriented programming languages it helps to think of a contract definition as a class definition.

For better maintainability we will store the contract files in a separate directory. So just go ahead an create a folder ~/ethcontracts!

Right inside this folder create a new text file named MyFirstContract.sol. This is your first Solidity source code file! Feeling great?

Now paste this code into the file and save:

pragma solidity ^0.4.8;

contract MyFirstContract { 

    function reflect(string yourself) public returns(string){
        return yourself;
        
    }
    
}

I think there isn't a detailed walkthrough required. You will have noticed that in the first line we define the smallest Solidity version supported by this contract. Then we create a contract named MyFirstContract which has one method that simply reflects its input.

But now comes the challenging part:

5. Compile the Contract

As told earlier in this tutoriel, calling the Solidity compiler right from the geth console has been removed from geth 1.6. So we have to compile our source file outside the running Ethereum network, and import it into it. In order to do so we need to have the Solidity compiler installed as explained in the first part of this tutorial.

As we have two instances of macOS terminal already running, we will need a third one. Believe it or not! So please open another terminal instance. We will use the ocean theme to identify it in this tutorial.

First we'll do a test run to check if the Solidity compiler is working as expected. So please issue:

$ solc --optimize --combined-json abi,bin,interface ~/ethcontracts/MyFirstContract.sol  

We should get something like this:

{"contracts":{"/Users/as/ethcontracts/MyFirstContract.sol:MyFirstContract":{"abi":"[{\"constant\":false,\"inputs\":[{\"name\":\"yourself\",\"type\":\"string\"}],\"name\":\"reflect\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]","bin":"6060604052341561000f57600080fd5b6101578061001e6000396000f3006060604052600436106100405763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663c1ce53fc8114610045575b600080fd5b341561005057600080fd5b61009660046024813581810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061010d95505050505050565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156100d25780820151838201526020016100ba565b50505050905090810190601f1680156100ff5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610115610119565b5090565b602060405190810160405260008152905600a165627a7a723058207e8ac985f99f507869c23d1d1457c38e5aace7b1eafa9f31eff3e02d9aecfd450029"}},"version":"0.4.18+commit.9cf6e910.Darwin.appleclang"}

If there are some warnings ahead of this output we just can ignore them! The important thing to notice is that we have our contract source code compiled into  an abi and a bin section.

Now let's use this for real!

In order to be able to deploy the compiled contract into our Ethereum dev network, we have to create a compiled file from the source code. We do it using good old terminal commands:

echo "var MyFirstContractCompiled=`solc --optimize --combined-json abi,bin,interface ~/ethcontracts/MyFirstContract.sol`" > ~/ethcontracts/MyFirstContract.js

What happens here is that we create an actual JavaScript file MyFirstContract.js where we assign the output JSON object of the Solidity compiler to a variable called MyFirstContractCompiled.

Now we're ready for the next step:

6. Import the contract 

We want to get the precompiled contract from the compiled JavaScript file into our Ethereum node and prepare it for deployment to our development network.

So we return to our geth console and load the JavaScript file just compiled (Note: We assume that the geth console was started from your user's home directory. If not, you have to specify the absolute path to the MyFirstContract.js file):

loadScript("./ethcontracts/MyFirstContract.js")

The resulting output should be:
true

So let's check if everything went right by outputting the value of the MyFirstContractCompiled variable:

MyFirstContractCompiled

Should give you an output like this:

{
  contracts: {
    /Users/as/ethcontracts/MyFirstContract.sol:MyFirstContract: {
      abi: "[{\"constant\":false,\"inputs\":[{\"name\":\"yourself\",\"type\":\"string\"}],\"name\":\"reflect\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
      bin: "6060604052341561000f57600080fd5b6101578061001e6000396000f3006060604052600436106100405763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663c1ce53fc8114610045575b600080fd5b341561005057600080fd5b61009660046024813581810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061010d95505050505050565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156100d25780820151838201526020016100ba565b50505050905090810190601f1680156100ff5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610115610119565b5090565b602060405190810160405260008152905600a165627a7a723058207e8ac985f99f507869c23d1d1457c38e5aace7b1eafa9f31eff3e02d9aecfd450029"
    }
  },
  version: "0.4.18+commit.9cf6e910.Darwin.appleclang"
}

Now we have to create an actual contract object from the compiled contract definition, which we can instantiate on our Ethereum network later. To achieve this, we have to select the abi part of our MyFirstContract stored in the MyFirstContractCompiled variable and pass it to the web3.eth.contract function:



MyContract = web3.eth.contract(JSON.parse(MyFirstContractCompiled.contracts["/Users/as/ethcontracts/MyFirstContract.sol:MyFirstContract"].abi))

Make sure to replace the "as" with your actual user name!
It is important to not forget the JSON.parse part! This will parse the string representation of our abi into an actual JavaScript object.

You should get an output like this:

{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "reflect",
      outputs: [{...}],
      payable: false,
      stateMutability: "nonpayable",
      type: "function"
  }],
  eth: {
    accounts: ["0x839d4ed149062e6e2e7ab772167f366282c600ce"],
    blockNumber: 0,
    coinbase: "0x839d4ed149062e6e2e7ab772167f366282c600ce",
    compile: {
      lll: function(),
      serpent: function(),
      solidity: function()
    },
    defaultAccount: undefined,
    defaultBlock: "latest",
    gasPrice: 0,
    hashrate: 0,
    mining: false,
    pendingTransactions: [],
    protocolVersion: "0x3f",
    syncing: false,
    call: function(),
    contract: function(abi),
    estimateGas: function(),
    filter: function(options, callback, filterCreationErrorCallback),
    getAccounts: function(callback),
    getBalance: function(),
    getBlock: function(),
    getBlockNumber: function(callback),
    getBlockTransactionCount: function(),
    getBlockUncleCount: function(),
    getCode: function(),
    getCoinbase: function(callback),
    getCompilers: function(),
    getGasPrice: function(callback),
    getHashrate: function(callback),
    getMining: function(callback),
    getPendingTransactions: function(callback),
    getProtocolVersion: function(callback),
    getRawTransaction: function(),
    getRawTransactionFromBlock: function(),
    getStorageAt: function(),
    getSyncing: function(callback),
    getTransaction: function(),
    getTransactionCount: function(),
    getTransactionFromBlock: function(),
    getTransactionReceipt: function(),
    getUncle: function(),
    getWork: function(),
    iban: function(iban),
    icapNamereg: function(),
    isSyncing: function(callback),
    namereg: function(),
    resend: function(),
    sendIBANTransaction: function(),
    sendRawTransaction: function(),
    sendTransaction: function(),
    sign: function(),
    signTransaction: function(),
    submitTransaction: function(),
    submitWork: function()
  },
  at: function(address, callback),
  getData: function(),
  new: function()
}


7. Deploy the contract

Now that we have our MyContract object, we want to deploy it to our Ethereum development network.

As you know: There's no free lunch! Especially not on the Ethereum network. Every transaction has its cost. And contract deployment is a transaction! So we have to check first if we have enough Ether to actually do the deployment.

For convenience we define a neat variable pointing to our coinbase account (where all the mined ether goes to)..

MyAccount = eth.coinbase

..and check the funds:

eth.getBalance(MyAccount)

If this returns 0, we have to mine some Ether:

miner.start()

This will start the mining process on our initial geth development node. Just check your first terminal window (the one that is black in this tutorial, but is likely to be white on your Mac).

Meanwhile, we want to know the expenses of deploying our contract. The deployment itself is a Ethereum transaction with the compiled binary contract data as payload. We can use the web3.eth.estimateGas function to simulate this transaction and estimate the gas required to execute it.

First we create a hex string from the bin section of MyFirstContractCompiled and store it in a variable for later use. This is done by suffixing the bin string with "0x":

MyContractBin = "0x" + MyFirstContractCompiled.contracts["/Users/as/ethcontracts/MyFirstContract.sol:MyFirstContract"].bin

Then we can estimate the costs of contract deployment:

eth.estimateGas({data: MyContractBin })

This will output a number to which we will refer a little later when actually deploying the contract.

For now it's time to stop mining:

miner.stop()

Prior to be able to deploy the contract we have to authorize (or unlock) our account with our password, so nobody else than you can spend your ether for this deployment:

personal.unlockAccount(MyAccount, "password")

And now we create the contract:

MyContractInstance = MyContract.new({data: MyContractBin gas: 143940, from: MyAccount})

Supply at least as much gas as we estimated a few steps earlier!

You should get an output like this:

{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "reflect",
      outputs: [{...}],
      payable: false,
      stateMutability: "nonpayable",
      type: "function"
  }],
  address: undefined,
  transactionHash: "0x42878f04878dd33dbb6969d72ff48385ed2c050e867def4b2b1c3536d8ec9f85"
}

Now our contract is deployed to the Ethereum development network. But it's not alive yet: Its address is still undefined!

8. Activate and test the Contract

What we've done in the step before is telling the Ethereum network that we want to execute a transaction which creates our contract as an executable unit of code in the network. Now it's up to the miners to decide when and where this transaction will be executed. In real life they would take this decision based on the amount of gas we provided. But since we are in the test net, and we currently have only one miner, our transaction will be executed anyway! So let's start mining again:

miner.start()

After a few seconds check the contract instance again:

MyContractInstance

It should have an address set now! So our contract is alive and we can test it.
But first let's stop mining:

miner.stop()

Then we call the reflect method of our contract:

MyContractInstance.reflect.call("I'm alive!")

And voilĂ : Your contract tells you that it is alive!

If you wonder why we had to add call to the actual method name, you will find the answer here.

Congratulations! You just implemented your first Ethereum contract!



Friday, November 17, 2017

Installing a Solidity Development Environment for Ethereum Contract programming

This is a step by step tutorial to prepare your Mac for the development of Ethereum Smart Contracts in Solidity.

We assume you have a fresh macOS installation, with no development tools and no Ethereum software (like a wallet app) installed. It is always a good idea to do development in an isolated environment which is not used for any other purpose.

1. Install homebrew

Homebrew is the packet manager for macOS you will need for installation of the most tools we use throughout this tutorial.

To install homebrew issue this command in terminal:

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

The installation requires some interaction from you. So watch progress and enter the information requested!

2. Install Ethereum

Now that homebrew is installed, we will use it to install the latest version of Ethereum:

$ brew tap ethereum/ethereum

and then:

$ brew tap ethereum/ethereum

This will as well install one of the most important tools for our development plans: geth, the go command line interface for Ethereum.

Just check it by issuing

$ geth

If everything went right, geth will start up and begin synchronizing the Ethereum blockchain to your Mac. As we don't want this by now, enter [CTRL]+[C] in the terminal window running geth. Just ignore the errors popping up, if any!

3. Install the Solidity Compiler

Solidity is the programming language of choice for implementing smart contracts on the Ethereum network. In order to be able to run our contracts, we have to compile them. So we need the compiler:

$ brew install solidity

Depending on the power of your Mac it might take a while for the installation to complete. Even if it lingers around an installation step (e.g. installing "boost") for several minutes (or even hours): Just be patient and wait! It will finish! I suggest spending your time watching the CPU load in Activity Monitor.

Congratulations! Now you're up and running to start your own Ethereum development network and start implementing your first smart contract!

So please proceed to the next part of this tutorial: Getting started with a private Ethereum Blockchain and Solidity Contract Development on geth 1.6 or higher 


Tuesday, July 7, 2015

How to enable JetBrains WebStorm Web Development Features in IntelliJ Idea


JetBrains offer a rich variety of Integrated Development Environment targeted towards several different development languages and platforms, such as PHP, Python, .NET, iOS / OS X, and more.

Their WebStorm IDE is one of the most popular, feature-rich commercial Web IDEs on the market, supporting HTML, CSS, Client-Side JavaScript, node.js, and much more.

On the other hand, JetBrains IntelliJ Idea is one of the most popular, feature-rich commercial Java IDEs on the market, supporting Scala and Groovy as well. It is the base, for instance, of Android Studio - The official Android Development Platform.

Most (if not all) of JetBrain's IDEs are based on the same core, featured by different sets of installed plugins. This makes it easy to put all the WebStorm functionality into IntelliJ IDEA by just installing the appropriate plugins. To do so, just open IDEAs preferences and select the plugins pane:


Click Install JetBrains plugin and type the plugin name to find it. If a specific plugin is not available in the JetBrains repository, use the Browse repositories button to find it.

Based on a full IntelliJ IDEA Ultimate 14 installation you just need to load these few plugins:


  • AngularJS
  • Cucumber.js
  • Dart
  • EJS
  • File Watchers
  • Handlebars/Mustache
  • Jade
  • JSTestDriver Plugin
  • Karma
  • Meteor
  • PhoneGap/Cordova Plugin
  • Polymer & Web Components
  • TextMate bundles support

Just in case you missed something, here's the complete list of all plugins installed in WebStorm:

All Plugins enabled in JetBrains WebStorm

Tuesday, June 30, 2015

How to fix: Mozilla Firefox opens Bing instead of Homepage every time a new Tab is opened

If you find Firefox suddenly opening Bing (or probably another unwanted web site) whenever you open a new tab, it is very likely that you became a victim of some kind of malware. The very popular PDFCreator software and printer driver, for example, changes Firefox settings during install, and installs additional "tools", if you do not opt-out explicitly:


So make sure you uncheck the Block dangerous websites by installing Ad-Aware Web Companion and Set Search powered by Bing as my homepage, newtabs and default search engine on Internet Explorer, Firefox check boxes in PDFCReator's installation wizard!

But even if you let the installer hijack you browser, everything is not lost! It is not too hard to get rid of all the programs and settings PDFCreator kindly installed for you!

Ad-Aware Web Companion can simply be uninstalled from Window's Programs and Features Control Panel:


During uninstall Web Companion kindly asks you whether you would like it to undo all the damage it did to your system during installation:



So you should check both Restore check boxes and click the Remove button. 

What you will find is, that the new tab in Firefox will work as usual again. But your search settings remain hijacked to Bing! So lets fix them manually.

Open Firefox Options and select the Search page:


As you can see, the only search engine available is Bing! 

Now go an click the Add more search engines link at the bottom. This will take you to the Mozilla Firefox Add-Ons page where you can select additional search engines. We will install DuckDuckGo Plus, so we type the word "duck" into the search field:


After selecting DuckDuckGo Plus from the dropdown, we are taken to the download page:


Now click Add to Firefox, follow the instructions, and then open Firefox options again. 


Now select DuckDuckGo as your preferred search engine. That's it!

Last but not least: Just in case you need to fix the hijacked newtab manually, open Firefox and type "about:config" in its address bar.


If you see a void warranty warning like the one shown above, just click I'll be careful, I promise!

Now type "browser.newtab.url" into the search field:


As you can see, the url for a new browser tab is set to something at bing.com. Just double-click the entry and change the URL to whatever you want!

If you want new tabs to show a blank page, enter: "about:blank".

If you want the standard new tab page with tiles of your favourite sites, enter: "about:newtab".

If you want to support Joobik Player, enter: "http://www.joobikplayer.com"



Tuesday, April 14, 2015

Fixing Xcode 6.3 (iOS SDK) Error: Could not load NIB in bundle

After the recent update of Xcode to version 6.3 iOS developers reported to encounter exceptions of kind


Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: Could not load NIB in bundle: ...

followed by the path to the running iPhone or iPad application, and the name of the NIB file the it was trying to load. These exceptions appear to fire at runtime only, not at compile time. So make sure you test your iOS applications completely after building them with Xcode 6.3!

The reason for this issue seems to be a bug of Xcode 6.3 when compiling XIB files using size classes. Size classes is a concept introduced with iOS 8 which enables you to define view layouts for different UI orientations and different iPhone and iPad devices within a single Interface Builder document. A very good introduction to size classes is given at adaptioncurve.net.

So let's have a look at a little example to elaborate the problem! 

We have an Xcode project with the deployment target set to iOS 7 and Universal device support:











We have two XIB files: TestSizeClasses.xib is targeted to iPhone and iPad. TestSizeClassesIphone~iphone.xib is named according to Apple's conventions to be targeted to iPhone only:










Both XIB files have size classes enabled:















After compiling these files with XCode 6.2, and running them in Simulator let's have a look at the NIB files created at compile time. You will find these NIBs in your user directory under a path of this structure:
~/Library/Developer/CoreSimulator/Devices/<cryptic_device_number>/data/Containers/Bundle/Application/<cryptic_app_number>/<app_name>.app

In order to identify the correct cryptic number directory, just sort directories by modification date and choose the last modified one.

Xcode 6.2 created these three NIB files:





TestSizeClasses.xib was split into two device specific NIB files, but TestSizeClassesIphone~iphone.xib was compiled to a single, iPhone specific NIB file because the '~' - part of the file name signals to the compiler that we care about device specific layouts by ourselfs. So everything is fine!

Now lets compile the same files with Xcode 6.3 and have a look at the results:





As you can see, Xcode appends another '~iphone' part to the name of TestSizeClassesIphone~iphone.nib, although we wanted it to leave our file name alone! So this is the bug in Xcode 6.3 XIB processing which will lead to runtime 'could not load nib' exceptions when your app tries to load the badly named nib file. 

The bug will haunt you when you have size classes enabled for a XIB file, and the deployment target of your Xcode project is set to something earlier than iOS 8. Because size classes are only supported in iOS 8.0 and later, Xcode will compile the old device specific nib files automatically for older iOS versions. It doesn't matter whether your app is universal or targeted to iPad or iPhone only. As soon as you name a XIB device specific using the '~', your app will crash.

Now that we know the reasons for this exception, we have four options to handle it:



Option 1: Target to iOS 8.0 or later 

The simplest option would be to target your app to iOS 8 or later, thus the device specific NIB files would just not be created. But if you want to support older iOS versions, this is not an option for you.

Option 2: Use storyboards instead of  XIB files

If you can afford to make the effort, migrate all your XIBs to storyboards. These will be compiled correctly by Xcode 6.3.

Option 3: Disable Size Classes

When you disable size classes for a XIB file, Xcode will force you to target this file to a specific device and will remove all data it thinks will not be of use to represent this device:












So choose this option only when you absolutely trust in that Xcode will not remove anything you need from your XIB files. As a rule of thump: If all layout constraints in a XIB apply to all size classes, you are safe. If different constraints apply to different size classes, think twice!

Option 4: Handle device specific XIBs in code

This is the less destructive of all options and it is not as expensive to implement as it might seem! All you have to do is to name your XIB device specific by avoiding Apple's naming conventions (the '~'), and add very few lines of code to load the correct NIBs.

So we rename our TestSizeClassesIphone~iphone.xib to TestSizeClasses-Iphone.xib. We create another TestSizeClasses-Ipad.xib to cover all devices. And we create a  single TestSizeClassesViewController, which we set the file's owner of both XIB files:










After compiling the code, we'll find the following NIBs:









As you can see, Xcode created both, an ~iphone version and an ~ipad version of all of our NIB files. Now all we have to do is to tweak our Objective-C code to load the correct NIB version per device.

So open TestSizeClassesViewController and implement its init method to load device specific nib files:

- (id)init
{
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
    {
        return [self initWithNibName:@"TestSizeClasses-iPad" bundle:nil];
    }
    else
    {
        return [self initWithNibName:@"TestSizeClasses-iPhone" bundle:nil];
    }

}

Do the same in all places of your code where the view controller is instantiated directly using initWithNibName:

...
TestSizeClassViewController* sizeClassController;    
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
    sizeClassController = [self initWithNibName:
        @"TestSizeClasses-iPad" bundle:nil];
}
else
{
    sizeClassController = [self initWithNibName:
        @"TestSizeClasses-iPhone" bundle:nil];
}

...

This way, the app will load the TestSizeClasses-Iphone~iphone.nib and TestSizeClasses-Ipad~ipad.nib only. It will ignore the TestSizeClasses-Iphone~ipad.nib and TestSizeClasses-Ipad~iphone.nib.


That's all there is about this Xcode issue. Now it's up to you to decide which of the four options is the best for your needs.




Monday, March 9, 2015

One more thing.. - *** The all vintage myWatch!!! ***


  • The smart watch that was always there!
  • Operates without a mobile phone in your pocket!
  • Displays current time on its 10k++HDSuperDuperDensityRealityViewRetina(TM)-Display!
  • Comes with pre-installed calendar app to display current date and day of week - all on a distinct tile!
  • Makes realistic tick-tock noise with it's built-in VintageSound(TM) Signal Processor!
  • Runs 4+ years without recharging!
  • DIY replaceable battery pack
  • Comes with built-in AnalogueCrown technology which lets you adjust time, date, and day of week in real time!
  • Covered by saphire glass with a single rounded edge!
  • Features Swipe-To-Clean gesture!
  • Knows your pulse - but won't tell!

This changes nothing - again!

http://www.joobikplayer.com

Tuesday, March 3, 2015

How iTunes Match does (or does not) sync Video Playlists to iPhone, iPod, and iPad



When Apple first introduced iTunes Match in 2011, everyone was excited: Eventually there was an easy way of getting all those iTunes media files to synchronize between all your Macs, PCs, iPhones, iPods, and iPads seamlessly via iCloud! But after a few days of using it it became obvious that there were some very annoying drawbacks and restrictions. And many of them do still exist today.

iTunes Match works best when used with music files (audio and music videos) purchased at Apples iTunes Store. It does not feel quite as comfortable with oder media kinds, especially videos. It works even worse with playlists. And it (almost) refuses to operate on media not available from the iTunes Store.

So the ultimate challenge for the media enthusiast these days is to get this playlist of home videos synced from iTunes to the iPhone via iCloud! And I will try to show you in this post how this can be achieved.

So lets start with the facts I found out during my research about playlists and videos in the realm of iTunes Match and iCloud. All these findings are based on iTunes 12.1 on OS X Yosemite and iOS 8.1.3 on iPod Touch 5g. There's no warranty that all or only some of these findings can be reproduced by everyone with the same or different hardware and software configuration:


Finding 1: There's almost no official documentation

You can check which media types iTunes Match will sync in your country at all. And somewhere in the F.A.Q-section of this page you will find the statement, that "playlists with videos, voice memos, or PDF files will not sync."
That's it! And it's not even half of the truth, as we will see later.

Finding 2: iTunes Match behaves different on an iOS device and on iTunes 

When you turn on iTunes Match in iTunes on your PC or Mac, it is still possible to select videos and playlists for local synchronization to your iOS device. iTunes will even try to tell you that these playlists are there:



BUT: When you turn on iTunes Match on an iOS device, only the videos are available in the original iOS Video or Music App - The playlists are not! 
The reason: When iTunes Match is turned on on an iOS device, this device will show only playlists available on iCloud. So in order to make some playlists appear on your device at all, you must have iTunes Match enabled on at least one of your desktop computers. Then you can check in iTunes easily if a playlist synced or not:


When the cloud symbol is struck through, the item is not on iCloud.


Finding 3: iTunes Match handles Music and Music Videos different from the Rest

Short side note: Everything just said above is not true for Music and Music Videos. These cannot be synced manually when iTunes Match is turned on on your iOS device:



Finding 4: iTunes Match will only sync media available from the iTunes Store

You will only get your media files into iCloud, if the iTunes Store offers them for sale in your country. It doesn't matter whether you purchased them from Apple or not. When iTunes Match is turned on, your media library will be scanned and iTunes tries to match each of your media files with the Store. It is Apple's secret how a match would be recognized. But you can definitely say that there is no chance to ever get any of your home made videos into iCloud. You will have to sync all of these files locally from your computer to your iOS device.
Whether a playlist is synced to iCloud depends on the playlist type and sync status of the items it contains. Details will be discussed in Finding 7.

Finding 5: It's cumbersome to check your iOS device for playlists synced to it

While you can use the native iOS Video App to check for all videos available on your device (whether from iCloud or not), this app will not reveal any of your playlists.
The native iOS Music App will show you all playlists available on your device. Remember that - as said in Finding 2 - all of these playlists reside on iCloud. You won't be able to access local playlists with iTunes Match turned on. While all playlists are listed here, only music and music video playlists can be played from the iOS Music App. All other playlists appear to be empty:



Use Joobik Player to view the content of all playlists and play them on your iPhone, iPod, or iPad:


In order for a playlist to appear in Joobik Player, the playlist itself must be synced to iCloud, but the media files must reside physically on your iOS device. I.e. if a playlist contains items from iCloud, at least one of these items must be downloaded from the cloud to your device using the native iOS Video or Music App. If a playlist contains items not available from iCloud, these items must be synced locally from iTunes to your iOS device. Detailed instructions on how to do this are given at the end of this post.

Finding 6: iTunes Match might not forget

When I turned on again iTunes Match on my iPod after several months of using only local synchronization, I was surprised to see appear several playlist that where not on my iTunes-Match-enabled Mac. The only explanation I see for this behaviour is that these lists must originate from an old computer, which I don't own anymore. So iTunes Match becomes even more confusing, when more than one Computer is involved in the synchronization pool. But this might be a topic for another blog post..


Finding 7: iTunes Match handles Smart Playlists different from ordinary Playlists

This is the most important finding because it will lead us to the solution of how to get complete playlists synced to an iOS device with iTunes Match turned on!
An ordinary playlist will sync to iCloud as long as it contains only tracks that sync to iCloud as well. So adding a single home video to an ordinary playlist will remove the whole list from the cloud in iTunes 12.
With Smart Playlists it's different: A Smart Playlist doesn't care about the iCloud status of the items it contains. A Smart Playlist containing only ineligible items will sync to iCloud anyway and, thus, appear on your iOS device as an empty playlist. A Smart Playlist becomes ineligible for iCloud sync only when you add the reference to another playlist to the smart playlist rules:



Putting it all toghether

When it's about music and music videos, you will depend on Apple's grace: Either they sync to iCloud or they don't. But all other media types can be tweaked by mixing iCloud Smart Playlists with files synchronized locally:

Create a smart playlist that syncs to iCloud as described in Finding 7. If you cannot find smart rules sufficient to group all desired tracks into one smart list, just create an ordinary playlist containing these tracks and add an unique tag to the comments field (or any other meta data field) of each of the tracks on this list:



Create a Smart Playlist referencing this unique tag:


Now the Smart Playlist itself will sync to iCloud, while the tracks will not:


Sync the Smart Playlist locally from iTunes to your iOS device:


Play the playlist with Joobik Player:



If you want to modify the iTunes Playlist on your iPhone or iPad, just copy it to a Joobik Playlist. With Joobik Playlists you can add, remove, and rearrange tracks.