Navigate "Foundation" for Errors when Working in Swift?

When working in ObjC, I can just jump to FoundationErrors.h and look through the possible errors I can get.


In Swift, it seems I have to go to the:


import Cocoa


Right click, and jump to definition. Then I can select Foudation from the pop up menu in the path bar. Now I'm there. But there's no pop up menu to filter through symbols. So I have to scroll through a sea of stuff to get to what I'm looking for, which is potential errors to handle using the NSURL getResourceValue:forKey: method.


Is there a better way? I may just be a creature of habit, but I find it nice to jump to a header of documentation to see what type of errors are possible, get an error from a parameter that is easily readable from the method signature, and check the error "code" for the type. It feels easy.


The do try catch catch catch thing, just know to place an CocoaError.fileNoSuchFile here feels weird. Does it get better with time? Could there be a way to annotate methods that "throws" with a specific "ErrorType" struct or domain or whatever it's called in Swift, and then when you use that method, code completion will auto fill the do-do catch catch?


//Insted of this:

getResourceValue(_ value: AutoreleasingUnsafeMutablePointer<AnyObject?>, forKey key: URLResourceKey) throws

//Maybe something like this:

getResourceValue(_ value: AutoreleasingUnsafeMutablePointer<AnyObject?>, forKey key: URLResourceKey) throws CocoaError


Though, there are so many keywords and annotation requirements already in Swift, maybe adding another one isn't such a good idea?


Would the code read nicer, if you just returned multiple types, with one of those types being an "error", or nil for "no error" to avoid 3 or more code blocks?

Accepted Reply

I'm assuming you mean using Command+F to bring up Find?

Nope, I’m talking about typing directly in the jump bar. Try this:

  1. In one of your Swift source files, command click on the

    Foundation
    in
    import Foundation
  2. Press control-6

  3. Type filexist

  4. Marvel at Xcode’s filtering

(Sidenote: I wish I could attach screenshots on these forums).

Quite. That’s a much requested feature (r. 22028729) but I don’t see it happening any time soon )-: In the meantime, I recommend that you post the image to some image hosting service and then post a URL. That URL will require moderation approval but I can take care of that.

… is the getResourceValue method in Swift deprecated?

Not formally. However, I encourage anyone using Foundation types from Swift to switch to their Swift equivalents. In this particular case, if you make the move from NSURL to

URL
, it’s easy to do the right thing here.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

Then I can select Foudation from the pop up menu in the path bar. Now I'm there. But there's no pop up menu to filter through symbols

After popping up that menu you can type to filter, complete with fuzzy matching.

The do try catch catch catch thing, just know to place an CocoaError.fileNoSuchFile here feels weird. Does it get better with time?

I don’t really understand this question.

Could there be a way to annotate methods that "throws" with a specific "ErrorType" struct or domain or whatever it's called in Swift, and then when you use that method, code completion will auto fill the do-do catch catch?

Typed errors is something that regularly crops up on the swift-evolution. It’s a complex issue, with pros and cons on both sides. I recommend you read through the archives (which, I’ll admit, is a bit tricky).

If you’re using

getResourceValue(_:forKey:)
it seems like you’re still using NSURL. I recommend a switch to
URL
. It’s equivalent,
resourceValues(forKeys:)
, is much more pleasant.

Would the code read nicer, if you just returned multiple types, with one of those types being an "error", or nil for "no error" to avoid 3 or more code blocks?

Well, the code’s nicer if you use the modern Swift API (-: Seriously though, I’m not entirely sure what you’re looking for here. Keep in mind the following:

  • You can use

    try!
    if you want to crash on throw
  • You can use

    try?
    if you want to get an optional instead of throwing
  • Lots of folks end up using a

    Result
    type, which holds either an error or a value; there’s no
    Result
    type built in to Swift (again, for complex reasons) but a quick ’net search will reveal lots of Swift lore on the subject

Probably the biggest issue I have with errors is dealing with APIs that don’t follow Cocoa standards. I’ve found that Swift is really good at building adaptors for this sort of thing. For example, here’s one approach to dealing with errors from BSD APIs.

struct SocketError : Error {
    let code: Int32
    init() {
        self.code = errno
    }
    init(_ code: Int32) {
        self.code = code
    }
}

private func again<Result : SignedInteger>(_ f: () throws -> Result) throws -> Result {
    repeat {
        let result = try f()
        if result != -1 {
            return result
        } else {
            if errno != EINTR {
                throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil)
            }
        }
    } while true
}

// Can now call `fcntl` and any errors get thrown (except
// `EINTR`, which triggers a retry).

let flags = try again { fcntl(fd, F_GETFD) }

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for the helpful response Quinn. I appreciate it.


>After popping up that menu you can type to filter, complete with fuzzy matching.


I'm assuming you mean using Command+F to bring up Find? That works to an extent. I like to go through the pop up menu like you can in your own source files though or in Obj-C mode. Typing requires that you *know* what you're looking for, but you may not know exactly what you are looking for. (Sidenote: I wish I could attach screenshots on these forums).


>>The do try catch catch catch thing, just know to place an CocoaError.fileNoSuchFile here feels weird. Does it get better with time?

>>I don’t really understand this question.


Heh, I did not really explained myself all that well on that. It was closer to a Colin Powell mini-tantrum than a question. 😁


In ObjC, the error handling pattern is informally established (as you know, a lot better than me). Most of the APIs pass an error back by reference. It's clear, you know if you call that method you can get an error just by reading the method signature; there is an error parameter. In Swift that pattern is swapped out in favor of the throws thing. I'm just not used to it, so I threw a mini-tantrum. The error to check in catch is kind of invisible. I can write:


catch
{
}
or
catch CocoaError.magicTime
{
}


I guess it's just something I need to get used to. I don't think it's pretty to have catch do catch code blocks everywhere. I can just use an error and stick its code in a switch statement.


I'd rather call a method, if there is an error, I can inspect it and handle it. Maybe typed errors is a bad idea as a language feature. It feels like the language may be trying to do a little too much already. Maybe I'm just accustomed to ObjC's informal nature that Apple taught me over the years. I'm no expert, I write high level programs. I guess my concern is while I'm making apps, I don't want to spend too much time fighting with the tools.

>Well, the code’s nicer if you use the modern Swift API (-: Seriously though, I’m not entirely sure what you’re looking for here. Keep in mind the following:

Thanks for letting me know about the newer API, is the getResourceValue method in Swift deprecated? I didn't get a warning from the compiler, perhaps informally?

I realize some of my complaints I post here may be valid, while others may be peppered with a bit of frustration because I already know how to do all this stuff in a different syntax and it feels like a semi-waste of time (of course it is not a waste of time). (And posts peppered with a bad joke here and there). So just ignore those parts of my posts 😁

I like writing apps, but I'm not the type of person who likes to just learn as many programming languages as possible. If I ever get rich enough, where I can sit in a room and just learn programming languages that could be fun to do one day 😊. There are a couple of things today I found that ObjC seems to handle better than Swift IMHO.

I hope as things settle down, Apple will concentrate on tools that help developers write better apps while also allowing devs to leverage their existing skills to do just that. I guess what I'm trying to say is, I hope we don't end up living in a world where we need to re-learn how to write apps every couple of years. I'd like to see the world we live in get better before we go to the Moon.

To look through symbols, click the Jump Bar at the top of the source code editor and start typing to search. Screenshot:

https://help.apple.com/xcode/mac/8.3/en.lproj/Art/se_codeannotations.png

Yeah. That's what I'm talking about. I''m able to do that from within my own source files, but if I jump into Foundation to take a look around, I was unable to.

I'm assuming you mean using Command+F to bring up Find?

Nope, I’m talking about typing directly in the jump bar. Try this:

  1. In one of your Swift source files, command click on the

    Foundation
    in
    import Foundation
  2. Press control-6

  3. Type filexist

  4. Marvel at Xcode’s filtering

(Sidenote: I wish I could attach screenshots on these forums).

Quite. That’s a much requested feature (r. 22028729) but I don’t see it happening any time soon )-: In the meantime, I recommend that you post the image to some image hosting service and then post a URL. That URL will require moderation approval but I can take care of that.

… is the getResourceValue method in Swift deprecated?

Not formally. However, I encourage anyone using Foundation types from Swift to switch to their Swift equivalents. In this particular case, if you make the move from NSURL to

URL
, it’s easy to do the right thing here.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for the tip.