Archive for category Uncategorized
No default parameter values in Swift Protocols
Posted by davefielding76 in Uncategorized on November 7, 2014
According to Apple’s Swift Programming Language documentation (emphasis mine):
Protocols declare that conforming types must implement a method by including a protocol method declaration in the body of the protocol declaration. Protocol method declarations have the same form as function declarations, with two exceptions: They don’t include a function body, and you can’t provide any default parameter values as part of the function declaration
This means that it is not possible to use any default values for any functions defined in a protocol. The reason that I stumbled across this was because I was attempting to do the following in a SpriteKit project I have built in Swift:
protocol SomeTheme { func animateSomething(completion: (() -> ()?) } class MyTheme { func animateSomething(completion: (() -> ()? = nil) { someNode.runAction( SKAction.sequence([SKAction.waitForDuration(0.25, withRange: 0.25)]) { if let comp = completion { comp() } }) } }
However, given its never actually possible to define the default value in the protocol, its impossible to take advantage of it in a calling method, unless the caller has explicit knowledge of the implementing class. So you cannot do this:
someThemeInstance.animateSomething()
you always have to explicitly include the completion, either as a parameter or closure:
someThemeInstance.animateSomething(nil) // or someThemeInstance.animateSomething() { }
Hopefully this is something that will be addressed in a future Swift update.
Problems using Swift + SpriteKit on iOS7 with XCode 6.1
Posted by davefielding76 in Uncategorized on November 7, 2014
I have been playing around with Apple’s new iOS development language, Swift, recently. Overall it seems a great language, but its clearly very early days and there are bugs in both the implementation and the development environment. Expect more posts on Swift in the coming weeks, but one of the most annoying issues I’ve found over the last few weeks has been this one:
There seems to be an issue with the way the XCode templates have changed between XCode 6.0 and 6.1 that causes problems when working with SpriteKit scenes in Swift.
The problem is with the initialization of the SKScene from the controller: XCode 6.1 generates some boilerplate code, which amongst other things, implements the ‘unarchiveFromFile’ extension method which doesn’t appear to work well with Swift on iOS7.1.
I got round this by using the following extension:
import UIKit import SpriteKit extension SKNode { // The original method generated by XCode6.1 to initialise SpriteKit SKScenes class func unarchiveFromFile<T: SKScene>(file : NSString) -> T { let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks") var sceneData = NSData(contentsOfFile: path!, options: .DataReadingMappedIfSafe, error: nil) var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData!) archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene") let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as T archiver.finishDecoding() return scene } class func safeInit<T: SKScene>(size: CGSize, _ skFile: NSString) -> T { let currentVersion = UIDevice.currentDevice().systemVersion let isIOS8 = currentVersion.compare("8.0", options: NSStringCompareOptions.NumericSearch) != NSComparisonResult.OrderedAscending if isIOS8 { let scene = T.unarchiveFromFile(skFile) scene.size = size return scene as T } else { return T(size: size) } } }
And then calling this from your controller using the following code:
let skView = self.view as SKView let scene = GameScene.safeInit(skView.bounds.size, "GameScene") as GameScene
That seems to work for me. It feels like a bit of a hack but I can’t see any alternative option that actually works. As it happens, someone reported a very similar issue on StackOverflow recently, so this answer is also available on there.
I am working on the basis that this is probably a bug and will hopefully get fixed in a future release, at which point I will remove the hacky version checking.
Using Exception Helpers but avoiding CA1062 errors
Posted by davefielding76 in Uncategorized on November 2, 2012
I generally like to activate Code Analysis on projects that I’m working on, but this does add overhead in terms of the restrictions of what the analysis can cope with.
A perfect example of this is adhering to CA1062: Validate Arguments of public methods, especially when checking for null. A prime example would be:
public void MyMethod(string parameter1, object parameter2) { return string.Format(CultureInfo.InvariantCulture, parameter1, parameter2); }
Now, if we were to run that past the code analysis engine, we would be on the receiving end of (at least) 2 violations for CA1062 and would then need to quadruple the codebase for this method:
public void MyMethod(string parameter1, object parameter2) { if (!string.IsNullOrEmpty(parameter1)) { throw new ArgumentNullException("parameter1"); } if (parameter2 == null) { throw new ArgumentNullException("parameter2"); } return string.Format(CultureInfo.InvariantCulture, parameter1, parameter2); }
Ugh. That’s a 10:1 ratio of validation code to actual work.
What would be much nicer would be to use an exception helper to allow us to do something like:
public void MyMethod(string parameter1, object parameter2) { Throw.IfNotNull(parameter1, "parameter1"); Throw.IfNotNull(parameter2, "parameter2"); return string.Format(CultureInfo.InvariantCulture, parameter1, parameter2); }
By default, if we do this then the code analysis engine is unable to delve into the IfNotNull method to see what its doing and so cannot confirm whether we are validating the parameter.
However, it turns out we can let it know that its doing this by creating a ValidatedNotNullAttribute:
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)] public sealed class ValidatedNotNullAttribute : Attribute { }
then use this in the helper method:
public static class Throw { public void IfNotNull([ValidatedNotNull]object toCheck, string name) { if (ReferenceEquals(toCheck, null)) { throw new ArgumentNullException(name); } } }
And no more CA1062 warnings!
Stopping Visual Studio breaking on exceptions in a specific method
Posted by davefielding76 in Uncategorized on September 6, 2012
I have just discovered this nifty little trick to stop VS breaking on Exceptions in a specific method, irrespective of the settings under Debug -> Exceptions.
The DebuggerStepThrough attribute on a method does not just stop the debugger stepping into the method when you are hitting F11 on it, it will also not pick up thrown exceptions.
So, if you, like me, have an exception that may get thrown that you can’t do anything about (ie if a user cancels an operation inside a COM call that throws an E_ABORT COMException), this is one way to ignore it in the debugger.
Of course, you can’t have your cake and eat it, if you set this attribute then you also can’t step into and debug the method in question either, but with a little bit of refactoring you should be able to keep the offending method as short as possible.
Example:
[DebuggerStepThrough] private void SendCrashLogs(string logFileName) { FileInfo logFile = new FileInfo(logFileName); if (logFile.Exists) { List<dynamic> toRelease = new List<dynamic>(); dynamic outlookApplication = null; Process[] existingOutlookProcess = Process.GetProcessesByName("Outlook"); bool alreadyRunning = existingOutlookProcess.Length > 0; try { outlookApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Outlook.Application")); toRelease.Add(outlookApplication); // Create a new message and set the contents); if (outlookApplication != null) { dynamic outlookMessage = outlookApplication.CreateItem(0); toRelease.Add(outlookMessage); if (outlookMessage != null) { // At the following line the user can cancel the operation // which causes a COMException to be fired. dynamic recipients = outlookMessage.Recipients; toRelease.Add(recipients); dynamic sender = recipients.Add(Environment.UserName); toRelease.Add(sender); foreach (string crashEmailRecipient in this.crashEmailRecipients) { recipients.Add(crashEmailRecipient); } foreach (dynamic recipient in recipients) { recipient.Resolve(); toRelease.Add(recipient); } outlookMessage.Subject = "Sending Logs"; string html = GenerateMessageBody(); outlookMessage.HTMLBody = html; // Add the logs as an attachment dynamic outlookMessageAttachments = outlookMessage.Attachments; toRelease.Add(outlookMessageAttachments); outlookMessageAttachments.Add( logFileName, Type.Missing, outlookMessage.Body.Length + 1, logFileName); outlookMessage.Send(); } } } catch (COMException cEx) { if (cEx.Message.Contains("E_ABORT")) { this.log.Warn("User aborted sending of error logs via email"); } else { this.log.Error("Could not send error logs via email", cEx); } } catch (Exception ex) { this.log.Error("Could not send error logs via email", ex); } finally { // Need to quit the Outlook application if it wasn't already running if (outlookApplication != null && !alreadyRunning) { outlookApplication.Quit(); } toRelease.Where(i => i != null).ForEach(i => Marshal.FinalReleaseComObject(i)); toRelease.Clear(); } } }
Using UAC to request Administrative Privileges from c#
Posted by davefielding76 in Uncategorized on February 27, 2012
With the advent of Windows Vista and Windows 7, we need to consider access rights more than ever. Previously, applications running on windows-based operating systems up to and including XP could just rely on having wide access to perform almost any task. Although many corporate systems are more locked down, the software running on them is generally heavily tailored to do so.
With Windows Vista/7, this locked down approach is brought to the consumer versions of the operating system – by default users do not get administrative privileges – to get these privileges the OS will request confirmation from the user that they are happy for the application to be run in the elevated context. There are 2 main ways of causing the OS to display the prompts:
- Creating / updating the application manifest file to include
- Launching the application setting the “runas” verb from code
As this blog is centered around c#, lets take a look at the latter.
Once the application is launched, there is no way to elevate the privileges from code. We must therefore look at making sure it is started correctly. Adding the following code to the program start does just this:
WindowsPrincipal pricipal = new WindowsPrincipal(WindowsIdentity.GetCurrent()); bool hasAdministrativeRight = pricipal.IsInRole(WindowsBuiltInRole.Administrator); if (!hasAdministrativeRight) { // relaunch the application with admin rights string fileName = Assembly.GetExecutingAssembly().Location; ProcessStartInfo processInfo = new ProcessStartInfo(); processInfo.Verb = "runas"; processInfo.FileName = fileName; try { Process.Start(processInfo); } catch (Win32Exception) { // This will be thrown if the user cancels the prompt } return; }
As you can see, what we are actually doing is re-launching the app, setting the ProcessStartInfo.Verb property to “runas”. This automatically causes the OS to prompt the user for admin access.
This can cause a few problems debugging – the easiest way round is to ensure the Visual Studio process is run as an administrator, otherwise we will just launch a new instance of the application whenever we attempt to debug.
An IDisposable Locking implementation
Posted by davefielding76 in Uncategorized on June 29, 2011
c# provides a very easy mechanism for simple thread safety and synchronisation: the lock statement. However, in many cases, a simple lock is too restrictive as it will block all other access o the locked object, irrespective of the operation being performed.
For more fine-grained control, there are a few options, but since .net3.5, my personal preference has always been to use the ReaderWriterLockSlim (see here for more information). This has the following advantages:
- We can have multiple concurrent threads reading
- Only 1 thread can perform write operations – this will wait for all currently executing readers to complete before blocking others and executing itself.
- When explicitly required, we can upgrade a Read operation to a Write operation
- We can choose whether to allow lock recursion or not
However, one of the nice advantages of the lock statement is the syntactic sugar added within the language spec which means we can do something like:
lock(myLockObject) { // access my x-thread data }
I don’t think anyone would disagree that this is a nice and neat way of writing a thread synchronization block. Unfortunately, to implement a ReaderWriterLockSlim (or any of the other locking mechanisms apart from the lock statement), we have no such options, leading to much bulkier code.
this.dataLock.EnterReadLock(); try { // access my x-thread data } finally { this.dataLock.ExitReadLock(); }
One way round this is to create a Disposable object which Enters the locks required and Exits them on calls to IDispose.
/// <summary>Type of lock operation</summary> public enum LockType { /// <summary>A read lock, allowing multiple simultaneous reads</summary> Read, /// <summary>An upgradeable read, allowing multiple simultaneous reads, but with the potential that ths may be upgraded to a Write lock </summary> UpgradeableRead, /// <summary>A blocking Write lock</summary> Write } /// <summary>Wrapper for the ReaderWriterLockSlim which allows callers to dispose the object to remove the lock </summary> public class DisposableLockWrapper : IDisposable { /// <summary>The lock object being wrapped</summary> private readonly ReaderWriterLockSlim readerWriterLock; /// <summary>The lock type</summary> private readonly LockType lockType; /// <summary> /// Initializes a new instance of the <see cref="DisposableLockWrapper"/> class. /// </summary> /// <param name="readerWriterLock">The reader writer lock.</param> /// <param name="lockType">Type of the lock.</param> public DisposableLockWrapper(ReaderWriterLockSlim readerWriterLock, LockType lockType) { this.readerWriterLock = readerWriterLock; this.lockType = lockType; switch (this.lockType) { case LockType.Read: this.readerWriterLock.EnterReadLock(); break; case LockType.UpgradeableRead: this.readerWriterLock.EnterUpgradeableReadLock(); break; case LockType.Write: this.readerWriterLock.EnterWriteLock(); break; } } /// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> /// <filterpriority>2</filterpriority> public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } /// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected virtual void Dispose(bool disposing) { if (disposing) { // dispose managed objects switch (this.lockType) { case LockType.Read: this.readerWriterLock.ExitReadLock(); break; case LockType.UpgradeableRead: this.readerWriterLock.ExitUpgradeableReadLock(); break; case LockType.Write: this.readerWriterLock.ExitWriteLock(); break; } } } }
To keep the implementation details away from the callers, I decided to implement a set of Extension methods to the ReaderWriterLockSlim class:
/// <summary>Extension methods for the ReaderWriterLockSlim object </summary> public static class ReaderWriterLockSlimExtension { /// <summary> /// Obtains a Read lock on the ReaderWriterLockSlim object /// </summary> /// <param name="readerWriterLock">The reader writer lock.</param> /// <returns>An IDisposable object that will release the lock on disposal</returns> public static IDisposable ObtainReadLock(this ReaderWriterLockSlim readerWriterLock) { return new DisposableLockWrapper(readerWriterLock, LockType.Read); } /// <summary> /// Obtains an Upgradeable Read lock on the ReaderWriterLockSlim object /// </summary> /// <param name="readerWriterLock">The reader writer lock.</param> /// <returns>An IDisposable object that will release the lock on disposal</returns> public static IDisposable ObtainUpgradeableReadLock(this ReaderWriterLockSlim readerWriterLock) { return new DisposableLockWrapper(readerWriterLock, LockType.UpgradeableRead); } /// <summary> /// Obtains a Write Lock on the ReaderWriterLockSlim object /// </summary> /// <param name="readerWriterLock">The reader writer lock.</param> /// <returns>An IDisposable object that will release the lock on disposal</returns> public static IDisposable ObtainWriteLock(this ReaderWriterLockSlim readerWriterLock) { return new DisposableLockWrapper(readerWriterLock, LockType.Write); } }
We can now use the ReaderWriterLockSlim nice an easily by calling as follows:
using (this.dataLock.ObtainReadLock()) { // access my x-thread data }
Reflection with Generic Methods
Posted by davefielding76 in Uncategorized on June 14, 2011
Two of the really powerful features of .net to me are Generics and Reflection. However, there seems to be very little documentation around indicating how you use them together.
For example, consider the following class:
public class MyNonGenericClass { void NormalMethod(object normalParameter) { Console.WriteLine(normalParameter); } void GenericMethod<T>(T genericParameter) { Console.WriteLine(genericParameter); } }
The first method is easy to execute using reflection:
public void CallNormalMethod() { MethodInfo method = typeof(MyNonGenericClass).GetMethod("NormalMethod"); method.Invoke(new MyNonGenericClass(), new object[] { "normal method" }); }
Until investigating recently, I was unsure how one would go about executing the second. It turns out that its also very easy:
public void CallGenericMethod() { // Use the reflection equivalent of "new MyNonGenericClass().GenericMethod<string>("...")" MethodInfo method = typeof(MyNonGenericClass).GetMethod("GenericMethod"); MethodInfo genericMethod = method.MakeGenericMethod(new[] { typeof(string) }); genericMethod.Invoke(new MyNonGenericClass(), new object[] { "generic method" }); }
Welcome to my blog
Posted by davefielding76 in Uncategorized on May 29, 2011
I have been thinking for quite some time that I should start a blog, for various reasons, and this is my first stab at actually doing something about it. As indicated by the title of the site, I’m a changeable sort and will no doubt decide that the entire format, platform or maybe even purpose of the blog is all wrong within a couple of months. However, in the meantime, here we are.
So… why start a blog? There are millions of them out there, does the world really need another one? Obviously I decided it did, so here are my thoughts on why:
- I’m an IT developer. One should read into this that, despite any protestations to the contrary, I’m really a geek at heart, and like all geeks like to have a variety of home projects on the go at any one time. This is another of those pet projects.
- I’m an IT developer. An inevitable part of the process of designing and developing software is trying to find occasions where others have completed a piece of work which you need to accomplish. Not the whole shebang, of course, just small components which should be easy to carry out, but inevitably are not. Google is your best friend for this search, but the acquaintances who add the real value inevitably turn out to be a myriad of blogs out in the ether, explaining away the method behind the madness of what I am attempting (and they have figured out how) to do (subject to licensing and permission of course). I therefore decided it was time to put something back, to allow others to build on top of my work and hopefully save lots of time and stop others reinventing the wheel.
- I’m an IT developer. Having a blog showing examples of my work (provided of course that the topics that I cover are sufficiently complex and not just demonstrating that I don’t know how to write a hello world application) can hardly harm my CV can it?
- I’m an IT developer. I therefore spend most of my day (when not in meetings or searching for code online) writing or reviewing code. This gives me an opportunity to make sure my English does not fade away into 140-character pseudo-English based purely on SMS messages, Facebook status updates and Tweets.