There are two aspects of this:
I don’t work for App Review, and so I can’t give definitive answers on their policy. However, I’ll come back to this once I’ve covered the technical stuff.
On the technical side, changing the user’s location is a relatively straightforward application of the System Configuration framework preferences API (SCPreferences
). To learn more that, and how it fits into the overall SC architecture, see System Configuration Programming Guidelines.
The good news here is that you can do this work using the higher-level SCNetworkSet
API, which is much nicer than messing around with SCPreferences
directly. At the end of this post I’ve included a small program that shows how to print a list of the current network sets (that is, the locations) with the current one highlighted.
[Just as an aside, Swift is really nice. I used to do a lot of work with SC framework and it was never fun to use. Swift makes it a lot easier.]
When it comes to making changes, you do that by calling SCPreferencesCommitChanges
and SCPreferencesApplyChanges
. These may or may not required user authorisation, depending on how the system is set up. If they do, you have some control over that by creating your preferences object with SCPreferencesCreateWithAuthorization
.
And that brings us back to the App Store. I’m not sure if these calls are blocked by the sandbox, but it’d be easy for you test that. If they are, then the App Store policy is irrelevant because all App Store apps must be sandboxed. If the sandbox does allow this then, yeah, you have a real policy question and that’s not something I can wade in to.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
import Foundation
import SystemConfiguration
// This `scCall(…)` function is based on the ideas explained in
// <https://developer.apple.com/forums/thread/710961>.
func scCall<Result>(_ body: () throws -> Result?) throws -> Result {
guard let r = try body() else {
let err = SCError()
throw NSError(domain: kCFErrorDomainSystemConfiguration as String, code: Int(err))
}
return r
}
func main() throws {
let prefs = try scCall { SCPreferencesCreate(nil, "Test776936" as NSString, nil) }
let currentSet = try scCall { SCNetworkSetCopyCurrent(prefs) }
let sets = try scCall { SCNetworkSetCopyAll(prefs) } as! [SCNetworkSet]
for set in sets {
let id = try scCall { SCNetworkSetGetSetID(set) } as String
let name = try scCall { SCNetworkSetGetName(set) } as String
let isCurrent = set == currentSet
print("\(isCurrent ? "*" : " ") \(id) '\(name)'")
}
}
try main()