Crash when using URL fragment() (macOS 13, iOS 16)

Hi all,

I was updating my usage of URL's fragment to fragment(percentEncoded:) due to the former being marked as deprecated, but seem to have encountered a bug in the latter's implementation. This function crashes (EXC_BREAKPOINT) whenever the URL contains no fragment, instead of returning nil as documented. I'm encountering this when running on macOS 13.2.1 and simulator for iOS 16.1. A very simple example can exhibit the crash:

if let url = URL(string: ""),
   let fragment = url.fragment() /* this crashes */ {
} else {
    print("No fragment")

I actually can't seem to find a way to use fragment() on a URL without a fragment without it crashing.

I wasn't able to find any other posts regarding this issue, so definitely let me know if this is a known issue and/or there's already progress on fixing it.

You'll want to report this to Apple using their Feedback reporter. They may be able to help you find a work around. Or perhaps fix it in the next release.

Does the old API also crash? Or the new API when you pass "percentEncoded: false"?

Also worth trying using components:

print(url.fragment(percentEncoded: false))
let components = URLComponents(url: url, resolvingAgainstBaseURL: false)!

Old API worked fine for me.

@Jon_Shier Sure thing, will do

@tera The old API works fine, it's the new API that is crashing

Then the solution is easy: file a bug, optionally post the bug id here, and use the old call in the meantime, unless you need to do something with escaping / unescaping that the old API doesn't provide, in that case reach out for one of the alternatives mentioned above or use some explicit escaping conversion functions.

(It's interesting though how the situation like this can surface in the first place; whoever implemented the new fragment() API didn't bother implementing a trivial unit test?)

I think the real problem is they fixed it, but never updated the available documentation. This api should be marked unavailable for versions where it will cause a crash if the host is nil.