Safari – Send Window To Back Command

I often end up with a Safari window in front that I don’t want to close or minimize, but that I do want to send behind all other windows. Alas, Safari doesn’t have this command in the Window menu. I’ve requested that it be added (FB7642150) and you can also ūüėČ

In the meantime, I don’t much like AppleScript so I don’t know it well, but this need finally hit the level where I was willing to suffer through the pain of AppleScript and hack something together (there’s probably a better way to write this). I put this into a simple Alfred workflow and it works great (yay!):

on alfred_script(q)
  tell application "Safari"
    local lastVisibleWindow
    repeat with n from 1 to count of windows
      if window n is visible then
        set lastVisibleWindow to window n
      else
        exit repeat
       end if
     end repeat
    set index of front window to index of lastVisibleWindow
  end tell
end alfred_script

You can also use this script from a scripts menu, or other utility able to invoke applescripts, by removing the first and last lines that make it a handler for Alfred.

Tested and works under Safari 13.0.5 on macOS 10.15.3

This script handles the case where you have minimized windows. The “set index of the frontmost window to (count of windows)” type script you’ll find elsewhere online doesn’t work if you have minimized windows.

cheers.

Improving on the common AnyCancellable .store(‚Ķ) pattern.

If you’ve been reading any Combine documentation or code, you’ve probably seen code like this before:

let newPhotos = photos.selectedPhotos
newPhotos
  .map { [unowned self] newImage in
    return self.images.value + [newImage]
  }
  .assign(to: \.value, on: images)
  .store(in: &subscriptions)

Pretty standard: call something that returns a publisher, map the results to whatever type you need, assign that value to an instance variable, and finally, store the resulting AnyCancellable into a Set named subscriptions which is an instance variable or property in the enclosing scope. In this case we’re in a UIViewController subclass where it’s defined as:

private var subscriptions = Set<AnyCancellable>()

This code is from the popular book on Combine.

The problem with this pattern in this particular case, and other similar situations, is that the AnyCancellable is never removed from the subscriptions Set. Sometimes this doesn’t matter – when the enclosing scope is going to go away and the code is only called once relatively soon before exiting scope cleans up memory. But sometimes, as in the sample project this code is from, the user can do the action invoking this code (adding photos in this case) repeatedly. Each time this code is invoked the .store(...) call adds another AnyCancellable to the Set. Since this view controller is the root view controller of the app it is never closed and this memory is never cleaned up during the lifetime of the app.


An easy solution is to add an instance variable to your class (a UIViewController in this case):

private var newPhotosSubscription: AnyCancellable?

and then change the code above to something like this so the AnyCancellable is assigned to the instance variable and the .store(..) part is removed:

self.newPhotosSubscription = newPhotos
  .map { [unowned self] newImage in
    self.images.value + [newImage]
  }
  .assign(to: \.value, on: images)

When this assignment happens it frees the previous value, if any, and thus there will be at most a single AnyCancellable kept around.

Ok, that works. But I’m a perfectionist and that single AnyCancellable hanging around bugged me. That’s fixable, but as I went and fixed this issue in more places in the project there was a proliferation of instance variables as I had to add one for each place this came up.

So here’s a solution I came up with to avoid that.

First, add an extension on AnyCancellable:

extension AnyCancellable {
  func store(in dictionary: inout [UInt64: AnyCancellable], 
             for key: UInt64) {
    dictionary[key] = self
  }
}

Then change the subscriptions instance variable to be a matching Dictionary (and remove the individual instance variables you added for each case previously, if you did that already):

private var subscriptions = Dictionary<UInt64, AnyCancellable>()

In our original function which created the newPhotosSubscription and let the user choose photos, change the code to:

let key = DispatchTime.now().uptimeNanoseconds
 
newPhotos
  .handleEvents(receiveCompletion: { [unowned self] _ in
    self.subscriptions.removeValue(forKey: key)
  })
  .map { [unowned self] newImage in
    self.images.value + [newImage]
  }
  .assign(to: \.value, on: images)
  .store(in: &subscriptions, for: key)

So above we created a Dictionary instead of a Set for our subscriptions instance variable that holds on to the AnyCancellable so it remains allocated while needed. The dictionary allows us to store the AnyCancellable under a unique key, which in this case is a UInt64. On the first line above we create that key and assign it the number of nanoseconds since the device rebooted.

Then we add a .handleEvents operator to the subscription pipeline. Once the publisher has sent the .finished or .failure completion event we no longer need to keep the AnyCancellable around. Our receiveCompletion closure code removes the AnyCancellable stored under the captured key from our subscriptions instance variable.

(Note: if you preferred, you could replace UInt64 with UUID in the dictionary declaration and the AnyCancellable extension. Then instead of setting the key value to DispatchTime.now().uptimeNanoseconds you could generate a new UUID with UUID(). All that matters is that the is a unique value conforming to Hashable and doesn’t cost too much to generate).


I’m relatively new to Combine, so if you know a better way to do this, I’d love to hear about it!


Addendum

1) Be aware that Swift closures capture variables by reference by default (unlike for Objective C). So don‚Äôt re-use the key variable like I did in my project 

2) I also ran into a case where the pattern above did odd things for a Combine pipeline subscribed to a Future publisher ‚Äď the store seems to happen after the pipeline has finished executing (huh?!) and thus the clean up in the completion handler is called before the store. I haven’t dug into that to understand why, but thought I’d mention it in case you are seeing things not get cleaned up when you expect like I was.

-> I later learned that this is because in Combine Future is “eager” and will complete immediately. One option is to wrap it in a Deferred publisher and another is to capture the AnyCancellable in a local variable and only save it to the dictionary if the completion block hasn’t been called yet.

“Help getting into the tech scene in Portland”

I get this question a lot, “I’m having trouble getting into the tech industry in Portland, any suggestions?” Usually from recent college graduates or people who are coming into tech from other than a CS degree path. ¬†I just wrote up this response to one and decided I was tired of typing similar stuff in over and over so extractedit and am putting it here:

—-

Jobs resources:

There are more for sure.

While you search (since one can only spend so many hours a day searching), build something that demonstrates your skills and helps you learn more skills. Picking something you see lots of job ads for (if it’s interesting to you) is a decent way to start. Lot of demand for machine learning these days. Taking online courses can help accelerate this learning but won’t get you a job; building something that works and that demonstrates what you can do is much more likely to.

If you find a place you want to work, get to know people there and let them get to know you.(1) ¬†If they like you then they’ll help you know about positions that open up. Learn from them what they need and go teach yourself those things. Ask smart questions (find answers to easy ones online and in documentation).

Finally, big companies like eBay, Apple, Google, Amazon etc open up there internships for current students and recent graduates in (Oct?)/Nov/Dec so inquiring about them can be a good route into larger companies.


1) don’t be creepy! See if you have any friends in common. ¬†See if there’s a meetup or other public social gathering they go to where you can meet them. ¬†Follow on twitter to get to know them over time. ¬†Look for their office having an open office gathering, etc.

Tax Time: Retirement plan for Indies

Tax Time here in the U S of A.   This post is for self-employeed and small business owners in the USA but does not constitute tax advice Рyou should consult a qualified licensed/certified tax professional Рbut is just some information to help you ask them some leading questions and pointers to documentation on the IRS.gov website for educational purposes.

ŌÄ

As I’m calculating the basis in my SEP-IRA due to some conversions of IRA to ROTH IRA, I’m reminded that I lost out on about 10 years of pre-tax retirement savings due to a bad CPA who said I wasn’t eligible to do so since it was an S-Corp. ¬†Got a new CPA and found out the first one was wrong (or the law changed and he was wrong at first but didn’t inform me that it had changed).

I suggest you educate yourself by starting at IRS.gov SEP FAQs and learn enough to ask the questions I should have :-/

The great thing about a SEP-IRA, for an S-Corp anyway (not sure about LLCs or sole-proprietors), is that the business makes the contributions for the employee and these contributions are deductible business expenses.

The limits are also a LOT higher than you as an individual have.  From an FAQ sub-page linked to from the one above:

How much can I contribute to my SEP?

The contributions you make to each employee’s SEP-IRA each year cannot exceed the lesser of:

  1. 25% of compensation, or
  2. $53,000 (for 2015 and 2016 and subject to annual cost-of-living adjustments for later years).

These limits apply to contributions you make for your employees to all defined contribution plans, which includes SEPs. Compensation up to $265,000 in 2015 and 2016 and subject to¬†cost-of-living adjustments¬†for later years) of an employee‚Äôs compensation may be considered. If you’re self-employed, use a special calculation to determine¬†contributions for yourself.

So if you’re making more than $72,000 a year you can start to exceed the¬†$18,000 personal contribution limit to a SEP-IRA or 401K.

This makes it sound like you don’t have to be a Corporation (but read Publication 560 & ask your CPA):

How much can I contribute if I’m self-employed?

The same limits on contributions made to employees’ SEP-IRAs also apply to contributions if you are self-employed. However, special rules apply when figuring the maximum deductible contribution. See Publication 560 for details on determining the contribution amount.

The only real down-side that I’m aware of (again, consult your hopefully better-than-my-old-CPA CPA) is that you make this contribution for¬†all employees who meet the criterion you set in the SEP Plan Document. ¬†The IRS has a “model SEP plan document”, form 5305-SEP that I used and that might be enough for you. ¬†See the details/restrictions¬†here.

My company mostly used contractors and I set the requirement to full-time employment for 3 years which was likely to exclude all but the most dedicated and valuable employees (and which I already qualified for :)).

On the other hand, having a good retirement plan that is competitive with with a big company’s 401K plan might help you attract employees that you otherwise couldn’t, so you might want eligibility that let’s employees participate as soon as they’ve passed some introductory trial period (90 or 180 days or whatever). ¬†Notice that the limits for the SEP-IRA are actually¬†higher than those for a 401K plan once compensation crosses the $72,000/year threshold. ¬†So you can actually provide a more aggressive retirement plan with a SEP-IRA plan than with that big company 401K plan (unless I’m missing something).

And the employee can also make a ROTH IRA contribution as well (subject to the usual ROTH IRA contribution limits).

A¬†SEP-IRA is cheaper to operate than a 401K plan (which is complicated enough that you have to pay a service to operate it for you – and they aren’t cheap). ¬†Your employees can open their own SEP-IRA account and your business simply deposits money into it. ¬†(See the IRS site for details).

Over the 10 years I was operating with the bad CPA I could have saved a lot more for retirement than the ~$4000-$5000 ROTH IRA limit, if only I’d known….¬† ¬†Now you know.

Go forth and save those pre-tax dollars for retirement!

Your 50-year-old self will thank you. ¬†ūüėÄ

 

This is not tax advice. All readers should consult a qualified tax professional about any tax decisions they make for themselves or their business.

iWork ’09 and .docx files

If you happen to rebuild a mac and put 10.9.5 on it and you install iWork ’09 from an older CD/DVD so you get iWork 9.0, you will find that you cannot open .docx files.

Going to the AppStore is fruitless – just wants to get you to update to the current versions of Pages (the rewrite) and then tells you that you have an incompatible system (requires OS X 10.10 or later). ¬†It doesn’t offer to update you to the updates for iWork ’09 that you may have been offered back when you first installed iWork and before the new iWork apps came out.

The solution is to get the updater from Apple’s Support area (search for “iWork 09 update”). ¬†Here’s a link to the newest we found (9.3).