tag:chrisbrandow.svbtle.com,2014:/feed
A Chemist Coding iOs
2020-01-18T11:40:02-08:00
Christopher Brandow
https://chrisbrandow.svbtle.com
chrisbrandow@gmail.com
Svbtle.com
tag:chrisbrandow.svbtle.com,2014:Post/poor-misunderstood-somedaymaybe-list
2020-01-18T11:40:02-08:00
2020-01-18T11:40:02-08:00
Poor Misunderstood "Someday/Maybe" List
<p>I’m gonna write this on the fly without fully referring to canonical “Getting Things Done” by David Allen, but I had a helpful realization when I pondered a problem that a friend (I’ll call him Sodmund) and I were having with regards to our GTD task lists.</p>
<p>Basically, Sodmund and I observed that we were typically accomplishing and average of <code class="prettyprint">n</code> items on our task list every day, but we were adding <code class="prettyprint">n</code>+2 items to our task list. These items were nice, next-action style items that we considered things we <em>really</em> wanted to get done, <strong>SOON</strong>. But inevitably, our averages stayed fixed. And thus the list of next actions that needed to be combed through, and reviewed on a weekly basis was growing and becoming way too long. (and here is where I need to review what DA would recommend).</p>
<p>My “aha” moment came when I discussed this problem (what to do with the tasks that build up in your task list that are important but aren’t getting done) with another friend of ours (will call him Edam) and he sort of didn’t understand our problem. He was all, “I add tasks to the list then I do them, and then there are none left”. </p>
<p>Obviously, we sort of hate Edam. JK, Edam!</p>
<p>But, that put in stark relief the obvious point, which is that the items on my list that weren’t getting done <em>are</em> important to me in that when I look at them and think about whether I want the outcome their completion would provide, I conclude, “yes, I want that task to be completed”. But when their importance is measured by whether I actually choose to do that task instead of some other activity, the harsh measure of reality concludes, “no, that task is just not as important <strong>right now</strong>.</p>
<p>This somehow triggered many thoughts about "loss aversion”, “accepting the reality that some people just are unsettled until all loose ends are tied up”<sup id="fnref1"><a href="#fn1">1</a></sup>, and “that accepting a half loaf is sometimes better than insisting on a full loaf that you cannot have and thus end up with nothing.” In this mix of thoughts, it occurred to me that this is really what the “someday/maybe” list is or should be<sup id="fnref2"><a href="#fn2">2</a></sup> for.</p>
<table>
<thead>
<tr>
<th style="text-align:center;"></th>
<th style="text-align:center;">“in the moment”</th>
<th style="text-align:center;">“must get everything done”</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center;">stricter about taking on tasks</td>
<td style="text-align:center;">most important things more likely get done<br>
</td>
<td style="text-align:center;">probably the sweet spot</td>
</tr>
<tr>
<td style="text-align:center;">less strict about taking on tasks</td>
<td style="text-align:center;">overwhelmed with everything that’s not getting done<br>unlikely to keep up with a system</td>
<td style="text-align:center;">things get done but with regular bouts of stress</td>
</tr>
</tbody>
</table>
<p>Clearly there is an advantage to being stricter about taking on tasks, but depending, again, on personalities, this can be very difficult. Dodmund and I, for example, are just plain interested in lots of “stuff” and by and large have lots of responsibilities. We probably both share an aversion to saying, “No”, as much as we should and so out of interest or obligation add a few too many things to our task lists. Dargaret, on the other hand, is a very others-centered person <strong><em>and</em></strong> is very forward looking, and wants to help many people and is thoughtful about opportunities for our family that typically can be best arranged ahead of time. Honestly, I am going to focus on my and Dodmund’s issue because I can understand the contours of it better.</p>
<p>When he and I would discuss this list problem, I learned that his list literally had > 1000 items on it that he could not let go of. Now I can look at that as a third party and realize that its absurd to have a list of “important tasks” that he expects to accomplish on some level (<em>no offense Dodmund</em>). At 5 minutes a piece, that is over 2 40 hour work weeks. But, when I suggested cutting most of the items of this list out, it freaked Dodmund out at the thought of losing track of those things. </p>
<p>Personally, I have also learned that loss aversion is a very difficult emotion to fight. It is draining to fight against, and it clouds judgement badly. I think that David Allen underestimates the impact of decision fatigue and loss aversion for many people. The correct answer for Dodmund and for me, is to say no to more things, or in our weekly review to make some hard choices and remove things from our next actions list. But in the moment, this is tough to do. Instead, we mostly stop doing the weekly review.</p>
<p>However, I have learned a great trick to deal with loss aversion that can be applied:</p>
<p>Emotional separation, in the form of time.<sup id="fnref3"><a href="#fn3">3</a></sup></p>
<p>I learned that when we have things in our house that I or my wife aren’t quite ready to get rid of, if we put them in a well-labeled box and put that box in our crowded basement, then next year when I am trying to make room in our crowded basement, it is much easier to just pitch or donate the item(s) because I just don’t care as much about them, and it saves me so much anguish in the moment.<sup id="fnref4"><a href="#fn4">4</a></sup></p>
<p>And so, <strong><em>finally</em></strong> my point about the someday/maybe list. If instead of treating the someday/maybe list as a dreamy “things I’d love to do” or aspirational projects (Learn Guitar!!) list, we should treat it primarily as a bin for the tasks that we really mean to get to but haven’t quite been able to get to.</p>
<p>Now, I know that even the prospect of manually putting items on a separate list like this would <strong><em>still</em></strong> lead to an aversion of not having them present. So my solution that I have worked successfully with is to automate this. Every task that is > ~2 weeks old, automatically is moved to a someday/maybe list. It’s still there and if in my monthly review or whatever, I want to put it back on the next action list, I can do that, but human psychology being what it is, I don’t often do that. I am happy for it to <em>stay</em> on the someday/maybe list.</p>
<p>An obvious reaction to this is that this will create a large, messy list of things that would be tough to act on. Yes. But it does so in service of simultaneously creating a short list with timely and actionable items that is where you will realistically spend your time, with the confidence that you aren’t “losing track” of any of the tasks you consider important, even if you can’t do them today or this week.</p>
<div class="footnotes">
<hr>
<ol>
<li id="fn1">
<p>Another point to recognize, is that I think there are obviously many different types of people when it comes to how they are wired when it comes to an actually psychological need to tie up loose ends. At all points along this spectrum, it seems to me to be a classic “strength/weakness” issue. I am fairly far on the “able to enjoy the moment, despite many unfinished, important untied loose ends”, while my wife (we’ll call her Nargaret) really can’t feel fully settled if there are any loose ends that <em>could</em> be tied. While it is easy to lionize the positive aspects of either approach, “Enjoy the moment!!” or “Set your mental table before moving on to the next thing!!”, it is easy to see the darker side of both, especially in hindsight, “How could you not taken care of this <strong>obviously</strong> important thing??”, and “How much of this wonderful day did you waste worrying about that stuff that turned out to be no big deal??” <a href="#fnref1">↩</a></p>
</li>
<li id="fn2">
<p>Let’s be honest, doesn’t David Allen strike you as much more of a Edam type of person, where he only puts things on the list that are going to get done, and is unsatisfied until they are finished <a href="#fnref2">↩</a></p>
</li>
<li id="fn3">
<p>There are other forms of separation that work. Physical separation – I don’t worry as much about things that I’m not doing when I can’t see them. Emotional separation – when friends or family are having a hard time getting rid of something they don’t have space for, I offer to take, even if I don’t want it, because I will have no problem putting it in the trash or sending it to Goodwill. <a href="#fnref3">↩</a></p>
</li>
<li id="fn4">
<p>Not a perfect system, since the build-up of these put-off decisions in the form of boxes can make “discovery” and rearrangement difficult. <a href="#fnref4">↩</a></p>
</li>
</ol>
</div>
tag:chrisbrandow.svbtle.com,2014:Post/i-can-t-overstate-this-enough
2020-01-17T08:13:48-08:00
2020-01-17T08:13:48-08:00
I Can’t Overstate This Enough
<p>Hardly a new sentiment, but I personally will never not need <a href="https://overreacted.io/goodbye-clean-code/">this exhortation to KISS</a>.</p>
<p>And to be clear, when I talk about keeping things simple ( particularly in production code), I will forever mean to keep things conceptually simple. The price of minimalistic elegance can be high and not everyone on your team has paid that price (of advanced language features or category theoretical concepts). In addition to the price of learning that you have personally paid over the years, there is an added you paid while writing the code of your own immediate attention and concentration. Sadly, when you revisit this code, you will need to pay a a good bit of that price again.</p>
<p>The largest downside to the fact that our industry is made up of so many engineers who are learning as they go, is that they express their newfound knowledge in code that others may have to work with for years and don’t understand the cost they are incurring for others.</p>
<p>Just as medical students, apparently, go through a phase where they are convinced they have a rare, likely fatal disease, so do intermediate engineers think that the newest (and valuable!) lesson that they have learned is directly applicable to the likely more mundane task at hand.</p>
<p>Of course, this is where code review comes in. And that is the role of the more senior engineers. Insisting that the conditional assignment of two nearly identical strings is preferable to a function that can generate those strings. (Hint: When debugging, the strings are searchable and more readable than a three line function that’s located somewhere else in the code and has to be interpreted)</p>
<p>Ours is a young industry still and is absolutely much more of a craftsman-based profession than most realize. I read somewhere that it is closer to what civil engineering was like as of the 19th century, where there were still self-taught engineers and very few measurable or verifiable standards. That seems about right to me.</p>
tag:chrisbrandow.svbtle.com,2014:Post/faster-build-times-by-leveraging-multicore-cpu
2016-08-18T10:04:59-07:00
2016-08-18T10:04:59-07:00
Faster build times by leveraging multi-core CPU!
<p>How in the world is this not the default and how have I not heard of this before?!?</p>
<p>Buried in this <a href="http://merowing.info/2015/12/little-things-that-can-make-your-life-easier-in-2016/">helpful blog post</a> about making your XCode life easier, is this tip: </p>
<blockquote class="short">
<p>Faster build times by leveraging multi-core CPU ?</p>
</blockquote>
<pre><code class="prettyprint">defaults write com.apple.dt.Xcode IDEBuildOperationMaxNumberOfConcurrentCompileTasks `sysctl -n hw.ncpu`
</code></pre>
<p>I tested it on my work project. I cleaned, cleaned the build folder and restarted XCode in both cases. Results:</p>
<table>
<thead>
<tr>
<th style="text-align:left;">Before</th>
<th style="text-align:left;">After</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left;">23.4 s</td>
<td style="text-align:left;">13.9 s</td>
</tr>
</tbody>
</table>
<p>Considering how often I build this project in a day (>20 times?) that is a great return on investment, even if it is only minutes.</p>
<h4 id="caveats_4">Caveats <a class="head_anchor" href="#caveats_4">#</a>
</h4>
<ol>
<li>I am pretty much just cutting and pasting here. So read more if you want to be safe. Messing with defaults regarding cores like that can definitely impact battery life and other stuff.</li>
<li>I don’t know what the default value was. I don’t know how to restore it. I don’t know if/when it will be reset to the default value. I’ll check next time I restart my computer.</li>
</ol>
tag:chrisbrandow.svbtle.com,2014:Post/facebook-friend-suggestions-and-privacy
2016-08-10T16:28:59-07:00
2016-08-10T16:28:59-07:00
Facebook Friend Suggestions and Privacy Porosity (via Android IRL Friends?)
<p>A few months ago, my wife came to me asking how Facebook would know to suggest a couple of people that she had spoken to professionally on her phone. I asked if they had been in the same location, or if they were in her contacts, or if you had mutual Facebook friends. “Maybe, yes”, and “No”, and “No” were her replies. I checked her privacy settings, and sure enough the OS privacy settings indicate that , and I think that . We talked it through, and I couldn’t find anything online about how this could be happening, but we also didn’t know the nature of the other people’s phones.</p>
<p>Then just the other day, <em>I</em> got a friend suggestion for a person that I had spoken to on the phone and texted with. We had also been in the same location a number of times. And we don’t have any direct mutual “friends”.</p>
<p>I do know that this person uses an Android phone, and what little research I did do, indicates that their is more porous access to contacts, as well as phone logs.</p>
<p>I would love to know more about this. My wife is definitely not a person who gets too wigged out by Google/Facebook/whatever creeping into privacy, but this has definitely gotten her attention.</p>
tag:chrisbrandow.svbtle.com,2014:Post/finding-from-where-a-method-is-being-called
2016-08-09T16:04:56-07:00
2016-08-09T16:04:56-07:00
Finding From Where A Method Is Being Called
<p>The linked SO post has a nice method for logging where an Objective-C method is being called from. Simple but helpful.</p>
<pre><code class="prettyprint"> NSString *sourceString = [[NSThread callStackSymbols] objectAtIndex:1];
// Example: 1 UIKit 0x00540c89 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1163
NSCharacterSet *separatorSet = [NSCharacterSet characterSetWithCharactersInString:@" -[]+?.,"];
NSMutableArray *array = [NSMutableArray arrayWithArray:[sourceString componentsSeparatedByCharactersInSet:separatorSet]];
[array removeObject:@""];
NSLog(@"Stack = %@", [array objectAtIndex:0]);
NSLog(@"Framework = %@", [array objectAtIndex:1]);
NSLog(@"Memory address = %@", [array objectAtIndex:2]);
NSLog(@"Class caller = %@", [array objectAtIndex:3]);
NSLog(@"Function caller = %@", [array objectAtIndex:4]);
</code></pre>
tag:chrisbrandow.svbtle.com,2014:Post/csv-to-multimarkdown-tables
2016-07-13T13:36:36-07:00
2016-07-13T13:36:36-07:00
CSV to Multi-Markdown Tables
<p>One person noticed yesterday’s <a href="https://chrisbrandow.svbtle.com/a-quick-swift-script">yak-shaving</a> and liked it, which was all the excuse I needed to shave it some more. But I am good to go for now, though this still is still fairly fragile: you have to select only the table lines, there’s no way to escape a comma if you want it in a particular entry, it won’t catch if there are different number of items on each line, etc.</p>
<p>Here is the <a href="https://www.dropbox.com/sh/u0hh9df8olmlb5r/AABCTc-qL1wtg9ZG7yXgih6Aa?dl=0">downloadable workflow</a> . </p>
<p>I cleaned up the code in ways that were useful learning exercises for me and added support for >, <, = as separator indicators</p>
<p>so this:</p>
<blockquote class="short">
<p>one, two and a half, three and a quarter<br>
four, five, six</p>
</blockquote>
<p>still outputs to this:</p>
<pre><code class="prettyprint">| one | two and a half | three and a quarter |
| :---: | :---: | :---: |
| four | five | six |
</code></pre>
<p>but now this:</p>
<blockquote class="short">
<p>one, two and a half, three and a quarter<br>
>, =, <<br>
four, five, six</p>
</blockquote>
<p>outputs this:</p>
<pre><code class="prettyprint">| one | two and a half | three and a quarter |
| ----: | :---: | :---- |
| four | five | six |
</code></pre>
<p>Swift 3.0 code below (still vaguely embarrassed to share it):</p>
<pre><code class="prettyprint">#!/usr/bin/swift
import Foundation
let separators: [Character: String] = ["=": ":---:", ">": "----:", "<": ":----"]
let separatorSet = CharacterSet(charactersIn: "><=, ")
func titleAndEntriesFrom(string: String) -> (String, String?, [String])? {
var lines = string.components(separatedBy: "\n")
guard lines.count > 1, let titleLine = lines.first else {
print("need more than one line ->")
return nil
}
lines.removeFirst()
let separatorMarkdown: String?
if let second = lines.first where CharacterSet(charactersIn: second).isSubset(of: separatorSet) {
separatorMarkdown = separatorFrom(line: second)
lines.removeFirst()
} else {
separatorMarkdown = nil
}
return (titleLine, separatorMarkdown, lines)
}
func mdTableFrom(components: (String, String?, [String])) -> String? {
let titleMarkdown = markdownFrom(line: components.0)
let titleEntries = components.0.components(separatedBy: ",")
let separatorMarkdown = components.1 ?? titleEntries.reduce("\n| "){prev, sep in "\(prev) :---: | "}
let bodyMarkdown = components.2.reduce(""){prev, line in "\(prev) \(markdownFrom(line: line))"}
return titleMarkdown + separatorMarkdown + bodyMarkdown
}
func separatorFrom(line: String) -> String {
let entries = line.components(separatedBy: ",")
let things = entries.flatMap({$0.trimmingCharacters(in: CharacterSet.whitespaces).characters.first})
let markdown = things.reduce("\n|"){prev, entry in "\(prev) \(separators[entry] ?? ":xxx:") |"}
return markdown
}
func markdownFrom(line: String) -> String {
guard line.characters.count > 0 else {
return "\n"
}
let entries = line.components(separatedBy: ",")
return entries.reduce("\n| "){prev, entry in "\(prev) \(entry.trimmingCharacters(in: CharacterSet.whitespaces)) |"}
}
var string = ""
while let thing = readLine(strippingNewline: false) {
string += thing
}
if let titleAndBody = titleAndEntriesFrom(string: string), output = mdTableFrom(components: titleAndBody) {
print(output)
} else {
print(string)
}
</code></pre>
tag:chrisbrandow.svbtle.com,2014:Post/a-quick-swift-script
2016-07-12T10:43:34-07:00
2016-07-12T10:43:34-07:00
A Quick Swift Script Yak Shave
<p>[<em>Updated Version with <a href="https://chrisbrandow.svbtle.com/csv-to-multimarkdown-tables">downloadable OS X service</a></em>]<br>
In the process of writing a longer post yesterday, I wanted to add a markdown table, and was once again annoyed at the mild PITA that it is to use pipe characters and then the formatting characters a lá:</p>
<pre><code class="prettyprint">| title | title2 |
| :---------: | :--------: |
| entry one | entry two |
| entry three | entry four |
</code></pre>
<p>Being aware of Brett Terpstra’s excellent <a href="http://brettterpstra.com/projects/markdown-service-tools/">Markdown Services</a> that have a table cleanup function, but actually writing the da** tables is kind of annoying, so I in classic <a href="http://www.hanselman.com/blog/YakShavingDefinedIllGetThatDoneAsSoonAsIShaveThisYak.aspx">Yak-Shaving</a> fashion, I decided to write a simple <a href="http://krakendev.io/blog/scripting-in-swift">Swift script</a> that would turn the following into the format above. Then make that into an <a href="http://arstechnica.com/apple/2011/03/howto-build-mac-os-x-services-with-automator-and-shell-scripting/">OS X service</a>.</p>
<pre><code class="prettyprint">title, title2
entry one, entry two
entry three, entry four
</code></pre>
<p>It really wasn’t that tricky, and probably would have been at least as easy using python or ruby, but ¯_(ツ)_/¯. (<– typed using textexpander).</p>
<p>It’s written in Swift 3. I should use <code class="prettyprint">stdin</code> and <code class="prettyprint">stdout</code>, but the syntax for <code class="prettyprint">NSFileHandler</code> changed enough, and I know so little of it, that I decided to punt on that, as I didn’t need the Yak that well shaven. Fortunately the <code class="prettyprint">readline</code> function in a <code class="prettyprint">while</code> loop works just fine and simply <code class="prettyprint">print(output)</code> also works. Likewise the code is naive, could be more functional, does not handle many (any) exceptional cases or check for consistency, but again, it does the job for a simple case. (You know, I’m embarrassed for anyone to actually look at my code)</p>
<p>Likewise, I would like to add a small tweak so that I can optionally write it this way to add the alignment more easily:</p>
<pre><code class="prettyprint">title, title2, title3
>, -, <
entry one, entry two, entry three
entry four, entry five, entry six
</code></pre>
<p>that would translate the second line to:</p>
<pre><code class="prettyprint">| ---: | :---: | :--- |
</code></pre>
<p>But Yak-Shaving is done for now.</p>
<p>Entire script is here:</p>
<pre><code class="prettyprint">#!/usr/bin/swift
//
// main.swift
// CSVToTables
//
// Created by Christopher Brandow on 7/12/16.
// Copyright © 2016 flouu. All rights reserved.
//
import Foundation
func titleAndEntryFrom(string: String) -> (String, [String])? {
var lines = string.characters.split{$0 == "\n"}.map(String.init)
guard lines.count > 1, let titleLine = lines.first else {
return nil
}
lines.removeFirst()
return (titleLine, lines)
}
func markdownTableFromTitleAndEntries(title: String, body: [String]) -> String? {
let titleMarkdown = markdownFrom(line: title)
let entries = title.characters.split{$0 == ","}.map(String.init)
var separatorMarkdown = "\n|"
for _ in 0..<entries.count {
separatorMarkdown += " :---: |"
}
var bodyMarkdown = ""
for line in body {
bodyMarkdown += markdownFrom(line: line)
}
return titleMarkdown + separatorMarkdown + bodyMarkdown
}
func markdownFrom(line: String) -> String {
var markdown = "\n| "
let entries = line.characters.split{$0 == ","}.map(String.init)
for entry in entries {
markdown += entry
markdown += " |"
}
return markdown
}
var string = ""
while let thing = readLine(strippingNewline: false) {
string += thing
}
if let titleAndBody = titleAndEntryFrom(string: string) {
if let output = markdownTableFromTitleAndEntries(title: titleAndBody.0, body: titleAndBody.1) {
print(output)
}
}
</code></pre>
tag:chrisbrandow.svbtle.com,2014:Post/possible-macos-names
2016-06-24T12:50:44-07:00
2016-06-24T12:50:44-07:00
Possible Future macOS Names
<p>Just for funnies. <a href="http://appleinsider.com/articles/15/04/15/from-beaches-to-bridges-apple-has-plenty-of-possible-california-themed-names-for-next-os-x">Others</a> have done this as well before</p>
<p>We’ve had:</p>
<p><strong>Maverics</strong><br>
<strong>Yosemite</strong><br>
<strong>El Capitan</strong><br>
<strong>Sierra</strong></p>
<h2 id="criteria-as-i-see-them_2">Criteria as I see them <a class="head_anchor" href="#criteria-as-i-see-them_2">#</a>
</h2>
<ol>
<li>In California</li>
<li>Natural Feature or Area</li>
<li>Proper name.</li>
<li>Has to sound good when spoken.</li>
<li>Well known, or famous within a niche</li>
</ol>
<h2 id="bad-or-doesn39t-sound-right_2">Bad or doesn’t sound right <a class="head_anchor" href="#bad-or-doesn39t-sound-right_2">#</a>
</h2>
<p><strong>Death Valley</strong><br>
<strong>Long Beach</strong><br>
<strong>“Anything” Beach</strong><br>
<strong>Silicon Valley</strong>, plus, doesn’t meet criteria #2<br>
<strong>Lassen</strong><br>
<strong>Fresno</strong> LOL<br>
<strong>Sacramento</strong> ROFL</p>
<h2 id="possibly-but-connotation-may-be-wrong_2">Possibly, but connotation may be wrong: <a class="head_anchor" href="#possibly-but-connotation-may-be-wrong_2">#</a>
</h2>
<p><strong>Malibu</strong> - first three seem too fancy<br>
<strong>Napa</strong><br>
<strong>Sonoma</strong><br>
<strong>Cupertino</strong> - too self-promoting<br>
<strong>Ventura</strong> - at least to Californians, this might sound low rent</p>
<h2 id="possible-bets-vaguely-in-order_2">Possible Bets - vaguely in order <a class="head_anchor" href="#possible-bets-vaguely-in-order_2">#</a>
</h2>
<p><strong>Mojave</strong><br>
<strong>Capistrano</strong><br>
<strong>Shasta</strong><br>
<strong>Calistoga</strong><br>
<strong>Sequoia</strong><br>
<strong>Point Reyes</strong><br>
<strong>Ojai</strong> - technically a town, but also a very natural area<br>
<strong>a beach name</strong> without including “Beach” <em>e.g. Hermosa</em><br>
<strong>Pinnacles</strong><br>
<strong>Red Rock</strong><br>
<strong>Humboldt</strong><br>
<strong>Big Sur</strong><br>
<strong>Tahoe</strong><br>
<strong>Monterey</strong><br>
<strong>Carmel</strong></p>
<p>I may add to this over time. </p>
tag:chrisbrandow.svbtle.com,2014:Post/apple-watch-crown-events-workout-apps-rejoice
2016-06-15T13:00:57-07:00
2016-06-15T13:00:57-07:00
Apple Watch Crown Events -- Thinking About Discretely Triggered Events
<p>One of the biggest frustration points for me on Apple Watch when working out is that a wet screen does not recognize touches very well. So a workout app that lets me mark a lap, pause the workout, or anything like that is limited, because many times it fails because I sweat a lot <sup id="fnref1"><a href="#fn1">1</a></sup>.</p>
<p>But now, with Apple exposing <code class="prettyprint">WKCrownSequencer</code> and its delegate means that apps can receive direct input from the crown. Examples shown include rolling the crown and moving a marker along a plot.</p>
<p>But how does this help for discrete events? It is fairly trivial to create discrete events by triggering something based on a threshold <code class="prettyprint">rotationalDelta</code>. Below is the code (not Swift, sorry!) for a quick proof of concept for marking laps by quickly spinning up, and stopping the timer by quickly spinning down.</p>
<p>I’ve only tested on my simulator so far, but when I test on the watch, I’ll try to capture video.</p>
<p>I would kill for a workout app that does this.</p>
<pre><code class="prettyprint">#import "InterfaceController.h"
@interface InterfaceController()<WKCrownDelegate>
@property (unsafe_unretained, nonatomic) IBOutlet WKInterfaceLabel *label;
@property (unsafe_unretained, nonatomic) IBOutlet WKInterfaceLabel *resultLabel;
@property (unsafe_unretained, nonatomic) IBOutlet WKInterfaceTimer *timer;
@property (nonatomic) NSNumber *previousDelta;
@property (nonatomic) NSDate *startDate;
@end
@implementation InterfaceController
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
[self.label setText:@"--"];
[self.resultLabel setText:@"--"];
self.crownSequencer.delegate= self;
}
- (void)crownDidBecomeIdle:(WKCrownSequencer *)crownSequencer
{
self.previousDelta = nil;
}
- (void)crownDidRotate:(WKCrownSequencer *)crownSequencer rotationalDelta:(double)rotationalDelta
{
[self.label setText:[NSString stringWithFormat:@"delta: %.2f", fabs(rotationalDelta)]];
if (self.previousDelta && self.previousDelta.floatValue == 0) {
if (rotationalDelta > 0.5) {
[self discreteEventUp];
} else if (rotationalDelta < -0.5) {
[self discreteEventDown];
}
} else if (!self.previousDelta){
self.label.textColor = [UIColor whiteColor];
}
self.previousDelta = @(rotationalDelta);
}
- (void)discreteEventUp
{
self.label.textColor = [UIColor redColor];
[self.resultLabel setText:[NSString stringWithFormat:@"Lap: %.2f sec.", [[NSDate date] timeIntervalSinceDate:self.startDate]]];
self.startDate = [NSDate date];
[self.timer start];
}
- (void)discreteEventDown
{
self.label.textColor = [UIColor redColor];
[self.resultLabel setText:@"Timer Stopped"];
[self.timer stop];
}
- (void)didAppear {
[self.crownSequencer focus];
[self.timer start];
self.startDate = [NSDate date];
}
@end
</code></pre>
<div class="footnotes">
<hr>
<ol>
<li id="fn1">
<p>Ewww, I know. <a href="#fnref1">↩</a></p>
</li>
</ol>
</div>
tag:chrisbrandow.svbtle.com,2014:Post/there-are-a-lot-of-dudes
2016-06-14T12:52:22-07:00
2016-06-14T12:52:22-07:00
There Are A Lot Of Dudes
<p>Every so often, you have a moment when you briefly see something in an entirely new light, and last night I had such a moment.</p>
<p>While cramming into a room for a great <a href="https://chrisbrandow.svbtle.com">panel discussion</a> about some of the Apple announcements, I was just overwhelmed by profound homogeneity of the programming community (sloppily dressed, male, white and asian). This is something I already knew, have talked about, and thought about. But in the moment, I just realized how intimidating at a visceral level it must be at times to enter this profession for anyone that isn’t in the demographic.</p>
<p>And all things considered, this was a <em>SUPER</em> welcoming event, with a panel that was half women, half men, the moderator also introduced the event with fully articulated and affirmed code of conduct. Really friendly. No “bad” behavior present at all.</p>
<p>I don’t have a point, but wow, when you get a few thousand programmers together, it can be a little overwhelming to see the demographics on display. </p>
<p>It makes me just that much more impressed women/minority coders.</p>
<p>The near-absence of women in programming is a tough challenge and will defy any simple solutions, days like today remind me of how large that challenge is.</p>
<p>And although it’s ultimately just one small thing (of hopefully many), I did love the emphasis on new programmers from non-traditional backgrounds in the video at the end of the <a href="http://www.apple.com/apple-events/june-2016/">Apple Keynote. (1:16-1:20).</a></p>