who is this for, anyway?
Blindly Dispatching to the Main Queue
Update 9/12/2018 I’m told dispatch_get_specific
does not work the way I think it does, and this is not a valid solution. Please do not use this. Leaving up for posterity.
Original: In my current side-project, I’m writing a swift app that makes liberal use of dispatch queues to move work off the main queue to keep the app responsive. This works great, but there are some Apple APIs (like UIKit) that require calls to be made from the Main thread or Main queue (they are distinct things).
I want to be able to dispatch work to the main queue synchronously, without worrying about whether I’m already running on the main queue or not.
Typically people suggest checking NSThread.isMainThread()
before calling or dispatching an action, but if the api you’re calling requires the main queue this may not be enough. You can potentially be running on the main thread, but not the main queue.
There used to an API to check your current dispatch queue, but that was deprecated with iOS 6. The current strategy appears to be setting a queue specific variable that can only be read from the main queue. This is analogous to thread specific storage (TSS) in in C++ land.
I’ve wrapped this all in an extension to DispatchQueue in Swift 4.1. Now all I need to do to blindly dispatch synchronous work to the main queue is call DispatchQueue.dispatchMain { // uikit stuff }
.
extension DispatchQueue {
private static let mainQueueKey = DispatchSpecificKey<Int>()
private static let mainQueueValue = 1234
public class func initializeSafeDispatchMain() {
// set a queue-specific variable that can only be read from the main queue
DispatchQueue.main.setSpecific(key: mainQueueKey, value: mainQueueValue)
}
public class func dispatchMain(_ block: () -> Void) {
// if the queue-specific variable matches, execute the block immediately
if DispatchQueue.getSpecific(key: mainQueueKey) == mainQueueValue {
block()
} else {
// queue-specific variable was not found, so dispatch to the main queue
DispatchQueue.main.sync {
block()
}
}
}
}
The problem with this approach is initializing the queue specific variable. Right now I have it wrapped in a function called initializeSafeDisptchMain()
that must be called by the application before the first use of dispatchMain()
. I’d love to find a way to run this automatically on app startup without having to manaully call it from application(:didFinishLaunchingWithOptions:)
, but I’m blanking on it right now. If you can think of a way to do this that isn’t totally gross, please let me know.
Adding the OEM Backup Camera to a 2012 Dodge Charger
One of the biggest pain points of owning a modern Dodge Charger is that the rear visibility is basically nil. A backup camera was offered on the vehicle to compensate, but I bought mine used and the previous owner did not buy that option. Thankfully, there a couple sellers that offer the OEM part on Amazon, including Amazon itself.
The one I bought varies from $225-$250 ($228 at time of purchase), and comes with the tail light, wiring harness, and about 20 pages from the FSM describing how to install the wiring harness. On the Charger the rear view camera is built into the tail light, if equiped, so to add the camera you need to replace the whole light assembly.
I could not find any formal documentation on how to get the old light out of the trunk lid, or informal documentation that wasn’t behind a paywall or forum login, so I though I’d writing it up here with a few pictures.
Replacing a 2012 Dodge Charger Center Tail Light
The old light without a camera hole.
Open the trunk. Once open, you will need to remove the security box in this picture.
It is held in with a couple of small torx screws.
Then, each corner of the lid is covered with plastic peice. They are held in place with a plastic christmas tree. There are specialty puller tools you can buy, but I found the claw side of a hammer works just as well. Once the plug is out, the plastic cover should slide off.
Then there are 4 more christmas tree plugs holding the felt liner on that must be removed (at least on my 2012).
Once they are out, the felt liner should pull right off.
With the lid open, should should have clear access to the center tail light.
It is just held on with a pair of small bolts and also clips into place.
If you look closely, you will see an extra plug not connected to anything. My 2012 was already pre-wired for the backup camera. From what I have read, most Chargers with the 8.4 Uconnect screen should already be wired, so you should not need the wiring harness that came with the new light. If yours was not factory wired, you will need to follow the FSM directions included in the package to install the included harness. Good luck with that, as it looked like there was a lot of removing interior panels involved.
Once you have removed and disconnected the original light, just connect and bolt in the new one.
Once everything is strapped back in, replace the felt and the secured box and you should be done. The new light looks just like the old with the the addition of a camera on the left.
At this point it is installed and the light and trunk release work, but the camera still does not display on the Uconnect system when I am in reverse. I need to take it to the dealer and have them add the camera option to my VIN and flash the Uconnect firmware.
Update Feb. 5, 2016
I finally got the dealer and had them update the sales code for my vehicle and flash the Uconnect firmware. When in reverse, the view the from the camera fills the entire 8.4" screen. The picture quality is meh, and the bottom 1/10th is a shot of my bumper, but otherwise it works fine. I’ve finally got some rear visibility when backing up!
2016 Goals
I haven’t made New Years Resolutions in a few years, but I’ve got enough things rambling around in my head right now that I think it would be a good idea to write them down and attach a date to them. So without further ado:
- Lose 40 lbs. : The eternal lose weight/get healthier goal. I want to run a marathon by 2017, but I can’t even start training for that until I shed some serious weight.
- Get my eyes fixed : I’m too blind for lasik, but there is an intraocular lens implant procedure that I should finally have enough money in my HSA to cover.
- Move : Don’t care where to, just out of this house. I’ve been trying this one for years too, but it’s got to happen in 2016. Lots of half-done house projects to finish up before spring to make this work.
- Use Swift in anger : Not just a test class here or there, but ship an app that contains mostly swift so I don’t fall too far behind the curve.