Goolgle has a tablet app quality checklist recommended for anyone wanting to publish an app for Android tablets in the Play store.
It's no doubt useful for anyone porting their first Android app to run on a tablet (from a phone) but most of the points apply regardless of the OS being used and so could apply to those of you making the transition from Windows Phone to Windows 8.
As an idea of how it is relevant, see this partial* list of section headings:
1. Test for Core App Quality
2. Optimize your layouts for larger screens
3. Take advantage of extra screen area available on tablets
4. Use Icons and other assets that are designed for tablet screens
5. Adjust font sizes and touch targets for tablet screens
7. Offer the app's full feature set to tablet users
8. Don’t require hardware features that might not be available on tablets
* Android specific sections ommitted.
Check out the full details: http://developer.android.com/distribute/googleplay/quality/tablet.html
Let me know if you find this useful.
Thursday, December 20, 2012
Monday, December 17, 2012
Security and access to SMS
Lots of Windows Phone developers want access to SMS*. It's an interesting data source and can allow the creation of lots of useful, helpful and interesting apps. There are security implications of allowing such access though and, unfortunately, most developers seem happy to ignore this or not take it seriously.
Today I heard about a scam that was only possible due to SMS access and "stole an estimated 36+ million Euros from more than 30,000 bank customers from multiple banks" (emphasis mine).
You can read more about the Eurograbber attack here but I think the important takeaway for developers is to focus on security and not easily dismiss or criticise platform limitations and restrictions that are there to protect the person who's phone it is.
And for everyone entering passwords or security information on a website. Always type in the domain for a website directly. Avoid following links, especially if it's a shortened or redirect link.
* If you don't know, Windows Phone does not allow developers of third party apps to access a phone's SMS history as part of it's strategy for protecting data security.
Found via Simon Judge.
Today I heard about a scam that was only possible due to SMS access and "stole an estimated 36+ million Euros from more than 30,000 bank customers from multiple banks" (emphasis mine).
You can read more about the Eurograbber attack here but I think the important takeaway for developers is to focus on security and not easily dismiss or criticise platform limitations and restrictions that are there to protect the person who's phone it is.
And for everyone entering passwords or security information on a website. Always type in the domain for a website directly. Avoid following links, especially if it's a shortened or redirect link.
* If you don't know, Windows Phone does not allow developers of third party apps to access a phone's SMS history as part of it's strategy for protecting data security.
Found via Simon Judge.
Wednesday, December 12, 2012
WP8 lock screen alignment issues
Anyone else seen issues with the lock screen alignment? Like above?
It's like it's started to scroll over to kids corner but got stuck part way across. As the image on the right shows, it's staying like that even when scrolling up to reveal the start screen.
It's not a critical issue but I wondered if others have experienced this.
It's like it's started to scroll over to kids corner but got stuck part way across. As the image on the right shows, it's staying like that even when scrolling up to reveal the start screen.
It's not a critical issue but I wondered if others have experienced this.
Wednesday, December 05, 2012
Deployment Error 0x89731800
I got this error today when deploying a XAP file to an emulator and the only reference I could find to it was a 7 year old message in Chinese.
Fortunately I got round this problem by closing the emulator and then reattempting the deployment and all was good.
Just thought this might help out someone else who comes across this issue.
Fortunately I got round this problem by closing the emulator and then reattempting the deployment and all was good.
Just thought this might help out someone else who comes across this issue.
Tuesday, December 04, 2012
My #AlphaLabsCC developer diary
I was recently involved in a project for Alphalabs.
If you don't know, Alphalabs is a project sponsored by Nokia with the aim to inspire app developers to be more creative.
As part of my work I was asked to keep a diary of thoughts, notes, ideas, problems, etc. while the development was being done. The original plan was that this would be released bit by bit as part of regular (daily?) emails to those who were initially invited to take part in this years project "the always on telephone club".
Plans have changed and my entries have now all been posted at http://alphalabs.cc/matt-laceys-developer-diary/
If you want an idea of what I was thinking during the development or when I got weird errors or my Azure account was suspended when we load tested the app then take a look.
You may also notice that the "diary" entries all have titles, rather than dates (and times). This was just me trying to hide the inconsistent nature of the work and the fact most of it was done in the middle of the night. ;)
If you don't know, Alphalabs is a project sponsored by Nokia with the aim to inspire app developers to be more creative.
As part of my work I was asked to keep a diary of thoughts, notes, ideas, problems, etc. while the development was being done. The original plan was that this would be released bit by bit as part of regular (daily?) emails to those who were initially invited to take part in this years project "the always on telephone club".
Plans have changed and my entries have now all been posted at http://alphalabs.cc/matt-laceys-developer-diary/
If you want an idea of what I was thinking during the development or when I got weird errors or my Azure account was suspended when we load tested the app then take a look.
You may also notice that the "diary" entries all have titles, rather than dates (and times). This was just me trying to hide the inconsistent nature of the work and the fact most of it was done in the middle of the night. ;)
Monday, December 03, 2012
More on my opinion about commands
Last week I wrote about "A bad way to set up commands in your view model".
This prompted a few comments and strong opinions in both the comments and on twitter.
My main intention with the post was originally to rally against creating properties with a private setter when they will only ever be set once and the code that does the setting is kept apart from the property.
All things being equal I'd rather maintain code that looks like my preferred code than the first example.
I do, however,appreciate that this is not optimal in all situations. I've just spent lots of time working with code that does trivial things in the command or are executed occassionally and so the overhead of creating a new command each time it's needed is not an issue.
For the avoidance of doubt, I'm perfectly fine with any of the following when used at an appropriate time.
Anyway, moving on...
This prompted a few comments and strong opinions in both the comments and on twitter.
My main intention with the post was originally to rally against creating properties with a private setter when they will only ever be set once and the code that does the setting is kept apart from the property.
All things being equal I'd rather maintain code that looks like my preferred code than the first example.
I do, however,appreciate that this is not optimal in all situations. I've just spent lots of time working with code that does trivial things in the command or are executed occassionally and so the overhead of creating a new command each time it's needed is not an issue.
For the avoidance of doubt, I'm perfectly fine with any of the following when used at an appropriate time.
public class MyViewModel : ViewModelBase { private RelayCommand myCommand; public RelayCommand MyCommand { get { if (myCommand == null) { myCommand = new RelayCommand(() => { // some functionality here }); } return myCommand; } } }or
public class MyViewModel : ViewModelBase { private RelayCommand myCommand; public RelayCommand SaveCommand { get { if (myCommand == null) { myCommand = new RelayCommand(this.Save); } return myCommand; } } private void Save() { // do something } }and I've used both in the past.
Anyway, moving on...
Thursday, November 29, 2012
A bad way to set up commands in your view model
tl;dr; Put code where it is defined. It makes maintenance much easier.
This has become a bit of a pet-peeve of mine lately. Please indulge me while I share.
I spend a lot of time working with code that was started by someone else.
As MVVM Light is used in most projects I work on, I see code that looks like this a lot:
Seeing this just makes me think that the original developer was planning on allowing for the possibility that they may want to change what the command does at some point in the future.
But I haven't seen any code that actually does that, yet.
Remember Y.A.G.N.I.
I think this is much better:
And you probably don't really need the empty constructor. (I know in this instance you don't but depending on what else is being done in the VM you might.)
There is no difference in the actual number of lines of code or functionality but it's much better.
Putting the code where it is defined means it's easier to navigate the code when you aren't familiar with it.
Let's say I need to change (or fix) some behaviour that is triggered via a command. I'll start in the view (the UI) which uses/triggers that command. From there I can easily see where the command is defined (Ctrl + Click : with ReSharper). That's good, but if the code isn't there I have to search the code ("Find Usages" or "Find References") and then go to where I think it's most likely to be based on what I can see in the search results.
I've had to, unnecessarily, go hunting around the code for what I want.
The code I'm looking for has been hidden!
That's not a good way to treat the people who will be maintaining the code you wrote.
Not wanting to make any claims about my mental health and disposition but:
Am I missing something by doing this my way?
Does the maintainability benefit come at some other cost?
Obviously there are exceptions to the above and times when you may not want to have a readonly command. My point is to think about the code you're writing and the people who will be maintaining it and trying to work out what it does. The easier you can make this for them the less frustrated with you they'll get. :)
This has become a bit of a pet-peeve of mine lately. Please indulge me while I share.
I spend a lot of time working with code that was started by someone else.
As MVVM Light is used in most projects I work on, I see code that looks like this a lot:
public class MyViewModel : ViewModelBase { public MyViewModel() { MyCommand = new RelayCommand(() => { // some functionality here }); } public RelayCommand MyCommand { get; private set; } }This bugs me.
Seeing this just makes me think that the original developer was planning on allowing for the possibility that they may want to change what the command does at some point in the future.
But I haven't seen any code that actually does that, yet.
Remember Y.A.G.N.I.
I think this is much better:
public class MyViewModel : ViewModelBase { public MViewyModel() { } public RelayCommand MyCommand { get { return new RelayCommand(() => { // some functionality here }); } } }
There is no difference in the actual number of lines of code or functionality but it's much better.
Why do I think this is better?
It puts the actual code where it is defined and so when I identify the command I'm after I can see what it does.Putting the code where it is defined means it's easier to navigate the code when you aren't familiar with it.
Let's say I need to change (or fix) some behaviour that is triggered via a command. I'll start in the view (the UI) which uses/triggers that command. From there I can easily see where the command is defined (Ctrl + Click : with ReSharper). That's good, but if the code isn't there I have to search the code ("Find Usages" or "Find References") and then go to where I think it's most likely to be based on what I can see in the search results.
I've had to, unnecessarily, go hunting around the code for what I want.
The code I'm looking for has been hidden!
That's not a good way to treat the people who will be maintaining the code you wrote.
Not wanting to make any claims about my mental health and disposition but:
"Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live."
Am I missing something by doing this my way?
Does the maintainability benefit come at some other cost?
Obviously there are exceptions to the above and times when you may not want to have a readonly command. My point is to think about the code you're writing and the people who will be maintaining it and trying to work out what it does. The easier you can make this for them the less frustrated with you they'll get. :)
Do emulators have value if we still have to test on actual devices.?
This is in response to a comment on my post about the undocumented way I found of creating a xap file you can't deploy to a #wp8 device.
In that post I claimed that it was important to test on physical devices as well as in the emulator. The comment stated
Firstly, I'm not aware of anyone ever claiming that an emulator completely does away with the need for testing on real devices.
I've only heard people claim you MUST test on physical hardware in addition to an emulator/simulator. This goes back many, many years and has always been essential for phones as emulators have never given a complete representation of actual devices. They've gotten a lot better but by their very nature they're not perfect.
This is important:
An emulator (or simulator) emulates (or simulates) a real device. It doesn't claim to give a complete representation of a real device.
This list assumes use of VS2012 for testing Windows Phone (8) apps. For other platforms and emulators/simulators the above lists may vary slightly.
In that post I claimed that it was important to test on physical devices as well as in the emulator. The comment stated
"this seems to break the whole "emulator" thing, since it seems that it doesn't properly emulate a physical device!"
Firstly, I'm not aware of anyone ever claiming that an emulator completely does away with the need for testing on real devices.
I've only heard people claim you MUST test on physical hardware in addition to an emulator/simulator. This goes back many, many years and has always been essential for phones as emulators have never given a complete representation of actual devices. They've gotten a lot better but by their very nature they're not perfect.
This is important:
An emulator (or simulator) emulates (or simulates) a real device. It doesn't claim to give a complete representation of a real device.
What is an emulator actually good for then?
- Testing quickly
- Testing multiple devices or configurations and switching between them quickly
- Automated testing
- Testing before devices are available.
- Testing on devices you can't buy (due to financial or location restrictions) - but beware that this means you won't know about the experience of the app on those devices. This may or may not be an issue.
- Avoiding issues with the number of side-loaded apps installed on an actual device. (Or maybe I just need to keep track of what I side-load better)
- Testing use in different locations (without needing to create your own mocking layer)
- Testing use of the accelerometer (without needing to create your own mocking layer)
- Testing different network conditions (network speed & signal strength) - again without having to create your own mocking layer.
- Testing app behaviour when reminders are triggered.
What must you test on an actual device?
- What it's really like to use the app in the hand (your thumb and a mouse pointer are not the same!)
- What the actual performance is like on actual devices
- Any functionality that isn't available in the emulator (interruption from incoming phone calls, etc.)
- That the behaviour of the app on an actual device is the same as the emulator.
This list assumes use of VS2012 for testing Windows Phone (8) apps. For other platforms and emulators/simulators the above lists may vary slightly.
Wednesday, November 28, 2012
Why "scratching your own itch" is a bad idea for developers
There's a popular idea that if you have a need for something then it's likely that other people will too. It's often termed "scratching your own itch".
Developers like to take this idea and assume that if there's something they need or want and build an app to meet that scenario others will also buy that app to meet the same need.
I think this view ignores a big issue.
The "others" in this scenario are typically other developers, and developers like writing code to solve their own problems.
The corollary of this is that developers don't look to buy solutions written by other developers to solve their problems.
Yes this is a huge generalisation but I believe it also holds a lot of truth. Just ask a developer you know how often they buy solutions to their problems verses writing their own solutions.
The mis-assumption is that other developers will buy their app as they have the same problem because they are just like them. The problem is that just like them the other developers will be creating their own apps to solve the same problem.
Developers building small apps for other developers isn't a great way to find a big market and sell lots of apps.
By all means build such apps just don't get upset if you don't get millions of downloads.
Developers like to take this idea and assume that if there's something they need or want and build an app to meet that scenario others will also buy that app to meet the same need.
I think this view ignores a big issue.
The "others" in this scenario are typically other developers, and developers like writing code to solve their own problems.
The corollary of this is that developers don't look to buy solutions written by other developers to solve their problems.
Yes this is a huge generalisation but I believe it also holds a lot of truth. Just ask a developer you know how often they buy solutions to their problems verses writing their own solutions.
The mis-assumption is that other developers will buy their app as they have the same problem because they are just like them. The problem is that just like them the other developers will be creating their own apps to solve the same problem.
Developers building small apps for other developers isn't a great way to find a big market and sell lots of apps.
By all means build such apps just don't get upset if you don't get millions of downloads.
Tuesday, November 27, 2012
An undocumented way of creating a xap file you can't deploy to a #wp8 device
"Deployment failed" it's not a message you want to see when deploying your app to a device. Especially if you've previously deployed to the emulator without issue.
Even more worrying is this message:
A little googling for that message turns up the fact that this is also the error message displayed when trying to use the, now removed, WP8 version of the ReactiveExtensions but not a lot else. (As referenced at http://social.msdn.microsoft.com/Forums/en-US/rx/thread/ec22cacb-a996-4244-83ca-fe3b1d5ac5ff and reported http://blogs.msdn.com/b/rxteam/archive/2012/11/14/update-on-windows-phone-8-support-for-rx-v2-0.aspx.)
It turns out that this was a result of an issue caused by a workaround after moving to TFS in the cloud.
Before moving to the cloud we had a powershell script which would rename the XAP file to include the version number of the main assembly. (This is invaluable during testing when you want to know you're installing the right version.)
Unfortunately this didn't work on the server.
Plan B was to use a simple command line app to rename the XAP instead.(It seems you can run [console] apps on the build server - but presumably with very little functionality actually available.)
To ensure that the exe was in the appropriate output directory I added it the project, set it's build action to None and set it to always copy to the output directory. This was the problem. The WP8 (this problem didn't happen in the WP7 version) compiler was seeing that there was an EXE in the project and doing something different with the final XAP.
Fortunately, this was resolved by adding the EXE to the solution directory and then referring to it from there without adding it to the project. The after build event still knows where everything is and all is good.
TL;DR/Lesson: Don't include desktop EXEs in your WP8 project, even if they're not included in the XAP.
And be sure to always test on actual devices, not just the emulator. It is possible for apps to run in the emulator and not even load on an actual device.
Even more worrying is this message:
"Deployment optimization failed due to an invalid assembly. Rebuild your source projects and try again."Especially worrying after rebuilding several times.
A little googling for that message turns up the fact that this is also the error message displayed when trying to use the, now removed, WP8 version of the ReactiveExtensions but not a lot else. (As referenced at http://social.msdn.microsoft.com/Forums/en-US/rx/thread/ec22cacb-a996-4244-83ca-fe3b1d5ac5ff and reported http://blogs.msdn.com/b/rxteam/archive/2012/11/14/update-on-windows-phone-8-support-for-rx-v2-0.aspx.)
It turns out that this was a result of an issue caused by a workaround after moving to TFS in the cloud.
Before moving to the cloud we had a powershell script which would rename the XAP file to include the version number of the main assembly. (This is invaluable during testing when you want to know you're installing the right version.)
Unfortunately this didn't work on the server.
Plan B was to use a simple command line app to rename the XAP instead.(It seems you can run [console] apps on the build server - but presumably with very little functionality actually available.)
To ensure that the exe was in the appropriate output directory I added it the project, set it's build action to None and set it to always copy to the output directory. This was the problem. The WP8 (this problem didn't happen in the WP7 version) compiler was seeing that there was an EXE in the project and doing something different with the final XAP.
Fortunately, this was resolved by adding the EXE to the solution directory and then referring to it from there without adding it to the project. The after build event still knows where everything is and all is good.
TL;DR/Lesson: Don't include desktop EXEs in your WP8 project, even if they're not included in the XAP.
And be sure to always test on actual devices, not just the emulator. It is possible for apps to run in the emulator and not even load on an actual device.
Background agent expiry in Windows Phone 8
In Windows Phone 7[.x] background agents would expire (stop working/running) if an app wasn't launched for 14 days.
Today I noticed in MSDN that things are slightly different in Windows Phone 8:
There are a few cases where an app’s background agent will not expire or will be automatically renewed.
• If the Tile for your app is pinned to the phone’s Start screen, the expiration time for your background agent schedule is automatically extended to two weeks whenever your background agent calls Update(ShellTileData) to update the Tile.
• If your app is selected by the user to display notifications on the on the lock screen, the expiration time for your background agent schedule is automatically extended to two weeks whenever your background agent calls Update(ShellTileData) to update the lock screen.
• If your app auto-uploads photos using a resource-intensive agent, the resource-intensive agent schedule will not expire as long as the user has enabled this feature for your app in the photos+camera settings page.
Monday, November 26, 2012
Spinning my nodes #AlphaLabsCC
Hold the phone. I've been actually having fun writing XNA!
Ok, there was some head scratching getting some of the maths right but I got there.
Circles were boring.
Now I have spirals. And although you can't see it in these pictures they spin.
It's quite hypnotic to watch when animated.
The spirals (nodes) vary in direction of rotation, size and speed of rotation.
Ok, there was some head scratching getting some of the maths right but I got there.
Circles were boring.
Now I have spirals. And although you can't see it in these pictures they spin.
It's quite hypnotic to watch when animated.
The spirals (nodes) vary in direction of rotation, size and speed of rotation.
Saturday, November 24, 2012
Node Garden + multiple colours + transparencies #AlphaLabsCC
I've been playing with transparencies and multiple colours of node.
The screenshot below gives an idea but when animated it can create some really nice effects.
Best of all this only required adding a few lines of code. Plus I got to delete a load of other code I didn't need. - Deleting code is always good. :)
I'm looking forward to exploring other visual ideas.
This was done with Silverlight, but as the HTML version of the demo code is now available, I might look at using that for my next itteration.
The screenshot below gives an idea but when animated it can create some really nice effects.
Best of all this only required adding a few lines of code. Plus I got to delete a load of other code I didn't need. - Deleting code is always good. :)
I'm looking forward to exploring other visual ideas.
This was done with Silverlight, but as the HTML version of the demo code is now available, I might look at using that for my next itteration.
Thursday, November 22, 2012
Passing additional information between nodes #AlphaLabsCC
As promised, here's an example of how to pass additional information between nodes/devices as part of your AlphaLabs projects.
I'm going to show how to pass the color of the current node to other devices, along with it's position, so that instead of just having your own node coloured and all other nodes white, every node is represented by the theme colour of the device it is actually on.
I'm also going to show how to do this with the Silverlight version as I'm assuming that everyone will be able to follow along with that without issue.
Something like this:
Obviously this makes it harder to tell which is your own node (hint, in the base code it's slightly larger than the others) but I'm sure you can cope and come up with interesting and exciting ways of indicating this in your apps/experiments/art.
So how do we do this?
It's all down to the power of the Tag!
I'm sure you're familiar with the Tag property of a Control or FrameworkElement. It's a useful miscellaneous property for storing arbitrary information in an object. Well, NodeGardenLib.Node has one too. The only difference is that in the Node it's a string, not an object.
We can add anything (within reason) to this property and it can be passed between devices via the underlying messaging functionality.
We'll start by setting the Tag when we create the node.
In MainPage.xaml.cs:
You'll notice I'm using a helper method to abstract the serialization. Here are all the helper methods I'm using:
I'm using Json.Net for the serialization as it's already referenced (as a dependency of SignalR) but you could use whatever you want.
The other important point of note is that I have exception handling in the Deserialize[AsColor] method. This is REALLY important as we may be receive messages from apps on other devices and they may be sending different, or no, information in the Tag. Be sure to handle deserialization exceptions and never make assumptions about what you'll receive.
This is of minor issue when you're only connecting to your own devices as it's easy to tell when not all devices are running the same version of the app-that's why the version number is auto-generated and displayed on the debug/config page.
It becomes more of an issue when connecting to the internet and anyone else is running a version of the app and also connecting to the internet as you'll be notified of each others nodes.
BTW: Always connect via the web option unless you really, really have a good reason to use UDP.
This is for 2 reasons: 1. We get to track what you're doing as everything that goes via the web is logged. (We'll make all the logged data available at the end of the project.) And 2. It's cool when other nodes (representing real other people/devices) appear in your garden.
Once we've got the color information in the tag we have to make sure we send it. So update MyVisualNode.cs:
Then we need to make sure that we use the received color when drawing nodes.
In the Draw method of VisualNode.cs add:
Simples.
Now just fire up a couple of emulators and voila:
If you try this over Web comms you'll notice that other nodes don't show up until they're moved. I think this is because of the way the WIEB (Where Is EveryBody) message is handled. Let me know if this is a big issue for you. Or fix it and send me a patch. ;)
But what if we want to test this easily without deploying to lots of devices? We'll just update the default nodes-that's what they're there for.
So in MainPage.xaml.cs
The above is all quite trivial but hopefully shows how easy it is to send additional information. You can send ANYTHING so don't let yourself be limited by just thinking you're limited to accent colours.
Now go. And be creative...
I'm going to show how to pass the color of the current node to other devices, along with it's position, so that instead of just having your own node coloured and all other nodes white, every node is represented by the theme colour of the device it is actually on.
I'm also going to show how to do this with the Silverlight version as I'm assuming that everyone will be able to follow along with that without issue.
Something like this:
Obviously this makes it harder to tell which is your own node (hint, in the base code it's slightly larger than the others) but I'm sure you can cope and come up with interesting and exciting ways of indicating this in your apps/experiments/art.
So how do we do this?
It's all down to the power of the Tag!
I'm sure you're familiar with the Tag property of a Control or FrameworkElement. It's a useful miscellaneous property for storing arbitrary information in an object. Well, NodeGardenLib.Node has one too. The only difference is that in the Node it's a string, not an object.
We can add anything (within reason) to this property and it can be passed between devices via the underlying messaging functionality.
We'll start by setting the Tag when we create the node.
In MainPage.xaml.cs:
private void CreateOwnNode() { var myNode = new MyVisualNode(this.rand, MainCanvas, this.gardener); this.gardener.AddSelfNode(myNode.X, myNode.Y); myNode.Id = this.gardener.GetSelfNodeId(); var accentColor = (Color)Application.Current.Resources["PhoneAccentColor"]; myNode.Tag = accentColor.Serialize(); this.nodes.Add(myNode); }
You'll notice I'm using a helper method to abstract the serialization. Here are all the helper methods I'm using:
using System; using System.Windows.Media; using Newtonsoft.Json; public static class ColorExtensions { public static string Serialize(this Color source) { return JsonConvert.SerializeObject(source); } } public static class StringExtensions { public static Color DeserializeAsColor(this string source) { try { return JsonConvert.DeserializeObject<color>(source); } catch (Exception exc) { return Colors.White; } } public static Brush DeserializeAsBrush(this string source) { return new SolidColorBrush(source.DeserializeAsColor()); } }
I'm using Json.Net for the serialization as it's already referenced (as a dependency of SignalR) but you could use whatever you want.
The other important point of note is that I have exception handling in the Deserialize[AsColor] method. This is REALLY important as we may be receive messages from apps on other devices and they may be sending different, or no, information in the Tag. Be sure to handle deserialization exceptions and never make assumptions about what you'll receive.
This is of minor issue when you're only connecting to your own devices as it's easy to tell when not all devices are running the same version of the app-that's why the version number is auto-generated and displayed on the debug/config page.
It becomes more of an issue when connecting to the internet and anyone else is running a version of the app and also connecting to the internet as you'll be notified of each others nodes.
BTW: Always connect via the web option unless you really, really have a good reason to use UDP.
This is for 2 reasons: 1. We get to track what you're doing as everything that goes via the web is logged. (We'll make all the logged data available at the end of the project.) And 2. It's cool when other nodes (representing real other people/devices) appear in your garden.
Once we've got the color information in the tag we have to make sure we send it. So update MyVisualNode.cs:
this.gardener.UpdateSelfNodePosition(this.X, this.Y, this.Tag);
Then we need to make sure that we use the received color when drawing nodes.
In the Draw method of VisualNode.cs add:
this.NodeSize = Map(normalisedConnectedness, 0, 1, NodeSizeMin, this.NodeSizeMax()); this.Center.Fill = this.Tag.DeserializeAsBrush(); this.Center.Width = this.NodeSize; this.Center.Height = this.NodeSize;
Simples.
Now just fire up a couple of emulators and voila:
If you try this over Web comms you'll notice that other nodes don't show up until they're moved. I think this is because of the way the WIEB (Where Is EveryBody) message is handled. Let me know if this is a big issue for you. Or fix it and send me a patch. ;)
But what if we want to test this easily without deploying to lots of devices? We'll just update the default nodes-that's what they're there for.
So in MainPage.xaml.cs
private void CreateDefaultNodes(int numberOfNodes) { for (int i = 0; i < numberOfNodes; i++) { var visualNode = new VisualNode(this.rand, MainCanvas); visualNode.Tag = this.RandomAccentColor(this.rand).Serialize(); this.nodes.Add(visualNode); } } private Color RandomAccentColor(Random random) { // via http://chemicaloli.net/2011/10/01/windows-phone-7-accent-colour-list/ switch (random.Next(1, 10)) { case 1: return new Color { A = 255, R = 27, G = 161, B = 226 }; // Blue case 2: return new Color { A = 255, R = 160, G = 80, B = 0 }; // Brown case 3: return new Color { A = 255, R = 51, G = 153, B = 51 }; // Green case 4: return new Color { A = 255, R = 230, G = 113, B = 184 }; // Pink case 5: return new Color { A = 255, R = 162, G = 0, B = 255 }; // Purple case 6: return new Color { A = 255, R = 229, G = 20, B = 0 }; // Red case 7: return new Color { A = 255, R = 0, G = 171, B = 169 }; // Teal case 8: return new Color { A = 255, R = 162, G = 193, B = 57 }; // Lime default: return new Color { A = 255, R = 216, G = 0, B = 115 }; // Magenta } }
The above is all quite trivial but hopefully shows how easy it is to send additional information. You can send ANYTHING so don't let yourself be limited by just thinking you're limited to accent colours.
Now go. And be creative...
Wednesday, November 21, 2012
Important #AlphaLabsCC update
If you're involved in the current Alphalabs project (The Always-on Telephone Club) then you'll need to go grab the latest code from codeplex as I've just pushed an important fix. (changeset 17283)
This changeset includes the ability to include additional, arbitrary, information in the message that is sent between devices. Without this it's much harder to do interesting things.
I'll post an explanation of how to use it shortly.
The fact I shipped this and hadn't spotted it until now was a big error on my part.
I'm sorry.
Please forgive me.
This changeset includes the ability to include additional, arbitrary, information in the message that is sent between devices. Without this it's much harder to do interesting things.
I'll post an explanation of how to use it shortly.
The fact I shipped this and hadn't spotted it until now was a big error on my part.
I'm sorry.
Please forgive me.
Tuesday, October 30, 2012
The silverlight toolkit is now the #wptoolkit
If you've done any Silverlight development on Windows Phone 7 there's a 90 odd plus percetage chance you've used (or at least looked at) the Silverlight Toolkit for Windows Phone.
Now, with the release of Windows Phone 8, it's been separated into a separate, phone specific project.
Go and get all your favourite, essential, additional controls from:
http://phone.codeplex.com/
Now, with the release of Windows Phone 8, it's been separated into a separate, phone specific project.
Go and get all your favourite, essential, additional controls from:
http://phone.codeplex.com/
Monday, October 29, 2012
Windows Phone sessions at #bldwin
Update: See the final list at http://blogs.windows.com/windows_phone/b/wpdev/archive/2012/11/05/it-s-a-wrap-on-windows-phone-at-build-2012.aspx
If, like me, you're not at Microsoft's Build conference this week you'll probably want to keep up with the Windows Phone (8) related sessions that are happening there. Fortunately, they're all being made available online.
You can find a list of all sessions at http://channel9.msdn.com/events/Build/2012/ but if you just want the phone related ones I've linked them all individually below:
No, that's not a lot of sessions so let's hope for quality, not quantity and also hope that there will be more information and events coming soon.
If, like me, you're not at Microsoft's Build conference this week you'll probably want to keep up with the Windows Phone (8) related sessions that are happening there. Fortunately, they're all being made available online.
You can find a list of all sessions at http://channel9.msdn.com/events/Build/2012/ but if you just want the phone related ones I've linked them all individually below:
- Deep Dive into the Kernel of .NET on Windows Phone 8
- Designing awesome XAML apps in Visual Studio and Blend for Windows 8 and Windows Phone 8
- Developing Mobile Solutions with Windows Azure Part II
- Create Cross-platform Apps using Portable Class Libraries
- Building Cross-Device Xbox Games
- Building data centric applications for web, desktop and mobile with Entity Framework 5
No, that's not a lot of sessions so let's hope for quality, not quantity and also hope that there will be more information and events coming soon.
Tuesday, October 23, 2012
Debugging an MPNS issue
After struggling with debugging an issue with the Microsoft Push Notifications Service for Windows Phone (MPNS) today, I discovered that it's not possible to get a ChannelUri when on a Wi-Fi network that uses a proxy. It can also take several seconds (up to about 10 if today is anything to go by) before a channel is obtained. (Previously I've only known it to take less than 1.)
If a device has a low battery or battery saver is enabled you cannot get a URI either.
Just documenting as useful to know.
via http://social.msdn.microsoft.com/forums/en-us/wpnotifications/thread/8af38ab5-f6b9-441f-af68-b9fefe0184a5
If a device has a low battery or battery saver is enabled you cannot get a URI either.
Just documenting as useful to know.
via http://social.msdn.microsoft.com/forums/en-us/wpnotifications/thread/8af38ab5-f6b9-441f-af68-b9fefe0184a5
Tuesday, October 16, 2012
Preparing for Windows Phone 8 - Slides
In the last few months, I've spoken at WPUG, DDD10 and DDD North about Preparing for Windows Phone 8.
Sorry, there's no secrets revealed*. This is all public knowledge and sensible assumptions based on many years of working in the mobile space and with Microsoft products.
Sorry, as with most presentations the slides on their own don't give the full picture but may be useful - and some people have asked for them.
* I know very little that isn't public knowledge and don't have access to the SDK - yet.
Sorry, there's no secrets revealed*. This is all public knowledge and sensible assumptions based on many years of working in the mobile space and with Microsoft products.
Sorry, as with most presentations the slides on their own don't give the full picture but may be useful - and some people have asked for them.
* I know very little that isn't public knowledge and don't have access to the SDK - yet.
Wednesday, July 11, 2012
What's going on with WPUG?
Short of time? Here's the skinny:
WPUG is 2 years old. It's been awesome, helped loads of people build loads of great apps and is gonna continue.
Really?
Windows Phone?
Still beating that old horse?
Isn't it dead yet?
Not quite.
There's still lots of opportunities for enterprising ideas and with the Windows 8 and Windows Phone 8 announcements there are some exciting times ahead.
How did we get here?
We've picked up 1900+ followers on Twitter as we tweet lots of Windows Phone development related tips, techniques and news articles. (Yeah, it's been a bit quiet recently but will pick up again soon.)
We've had over 70 talks and demos, at 22 meetings, with over 650 different attendees.
I know of at least six people who've got jobs as a result of contacts they've made at the group.
We've spawned a couple of spin-off groups in Cardiff and Manchester.
And according to our recent survey:
We're directly responsible for helping over 200 people create and release their first app.
40% of the developers who've attended have released more apps as a direct result of attending meetings.
76% of attendees claim to have been able to release better apps as a result of attending meetings.
Moving forward
Our next meeting is next week and I'll be talking about how the announcements at the recent Windows Phone Summit provide some exciting opportunities for designing and developing for Windows Phone in the future.
Register via eventbrite or on meetup.
Longer term, we'll be meeting again in August and have plans to keep growing and having more meetings later in the year as we look towards Windows Phone 8 and partnering with other groups to learn and share about Win8 development too.
We hope this will be helpful as 91% of developers who've attended are planning on upgrading their apps to WP8 and 96% of attendees are interested in learning about developing apps for Win8 as well as WP8.
Plus more.....
As part of the survey we also asked people what they enjoyed about our meetings so far. Here are a few quotes:
We'll have some more feedback from the survey on the WPUG blog soon.
WPUG is 2 years old. It's been awesome, helped loads of people build loads of great apps and is gonna continue.
Really?
Windows Phone?
Still beating that old horse?
Isn't it dead yet?
Not quite.
There's still lots of opportunities for enterprising ideas and with the Windows 8 and Windows Phone 8 announcements there are some exciting times ahead.
How did we get here?
We've picked up 1900+ followers on Twitter as we tweet lots of Windows Phone development related tips, techniques and news articles. (Yeah, it's been a bit quiet recently but will pick up again soon.)
We've had over 70 talks and demos, at 22 meetings, with over 650 different attendees.
I know of at least six people who've got jobs as a result of contacts they've made at the group.
We've spawned a couple of spin-off groups in Cardiff and Manchester.
And according to our recent survey:
We're directly responsible for helping over 200 people create and release their first app.
40% of the developers who've attended have released more apps as a direct result of attending meetings.
76% of attendees claim to have been able to release better apps as a result of attending meetings.
Moving forward
Our next meeting is next week and I'll be talking about how the announcements at the recent Windows Phone Summit provide some exciting opportunities for designing and developing for Windows Phone in the future.
Register via eventbrite or on meetup.
Longer term, we'll be meeting again in August and have plans to keep growing and having more meetings later in the year as we look towards Windows Phone 8 and partnering with other groups to learn and share about Win8 development too.
We hope this will be helpful as 91% of developers who've attended are planning on upgrading their apps to WP8 and 96% of attendees are interested in learning about developing apps for Win8 as well as WP8.
Plus more.....
As part of the survey we also asked people what they enjoyed about our meetings so far. Here are a few quotes:
"I enjoy the social aspect of it"
"The breadth of topics discussed is great."
"The demos and talks have been great"
"The networking, the helpful advices, the motivation that you are not the only one who develop for Windows Phone."
"I have enjoyed talks about the design considerations, techical architecture design that gets round specific problems and how people have monetised their apps"
We'll have some more feedback from the survey on the WPUG blog soon.
Tuesday, May 29, 2012
The 256MB device difference which isn't documented
The 7.1.1 SDK update allows us to support and detect devices with only 256MB and there are a few noted points of things to avoid on the 256-MB devices. Recently I've discovered another one.
32Bit image support!
256-MB images only support displaying images at 16 Bits Per Pixel.
For most cases this isn't a problem, but if you're using gradients it may be.
Let me demonstrate with a simple app.
The app just shows an image with a gradient (from red to cyan) and an indication of if we're running in the regular emulator (with 512MB of memory) or the version with 256MB.
Here's what it looks like by default on the 512-MB emulator.
You'll notice the banding of the color in the gradient.
The standard way we'd adjust the app to cope with this would be to configure the app to use 32bits per pixel-which is enough to show the full range of colors in the gradient.
From WMAppManifest.xml:
There. Much better. No banding.
But what if we flip over to the other emulator the problem returns.
Oh no. The banding is back. And yes, we have still configured to use 32 BitsPerPixel
But, you may be thinking, perhaps this only affects the emulator.
No. I've tested this on a Nokia Lumia 610 (which is a 256MB device) and the same thing happens there.
So what can we do?
We can dither the image.
Voila. A lot less banding.
Now we can use a gradient image in an app on a 256MB device without banding.
The dithering in the above example was done with the tool from http://adtsai.blogspot.co.uk/2011/03/high-quality-dithering-for-windows.html
On the plus side we can use this same image on 512MB devices without the need for the memory overhead of using 32BPP.
On the negative side the dithered image is larger though.
Presumably, this lack of support for a higher number of bits per pixel, has been done to reduce the amount of memory needed to display graphics and therefore reduce the total memory used by the app.
If you're going to use gradients in your apps this is an important thing to be aware of.
32Bit image support!
256-MB images only support displaying images at 16 Bits Per Pixel.
For most cases this isn't a problem, but if you're using gradients it may be.
Let me demonstrate with a simple app.
The app just shows an image with a gradient (from red to cyan) and an indication of if we're running in the regular emulator (with 512MB of memory) or the version with 256MB.
Here's what it looks like by default on the 512-MB emulator.
You'll notice the banding of the color in the gradient.
The standard way we'd adjust the app to cope with this would be to configure the app to use 32bits per pixel-which is enough to show the full range of colors in the gradient.
From WMAppManifest.xml:
<App BitsPerPixel="32"
There. Much better. No banding.
But what if we flip over to the other emulator the problem returns.
Oh no. The banding is back. And yes, we have still configured to use 32 BitsPerPixel
But, you may be thinking, perhaps this only affects the emulator.
No. I've tested this on a Nokia Lumia 610 (which is a 256MB device) and the same thing happens there.
So what can we do?
We can dither the image.
Voila. A lot less banding.
Now we can use a gradient image in an app on a 256MB device without banding.
The dithering in the above example was done with the tool from http://adtsai.blogspot.co.uk/2011/03/high-quality-dithering-for-windows.html
On the plus side we can use this same image on 512MB devices without the need for the memory overhead of using 32BPP.
On the negative side the dithered image is larger though.
Presumably, this lack of support for a higher number of bits per pixel, has been done to reduce the amount of memory needed to display graphics and therefore reduce the total memory used by the app.
If you're going to use gradients in your apps this is an important thing to be aware of.
Sunday, May 27, 2012
The PhoneGap/Cordova misconception
2 years ago I was in the hotel I'm in right now and PhoneGap for WP7 was born.
In the time since it's come a long way--due to the work of a few very smart people.
I haven't done a lot with PhoneGap/Cordova for a while nor talked/blogged about it. Fortunately those other people have.
There is, however, something that many people still seem confused about and I'd like to try and clear it up now. The confusion is that the impression that the architecture diagram of a multi-platform PG/C app should look something like this.
The assumption is that because the UI for each version of the app will be written in HTML, CSS & JavaScript they should all be the same.
THIS IS WRONG!
That was never the intention.
For each version of the app that is built, it should have a UI that is appropriate to and targets the platform it will run on. The above diagram should actually look something like this.
PG/C allows you to create native apps with "web" technologies. It doesn't mean you should create an app that looks the same on each platform.
If you're building apps with PG/C then please keep this in mind.
In the time since it's come a long way--due to the work of a few very smart people.
I haven't done a lot with PhoneGap/Cordova for a while nor talked/blogged about it. Fortunately those other people have.
There is, however, something that many people still seem confused about and I'd like to try and clear it up now. The confusion is that the impression that the architecture diagram of a multi-platform PG/C app should look something like this.
The assumption is that because the UI for each version of the app will be written in HTML, CSS & JavaScript they should all be the same.
THIS IS WRONG!
That was never the intention.
For each version of the app that is built, it should have a UI that is appropriate to and targets the platform it will run on. The above diagram should actually look something like this.
PG/C allows you to create native apps with "web" technologies. It doesn't mean you should create an app that looks the same on each platform.
If you're building apps with PG/C then please keep this in mind.
Friday, May 25, 2012
4 ways to make money with Windows Phone
I hear lots of complaints about Windows
Phone not having many users and developers frustrated that they haven't made
loads of money from the apps they've developed.
I think there are 4 ways you can make money
though:
- Get paid to build apps for other people
- Build apps which allow you to monetize another service
- Build a targeted app and promote it appropriately
- Get very lucky
For most people these are listed in order
of likelihood of being successful.
Let's look at them in more detail.
1. Get paid to build apps for other people
*disclosure: this is how I make my living*
There are companies that want windows phone
apps but don't have the staff, resources or experience to develop them. In this
scenario they will typically look to agencies or contractors to create the apps
for them. (Note that some agencies look to contractors too, but this is
becoming less common as agencies are increasing/improving their Windows Phone
development skills and experience.)
This is still a very niche market and the
companies looking to hire for these roles want experts who can get things done
and have a proven level of experience with the platform. Design and project
management skills also come in handy too.
If you have the skills and experience this
could work for you.
2. Build apps which allow you to monetize
another service
This is the way that provides the most
opportunity for the widest number of companies to make money on the platform in
the short to medium term.
The idea is that you have an existing
service which people pay to use and by building a client app that runs on Windows
Phone you can reach more users or increase engagement with existing users. Both
of which should increase income (and hopefully profit).
If you've got an idea for a service that
could extend its reach by being made available via a mobile app Windows Phone is
probably not the best platform to start with as you'll probably be better off
by targeting a platform where you could reach/get a greater number of users
(who you can monetize) for the same level of development effort.
If you do
target Windows Phone first it can be a differentiator for you and an
opportunity to create a unique marketing/promotional story. I know a couple of
companies/apps which have done this.
3. Build a targeted app and promote it
appropriately
If you think that the addressable market of
total Windows Phone owners contains a large enough subsection that you can
market and sell to enough of them with a relevant app that you can make money
then this may be an approach that could make you a profit. Remember, you need
to consider all the ways that an app can be monetized. Don't just think about
an initial sales price. If you have one.
If considering this approach be sure to
consider and treat the app you're creating like any other product. Remember:
"Think product, not app".
4. Get very lucky
You could release an app with no great
level of advance planning or promotion and have it turn out to be wildly
successful. You may have heard stories of people who have done just that.
Unfortunately though the reason you hear such stories is that they are
remarkable and the exception. If it was common it wouldn't be news worthy.
If you're relying on this method you may
want to consider a lottery ticket instead. That's not to say that you can't
make money from apps, just that you shouldn't rely on luck if that's what you
want to achieve.
Have I missed anything else? [How ]do you
make money form Windows Phone?
Thursday, May 24, 2012
How to read and send text messages on Windows Phone without user input!
It's a popular request from those new to Windows Phone, but with familiarity of other platforms, to want to be able to interact with SMS.
This typically means one or more of the following:
For very good reasons this isn't possible.
Those good reasons are:
But, you may argue, "I'd never do anything malicious".
Hopefully that's the case, but it's not possible to guarantee that everyone will be so good.
Just ask some android owners who installed applications only to find expensive SMS messages showing up on their bill that they had no record of:
While in this case the issue has been addressed and those affected will be getting their money refunded, stories like this hurts the platform. While Microsoft are busy trying to grow the platform and attract new users, stories about the security of the platform and how people with those phones can end up with unexpected charges on their bill if they install apps would not be helpful.
While you can't read or be notified of new SMS messages you can compose one for the user to send. See "How to: Use the SMS Compose Task for Windows Phone" for more details.
This typically means one or more of the following:
- Access the text messages on the device.
- Be notified when new messages arrive.
- Send messages without the user having to directly do something.
For very good reasons this isn't possible.
Those good reasons are:
- to provide a predictable experience to the user/owner of the phone (so they know what messages are sent and what data apps have access to)
- and to prevent malicious activity
But, you may argue, "I'd never do anything malicious".
Hopefully that's the case, but it's not possible to guarantee that everyone will be so good.
Just ask some android owners who installed applications only to find expensive SMS messages showing up on their bill that they had no record of:
"UK Regulator swiftly resolves Android malware infection"
While in this case the issue has been addressed and those affected will be getting their money refunded, stories like this hurts the platform. While Microsoft are busy trying to grow the platform and attract new users, stories about the security of the platform and how people with those phones can end up with unexpected charges on their bill if they install apps would not be helpful.
While you can't read or be notified of new SMS messages you can compose one for the user to send. See "How to: Use the SMS Compose Task for Windows Phone" for more details.
Wednesday, May 23, 2012
What do you want from Tombstone Helper?
A little over a year ago I created http://tombstonehelper.codeplex.com/. It was a response to the large number of apps which didn't implement support for saving state during tombstoning and the fact the framework provides little to help.
My aim was to create something that was so simple to use that there would be no excuse, at least in a simple app, for not adding tombstone persistence support. My thought was that if you're up to developing a more complex app you would be capable of adding appropriate persistence support and so not need my help.
The library has been noted amongst the more popular third party libraries in general use and at one point was estimated to be in 3% of all apps in the marketplace. I also know, based on some of the apps it's in, that it's been included in apps on at least several hundred thousand devices.
It's currently at version 2.5.
I've started a version 3.0 several times with a view to adding viewmodel support but each time have failed to find a way I consider suitable for a broad enough number of use cases and which doesn't require too much effort from the person using the library.
As you may have guessed from the tone of this post so far, I'm going to try again but I'm interested to know if there is anyone out there using it who would like extra features, functionality or has a strong opinion on how viewmodel persistence should be handled.
I want to help those who were building simple apps a year ago as they move on to more complex scenarios.
If you have any thoughts, comments or opinions please: leave them in the comments below; email me; or tweet your suggestion.
Thanks
My aim was to create something that was so simple to use that there would be no excuse, at least in a simple app, for not adding tombstone persistence support. My thought was that if you're up to developing a more complex app you would be capable of adding appropriate persistence support and so not need my help.
The library has been noted amongst the more popular third party libraries in general use and at one point was estimated to be in 3% of all apps in the marketplace. I also know, based on some of the apps it's in, that it's been included in apps on at least several hundred thousand devices.
It's currently at version 2.5.
I've started a version 3.0 several times with a view to adding viewmodel support but each time have failed to find a way I consider suitable for a broad enough number of use cases and which doesn't require too much effort from the person using the library.
As you may have guessed from the tone of this post so far, I'm going to try again but I'm interested to know if there is anyone out there using it who would like extra features, functionality or has a strong opinion on how viewmodel persistence should be handled.
I want to help those who were building simple apps a year ago as they move on to more complex scenarios.
If you have any thoughts, comments or opinions please: leave them in the comments below; email me; or tweet your suggestion.
Thanks
Tuesday, May 22, 2012
If the customer/user doesn't understand: it's your fault, not their problem
I remember, a few years ago, a client was in the office of
the company I was working for at the time and they were showing off the
promotional flyers they'd printed and were busy distributing to potential customers.
After they'd handed us copies they remarked that the people they were trying to reach just "didn't get it". They were handing out all this information about how clever the technicalities of the system were and all the things it would now enable them to do but everyone they spoke to just asked about price (which wasn't mentioned on the flyer).
As far as their potential users were concerned, all they were interested in was price. All the other whizz-bang features were of no interest to them. The company in question had wasted a lot of time money and effort in trying to tell people about what they were offering but it wasn’t anything their potential customers were interested in.
So what does this have to do with building phone apps?
Understand your market
If you're not making something people want or that is different from an alternative in a way that is “better” from the users perspective, you’ll find making sales hard.
This means:
- thinking before building an app
- building something that there is a market for. (Yes, this means going and doing some research first.)
- not just building it because you can or it's technically possible
It’s easier to sell something if you build what people want than it is to build what you want and then try and persuade people to buy it.
Make your value proposition clear
After they'd handed us copies they remarked that the people they were trying to reach just "didn't get it". They were handing out all this information about how clever the technicalities of the system were and all the things it would now enable them to do but everyone they spoke to just asked about price (which wasn't mentioned on the flyer).
As far as their potential users were concerned, all they were interested in was price. All the other whizz-bang features were of no interest to them. The company in question had wasted a lot of time money and effort in trying to tell people about what they were offering but it wasn’t anything their potential customers were interested in.
So what does this have to do with building phone apps?
I think it demonstrates two areas where app developers often make mistakes. They build an app without understanding their desired and potential market and they don't make their value proposition clear.
Understand your market
If you're not making something people want or that is different from an alternative in a way that is “better” from the users perspective, you’ll find making sales hard.
This means:
- thinking before building an app
- building something that there is a market for. (Yes, this means going and doing some research first.)
- not just building it because you can or it's technically possible
It’s easier to sell something if you build what people want than it is to build what you want and then try and persuade people to buy it.
Make your value proposition clear
Explain what your application does and how that will help,
benefit and provide value to the user. This will enable them to make an
informed decision about purchasing the application and ultimately encourage
them to do so.
Of course, this may mean that you have to explain what the application cannot do. Whether this is through decision or technical limitation. By making this clearer before they have the app and are trying to get it to do something it can't you'll make them happier. No, not everyone will read a long description about the capabilities and limitations of the app so you'll need to be smart about how you communicate this.
I think no customer is better than a disappointed one who is complaining and spreading negative word of mouth. Focus on getting the ones you want and the ones who want your app. It'll make everyone happier in the long run.
At the end of the day it comes down to building what will sell and communicating (marketing) clearly. Do this and you'll have more success with your apps.
Of course, this may mean that you have to explain what the application cannot do. Whether this is through decision or technical limitation. By making this clearer before they have the app and are trying to get it to do something it can't you'll make them happier. No, not everyone will read a long description about the capabilities and limitations of the app so you'll need to be smart about how you communicate this.
I think no customer is better than a disappointed one who is complaining and spreading negative word of mouth. Focus on getting the ones you want and the ones who want your app. It'll make everyone happier in the long run.
At the end of the day it comes down to building what will sell and communicating (marketing) clearly. Do this and you'll have more success with your apps.
Monday, May 21, 2012
How to respond to bad apps?
Update: In response to comments below and on Twitter, I've tried to clarify things better below.
What do you do when you find a bad app?
What do you do?
I've started leaving 1 star reviews to bad apps, rather than just ignoring them.
I figure this helps serve as a warning to others who may download it.
If I know hte develoepr I'll talk to them but I just don't have the time to talk to everyone :(
Do you consider reviews when downloading an app? Is lots of bad reviews worse than no reviews?
I'd love to know your thoughts...
I also uninstall it, but that's just because I've got hundreds (not exagerating) of apps installed and I don't want the clutter.
Of course, if I come across an app which shouldn't be in the, marketplace in the first place I report it.
If you are/were the developer you'll want direct feedback, not a negative review.
That's a given.
But what if we're talking about another persons app?
Imagine the app has so much wrong with it you don't know where to begin and haven't got the time to get in to a long discussion about why that's the case and all the ways the app could and should be improved.
This leaves 2 options:
1) do nothing
2) leave a low rating
In this scenario, what do you do?
If you do nothing then my theory is that there's a greater likelihood that someone else will waste part of their life tryint to use that app.
If you give a low rating they may think twice.
Yes, in an ideal world there would be the time to help everyone make a great app and developers would avoid the situation in the first place by taking the time to understand what makes a good app and to test their designs, assumptions and quality prior to releasing it. Unfortunately a quick look at any marketplace reminds us that we're not in a perfect world though.
Yes, if you're the developer you'll want a detailed description of why you've got a bad review but reviews aren't written for the developer. They're written to help other people get a feel of what other users think of the app before they download it.
If you're a developer of an app and you're getting bad reviews and don't know why then it's your responsibility to go and find out why. It's not the responsibility of the person giving the review.
, th
What do you do when you find a bad app?
- Engage with the developer to report why?
- Leave a negative review?
- Leave a low rating?
- Uninstall it?
- Just never launch it again?
What do you do?
I've started leaving 1 star reviews to bad apps, rather than just ignoring them.
I figure this helps serve as a warning to others who may download it.
If I know hte develoepr I'll talk to them but I just don't have the time to talk to everyone :(
Do you consider reviews when downloading an app? Is lots of bad reviews worse than no reviews?
I'd love to know your thoughts...
I also uninstall it, but that's just because I've got hundreds (not exagerating) of apps installed and I don't want the clutter.
Of course, if I come across an app which shouldn't be in the, marketplace in the first place I report it.
If you are/were the developer you'll want direct feedback, not a negative review.
That's a given.
But what if we're talking about another persons app?
Imagine the app has so much wrong with it you don't know where to begin and haven't got the time to get in to a long discussion about why that's the case and all the ways the app could and should be improved.
This leaves 2 options:
1) do nothing
2) leave a low rating
In this scenario, what do you do?
If you do nothing then my theory is that there's a greater likelihood that someone else will waste part of their life tryint to use that app.
If you give a low rating they may think twice.
Yes, in an ideal world there would be the time to help everyone make a great app and developers would avoid the situation in the first place by taking the time to understand what makes a good app and to test their designs, assumptions and quality prior to releasing it. Unfortunately a quick look at any marketplace reminds us that we're not in a perfect world though.
Yes, if you're the developer you'll want a detailed description of why you've got a bad review but reviews aren't written for the developer. They're written to help other people get a feel of what other users think of the app before they download it.
If you're a developer of an app and you're getting bad reviews and don't know why then it's your responsibility to go and find out why. It's not the responsibility of the person giving the review.
, th
Your app sucks and now I know what to do about it
The Windows Phone
marketplace is a semi curated environment. This is both a good and a bad thing.
It makes the app
submission process fairly reliable and keeps the very buggy and inappropriate
apps out.
It does, however,
require a human element in the certification process that can be subject to
inconsistency and error.
Sometimes apps pass
certification which shouldn't have. This is separate from any quality
judgement, I'm referring here to apps breaking the marketplace rules and certification requirements
Fortunately, there
is a place to report such occurrence: Reporting a Concern about an App in the Marketplace
If you're interested
in and concerned about the general quality of what's in the marketplace -
presumably because you want to see high quality, predictable apps which bring
value to the overall ecosystem then I'd like to encourage you to report any
such apps that break the certification rules too.
!!! This is not a
place for reporting "bad" apps, just ones that break certification
rules !!!
This isn't a
substitute for also reporting such issues to the creators/publishers of such
apps and engaging with them also. So that they can address the issues and learn
what they shouldn't be doing.
Wednesday, May 16, 2012
13 ways to improve the performance of your app
There are lots of ways you can improve the performance (and the perceived performance) of your app.
This is not a complete list, just what came to mind right now.
The important (though unfortunate) thing to take from this is that great performance doesn't come easily and there are lots of things you can (or have to) do to give your users an awesome experience.
Note that some MVVM purist may dispute some of these but they're based on real world experience.
The above has helped me in the past. Hopefully it may help you too.
This is not a complete list, just what came to mind right now.
The important (though unfortunate) thing to take from this is that great performance doesn't come easily and there are lots of things you can (or have to) do to give your users an awesome experience.
Note that some MVVM purist may dispute some of these but they're based on real world experience.
- Get off the UI thread - Don't use it when you don't have to. Keep the UI responsive.
- Don't use value converters - They have a much greater performance impact than direct properties.
- Don't use dependency properties when you don't need to - If regular properties will work for your needs then keep it simple as they're much faster to read
- Have fewer external dependenices - Loading fewer third party libraries saves time
- Split up your assemblies - Don't load all the pages (and code) in your app when you don't need to
- Cache images (and data) - Downloading external resources takes time. Don't repeat it unnecessarily. The same goes for processing or reformatting data.
- Use a "boot loader" - If you have a large app or a complicated start up process, only have the bare minimum in the app and push everything else to separate assemblies. This will help you get as animated loading page up as quickly as possible.
- Preload/prefetch data - If you can, get the data before you need it so that when you do need it the user doesn't have to wait.
- Lazy load data - If there is a large amount of data, only load it as you need it. Don't waste time forcing your user to wait while it's all loaded.
- Reuse [data] templates (load less xaml) - Loading fewer templates is faster. Make sure you don't reload the same ones repeatedly
- Have less XAML - Don't use any more XAML than you need to. I often see slow apps which have unnecessarily complicated, nested controls when the same thing coudl have been created with fewer controls.
- Avoid nested margins - Reduce the amount of work the loyout engine has to do measuring the elements in creates.
- Don't use XAML - Yes, it's extreme but you can get better performance from a UI created in code than in XAML (you save the parsing time) This can make supporting the code and making changes harder though.
The above has helped me in the past. Hopefully it may help you too.
Tuesday, May 15, 2012
In the interest of balance: 101 Reasons Not to Buy A Windows Phone 7.5
I've been alerted by Tomi Ahonen about a list of 101 reasons NOT to buy a Windows Phone 7.5.
My initial response was to roll my eyes but some of it is insightful about how some people are perceiving the platform.
There's a few points I'd disagree with and plenty that are purely criticisms because it's not the same as other devices or platforms.
It seems to have been written by a disappointed (frustrated?) Symbian user.
What I know though is that I like it ;) and only one person I know who's used a WP device didn't like it, compared with many who upgraded from or changed their plans to buy an iPhone after using mine for a short while.
Diversion over, normal developer related content will resume shortly.
My initial response was to roll my eyes but some of it is insightful about how some people are perceiving the platform.
There's a few points I'd disagree with and plenty that are purely criticisms because it's not the same as other devices or platforms.
It seems to have been written by a disappointed (frustrated?) Symbian user.
What I know though is that I like it ;) and only one person I know who's used a WP device didn't like it, compared with many who upgraded from or changed their plans to buy an iPhone after using mine for a short while.
Diversion over, normal developer related content will resume shortly.
Friday, May 11, 2012
BitsPerPixel and 256MB devices
At some point (I think it was with the mango tools release) we gained the ability to specify that an app should use 32 bits for each pixel when showing a color, compared with the default 16. This enabled the ability to show smooth gradients and avoided "banding".
It just takes a setting in the manifest file.
Based on my experiences with the new 256MB emulator (which is included with the 7.1.1 SDK update) the new, lower spec devices don't appear to support the 32bit option. This would make sense as it would mean the device would need to use less memory to load/display the image and could also mean a cheaper screen.
This is currently only tested in the emulator but as soon as I can get a real device I'll check there too.
Do you have a device you can check this on? If so, do you see this behaviour?
Need to do some dithering of images to wrok around this? Check out http://adtsai.blogspot.co.uk/2011/03/high-quality-dithering-for-windows.html
It just takes a setting in the manifest file.
Based on my experiences with the new 256MB emulator (which is included with the 7.1.1 SDK update) the new, lower spec devices don't appear to support the 32bit option. This would make sense as it would mean the device would need to use less memory to load/display the image and could also mean a cheaper screen.
This is currently only tested in the emulator but as soon as I can get a real device I'll check there too.
Do you have a device you can check this on? If so, do you see this behaviour?
Need to do some dithering of images to wrok around this? Check out http://adtsai.blogspot.co.uk/2011/03/high-quality-dithering-for-windows.html
Monday, March 26, 2012
Android screen sizes
For my own reference, but possibly interesting to others.
Android screen sizes of note:
ldpi: small screens in low numbers
mdpi: range of sizes and quite popular
hdpi: most popular
xhdpi: very few devices
summary: must support normal screens at hdpi and mdpi densities.
See more at http://developer.android.com/resources/dashboard/screens.html
See also, the android guide to supporting multiple screen sizes.
Android screen sizes of note:
ldpi: small screens in low numbers
mdpi: range of sizes and quite popular
hdpi: most popular
xhdpi: very few devices
summary: must support normal screens at hdpi and mdpi densities.
See more at http://developer.android.com/resources/dashboard/screens.html
See also, the android guide to supporting multiple screen sizes.
Think mobile at DDD South West
If you're not aware of the DDD (or Developer Developer Developer) series of community events then you've missed out. They provide a great opportunity to learn what's new in the .Net community. Or, officially:
DDD South West is a free one day technical event for developers. It is a day of learning, discussing, contributing and being part of the community in the South West. Our goal is to provide free technical education, the opportunity to mix with peers and to make and develop relationships in the .NET industry.
If you're interested in going to the event then I'd love to be able to talk to you about how an understanding of developing for mobile provides a great gounding for developing for other (non desktop/PC) platforms too. If you'd like to hear it that means voting for my session once you've registered/logged in to the site.
If you're undecided then let me make 2 points.
- When I've talked about this subject before (at DevEvening, Cheltenham, Edinburgh, Dundee & Aberdeen - either on it's own or as part of an introduction to Windows Phone development) it's always proved really popular, prompted lots of positive feedback and people have been helped to think about new things or think about things in new ways which they've found helpful.
- A full day of technical content can be very challenging and tiring. Sometimes it's useful to take a bit of a break and just listen without having to follow along while someone writes code or explain complex new concepts. Let this session be a welcome break in your day at DDDSW.
Friday, March 23, 2012
So you want some help?
Warning: Rant!
So you want help with something.
Ok.
Now make it easy to help you.
I get a bit annoyed by people posting questions (on SO mainly) with a vague problem or descriptions of what's been tried but no actual code
Deliberately including no examples to protect the guilty
Before you ask for help, please read the following:
http://stackoverflow.com/questions/how-to-ask
http://tinyurl.com/so-hints
http://www.codinghorror.com/blog/2012/03/rubber-duck-problem-solving.html
It'll help us to help you.
We want to help, just don't make us jump through unnecessary hoops.
Not just a rant, I also wanted a place I could quickly find the above links again.;)
So you want help with something.
Ok.
Now make it easy to help you.
I get a bit annoyed by people posting questions (on SO mainly) with a vague problem or descriptions of what's been tried but no actual code
Deliberately including no examples to protect the guilty
Before you ask for help, please read the following:
http://stackoverflow.com/questions/how-to-ask
http://tinyurl.com/so-hints
http://www.codinghorror.com/blog/2012/03/rubber-duck-problem-solving.html
It'll help us to help you.
We want to help, just don't make us jump through unnecessary hoops.
Not just a rant, I also wanted a place I could quickly find the above links again.;)
Thursday, March 15, 2012
Ideas of March | #IdeasOfMarch
As prompted by http://shiflett.org/blog/2012/mar/ideas-of-march
I like blogs.
I read the titles of hundreds of blog articles each day and usually end up reading dozens of posts.
There are 2 main reasons (that I can think of right now) that I like blogs though:
1. I like how anyone can write a blog. Yes, even little old me. Blogs have allowed me to read the thoughts, ideas, experiments, plans and more of hundreds of people. And I'd never have even heard of or met most of them if it wasn't for their blog.
Not that this means I think everyone should write a blog though. And yes, I include myself again there sometimes. ;)
2. Blogs are probably the way I learn most new things in the software development world. Yeah, StackOverflow is probably up there too, but all the important and useful information in software dev seems to come from individuals experiences and not from official documentation. I'm certain that if no-one was blogging I'd spend more of my time fumbling through badly orgainsed and ill structured documentation.
Thank you bloggers of the world.
I like blogs.
I read the titles of hundreds of blog articles each day and usually end up reading dozens of posts.
There are 2 main reasons (that I can think of right now) that I like blogs though:
1. I like how anyone can write a blog. Yes, even little old me. Blogs have allowed me to read the thoughts, ideas, experiments, plans and more of hundreds of people. And I'd never have even heard of or met most of them if it wasn't for their blog.
Not that this means I think everyone should write a blog though. And yes, I include myself again there sometimes. ;)
2. Blogs are probably the way I learn most new things in the software development world. Yeah, StackOverflow is probably up there too, but all the important and useful information in software dev seems to come from individuals experiences and not from official documentation. I'm certain that if no-one was blogging I'd spend more of my time fumbling through badly orgainsed and ill structured documentation.
Thank you bloggers of the world.
Wednesday, March 14, 2012
Slides from last months Scottish user group talks
Last month I went to Scotland to talk at some user groups about Windows Phone development and general mobile development principles that can be applied to all platforms.
I've had some requests for the slides from those talks. (The latest evolution of the slides since the last time I gave these talks.) So here they are:
I've had some requests for the slides from those talks. (The latest evolution of the slides since the last time I gave these talks.) So here they are:
NanoIOC - How I do Depenedency Injection on #WP7
When it comes to Dependency Injection / IOC there isn't a good story for Windows Phone*.
There's nothing built in and lots of people have created their own solutions. Including, but not limited to,: Funq, MicroIoc, TinyIoc, this or this. But none of them work the way I want to.
I want:
I don't want:
I don't care about:
There are two factors which influence my requirements:
1. My past experience with Castle Windsor - Chosen after evaluating what was available at the time (about 4 years or so ago.)
2. My experience with working in development teams where there would always be at least one person who wasn't interested in learning anything new, best practices or, seemingly, code quality. I've learnt that if you're working with such people, or anyone new to the industry, that you'll save yourself a lot of work (in fixing up their errors, mistakes and repeatedly explaining things to them) if everything is explicit and clear and not "magic" because if they can't understand it they can't update it or fix it if there's a problem.
So I've written something myself: http://github.com/mrlacey/NanoIoC
Yes, the name is a tounge-in-cheek reference to MicroIoc & TinyIoC but hints that mine has much less code. (It's less than 90 LOC.)
Yes, I know it's more of a DI framework than an IOC one but the terms are used fairly interchangable out in the real world so I'm happy with this.
How to use it:
For the class that has some external dependencies, we declare this by marking them up with an interface "ISupportInjectionOf<T>". As an example, if we wanted to indicate a page had a dependency up an "IRepository" and an "IDateTimeHelper" we'd do this:
Then within our constructor we'd resolve these dependencies:
Yes, we could resolve the dependencies at any time, but in my code it'll always be in the constructors.
This is important for maintaining testability and maintainability. (I'm establishing a convention.)
In the above example I'd also include a constructor overload for directly injecting the dependencies during testing:
Simple!
Configuration:
Configuration is simple and done at app level. We can declare how each dependency should be resolved separately:
Or via a fluent interface:
Obviously these examples all use interfaces. But we don't have to. Assuming that we didn't want to hide "DateTimeHelper" behind an interface, we can just do this (note the type is inferred):
The above examples are all creating an instance to use for every time the dependency is resolved.
Instead, we could pass an instance of a singleton in the traditional way:
If you want different instances each time a dependency is resolved simply pass a factory and get the new instances that way.
What do you think?
Useful?
Interesting?
Something you may consider using?
Want it bundled into a NuGet package? (Either as a library or the single source file)
I'd love to know what you think.
* It would be awesome if in a (prefereably near) future version of the Windows Phone SDK, it included tooling to allow it to be easier to implement good development practices in our Windows Phone code. It's awesome that they've made it easy for people to get started with developing for the platform but those beginners need, in time, to know how to write better code and if the tools stop them there's no incentive for them to learn. And for those of us who consider ourselves professionals and do this for a living, we want to be able to apply best practices to our code (work) and not have the SDK and the tooling get in the way and stop us doing basic things.
There's nothing built in and lots of people have created their own solutions. Including, but not limited to,: Funq, MicroIoc, TinyIoc, this or this. But none of them work the way I want to.
I want:
- Automatic constructor parameter injection
- Explicit indication of where a dependency exists
- Explicit configuration of how dependencies should be resolved
- Fluent configuration
I don't want:
- Parameter injection
- Automatic resolving of dependencies
- An aribtrary ServiceLocator
I don't care about:
- Letting the container manage singletons
- Nested/chained dependency resolution
There are two factors which influence my requirements:
1. My past experience with Castle Windsor - Chosen after evaluating what was available at the time (about 4 years or so ago.)
2. My experience with working in development teams where there would always be at least one person who wasn't interested in learning anything new, best practices or, seemingly, code quality. I've learnt that if you're working with such people, or anyone new to the industry, that you'll save yourself a lot of work (in fixing up their errors, mistakes and repeatedly explaining things to them) if everything is explicit and clear and not "magic" because if they can't understand it they can't update it or fix it if there's a problem.
So I've written something myself: http://github.com/mrlacey/NanoIoC
As pointed out in the comments, this doesn't provide automatic constructor injection. Unfortunately the platform just doesn't support a way of doing that. This is my next best thing. - Hope that makes it clearer.
Yes, the name is a tounge-in-cheek reference to MicroIoc & TinyIoC but hints that mine has much less code. (It's less than 90 LOC.)
Yes, I know it's more of a DI framework than an IOC one but the terms are used fairly interchangable out in the real world so I'm happy with this.
How to use it:
For the class that has some external dependencies, we declare this by marking them up with an interface "ISupportInjectionOf<T>". As an example, if we wanted to indicate a page had a dependency up an "IRepository" and an "IDateTimeHelper" we'd do this:
public partial class MainPage : PhoneApplicationPage, ISupportInjectionOf<IRepository>, ISupportInjectionOf<IDateTimeHelper> {
Then within our constructor we'd resolve these dependencies:
private IRepository repository; private IDateTimeHelper dateTime; public MainPage() { InitializeComponent(); repository = this.GetDependency<IRepository>(); dateTime = this.GetDependency<IDateTimeHelper>(); }
Yes, we could resolve the dependencies at any time, but in my code it'll always be in the constructors.
This is important for maintaining testability and maintainability. (I'm establishing a convention.)
In the above example I'd also include a constructor overload for directly injecting the dependencies during testing:
#if TEST public MainPage(IRepository repo, IDateTimeHelper dateTimeHelper) { InitializeComponent(); this.repository = repo; this.dateTime = dateTimeHelper; } #endif
Simple!
Configuration:
Configuration is simple and done at app level. We can declare how each dependency should be resolved separately:
NanoIocConfig.RegisterDependency<IRepository>(new ViewModelRepository()); NanoIocConfig.RegisterDependency<IDateTimeHelper>(new DateTimeHelper());
Or via a fluent interface:
NanoIocConfig.RegisterDependency<IRepository>(new ViewModelRepository()) .And<IDateTimeHelper>(new DateTimeHelper());
Obviously these examples all use interfaces. But we don't have to. Assuming that we didn't want to hide "DateTimeHelper" behind an interface, we can just do this (note the type is inferred):
NanoIocConfig.RegisterDependency(new DateTimeHelper()); dth = this.GetDependency<DateTimeHelper>();
The above examples are all creating an instance to use for every time the dependency is resolved.
Instead, we could pass an instance of a singleton in the traditional way:
NanoIocConfig.RegisterDependency<IRepository>(ViewModelRepository.Instance);
If you want different instances each time a dependency is resolved simply pass a factory and get the new instances that way.
What do you think?
Useful?
Interesting?
Something you may consider using?
Want it bundled into a NuGet package? (Either as a library or the single source file)
I'd love to know what you think.
* It would be awesome if in a (prefereably near) future version of the Windows Phone SDK, it included tooling to allow it to be easier to implement good development practices in our Windows Phone code. It's awesome that they've made it easy for people to get started with developing for the platform but those beginners need, in time, to know how to write better code and if the tools stop them there's no incentive for them to learn. And for those of us who consider ourselves professionals and do this for a living, we want to be able to apply best practices to our code (work) and not have the SDK and the tooling get in the way and stop us doing basic things.