I'm reverse geocoding a pair of coordinates to find the user's city, but am having a hard time gettingthe city into a Motion-Kit layout. What's the best way to get the city into the layout? I also will be adding other information from an API to the layout, so that will probably run into the same problem.
There is a basic MK layout like this:
class HomeLayout < MK::Layout
def initialize(data)
@city = data[:city]
super
end
def layout
add UILabel, :location
end
def location_style
text @city
color :white.uicolor
font UIFont.fontWithName("Avenir", size: 22)
size_to_fit
center ['50%', 80]
end
end
I get @city
from this method in HomeScreen
:
def city
loc = CLLocation.alloc.initWithLatitude App::Persistence['latitude'], longitude: App::Persistence['longitude']
geo = CLGeocoder.new
geo.reverseGeocodeLocation loc, completionHandler: lambda { |result, x|
return result[0].locality
}
# This currently returns a CLGeocoder object, but I want it to return the city as a String.
end
I get App::Persistence['latitude']
from in on_activate
in AppDelegate, like so:
def on_activate
BW::Location.get_once do |result|
if result.is_a?(CLLocation)
App::Persistence['latitude'] = result.coordinate.latitude
App::Persistence['longitude'] = result.coordinate.longitude
open HomeScreen.new
else
LocationError.handle(result[:error])
end
end
end
Any help would be appreciated. Thanks ahead of time.
I'd have to see how you are instantiating the layout, but even without that I have a guess: you should consider supporting a
fetching location
message that is dismissed when the data is available.The workflow would look something like this:
class HomeLayout < MK::Layout def location(value) # update view locations. # you might also provide an `animate: true/false` argument, # so that you can update the UI w/out animation if the # location is available at startup end end
Once this is done you can do a second pass: providing the city data at startup. If the data is available, you should be able to pass it in to your initializer like you are above, and the layout should bypass the "loading" state.
The reason I recommend this approach is because it makes the controller more "idempotent". Whether it is provided the location data at startup or not, it can handle both cases.
Also, you'll be able to
open HomeScreen.new
before waiting for theget_once
block to finish.