Skip to content

RFC - Remove asURL() method and AppEnvironment base URL access#24333

Closed
mokagio wants to merge 5 commits intotrunkfrom
mokagio/remove-asURL-rfc
Closed

RFC - Remove asURL() method and AppEnvironment base URL access#24333
mokagio wants to merge 5 commits intotrunkfrom
mokagio/remove-asURL-rfc

Conversation

@mokagio
Copy link
Contributor

@mokagio mokagio commented Mar 27, 2025

@kean @crazytonyli I need to move the convenience init for WordPressOrgRestApi init?(blog:) because it's implemented in Swift but used in Objective-C...

I have two suggestions:

  • Remove the asURL() usages that come from Alamofire
  • Bypass AppEnvironment to read the WordPress.com base URL

I open this PR as an RFC so it'll make more sense in code.

Keen to hear what you think..


This is part of #24165

@dangermattic
Copy link
Collaborator

1 Message
📖 This PR is still a Draft: some checks will be skipped.

Generated by 🚫 Danger

Comment on lines -10 to +15
return try? blog.url(withPath: "wp-json/")?.asURL()

guard let urlString = blog.url(withPath: "wp-json/") else {
return nil
}

return URL(string: urlString)
Copy link
Contributor Author

@mokagio mokagio Mar 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

asURL() comes from Alamofire

extension String: URLConvertible {
    /// Returns a `URL` if `self` can be used to initialize a `URL` instance, otherwise throws.
    ///
    /// - Returns: The `URL` initialized with `self`.
    /// - Throws:  An `AFError.invalidURL` instance.
    public func asURL() throws -> URL {
        guard let url = URL(string: self) else { throw AFError.invalidURL(url: self) }

        return url
    }
}

I makes sense as a util, but not if we need to carry Alamofire with us for it.

I considered reimplementing it is as something like:

    func asURL() throws -> URL {
        guard let url = URL(string: self) else { throw ToURLConversionError(string: self) }

        return url
    }

But then I realized that URL(string:) returns a URL for all string inputs I threw at it, see the test below in the diff for a little proof of concept.

Realistically, it's unlikely we'll have malformed URLs going through that code. But even if we did, URL(string:)'s behavior is such that it would not reject them, so there's little point in wrapping it in a throwing function...

My suggestion therefore is to get rid of these calls. At least in the code we want to move away from where Alamofire is already available.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My suggestion therefore is to get rid of these calls. At least in the code we want to move away from where Alamofire is already available.

Absolutely!

Btw, I recently reworked the remaining code that was using AlamofireImage and ultimately removed it. It doesn't seem like there is much that's stopping us now from removing Alamofire as well.

convenience init?(
blog: Blog,
userAgent: String = WPUserAgent.wordPress(),
wordPressComApiURL: URL = WordPressComRestApi.apiBaseURL
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before, we were using AppEnvironment.current.wordPressComApiBase but that's not available outside of the app targets.

Looking at the implementation, it looks like the only value of reading from there is because it can be changed at runtime somehow—but it would have to change before it's read in this init. Correct me if I'm wrong.

extension AppEnvironment {
/// Creates a new Environment, changing just a subset of the current global dependencies.
///
@discardableResult
static func replaceEnvironment(
appRatingUtility: AppRatingUtilityType = AppEnvironment.current.appRatingUtility,
contextManager: CoreDataStack = AppEnvironment.current.contextManager,
wordPressComApiBase: URL = AppEnvironment.current.wordPressComApiBase) -> AppEnvironment {

With that in mind and with the intention of moving this to WordPressData, then I think it makes sense to use the value it's initialized with:

wordPressComApiBase: URL = WordPressComRestApi.apiBaseURL) {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes total sense. AppEnvironment is largely unused (for now). It also appears to be a container for dependency injection and not a configuration manager, so wordPressComApiBase doesn't belong there.

@mokagio mokagio changed the title Add test to show URL(string:) behavior RFC - Remove asURL() method and AppEnvironment base URL access Mar 27, 2025
@mokagio
Copy link
Contributor Author

mokagio commented Mar 27, 2025

Thanks for the input @kean! I'll execute on this today then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants