Friday, February 7

SubscriptionStoreView and appAccountToken

Being new to iOS development, I'm assuming that I'm missing something here; but for the life of me I had a horrific time figuring out how to use an appAccountToken with a SubscriptionStoreView in iOS's StoreKit. I can just send my user's UUID in the purchase transaction, and have my server handle everything independently on the back end. Why wouldn't I want to do that?

I naively figured just googling those two keywords would be enough, but no. ChatGPT 4o said it was impossible to use those two things together, and DeepSeek R1 referenced inAppPurchaseStart instead of inAppPurchaseOptions.

Hopefully if anyone else is out there googling, here you go!


This is all you need,


Saturday, November 6

The Emperor's Smart Clothes...

Ever since reading Rainbow’s End by Vernor Vinge in 2007, I’ve been fascinated by the idea of wearable computing and alternate forms of computer user interfaces. While the book came out in 2006, the story is set in 2025 and it envisions amazing leaps in how technology can and will transform our lives. While much of it may seem obvious now, the book was released prior to the first iPhone when the RAZR flip phone was all the rage.


When I got my first iPhone in 2008, I was captivated by its potential but immediately felt constrained by it’s on screen keyboard. Now I could suddenly get online and do all these great things, but I had to fumble with the onscreen keyboard to type anything. 


In Rainbow’s End, children could chat with friends in class, and search online, etc; all without the teacher even really noticing. I desperately wanted the smart clothing from the book that provided custom gesture recognition, and with enough practice/experience would make text entry effortless whether sitting at a desk or walking down the street. 


The basic goals were simple;

  1. Support an interface for wearable computing

  2. Have it be built around a learning system to best personalize itself for each user.

  3. Have it work without touching or moving against anything.

  4. Make it always readily available.

  5. No vision required.


In researching, the closest I could find was a product called the Twiddler which was a one handed chording keyboard for mobile entry. I wanted a solution that didn’t require holding something in your hand though, to cover points #3 and #4 above.


Unfortunately nothing yet existed, but I thought if something even half as good as what was in the book could be built it would still be a huge improvement. The sensitivity of the iPhone’s accelerometer and gyroscope demonstrated what was already available, so what I thought were the key building blocks already existed.


Surface mount accelerometer/gyroscope chips were only about 1 square cm, so the idea was to mount a number of the sensors on rings and/or a glove to capture small hand movements/gestures without having to actually hold anything. As the user could be swinging their arms as they walked down the street, additional sensors above the palm/wrists/forearms could be used to help normalize the movement of individual fingers. Like the Twiddler, cording could be used to expand the range of possible inputs. 


As I experimented more and more with the sensors of my iPhone, I realized the gestures didn’t need to be rigidly defined. Maybe to enable/disable keyboard mode it could be as simple as wiggling both hands up and down simultaneously. Each use of `backspace` would be a valuable input to the ML model to not only identify that something was handled incorrectly, but the user’s final intent could be captured as well. (Ex. gesture "A"  was notnote).


Beyond just text, scrolling could be as simple as moving the pointer finger in a circle, `alt-tab` could be a flick of the wrist, etc. The gyroscope would capture the direction of gravity, so the direction or angle of the hang up/down could be used to differentiate meaning.


By toggling different input/interface modes, the inadvertent movements of a train/car/elevator/etc could be prevented from producing false input.


To support blind entry, simple haptic feedback could be used to register the recognition of a gesture. Like the little click a key makes on a keyboard.



While the ideas and simple experiments were abundant, I unfortunately lacked the CE or EE background to actually connect a number of small sensors together with a microcontroller. The Arduino Uno wasn’t released until late 2010, and I didn’t begin to develop against one until years later. Ten plus years ago, I had no idea how to solder well, or even have a microcontroller communicate with a surface mount MEMS sensor.


I figured the iPhone had only been out a few years by that point, so if I just gave it time someone would bring something to market. I mean Rainbow’s End won the Hugo award in 2007, so I figured whole rooms of CE undergrads working on wearable computing would be likely building something better than I could even imagine. 


Unfortunately it’s 2021 now, the iPhone has been out ~14 years; and the closest I’ve seen to Mr. Vinge’s vision was Google Glass. 


Now surrounded in a room littered with various Arduino hardware, it looks like I may have to build one myself after all. Luckily I’ve learned a lot in the past ten years, and the RP2040 looks like the perfect platform to get started with.


Wish me luck!


Sunday, July 8

$12 USB Pedals = Excellent

Spending many many hours in front of the computer, both for work and leisure; I've invested heavily in setting up the best human-computer interface I could. Even tiny improvements in productivity add up quickly when multiplied by the hours/month/years I'll be able to take advantage of them.

In that spirit I don't shy away from tools or systems that have steep learning curves if I believe they offer some efficiency improvement once mastered. This has pushed me towards things like Linux, the dvorak key layout, GNU Emacs, and the Kinesis keyboard.


[Here is a picture of my desk at work. I've attached a large touchpad to the top of my keyboard so I can put the entire keyboard in my lap and not have to move my arms to use the mouse.]

Obviously having the above sitting on your desk at your office, makes you stick out a little (especially in conformist Japan). During one discussion with a coworker I was joking that the Kinesis even offers an optional foot pedal for those interested.

Now at least the old Kinesis foot pedals simply generated a key press to help with something like holding down the shift key to reduce strain on your hands or arms. Thinking further though, I wondered if someone hadn't come out with a generic USB foot pedal that could do something more.

While still chatting with my coworkers a quick search turned up exactly what I was looking for. Amazon now sells a $12 USB foot pedal!

Some Googling around quickly determined that these pedals have some driver software that's leaves you a little wanting, but which updates the hardware so it knows which key press to transmit when stepped on. A number of issues here, yada yada yada; but the hardware will connect to anything using the USB HID keyboard driver!

I didn't want to mess with the hardware, but I figured if it used a standard USB keyboard driver then I could code something up and make it do whatever I so desired ($ sudo make me a sandwich).

Talking to a friend about my idea, he later pointed me to Aleksandr Levchuk's VIM Clutch which was the exact kind of thing I wanted to do. Still wanting a bit more flexibility to define pedal actions, and to prevent burning myself while soldering; I just tossed together a tiny ruby script/driver to handle the pedal.



Now after getting everything working, using ruby and libusb; I've re-created the VIM clutch in software using the xautomation package. You can drop in your own onpress and onrelease functions though to enable the above script and $12 pedal to do anything you want.

I still haven't decided how to best use my new pedal yet, but here are a few ideas;

  • Play/Pause for music
  • Meta-key for Emacs
  • Bring my chat window to center screen when pressed, then return when released
  • Record keyboard macro for Emacs while held down, playback macro when pressed quickly.
  • Next tab in Firefox
One of the nice things of implementing the driver in Ruby, is that I can easily have it do all of the above just by detected what my active window is.


Anyways, hope this helps!

Tips & Tricks with Clojure Reducers

After noticing a few others encounter the same issues I ran into when first playing with Clojure's reducers, I thought I should collect some of what I discovered into a quick blog post.

First off, reducers are *AWESOME* and fully realize the power of parallel sequences but as they are still alpha have a few rough edges to work around. I'm sure in the near future it will become much more polished but until then be aware of the follow.


Note, clojure.core.reducers will be abbreviated as "r" below;

  • In many cases r/map and r/reduce are faster than their core counterparts, but not in all cases. At this point in time I only use the r/ variants for larger collections (> 1000 elements) and that has worked well.
  • The parallel part of reducers doesn't kick in until you use r/fold instead of reduce. For r/fold to be faster than r/reduce though, it needs to be able to "divide-n-conquer", and hence needs to be able to quickly divide up the collection.
    Summary: r/fold is only faster than r/reduce when operating on a vector.
  • (into [] (r/map inc (vec (range 10)))) works, but uses r/reduce instead of r/fold.
    Instead it's faster to use the following to take advantage of fold;


    so,
    (fold-into-vec (r/map inc (vec (range 2000))))
  • Reducing into map is many times slower than reducing into a single value or vector. Unfortunately merge and merge-with become the bottlenecks here, and this is the biggest rock in my sandal at the moment. :(
  • Don't forget mapv, which was introduced in Clojure 1.4 I believe. It provides a nice middle ground between core/map and core.reducers/map.


The function I'd specifically like to tune further with reducers is the following;

Wednesday, July 4

Datomic with examples in Clojure

So for some quick background, Rich Hickey the inventor of Clojure created yet another NoSQL database called Datomic. I was quite skeptical at it's release with the plethora of other NoSQL solutions available, but was converted by a simple question asked during Clojure Conj West. 

"What is faster, a local spinning disk or an SSD connected via a fat pipe?"

Hearing this I suddenly realized that the significant changes that have occurred with large memory, many locally connected machines, and SSD's really have changed the game and that a re-architecture of databases was called for. 

For more details on that topic, I high recommend starting with Jay Kreps blog post here.

Anyways, Datomic's idea of moving much of the read-only query work to the client, and abstracting away data storage, is very attractive. Loads more details here.

Finally jumping in to Datomic, after I started playing with working sets many times larger than available RAM; I ran into a couple issues that I thought I should mention to hopefully help any other "datomic clojure intro howto" googlers.
  1. Grab the latest greatest version of datamic from here.
  2. Second, unzip it and do;
    $ mvn install:install-file -DgroupId=com.datomic -DartifactId=datomic -Dfile=datomic-${VERSION}.jar -DpomFile=pom.xml

  3. Where ${VERSION} is the numbered version of datomic that you download.
  4. Check out some Clojure examples, and project, I extracted from official Datomic tutorial found here.Examples -> https://github.com/thebusby/datomic-tester/blob/master/src/datomic_tester/core.clj

Hope it helps ;)

Friday, July 9

Back in town for a bit, and lots of photos

Well I'm back in the US for a few weeks, working and having fun. I wont be posting much here for a while, but lots of new pictures on flickr.

Wednesday, February 17

Capturing a screenshot, displaying an image, and load/saving an image in Clojure

The following functions perform a screenshot, or capture a region of the screen, and then provide a method to display the captured image in a new window or load/save to disk.

Note: I'd like to thank hoeck (from the Clojure IRC channel) for writing the display-image function.

(defn display-image
"Displays an image in a new window"
[image]
(let [frame (doto (javax.swing.JFrame. "Display Image")
(.setBounds 0 0 (. image getWidth) (. image getHeight))
(.setVisible true))
cv (proxy [java.awt.Canvas] []
(paint [g] (. g drawImage image nil nil))
(update [g] (. g drawImage image nil nil)))]
(.add (.getContentPane frame) cv)))


(defn capture-image
"Captures an image of a section of the primary screen"
[from-x from-y x-size y-size]
(let [rob (java.awt.Robot.)
rect (java.awt.Rectangle. from-x from-y x-size y-size)]
(. rob createScreenCapture rect)))


(defn grab-screen
"Returns an image of the entire primary screen"
[]
(let [my-scr (.. java.awt.Toolkit (getDefaultToolkit) (getScreenSize))]
(capture-image 0 0 (. my-scr width) (. my-scr height))))


(defn save-image
"Save an image to disk as jpg"
[image filename]
(javax.imageio.ImageIO/write image "jpg" (java.io.File. filename))


(defn load-image
"Read a jpg from disk"
[filename]
(javax.imageio.ImageIO/read (java.io.File. filename)))

A Change of direction

With my last post about Japan at least a year old now, I've decided to use this space as a giant notepad for my other interests and pursuits.

For the time being this means I'll start posting again but mainly with the discussion relating to software engineering, code snippets, and interesting math.

Wednesday, May 30

Tokyo wonderland

Well after spending all weekend running around, it's the middle of the week and I'm dead tired and ready to collapse into bed. I have another 8-10 new pictures to scan in and post from last weekend, but that'll be for later...


Sanja Matsuri

I was going to talk about the Sanja Matsuri in detail, but I think you can find a lot more information about just about all of Japan's Matsuris online these days; and the only thing that really stood out about this one was the Matsuri riders. Now just to be clear I'm making up the name "Matsuri riders" right now to describe a group of people who climb up and then ride the omikoshi (portable shrine).

For some quick background, the center piece of any good matsuri is a very heavy omikoshi (portable shrine) which is hauled on the shoulders of lively festival goers around their local town to promote X. The idea is that the heavy shrine would crush any single human being (like much of Japanese society), and so it's a group effort which usually involves lots of alcohol and cheering. These portable shrines are considered holy maybe, and they are owned/stored by the local temples (which typically have some connection to the mob).

Well evidently in this years Sanja Matsuri things went a little too far (Alcohol + "too far", imagine that...), and some people climbed up on the top of the shrine,
that 50+ people were hauling around, and danced the funky dance. The matsuri riders as I like to call them garnered quite a bit of publicity since the local TV crews grabbed some great footage of them acting like asses, and the public outcry began.
Now try and think of Elvis gyrating his pelvis on top of a cross at Easter mass in the 1950's, and you have a pretty good grasp of the situation here now. For more details you can read the heavily sanitized story here in English.


Sugamo
The rest of my weekend I spent walking around Sugamo, the shopping district for ladies age 70 plus. This area is colorfully known as the "Harajuku for old women", and quickly grabbed my interest with the title alone. I mean what could a district for older people look like?

I was imagining,
1. Bingo Halls
2. White slacks on sale everywhere
3. Slow moving polite shoppers, images of Wal-mart greeters come to mind
4. Lots of haggling to save $0.02 on the price of dried squid
5. Complaints about how everything used to be better

What I found,
1. Quick old women fighting to get at items in the discount rack
2. Grandmotherly ladies throwing elbows to make space through the crowd
3. Red ladies panties everywhere, with signs proclaiming excellent prices...
4. Lots of really cheap clothes only your grandmother would be caught wearing.
5. Horrible foot traffic, because 3 old ladies in walkers chatting side by side might as well be a wall.
7. Lots of complaints about how store clerks used to be more helpful
7. Cackling that would make the wicked witch of the west pause in envy

I'll add pictures of the above here shortly, but until then
Continued in Part 2 next week...

Wednesday, May 23

Going film

Well after selling off my Nikon D2x (Digital camera) and a few unused lenses, in exchange for a Nikon F100 (Film camera) and a Leica 50mm lense for my M6; I think I'm becoming a film convert.
Digital is great when you want to shoot 2-400 shots, and then spend the next 2 hours selecting the best 10-20 shots to cleanup and post; but I typically find something lacking in both the images and the workflow. I'm sure if I was shooting professionally digital would be the way to go, but these days I'd rather just toss a camera and two rolls of film in a bag while I'm out and about than haul all the digital gear around with me.


So since it was my birthday, the GF spent one afternoon poking around Shinjuku and got me a Holga toy camera. This is inexpensive toy camera has become all the rage these days because of the unique style of less than perfect pictures it produces, and was recommended to me by my Aunt in Santa Cruz.



The camera has two shutter speeds, 1/100 of a second and bulb; with one working aperture (f8). Unlike most popular camera's from the past 20-30 years, it uses 120 size film (6cm wide spool film, no nice disposable case here) which is still quite popular in asia. You focus a holga by guessing the distance between the subject and yourself, and hence this camera is all about just taking pictures. It's an incredibly light camera, being nearly 100% cheap plastic, and makes it easy to carry where ever you go and take great snapshots. The only drawback being you better hope the light level falls within a couple stops of f8@1/100 (Overcast day with ISO100 film) or you're out of luck getting any useable pictures.

Well after putting my first roll of film through the Holga I was already hooked, and went straight out and picked up a couple extra handfulls of black and white (Kodak T-Max 100) 120 film. 120 film is actually cheaper than normal 35mm film for both the purchasing film and development here in Tokyo ($3 film/$4 dev for 120 versus $5-9 film/$8 dev for 35mm), but you only get 12 square shots per roll.

Now all setup with my new Holga and plenty of film, I made my way to Sugamo, the place they call the "Old Woman's Harajuku"; which is in stark contrast to the famous Harajuku that I've shot many times before. I ran around for an hour or two before the light dwindled, and got a few shots of what a shopping district for ladies age 70 plus looks like. I'll be posting these photos in the next week or so after I've scanned them for everyone to gander at.

Although I loved shooting with the Holga, the one drawback ended up being that I could only take pictures in bright sunlight. So after doing some poking around on the web, I decided to pair the holga up with another 120 film camera that I could use when the light changed, or when I needed to use slide film. So the next day I went out and got myself a cheap chinese copy of the venerable German Rolleiflex, the Seagull. Now paired with both the Holga and the Seagull, and sounding like a storybook with these names; I spent the next morning taking pictures of one of Tokyo's largest festivals, the Sanja Matsuri.

Between using the Holga for action shots around the Omikoshi, and the Seagull for taking candid shots of festival goers, everything worked out really well. I won't go in to any more details about the event here until I get my film back, but this had to be the most crowded place I've ever been in Tokyo (excluding commuter trains).

The Holga is just great to take pictures with, since it makes it easy to take unique interesting pictures, and you really never know what kind of results you're going to get with a toy camera; while the Seagull lets me take the quality shots that want to make sure look good. The other benefit of the Seagull is that because it's a TLR, and you stare down into the view finder from above, I can look down in to the viewfiender and take pictures from a normal Japanese persons eye level without having to stoop down to their eye level myself. The other key advantage is because I'm staring down into the viewfinder of this strange black box to frame and focus, I'm not making eye contact with the subject and hence they ignore me and act more natural.

To be honest I doubt that few people born since the 1950's are even familiar with a TLR camera, and very likely don't even realize I'm holding a camera.


Now as soon as I pick up a cheap flatbed scanner for these big negatives, I'll be adding a new collection or rather unique photos of Japan to Flickr and my website!

Monday, May 21

Breathing new life into my site


Well after not really adding anything new online in the last few months, I've decided to try and do a better job of both updating my website and Flickr.
I'm not sure what'll happen to the website in the next few weeks, but I expect it'll look a little different, and be a lot more interesting soon.

To help kick this off, I've setup my desktop computer to add one new image to my Flickr page daily. That way people can expect to see new pictures appear on Flickr daily, instead of 15 new pictures once a month or more.
  • A new public photo should appear every Monday, Wednesday, and Friday (Japan time)
  • A new friends and family photo should appear every Sunday, Tuesday, Thursday, and Saturday (again Japan time).

Thursday, March 15

In Transition

Sorry for the abrupt change, but I'm currently changing my site's host provider so things will be offline for a bit!