Load JSON from file/URL in Swift 3

Load JSON from file/URL in Swift 3

onedayitwillmake No Comments

Simple snippet to load JSON into from a filepath or URL

// Retrieves JSON from bundle
  private func loadJSON(fileURL:URL)->[String : Any]? {
    // Parse the JSON
    do {
      // Create a string out of the file contents
      let contents = try String(contentsOf: fileURL) // use contentsOfFile for strings
      // Turn it into data to feed JSONSerialization class
      let data     = contents.data(using: String.Encoding.utf8)
      // Attempt to turn it into JSON, or show error
      let json:[String:Any]? = try? JSONSerialization.jsonObject(with: data!, options: []) as! [String : Any]
 
      return json
 
    } catch {
      Swift.print("Error parsing json")
      return nil
    }
  }

Bringing an application window to the front Swift

onedayitwillmake No Comments

There are many ways to do this, however this simple method below has worked for me better than window?.makeKeyAndOrderFront(self)

override func viewDidAppear() {
  super.viewDidAppear()
  NSApp.activate(ignoringOtherApps: true)
}

Concisely animating a local T value along a path

onedayitwillmake No Comments

If you have a T value, in the range of [0.0-1.0] you can convert that to a local T value for each part of that curve.

    var rangePerItem = 1.0 / items.length;
    var t = 0.73;
 
    for(var i = 0; i < items.length; i++) {
        // determine which piece of the line this item falls into
        var a          = i * rangePerItem;
        var b          = (i + 1) * rangePerItem;
 
        // normalize the value so that 0.51 on the third one becomes 1.0 for the first and second, and 0.2 for the third, and 0 for the 4th
        var localT     = (t - a) / (b - a);
        localT = clamp(localT, 0, 1);
        item.update(localT);
    }

VSCode in Unity

onedayitwillmake No Comments

If you’re tired of MonoDevelop’s editing capabilities, you should try VSCode!
It’s super snappy, and lightweight

Screen Shot 2016-08-24 at 1.36.38 PM

  1. Download VSCode insiders edition
  2. Install the C# 1.3.0 support
  3. Install mono debugger
  4. brew install mono (need this for intellisense to work)
  5. In unity, open C# project by going to Assets > Open C# Project In Code (don’t just double click a file)

CAAnimation completion callback block

onedayitwillmake No Comments

It’s really useful to fire a function when an animation is complete.
There’s no built in way to do that in CoreAnimation, it does have the concept of delegate’s, which get you half way there.

However if you have multiple animations firing, and your delegate is catching everything, you’re gonna be in for a world of hurt.

Here is a simple Swift class I wrote to extend CAAnimation to accept onStart/onCompletion blocks:


import Foundation import Cocoa public typealias CAAnimationCallback = (CAAnimation, Bool) -> (); public class CAAnimationDelegate:NSObject { var onStartCallback:CAAnimationCallback? var onCompleteCallback:CAAnimationCallback? override public func animationDidStart(anim: CAAnimation) { if let startHandler = onStartCallback { startHandler(anim, true); } } override public func animationDidStop(anim: CAAnimation, finished flag: Bool) { if let completionHandler = onCompleteCallback { completionHandler(anim, flag); } } } public extension CAAnimation { // See if there is already a CAAnimationDelegate handling this animation // If there is, add onStart to it, if not create one func setonStartCallbackBlock(callback:CAAnimationCallback) { if let myDelegate = delegate { if(myDelegate.isKindOfClass(CAAnimationDelegate)) { let myThing = myDelegate as! CAAnimationDelegate; myThing.onStartCallback = callback; } } else { let callbackDelegate = CAAnimationDelegate(); callbackDelegate.onStartCallback = callback; self.delegate = callbackDelegate; } } // See if there is already a CAAnimationDelegate handling this animation // If there is, add onCompletion to it, if not create one func setCompletionBlock(callback:CAAnimationCallback) { if let myDelegate = delegate { if(myDelegate.isKindOfClass(CAAnimationDelegate)) { let myThing = myDelegate as! CAAnimationDelegate; myThing.onCompleteCallback = callback; } } else { let callbackDelegate = CAAnimationDelegate(); callbackDelegate.onCompleteCallback = callback; self.delegate = callbackDelegate; } } }

Usage

var animation = CABasicAnimation(keyPath: "strokeEnd")
animation.duration = duration
animation.fromValue = 0.0
animation.toValue = 1.0
animation.setCompletionBlock({ (anim:CAAnimation) in
  Swift.print("On Complete!")
})

CAAnimation delegate not working (Swift)

onedayitwillmake No Comments

CAAnimation provides a way of receiving a callback upon start or completion of an animation.
If you have a ‘pure’ class, that is a class that does not inherit from anything, doing this will have no effect:


class Petal { func startAnimation(duration: Double = 2.0) { let pathAnimation = CABasicAnimation(keyPath: "strokeEnd"); pathAnimation!.delegate = self; pathAnimation!.duration = duration; pathAnimation!.fromValue = 0.0; pathAnimation!.toValue = 1.0; self.shapeLayer.addAnimation(pathAnimation!, forKey: "strokeEnd"); } func animationDidStart(anim: CAAnimation) { Swift.print("ANIMATION DID START!"); } func animationDidStop(anim: CAAnimation, finished flag: Bool) { Swift.print("ANIMATION DID END!"); } }

The reason is because:
You must subclass NSObject, as the delegate methods exist as an informal protocol extension on NSObject

So simply changing it to this is enough:


class Petal:NSObject { // Subclass NSObject func startAnimation(duration: Double = 2.0) { .... } // These are now overrides override func animationDidStart(anim: CAAnimation) { Swift.print("ANIMATION DID START!"); } override func animationDidStop(anim: CAAnimation, finished flag: Bool) { Swift.print("ANIMATION DID END!"); } }

Numeric operator overloading in Swift

onedayitwillmake No Comments

Sometimes when developing in Swift if you’re trying to do seemingly simple things like divide 2 numbers:

let interval:Double = 1.0/fps;

You’ll get errors like these:

binary operator '*' cannot be applied to operands of type 'CGFloat' and 'Double'
binary operator '*' cannot be applied to operands of type 'Int' and 'CGFloat'
cannot convert value of type 'Float' to expected argument type 'Double'
binary operator '*' cannot be applied to operands of type 'CGFloat' and 'Int8'

This is because Swift is more strict about how it treats numeric types, and you have to manually cast them to the same type in order for those operations to work.

However cause we can write our own operator in Swift, we can make it so that when it encounters 2 types, it will check to see if we have a matching operator and use that instead.

So as I’ve encountered them, I’ve been appending to a my little NumericOperatorOverloadingExtensions.swift file:

import Foundation

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////// ADDITION ////////////////////////////////////////////////////////////////
public func +(a: Float, scalar: Int)  -> Float  { return a + Float(scalar); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////// MULTIPLICATION  //////////////////////////////////////////////////////////////
// Int *
public func *(a: Int, scalar: CGFloat)  -> CGFloat  { return CGFloat(a) * scalar; }
public func *(a: Int, scalar: Float)    -> Float    { return Float(a) * scalar; }
public func *(a: Int, scalar: Double)   -> Double   { return Double(a) * scalar; }
public func *(scalar: CGFloat, a: Int)  -> CGFloat  { return CGFloat(a) * scalar; }
public func *(scalar: Float, a: Int)    -> Float    { return Float(a) * scalar; }
public func *(scalar: Double, a: Int)   -> Double   { return Double(a) * scalar; }

// Int8 *
public func *(a: Int8, scalar: CGFloat)  -> CGFloat  { return CGFloat(a) * scalar; }
public func *(a: Int8, scalar: Float)    -> Float    { return Float(a) * scalar; }
public func *(a: Int8, scalar: Double)   -> Double   { return Double(a) * scalar; }
public func *(scalar: CGFloat, a: Int8)  -> CGFloat  { return CGFloat(a) * scalar; }
public func *(scalar: Float, a: Int8)    -> Float    { return Float(a) * scalar; }
public func *(scalar: Double, a: Int8)   -> Double   { return Double(a) * scalar; }

// Int32 *
public func *(a: Int32, scalar: CGFloat)  -> CGFloat  { return CGFloat(a) * scalar; }
public func *(a: Int32, scalar: Float)    -> Float    { return Float(a) * scalar; }
public func *(a: Int32, scalar: Double)   -> Double   { return Double(a) * scalar; }
public func *(scalar: CGFloat, a: Int32)  -> CGFloat  { return CGFloat(a) * scalar; }
public func *(scalar: Float, a: Int32)    -> Float    { return Float(a) * scalar; }
public func *(scalar: Double, a: Int32)   -> Double   { return Double(a) * scalar; }

// Float *
public func *(a: Float, scalar: Double)  -> Float  { return a * Float(scalar); }
public func *(a: Float, scalar: Double)  -> CGFloat  { return CGFloat(a * Float(scalar)); }
public func *(a: Float, scalar: Double)  -> Double  { return Double(a) * scalar; }

// CGFLOAT  *
public func *(a: CGFloat, scalar: Double)  -> CGFloat  { return a * CGFloat(scalar); }
public func *(a: CGFloat, scalar: Double)  -> Float  { return Float(a) * Float(scalar); }
public func *(a: CGFloat, scalar: Double)  -> Double  { return Double(a) * scalar; }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////// DIVISION ////////////////////////////////////////////////////////////////
// Double /
public func /(a: Double, b: Int)  -> Double  { return a / Double(b); }
public func /(a: Double, b: Float)  -> Double  { return a / Double(b); }
public func /(a: Double, b: Int)  -> Int  { return Int(a) / b; }
public func /(a: Int, b: Double)  -> Double  { return Double(a) / b; }
public func /(a: Int, b: Double)  -> Int  { return Int(Double(a) / b); }

// Float /
public func /(a: Float, b: Int)  -> Float  { return a / Float(b); }
public func /(a: Float, b: Int)  -> Int  { return Int(a) / b; }
public func /(a: Int, b: Float)  -> Float  { return Float(a) / b; }
public func /(a: Int, b: Float)  -> Int  { return Int(Float(a) / b); }
public func /(a: Float, scalar: Double)  -> Float  { return a / Float(scalar); }

NPM install from branch on private repo

onedayitwillmake No Comments

Something you need a specific branch of a repository that has not been published yet.

git+http://git@SUBDOMAIN.DOMAIN.COM/USER/REPO-URL.git#4d331600

For example:

// this URL
https://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs/tree/39333c6227ea537e3f5d4ec9e893d7f9c670c867
 
// becomes in your package.json
git+https://git@github.com/USERNAME/REPO_NAME.git#39333c6227ea537e3f5d4ec9e893d7f9c670c867
 
// If that doesn't work, try:
npm install --save git+ssh://git@github.com/USERNAME/REPO_NAME.git#HASH

Swap HTTP for HTTPS, depending on your repo location

Running a python/shell script from the UnityEditor

onedayitwillmake No Comments

While working on your game, sometimes you develop little python or shell scripts that help along the process, and it’d be nice to run them from the editor.
Or better yet, during your automated build process, have it call out to this from within Unity.

It’s actually quite simple, and you can even capture the output into the editor.

[MenuItem("MyGame/Downscale Reference Textures")]
public static void DownscaleRefTextures() {
        // using System.Diagnostics;
    Process p = new Process();
    p.StartInfo.FileName = "python";
    p.StartInfo.Arguments = "resize_reference_sprites.py";    
        // Pipe the output to itself - we will catch this later
    p.StartInfo.RedirectStandardError=true;
    p.StartInfo.RedirectStandardOutput=true;
    p.StartInfo.CreateNoWindow = true;
 
       // Where the script lives
    p.StartInfo.WorkingDirectory = Application.dataPath+"/SpriteCollections/"; 
    p.StartInfo.UseShellExecute = false;
 
    p.Start();
        // Read the output - this will show is a single entry in the console - you could get  fancy and make it log for each line - but thats not why we're here
    UnityEngine.Debug.Log( p.StandardOutput.ReadToEnd() );
    p.WaitForExit();
    p.Close();
}

ios-creating-reusable-uiviews-with-storyboard – Part 2

onedayitwillmake No Comments

This has is an updated version of ios-creating-reusable-uiviews-with-storyboard for Xcode 6.

TL:DR version:

  1. Create a new UIView subclass name it MyView.h/MyView.h
  2. Create a new XIB name it MyView.xib
  3. In MyView.xib select the File's Owner and set the class (using the right pane, third tab) to MyView
  4. Create an IBOutlet in MyView.h is of the type UIView*, call it contentView
  5. In InterfaceBuilder (with MyView.xib open) right-click drag the File's Owner the root view, and link it to contentView
  6. In MyView.m, override -awakeFromNib with the following:
    -(void)awakeFromNib {
        [[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil];
     
        // The following is to make sure content view, extends out all the way to fill whatever our view size is even as our view's size is changed by autolayout
        [self.contentView setTranslatesAutoresizingMaskIntoConstraints:NO];
        [self addSubview: self.contentView];
     
        [[self class] addEdgeConstraint:NSLayoutAttributeLeft superview:self subview:self.contentView];
        [[self class] addEdgeConstraint:NSLayoutAttributeRight superview:self subview:self.contentView];
        [[self class] addEdgeConstraint:NSLayoutAttributeTop superview:self subview:self.contentView];
        [[self class] addEdgeConstraint:NSLayoutAttributeBottom superview:self subview:self.contentView];
     
    }
     
    +(void)addEdgeConstraint:(NSLayoutAttribute)edge superview:(UIView *)superview subview:(UIView *)subview {
        [superview addConstraint:[NSLayoutConstraint constraintWithItem:subview
                                                              attribute:edge
                                                              relatedBy:NSLayoutRelationEqual
                                                                 toItem:superview
                                                              attribute:edge
                                                             multiplier:1
                                                               constant:0]];
    }

So that’s the first part, the second part is to create a UIView in some other XIB or storyboard, do whatever autolayout stuff you want with it and set it’s UIView class to “MyView”. When the XIB is loaded and displayed -it will show your view in there allowing you to customize views and reuse them.