-
Notifications
You must be signed in to change notification settings - Fork 313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hides delimiters in banner when surrounded by loaded shield images #1046
Conversation
} | ||
|
||
private func instructionHasDownloadedAllShields() -> Bool { | ||
for component in instruction! { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: this seems to be safe considering the guard in attributedTextForLabel(_:)
but the linter will complain about unwrapping when we decide to enable it.
|
||
SDImageCache.shared().clearMemory() | ||
|
||
let clearDiskSemaphore = DispatchSemaphore.init(value: 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: .init can be dropped.
import UIKit | ||
import MapboxDirections | ||
|
||
class InstructionPresenter { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Cool. Perhaps an Instructable protocol could be the next step.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm into the idea -- let's look out for a unified interface when we write/refactor the next view which might otherwise contain logic for setting up & displaying a complex domain object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great. Let's hold off on finally merging until we can properly test this with the server. It looks like there is a slight bug that prevents delimiter: true
from showing up in some cases.
Cool. I addressed the code nit and rebased on master again. |
25c4a07
to
a748cd1
Compare
812935b
to
45caabf
Compare
MapboxNavigation/ImageCache.swift
Outdated
let diskCacheURL: URL = { | ||
let fileManager = FileManager.default | ||
let basePath = fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first! | ||
return basePath.appendingPathComponent("com.mapbox.directions.downloadedImages") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: directions
is somewhat misleading, perhaps we could use Bundle.mapboxNavigation.bundleIdentifier+suffix
? ×2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is helpful, you've answered one of my tail work questions.
MapboxNavigation/ImageCache.swift
Outdated
|
||
if toDisk == true { | ||
diskAccessQueue.async { | ||
self.createCacheDirIfNeeded() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be mistaken but capturing self here should result in a retain cycle?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, there is a transient retain cycle there. While this block is in the queue or executing, self will be retained which ensures it sticks around long enough to complete its work. Once the block exits it is disposed of, breaking the cycle.
Does this reasoning hold water or does the team prefer a weakSelf/strongSelf pattern in these disk access methods?
d82aaed
to
14de9cb
Compare
MapboxNavigation/ImageCache.swift
Outdated
} | ||
|
||
private func createCacheDirIfNeeded() { | ||
if fileManager!.fileExists(atPath: diskCacheURL.absoluteString) == false { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we gently unwrap fileManager
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done - also refactored to rely less on data from self in closures, addressing @frederoni 's previous observation about the transient retain cycles on the disk access queue.
completionHandler(.cancel) | ||
return | ||
} | ||
operation.urlSession!(session, dataTask: dataTask, didReceive: response, completionHandler: completionHandler) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
operation.urlSession!
can also be unwrapped above in the guard.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of unwrapping, I've opted to ask before telling in the latest commit ( which will ensure that the force unwrap is safe )
A few TODOs remain, specifically around handling memory warnings. Also some DRY refactoring still needed
ImageCache dumps its in-memory cache if a memory warning is received
Provide a backwards-compatible shim for SDImageCache even though we're no longer using it
This only works for one request per URL at the moment. Next step is to encapsulate work into an operation which will allow for the addition of callbacks for an in-flight request (and avoid duplicate parallel requests for the same resource)
Sad paths still need to be implemented.
Co-Authored-By: Fredrik Karlsson <bjorn.fredrik.karlsson@gmail.com>
Remove redundant success flag from callbacks A few test backfills still needed Co-Authored-By: Fredrik Karlsson <bjorn.fredrik.karlsson@gmail.com>
Allow presenter to be thrown away when re-setting an instruction Log error on image download error Pad shield images with a space
Refactor InstructionPresenter to take its dependencies on init, removing some unnecessary optionality Nil out the instructions in StepTableViewCell's prepareForReuse()
I just merged master into this branch as the semantic disconnects were a bit much. /cc @frederoni Would love to merge this with a final 👍 and follow on with some tail work as enumerated in the OP |
@@ -71,8 +71,8 @@ open class BaseInstructionsBannerView: UIControl { | |||
delegate?.didTapInstructionsBanner(self) | |||
} | |||
|
|||
func set(_ instruction: VisualInstruction) { | |||
let secondaryInstruction = instruction.secondaryTextComponents | |||
func set(_ instruction: VisualInstruction?) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This optionality is needed in order to unset the instruction in StepTableViewCell.prepareForReuse()
/cc @frederoni
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, should we use a different semantic here now that we've wrapped the primary and secondary components in the VisualInstruction
class? Or does this feel idiomatic enough?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just set
or set(_:)
in this case almost feels like a reserved keyword but I don't have a strong opinion about that. Maybe setInstruction(_:)
or updateInstruction(_:)
would be more idiomatic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯 % agree, @frederoni. A update(routeProgress:)
, update(legProgress:)
or update(instruction:)
pattern would be pretty straightforward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's do this as tail work.
This delivers #1027
Includes some refactoring to avoid use of disk cache under test, and adds some synchronous and asynchronous integrated tests of the desired behavior.
Presentation and domain logic are moved into an
InstructionPresenter
class, which already knows about too much but I think it's an incremental improvement on doing all this work in the view.TO DO list before merging:
Tail work: