A curiosity on Chapel Street in Blackpool, U.K.

I’ve never been to Blackpool, and according to Ian Anderson, it’s not the nicest place to visit. That said, I was listening to “Ian Anderson Plays the Orchestral Jethro Tull (Live)” and when “Up the Pool” played into my sweet, sweet Bose QuietComfort 35s, I had a¬†wonder about the place. So I fired up Google Maps in my browser and had a look.

I ended up zooming into a central location near the Irish Sea, on Chapel Street – across from The Sea Fish and Chips Restaurant. Close enough the almost hear the gulls. I mistakenly zoomed in too close and ended up in street view (which is a great user experience by the way). I saw two images for a sign above a doorway.

Chapel Street

Quite the difference as I navigated down the street a little and looked back at the same sign. A 9/11 conspiracy museum versus some exhibition of the universe. I believe that the 9/11 conspiracy museum is a more recent image and represents what is really there at the moment. That 9/11 thing has the look of a P.T. Barnum effort in my humble opinion.

When I next visit England, I have my sights more on Hampstead Heath & Ascot than I do for Blackpool. But who knows, maybe I’ll walk their sands at some point.

Returning data from an async network operation in Swift

Swift is cool

If you’re ever using asynchronous network operations (say GET or POST) and want to return data when calling a method, you’ll quickly understand that it’s not so easy. But you’ll see below how you can do this fairly easily.

Let’s say you have a Class that handles all kinds of network communication. I call mine an “adapter” for lack of a better name. I can call methods on the Class and get data returned from it. You’re never going to be sure when the data returned is available, so you need to set things up with a block. Here is an example method in an adapter Class that I have. I included the Struct so you know how it’s set up. I’m also using AEXML to parse the returned XML to make things easier for me as a developer.

struct SpeakerInformation {
    var deviceID: String
    var name: String
    var type: String
}

func getSpeakerInformation(callback:@escaping (SpeakerInformation) -> () )
{
    var request = URLRequest(url: URL(string: "http://\(ipAddress):\(port)/info")!)
    request.httpMethod = "GET"
    let session = URLSession.shared
    session.dataTask(with: request) { data, response, err in
            
        var options = AEXMLOptions()
        options.parserSettings.shouldProcessNamespaces = false
        options.parserSettings.shouldReportNamespacePrefixes = false
        options.parserSettings.shouldResolveExternalEntities = false
                        
        do {
            let xmlDoc = try AEXMLDocument(xml: data!, options: options)
                
            if let name = xmlDoc.root["name"].value {
                    
                let thisName = name
                let thisDeviceID = xmlDoc.root.attributes["deviceID"]
                let thisType = xmlDoc.root["type"].value!
                let thisInfoPacket = SpeakerInformation(deviceID: thisDeviceID!, name: thisName, type: thisType)
                callback(thisInfoPacket)
            }
        } catch {
            print(error)
        }
        }.resume()
}

See that callback with the typed object? This is how you access the data from this sample GET call. I have the blocked wrapped up in a method.

func whatAreMyDetails() 
{
    // The response object in the block.
    stAdapter.getSpeakerInformation() { (response) in
        if let responseObj = response as SpeakerInformation! {
            DispatchQueue.main.async {
                self.headerLabel.text = responseObj.name
                self.deviceTypeLabel.text = responseObj.type.uppercased()
            }
        }
    }
}

So you can’t set something up which would allow for this kind of syntax:

let foo = stAdpater.getSpeakerInformation()

I hadn’t done a lot of networking calls in quite some time and I stumbled a bit trying to force the direct operation¬†before I thought about it some more and did some research. You can return an object, you can return an array of objects, a dictionary, all kinds of stuff. Super handy and the block keeps things nice and tidy.

Tagged : / / / / /

UILabel centered text – getting the text’s rect

Swifty

I recently had a section of user interface where I had a UILabel that took up an iPhone’s full width. It contained text which would be dynamic over time, meaning that the text would update at times. I wanted to place an image icon beside the first character of the label, but I needed to know where to place it. I had done it in the past but honestly forgot exactly how to do it.

Kyle Sluder from the Apple Cocoa-Dev list reminded me what I should be looking for.

UILabel.textRect(forBounds:limitedToNumberOfLines:)

Doh! I should have decided to RTFM — read the documentation. You can get a rect for the label, but you can’t use all of it for positioning. Here is sample code in how to get the job done.

let label = UILabel(frame: CGRect(x: 0, y: 100, width: self.view.frame.size.width, height: 30))
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 16)
label.numberOfLines = 1
label.text = "This show is crazy."
        
let rect:CGRect = label.textRect(forBounds: label.bounds, limitedToNumberOfLines: 1)
let v = UIView(frame: CGRect(x: rect.origin.x, y: label.frame.origin.y, width: rect.width, height: label.frame.height))
v.backgroundColor = UIColor.red.withAlphaComponent(0.3)
        
self.view.addSubview(label)
self.view.addSubview(v)

Pretty easy. I just forgot how to do it. This is for the whole text, not substrings within it.