Dirty beards?

Gimli and his beard
Somehow my wife was directed to a web page that states “Apparently beards are filled with fecal bacteria and are ‘as dirty as toilets'”. Okay… this has to be some kind of joke or part of the anti-hipster beard movement. Hipster beards, I agree, are pretty ridiculous.

Filled with fecal bacteria? How? What are guys doing that could possibly cause such a thing? Dirty as a toilet? Really?

I simply can’t believe the report. I do shampoo my face stalks a few times a week, but never every day as that could dry the stuff out and it gets, even more, wirey. I have beard oil but I don’t use that until we’re really into winter and I decide to grow things out a little more than normal.

As dirty as a toilet? Come on…

Tagged :

Swift 3 appearance extensions

Appearance
I just read about this and smacked myself on the forehead. Normally when developing an application I follow some sort of branding guidelines or perhaps make use of a custom font. I think most developer/designers DOI this quite regularly.

Now, I’ve found myself coding to those conventions over and over for various labels and like user interface controls. It’s a pain in the ass. If it needs to change you can search and replace in the project, or use messier methods. Not fun and prone to errors.

Extensions. We all use them too. However, they can be used to simplify your code and maintain consistency application-wide. You can put these in a separate Swift file to make them easier to track down.

/** Appearance .swift */ 
import UIKit 
extension UIColor { 
    // Custom colours go here 
    func custom() -> UIColor { 
        return UIColor(red: 0.45, green: 0, blue: 0.95, alpha: 1) 
    } 
} 
extension UIFont { 
    // Custom fonts go here 
    func custom(size:CGFloat) -> UIFont { 
        return UIFont(name: "Avenir Next", size: size)! 
    }
}

I’ll reformat the above code soon, I’m on my phone at the moment. But look at that. It can be so simple to make edits to affect a great number of controls.

Here is an example implementation of the extension.

// Use the extensions from Appearance .swift 
label.textColor = UIColor().custom() 
label.font = UIFont().custom(size: 20)

How about using static variables? Excellent and clean!

import UIKit 
extension UIColor { 
    // Static, computed variable for custom colour 
    static var custom:UIColor { 
        return UIColor(red: 0.45, green: 0, blue: 0.95, alpha: 1) 
    }
}

Now here is the implementation using a static variable.

label.textColor = .custom

Shazam. To me, this is really excellent. Easy to use, easy to modify, and it keeps your view controllers and the like slimmer and thus easier to read. No long lists of label modifications. You can take this concept quite far if you’d like to.

Casio Pathfinder: A key to atomic clock syncing on the east coast.

When I first received my PAW1300T-7V, it had a medium charge. After a few days I managed to get it powered to high, but it must have been early on into high. I would get an atomic sync perhaps twice a week. This was while placing the watch on a window sill facing southwest as I live in Boston. Syncing was hit or miss.

I purchased a LED solar watch charger and after about 10 hours on that, the watch is on high, but I know it’s got to be on the high end of that charge state. Since that time, the watch has synced every single night while I wear it on my wrist. On the wrong side of the house far away from any of the windows.

So I believe that the atomic watch signal reception in the watch depends highly on the battery status of the watch. With my Pathfinder at a high charge all of the time now I am getting syncs without fail every night on the east coast (which I have read can be dicey because of the distance from Colorado). Given the watch is quartz, the accuracy is rather high and nightly syncing isn’t that much of a concern, generally speaking. You can easily get away without syncs for weeks at a time and you’re still going to be close to the accurate time.

Having a watch that you know is completely accurate without fail – down to the second – is a nice feeling. After a sync, go to http://www.time.gov and see your watch exactly synced with the atomic clock. It’s pretty awesome.

Your Apple Watch would have the same kind of accuracy, but I’d hesitate to take my Apple Watch on a mountain hike. You’d get more accurate altimeter readings (GPS of the watch versus Barometer of the Casio) but at a cost of battery life and cell strength.

So, keep that battery charged!

Tagged : / / /

Weird things this morning.

Random

This morning has been a bit strange. Out of the ordinary. While driving to work and stopped at a light, I pulled out my phone to do some cursory Facebook and Feedly browsing. I had a terrible connection – like none. My phone decided to pair some someone’s XFiniity Wi-Fi router near the light. I had to forget the network to get my LTE back. Kind of weird that – and my browser kept asking me to set up that XFiniity router before I forgot it.

While driving to work and stopped at a light, I pulled out my phone to do some cursory Facebook and Feedly browsing. I had a terrible connection – like none. My phone decided to pair some someone’s XFiniity Wi-Fi router near the light. I had to forget the network to get my LTE back. Kind of weird that – and my browser kept asking me to set up that XFiniity router before I forgot it.

If I’m wearing BLE headphones and jamming to Apple Music while coding, and I build to a simulator, the BLE signal from my laptop stutters – going into a 500ms loop of the last segment of audio before the simulator launches the build. It will loop until I stop the app running in the simulator. So weird.

That’s it. Back to Cafe du Monde and some Carbon Based Lifeforms.

 

My PAW1300T-7V Finally Synced!

itsynced

Living on the east coast of the United States (outside Boston), I had a slim hope that my Casio Protrek PAW1300T-7V would ever receive a signal from Colorado. A night went by when I placed the watch on a South West windowsill to no avail. I read many forum posts online which mentioned the difficulty in syncing from the East Coast.

I checked the next day and saw that the atomic clock and my watch differed by less than 3 seconds. So I didn’t worry a lot about the sync. It was really close.

Last night I went to bed, making sure Auto Sync was turned on. It was. I went to sleep, being on the North East side of the house, where our bed is located in the master bedroom. I figured whatever, it doesn’t matter.

This morning I woke up and looked at the watch face – there were the three bars showing me a sync did indeed take place last night. I checked the R/C status and at 12:05 the sync happened. Wonderful! In the wrong corner of the house and wearing it (not facing a window)… and it worked.

Happy!

Code shelving before a holiday…

It seems that before holidays my list of features coding and bug solutions in mind always grow before holidays. I ruminate on things I want to do and think of solutions to particular bugs. And I have to shelve them until after the festivities are enjoyed.

It’s true.

Right now I’m thinking about VPN and logging into work and accessing the project repository and firing up Xcode. Instead I’m using Wunderlist to document some thinking I have coursing throughout my mind, not wanting to lose them.

Wine. Port. Mead. Family. Wunderlist. I’ll be 👌.

iOS Bug: Occluded UIView with CABasicAnimation not redrawn

I have a UIImageView that holds album artwork in a project. When I get a new now playing notification, instead of simply setting the image to the image view, I perform a crossfade. It’s a lot prettier that way. No problems so far.

Here is a snippet of the crossfading code.

myfade = CABasicAnimation(keyPath: "contents")
myfade.duration = 0.4
myfade.fromValue = largeAlbumCover.image!.cgImage
myfade.toValue = artImage!.cgImage
myfade.delegate = self
largeAlbumCover.layer.add(myfade, forKey: "animateContents")
largeAlbumCover.image = artImage!

Nothing remarkable there. Now… if I add a sliding panel above the UIImageView, and it expands over the image view, and a crossfade is initiated, when the panel slides away later, the image won’t have updated with the new one. It shows the old artwork associated with the previous song. A stale image state. I thought I was going mad for a bit.

I had a suspicion that the image view needed to be visible to perform the redraw update, so I added a small delay to crossfade after the panel responded to my close event. Enough for a tiny sliver of the image view to be visible in the UI before the crossfade was called. It worked.

My final solution: set the panel on top to an alpha value of 0.99 instead of 1.0 – you can’t visually tell that the panel is a tiny bit transparent. This works – I removed the delay thing because that was even more hackish in my opinion.

I have filed this iOS UIKit bug with Apple. My device is running 10.1 and not 10.1.1 – because I didn’t want to potentially change the core OS before my application delivery (just in case it caused a bug or two someplace).

Swift 3: Always display the UITableView scrollbar

I recently had a strange request in regards to a UITableView. You see, the table in a UI could only display 3 rows before scrolling was enabled. Given the minute stature of this table, showing a user that there were more items in it was important. So it was decided that if this table had more than 3 rows in it, always display the scrollbar. The trouble with this was that Apple Human Interface Guidelines and the iOS SDK don’t allow for this behavior. One is able to flash the scrolling indicator, but that’s about it.

So it was decided that if this table had more than 3 rows in it, always display the vertical scrollbar. The trouble with this was that Apple Human Interface Guidelines and the iOS SDK don’t allow for this behavior. One is able to flash the scrolling indicator, but that’s about it.

So the problem here is twofold.

  1. Display the scrollbar upon table reload.
  2. Maintain the visible scrollbar when the table has been scrolled.

These actually aren’t too bad to nail down. You’ll want to set your showsHorizontalScrollIndicator to false. The solution below relies on only having vertical available as we’re going to loop through the table to find a UIImageView (which holds the stretching image used by the table (subclass of UIScrollView)). Set your table up normally beyond this. Make sure you’re using delegates for the table – of course, right?

How do you loop through a table to find it’s scrollbar now?

for view in self.upNextTableView.subviews
{
    if view is UIImageView
    {
        let imageView = view as? UIImageView
        imageView?.isHidden = false
        imageView?.layer.removeAllAnimations()
        imageView?.alpha = 1.0
    }
}

There you go. This is brittle as HELL. If you don’t turn off the horizontal scroll indicator, you’ll affect it t0o – and make that display in addition to the vertical. Didn’t want that. And it’s brittle because Apple could update the underpinnings of how these things are constructed and this method won’t work accurately anymore.

So this turns the scrollbar on. If a user scrolls it at all, though, it’s going to fade away again. This part is a tiny bit tricky. Since you’ve set up delegates for the table, you can implement a scroll view delegate in regards to scrolling… or namely dragging.

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    if scrollView == upNextTableView {
        if upNextTableView.numberOfRows(inSection: 0) > 3 {
            for view in self.upNextTableView.subviews
            {
                if view is UIImageView
                {
                    let imageView = view as? UIImageView
                    delay(bySeconds: 0.7) {
                        imageView?.isHidden = false
                        imageView?.layer.removeAllAnimations()
                        imageView?.alpha = 1.0
                    }
                }
            }
        }
    }
}

There is the delegate method – and because I had more than one table, I perform a check first. You probably don’t need that. Anyway, we wait 0.7 seconds before turning the scrollbar back on after a drag. If we attempt before, the animation will prevent the scrollbar alpha change to “take”. Here is the helper stuff for the delay call:

public func delay(bySeconds seconds: Double, dispatchLevel: DispatchLevel = .main, closure: @escaping () -> Void) {
    let dispatchTime = DispatchTime.now() + seconds
    dispatchLevel.dispatchQueue.asyncAfter(deadline: dispatchTime, execute: closure)
}
    
public enum DispatchLevel {
    case main, userInteractive, userInitiated, utility, background
    var dispatchQueue: DispatchQueue {
        switch self {
        case .main: return DispatchQueue.main
        case .userInteractive: return DispatchQueue.global(qos: .userInteractive)
        case .userInitiated: return DispatchQueue.global(qos: .userInitiated)
        case .utility: return DispatchQueue.global(qos: .utility)
        case .background: return DispatchQueue.global(qos: .background)
        }
    }  
}

So without using a custom scrollbar or subclassed table, you’re able to get what you need to be done. This is most of the code, but the gist of this is to show that it can be done, albeit in a very brittle way that makes me cringe.

 

Microsoft Surface…

It sucks. Hard. My wife purchased one to use for work and she abandoned it not long afterward. About a day. So it’s been laying around and I have given it a go a few times.

Every single time it hangs, mysteriously brings up the right-click menu and prevents scrolling, scrolling is highly erratic, etc. It really sucks.

Update (Thu Dec 22). The Surface still sucks. I keep giving it a go, and it keeps saying, “No!” Using the keyboard with it improves things slightly, but touch for scrolling and manipulations is horrific. If you pair a mouse with it, then perhaps it’s more usable, but then you should just buy a laptop.

I keep giving it a go, and it keeps saying, “No!” Using the keyboard with it improves things slightly, but touch for scrolling and manipulations is horrific. If you pair a mouse with it, then perhaps it’s more usable, but then you should just buy a laptop. Perhaps there is a more recent version of this thing, but even being a Mac-guy, it should work well. And for me, it doesn’t do that.

Apple Watch notification when Mac is unlocked with it.

I appreciate unlocking my Mac using my Apple Watch. It’s convenient. It’s not as robust as some other solutions that use my phone as a beacon and unlock as I approach. But it’s good.

One thing I don’t especially like is when the Mac is unlocked with my watch: I get a temporary notification on the watch telling me the Mac was unlocked. It goes away upon the next wrist raise, but it might be nice to just turn that notification off if possible. Maybe in the next

Maybe we’ll see such a checkbox in a future macOS release.

My mouse suddenly stuck?

I am currently running MacOS Sierra 10.12.1. I have a magic mouse 2, magic trackpad, Wacom tablet, and a spare magic mouse. Suddenly while working my mouse cursor became stuck in the menu bar above my username. I could shake the cursor with the mouse to enlarge the pointer, but I couldn’t seem to move it.

  • Turned off my Bose QC 35s
  • Turned off my magic trackpad
  • Tried my extra magic mouse
  • Tabbed with my magic keyboard to BT in the menu bar to check battery levels
  • Restarted

Still, the mouse cursor was stuck in place. 30 minutes later I see that my Wacom tablet stylus has rolled onto the tablet and was intercepting all mouse input with the stylus. Flipped it off and I could use my mouse again.

Grrr.

Swift 3: UITableView snap to cells

If you have your UITableViews snap to their cells, you’ll end up with a more refined user experience. This solution I have works with cells that are consistent in their height (static). You could always work with dynamic heights if you wanted to.

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        if scrollView == suggestionsTableView {
            let cellHeight = CGFloat(60.0)
            let y          = targetContentOffset.pointee.y + scrollView.contentInset.top + (cellHeight / 2)
            let cellIndex  = floor(y / cellHeight)
            targetContentOffset.pointee.y = cellIndex * cellHeight - scrollView.contentInset.top
        }
    }

As you can see cellHeight is a set float value, it’s there where you would want to determine the dynamic height. This little bit of code makes a UITableView a lot more refined as it doesn’t clip cell contents when a user lifts their finger from a drag.

Tagged :

Swift 3: Distance between two CGPoints

Here it is in Swift 3, it’s a little different. I tried to use hypotf but it didn’t like CGFloat subtraction.

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if touches.first != nil {
        let pointCenter = CGPoint(x: self.view.frame.width / 2, y: self.view.frame.height / 2)
        let touchPoint = touches.first?.location(in: self.view)
        let distance = CGPointDistance(from: pointCenter, to: touchPoint! )
        print("distance: \(distance)")
    }
    super.touchesBegan(touches, with: event)
}
    
func CGPointDistanceSquared(from: CGPoint, to: CGPoint) -> CGFloat {
    return (from.x - to.x) * (from.x - to.x) + (from.y - to.y) * (from.y - to.y)
}
    
func CGPointDistance(from: CGPoint, to: CGPoint) -> CGFloat {
    return sqrt(CGPointDistanceSquared(from: from, to: to))
}

 

iOS to macOS: Reading keyboard input

Coming from iOS to macOS, I wanted to read keyboard input in my macOS application. Not from a textfield but rather from the window itself. I thought this would be an easy task. After some trial and error, Googling, and then some StackOverflow fishing, I managed to get this to work. It wasn’t exactly straightforward for me to get but now that I did, I’d like to share the code that makes it work.

In my ViewController.swift file, I set up a few delegate callbacks

override var acceptsFirstResponder: Bool { return true }
override func becomeFirstResponder() -> Bool { return true }
override func resignFirstResponder() -> Bool { return true }

In my viewDidLoad, I added event monitoring (which eluded me for some time).

NSEvent.addLocalMonitorForEvents(matching: .keyUp) { (aEvent) -> NSEvent? in
    self.keyUp(with: aEvent)
    return aEvent
}

NSEvent.addLocalMonitorForEvents(matching: .keyDown) { (aEvent) -> NSEvent? in
    self.keyDown(with: aEvent)
    return aEvent
}

I then added keyUp and keyDown functions for the NSViewController itself.

override func keyDown(with event: NSEvent) {
    if keyIsDown == true {
        return
    }
    keyIsDown = true
    if event.keyCode == 1 {
        print("s key pressed")
    } else if event.keyCode == 49 {
        print("spacebar pressed")
    }
 }
    
override func keyUp(with event: NSEvent) {
    keyIsDown = false
    if event.keyCode == 1 {
        print("s key released")
    } else if event.keyCode == 49 {
       print("spacebar released")
    }
}

I have a class variable (keyIsDown) which prevents keyboard repeats to flood the methods. Set that to false at the start.

This works a treat – and I didn’t have to subclass NSView, do anything in AppDelegate, etc. It’s clean, legible, and it does exactly what you’d expect it to do. This is for a single windowed application.

Protocol/delegates in Swift 3.0

I declare this day a fine day having discovered non-Objective-C protocols! No more @objc protocol usage. Now it’s as simple as something like this:

protocol myDelegate {
    func report(info:String)
}

class MyClass: NSObject {
    var delegate:myDelegate?
    var serviceType = "hephaestus"

    init(withServiceType: String){
        self.serviceType = withServiceType
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
            self.delegate?.report(info: UIDevice.current.name)
        }
    }

    convenience override init() {
        self.init(withServiceType: "hephaestus")
    }
}

And then in implementation

import UIKit

class ViewController: UIViewController, myDelegate {
    
    // Delegate method
    func report(info: String) {
        print("delegate: \(info)")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let mc = MyClass()
        mc.delegate = self
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

This is a really simple example, but it works and seems cleaner to me in Swift.

Tagged :

Shaking a macOS Window

There may come a time when you’d like to shake a macOS application’s window (or one of them) to reinforce an event. In my case, I am creating a macOS application that serves as a conduit to control aspects of a user experience. It communicates with an iOS application which serves as a kind of remote control for the macOS application. And settings are synchronized back and forth. It’s pretty cherry.

macOS Sierra and iOS 10 using Swift 3 are quite similar. I know enough about iOS development to make myself a drunken lumberjack in a glade of birch trees – swinging wildly hoping to hit things. Anyway, I am using MultipeerConnectivity framework for the communication discovery and data transfer (at a top-level explanation). When a connection is made (the iOS app advertises), I turn a little grey dot into a green one to show this state. When a disconnection is made, I turn it back to grey.

However, this might not be enough. I could play a disconnection tone (and I still might), but I wanted to shake the window to let someone know, “Hey! I lost a connection.” This sets expectations and it’s a cool effect I wanted to try out.

I have an extension that will do this, written for Swift 3. It’s implementation is a little different than for previous versions of Swift. Here is the extension. The Cocoa import is because I keep separate extension swift files instead of in-lining everything into a view controller, etc. This keeps things cleaner and a little easier for me and others to find.

import Cocoa

/**
 
 window?.shakeWindow()
 view.window?.shakeWindow()
 NSApp.windows.first?.shakeWindow()
 
 */

extension NSWindow {
    func shakeWindow(){
        let numberOfShakes          = 3
        let durationOfShake         = 0.3
        let vigourOfShake : CGFloat = 0.04
        let frame : CGRect = self.frame
        let shakeAnimation :CAKeyframeAnimation  = CAKeyframeAnimation()
        
        let shakePath = CGMutablePath()
        shakePath.move( to: CGPoint(x:NSMinX(frame), y:NSMinY(frame)))
        
        for _ in 0...numberOfShakes-1 {
            shakePath.addLine(to: CGPoint(x:NSMinX(frame) - frame.size.width * vigourOfShake, y:NSMinY(frame)))
            shakePath.addLine(to: CGPoint(x:NSMinX(frame) + frame.size.width * vigourOfShake, y:NSMinY(frame)))
        }
        
        shakePath.closeSubpath()
        shakeAnimation.path = shakePath
        shakeAnimation.duration = durationOfShake
        
        self.animations = ["frameOrigin":shakeAnimation]
        self.animator().setFrameOrigin(self.frame.origin)
    }
}

I certainly hope that you enjoy it.

Quick & Easy JavaScript/PHP CMS

I needed to create a website where I could update multiple pages worth of content remotely. It’s a travel blog. I could use WordPress to do this out of the gate, but I wanted to get away from the whole commoditized theme look and feel. Something where I have more control without customizing a lot.

So I created a site structure with multiple pages (one per travel day – ahead of time). Each of those PHP pages has a PHP include for the guts of the content for that day. For example

 <?php include ('day_includes/day_12.php'); ?>

Easy peasy. That PHP file contains HTML of the contents. So for each day there is a file to include. Each one could contain a lot of information, so I didn’t want to do run down the dynamic population route too far.

So that part is easy. What about editing/adding content to the PHP files remotely? Enter an admin page.

The admin page has a drop-down menu of all the PHP include files. The first one it automatically loaded into a textarea control. You can select different pages and load them into the textarea with some JavaScript.

function loadDay()
{
    var e = document.getElementById("days");
    var selectedDay = e.options[e.selectedIndex].value;
    var c = document.getElementById("content");
    c.innerHTML = "";
            
    setTimeout(function() {
        var timestamp = +new Date;
        var file = "day_includes/" + selectedDay + "?time=" + timestamp;
        $( "#content" ).load( file );
    }, 500); 
}

Easy too. However JavaScript can’t write back to the files, so we POST the text to a PHP script page and that writes to the file (filename and contents are posted).

function saveDay()
{    
    var e = document.getElementById("days");
    var selectedDay = e.options[e.selectedIndex].value;
    var fileNameToSaveAs = "day_includes/" + selectedDay;            
    var enteredText = $('#content').val();

    $.ajax({
        url:'post_data.php',
        type: 'POST',
        data: {'data':enteredText, 'fileName':fileNameToSaveAs },
        success: function(data) {
            alert(data);
        },
        error: function(data) {
            alert("There may an error on uploading. Try again later");
        },
    });  
}

Easy again. The PHP script takes the variables and uses them to save the data. So with a little PHP and a little JavaScript, we have a CMS system. It’s not robust but rather lightweight. And I have full control over all aspects of how things look, feel, and operate.

Something to consider to avoid the continued WordPress onslaught.

 

Bose QC 35 versus Blue Microphone Mo-Fi

bose_mofi

I’m lucky enough to have access to both products, the Bose QuietComfort 35 and the Blue Microphone Mo-Fi. The Mo-Fi currently can be purchased from Amazon for $318.99 (discounted from $349.99) and the Bose for $349.99 (no discount offered).

Screen Shot 2016-09-02 at 1.45.50 PMI was told to try out the Mo-Fi by BT himself (Brian Transeau) as he swears by them. That was about a year ago. So I sought the Mo-Fi out and I’ve been using them on and off, with QC25s and then QC35s. A note: The QC35s are wireless BT, the Mo-Fi are wired with a built-in amplifier with three states: off, on, and on+ for some bass boost.

I listen to an eclectic set of music. New Age (Andreas Vollenweider), Electronic (BT, Trentmøller, Sasha, Zomby, etc.), Rock (Rush, Queensrÿche, Afghan Whigs, Led Zeppelin, etc.), Heavy Metal (Megadeth, Iron Maiden, old Metallica, etc.) In no situation has the Mo-Fi bested the Bose sound, even with the on+ setting activated.

Countless hours of listening, I get far more clarity from the Mo-Fi, regardless of what BT thinks of them. I am not taking into account the comfort of either headphone. However, the Bose are 1,025 times more comfortable in my opinion. And far lighter.

It might just be my ears, as the Mo-Fi are indeed highly rated. And BT loves them. He’s a brand ambassador on the Blue website. I just don’t get it. I’ve tried to as the headphones are unique in their appearance. And I like the idea of a powered amplifier (that also saves my phone from some power draw). My audio files are good/great quality. Not listening to vinyl with them –  and perhaps that’s the rub?

I may never know. Putting the Bose back on 🙂

Tagged : / / /