Repository: realm/realm-swift
File: Realm/RLMApp.mm (Objective-C++)

Code before:
- (RLMUser *)currentUser {
    if (auto user = _app->sync_manager()->get_current_user()) {
        return [[RLMUser alloc] initWithUser:user app:self];
    }
    return nil;
}

- (RLMEmailPasswordAuth *)emailPasswordAuth {
    return [[RLMEmailPasswordAuth alloc] initWithApp: self];
}

- (NSString *)baseUrl {
    return getOptionalString(_app->get_base_url()) ?: RLMStringViewToNSString(_app->default_base_url());
}

- (void)updateBaseUrl:(NSString *)baseURL
           completion:(RLMOptionalErrorBlock)completionHandler {
    auto completion = ^(std::optional<app::AppError> error) {
        if (error) {
            return completionHandler(makeError(*error));
        }

        completionHandler(nil);
    };
    return RLMTranslateError([&] {
        return _app->update_base_url(baseURL.UTF8String, completion);
    });
}

- (void)loginWithCredential:(RLMCredentials *)credentials
                 completion:(RLMUserCompletionBlock)completionHandler {
    auto completion = ^(std::shared_ptr<SyncUser> user, std::optional<app::AppError> error) {
        if (error) {
            return completionHandler(nil, makeError(*error));
        }

        completionHandler([[RLMUser alloc] initWithUser:user app:self], nil);
    };
    return RLMTranslateError([&] {
        return _app->log_in_with_credentials(credentials.appCredentials, completion);
    });
}

- (RLMUser *)switchToUser:(RLMUser *)syncUser {
    return RLMTranslateError([&] {
        return [[RLMUser alloc] initWithUser:_app->switch_user(syncUser._syncUser) app:self];
    });
}

- (RLMPushClient *)pushClientWithServiceName:(NSString *)serviceName {
    return RLMTranslateError([&] {

Review comment (suggestion):
Core doesn't seem to strip the trailing `/` from that string and if you supply a new url with a trailing `/`, the error message is super weird, so I'd suggest doing it just in case. Here's how it's done in .NET:

https://github.com/realm/realm-dotnet/pull/3587/files#diff-ca0367734388dc85b302d51f53b4d19f6329a26dc3f7b5d3db279305d21701e3R358

Code after:

- (RLMUser *)currentUser {
    if (auto user = _app->current_user()) {
        return [[RLMUser alloc] initWithUser:user];
    }
    return nil;
}

- (RLMEmailPasswordAuth *)emailPasswordAuth {
    return [[RLMEmailPasswordAuth alloc] initWithApp:_app];
}

- (NSString *)baseUrl {
    return getOptionalString(_app->get_base_url()) ?: RLMStringViewToNSString(_app->default_base_url());
}

- (void)updateBaseURL:(NSString * _Nullable)baseURL completion:(nonnull RLMOptionalErrorBlock)completionHandler {
    auto completion = ^(std::optional<app::AppError> error) {
        if (error) {
            return completionHandler(makeError(*error));
        }

        completionHandler(nil);
    };
    return RLMTranslateError([&] {
        NSString *url = (baseURL ?: @"");
        NSString *newUrl = [url stringByReplacingOccurrencesOfString:@"/" withString:@"" options:0 range:NSMakeRange(url.length-1, 1)];
        return _app->update_base_url(newUrl.UTF8String, completion);
    });
}

- (void)loginWithCredential:(RLMCredentials *)credentials
                 completion:(RLMUserCompletionBlock)completionHandler {
    auto completion = ^(std::shared_ptr<app::User> user, std::optional<app::AppError> error) {
        if (error) {
            return completionHandler(nil, makeError(*error));
        }

        completionHandler([[RLMUser alloc] initWithUser:user], nil);
    };
    return RLMTranslateError([&] {
        return _app->log_in_with_credentials(credentials.appCredentials, completion);
    });
}

- (RLMUser *)switchToUser:(RLMUser *)syncUser {
    RLMTranslateError([&] {
        _app->switch_user(syncUser.user);
    });
    return syncUser;
}