I want to download modified Info.plist file into the Documents folder in the runtime and make iOS to read some value from it.(Something like swizzling) I know it's impossible to write on the main Info.plist file in the App bundle but I want to set some value like: "Privacy - Location When In Use Usage Description" or "UIApplicationShortcutItemTitle" I've seen some apps have done this. I was wondering how can I implement it.
I've done some work to replace the object:
class IconInfoBundle: Bundle {
override var infoDictionary: [String : Any]? {
let bundle: Bundle? = objc_getAssociatedObject(self, &iconInfoBundleKey) as? Bundle
var propertyListFormat = PropertyListSerialization.PropertyListFormat.xml //Format of the Property List.
let plistPath: String? = bundle!.path(forResource: "Info", ofType: "plist")! //the path of the data
let plistXML = FileManager.default.contents(atPath: plistPath!)!
let plistDictonatry = try! PropertyListSerialization.propertyList(from: plistXML, options: .mutableContainersAndLeaves, format: &propertyListFormat) as? [String:Any]
return plistDictonatry
}
}
extension Bundle {
class func setIconFromInfoPlist() {
// TODO: - Dispatch once
object_setClass(Bundle.main, IconInfoBundle.self)
let bundleDisplaced = Bundle.displace
objc_setAssociatedObject(Bundle.main,&iconInfoBundleKey, bundleDisplaced,.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
and what is Bundle.displace?
extension Bundle {
static var name: String {
return Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as! String
}
static var displace: Bundle {
guard let documentsDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first else {
fatalError("Couldn't find Documents path")
}
let path = documentsDirectory.appending("/\(Bundle.name).bundle")
guard FileManager.default.fileExists(atPath: path) else {
fatalError("There is no file in this PATH:\(path)")
}
guard let bundle = Bundle(path: path) else {
fatalError("the file is not like a Bundle")
}
return bundle
}
}
I've called Bundle.setIconFromInfoPlist()
in the main.swift (the very first place I can run my code)
but the problem is the Location access message is not changing to what I set in Info.plist (located in the Documents folder)
Look at this property in one app from App Store:
Contact Permission Message in the info.plist from App main bundle