Yesterday we released [Goalee][1], an app that helps you not lose sight of your life’s goals. The main idea behind the app is that all the annoyances, conflicts or so-called problems we face in our everyday lives pale in comparison with our true goals in life.
The issue I faced, as many others, is that I tend to lose track of what I desire most, exactly because of problems here and there. One approach is to start writing down your goals on a sheet of paper, which I did and it worked; for a while, because I eventually started overlooking said sheet of paper.
Entering text in multiple text fields is such a common pattern — everywhere, not just iOS — there should be a way to easily navigate from on field to the next, preferably the ”correct” one. Sadly, iOS doesn’t offer this feature, but let’s see how we could accomplish this ourselves.
First, a quick recap on what we need:
I’ve [recently][1] gave [Micro.blog][2] a try and [ shortly after ][3] I thought of importing all my tweets here, because … why not own my content? This post will be about extracting and converting your Twitter archive into simpler objects with just text and timestamp — there are many more available fields, but these were the only ones I was particularly interested in.
First things first, we need to request your archive: in our Twitter’s profile settings, all the way to the bottom we can find ”Your Tweet archive”; we need to click on ”Request your archive” and after a while we’ll receive an email with a link to the download.
UIKit does this really nice thing, where the user can tap around a text knob — with quite some margin, too — and still intercept the touch; but it appears that all knobs are created equal, but some are more equal than others; and so our story begins…
A few months ago [I was writing][1] about a new beginning and I mentioned a couple of projects. I mentioned the [first one][2] in a [previous post][3] and now I'm writing about the second.
The main goal of the app is for users to save their fidelity cards digitally (or request new ones), combined with the conveniences of displaying merchants & their offers, and having a shopping list at hand. There's also a friends feature, with which users can share their shopping lists — shopping together, faster and smarter has never been easier!
2 years and a half ago, I was [writing][1] about how I recently started using [Tower][2] — didn't even realize it's been so long. In that post I was explaining how I solved the fact that it doesn't support opening Pull Requests. Well ... The latest version of Tower now supports it, and I gotta say they're as seamless as one would expect!
A few new features:
Say we have a UILabel where we want to display a birthdate with a full format, and an API from where we get a String? with iso8601 format. One of the ways to do this would be:
let dateFromAPI: String?
// [...]
let dateFormatter = DateFormatter.shared // 1
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
if let dateString = dateFromAPI, // 2
let date = dateFormatter.date(from: dateString) { // 3
dateFormatter.dateFormat = nil
dateFormatter.dateStyle = .full
dateLabel.text = dateFormatter.string(from: date) // 4
}The other day, [Soroush][1] wrote a great [post][2] about hitTest(_:with:) (you should check it out), which reminded me of a problem I solved the other week: I wanted to increase a UIButton’s tap area, without increasing the button’s frame.
The following code would go in one of the button’s superviews; for example, you might have a mainContainer, which has a UIStackView that contains the button — we’d implement it in mainContainer:
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let biggerButtonFrame = theButton.frame.insetBy(dx: -30, dy: -30) // 1
if biggerButtonFrame.contains(point) { // 2
return theButton // 3
}I’d like to quickly explain how to let the user pick a photo and automatically extract the location for them. The post is targeted at iOS 11+, because starting with this version, to use an UIImagePickerController we don’t need to ask the user’s permission to access their photo library, because the controller runs as a separate process from the app, which means the app gets read-only access only to the image the user selected, and just to the image — no metadata included.
For this, we will need the UIImagePickerController:
func pickPhotoFromLibrary() {
// 1
guard UIImagePickerController.isSourceTypeAvailable(.photoLibrary) else { return }The usual solution to observe and broadcast is to use NotificationCenter:
final class Post { // 1
var title: String
var body: String
init(title: String, body: String) {
self.title = title
self.body = body
}
}
extension Notification.Name { // 2
static let LTHPostReceived = Notification.Name(rawValue: "com.rolandleth.com.postReceivedNotification")
}
final class PostCreationController: UIViewController { // 3
private let post: Post
// [...]
private func savePost() { // 4
// [...]
let userInfo = ["post": post] // 5
let notification = Notification(name: .LTHPostReceived, object: nil, userInfo: userInfo) // 6