I am stuck on this problem for many hours now and cannot find any solution. I have a p12 file which may contain some key pairs and also some certificates on their own. When I try the following code below, it gives me the list of only key pairs but not standalone certificates.
//open the p12 file
let bundle = NSBundle.mainBundle()
let path = bundle.pathForResource(“keychainfile”, ofType: "p12")!
let pdata : NSData = NSData.dataWithContentsOfMappedFile(path)! as NSData
let dictionary = [String(kSecImportExportPassphrase!.takeRetainedValue()) : “password”]
var keyref: Unmanaged<CFArray>?
var error = SecPKCS12Import(pdata, dictionary, &keyref)
//retrieve file entries
var list = keyref!.takeRetainedValue() as NSArray
println(list.count) // finds only key pairs
And also part 2 of my question is that how can I retrieve only one specific certificate (by alias or name) from the p12 file instead of getting all of the entries and then looping through to find the certificate I am looking for?
Related
Short version:
How to access an archived file in the bundle for unarchiving with unarchivedObject(ofClass:from:). The core issue is going from a path (string or URL) to Data which is required by the method.
Long version:
I have many plists containing SCNNode hierarchies stored as plists in bundle resources.
I was able to access them in Swift 3 with:
let fileName = MoleName.DNA_ideal_comps // retrieves String
let filePath = getFilePath(fileName)
guard let components = NSKeyedUnarchiver.unarchiveObject(withFile: filePath) as? [SCNNode] , components.count >= 4
else { // no value for this key, or not enough nodes
print("Couldn't find molecule (DNA_ideal_comps)")
return
} // [ atoms_A, bonds_A, atoms_B, bonds_B ]
scaleNode_2 = components[0] // DNA A
fixedNode_2 = components[1] // bonds
scaleNode_3 = components[2] // DNA B
fixedNode_3 = components[3] // bonds
// where filePath is:
func getFilePath(_ fileName: String) -> String {
if let path = Bundle.main.path(forResource: fileName, ofType: "plist") {
return path
}
return "path could not be found"
}
Here fileName is the name of the plist to retrieve, "DNA_ideal_comps" in this example. I created these independently of the active program due to the sheer volume of data; some of these plists contain over 30,000 items and there are about 90 total.
The above attempt to unarchive is deprecated and I've struggled to replace it. My best try so far:
guard let components = NSKeyedUnarchiver.unarchivedObject(ofClass: SCNNode.self, from: moleData), components.count >= 4
But this fails with Cannot convert value of type 'String' to expected argument type 'Data'. Unlike the method in Swift 3, there appears no way here to use the path of the object to retrieve it.
Is there a way to access these plists using this method? Is there another method more appropriate?
The core issue is going from a path (string or URL) to Data which is required by the method
Well, that's trivial enough; just call the Data initializer that reads from a file on disk. You would then decode the Data by calling NSKeyedUnarchiver.unarchivedObject(ofClass: SCNNode.self, from: theData).
https://developer.apple.com/documentation/foundation/data/3126626-init
https://developer.apple.com/documentation/foundation/nskeyedunarchiver/2983380-unarchivedobject
However, I'm confused as to why you're using NSKeyedUnarchiver to read a plist file. A plist file would be read using a PropertyListSerialization object.
https://developer.apple.com/documentation/foundation/propertylistserialization
I am new to swift/ios programming. I created a small app with settings but I can't seem to read value.
UserDefaults.standard.register(defaults: [String : Any]())
let settings = UserDefaults.standard;
let k = Bundle.main.infoDictionary!;
let b = settings.dictionaryRepresentation()
let val3 = Bundle.main.object(forInfoDictionaryKey: "digit_preference")
let value2 = settings.string(forKey: "digit_preference")
I can't find my settings "digit_preference" in Bundle.main.InfoDictionary or UserDefaults.standard.dictionaryRepresentation()
I can view my application settings properly in my phone. (Digits set to 2)
You need to cast the file data to a dictionary at first since the root structure is a Dictionary. This of course, if the file you're showing us is actually a .plist file; the following is how to access a .plist file, but the first step is also common for almost every other file type in your app bundle. What differs (say from .txt, .json, etc) is the second step depending on what you want to do..
Like so:
guard let idForResource = Bundle.main.path(forResource: "pListFilename", ofType: ".plist"),
let dict = NSDictionary(contentsOfFile: idForResource) as? [String: Any] else {
return }
Then you access the variable through dict like you would from any other dictionary.
Use case:
The app imports PKCS 12 file (with cert and private key) and saves it for later use.
Current status:
I was able to use SecImportExport.ImportPkcs12 in order to get SecIdentity and SecTrust objects.
Unfortunately I’m unable to assign SecIdentity and SecTrust object to SecRecord.
The code:
SecIdentity identityObject = ...;
SecTrust trustObject = ...;
SecRecord record = new SecRecord(SecKind.Identity);
record.Account = "Identity";
record.ValueData = ? //HOW TO CONVERT SecIdentity to NSData?
var res = SecKeyChain.Add(record);
You can use the SecRecord.SetValueRef (identityObject) which can be used to store keys (SecKey), certificates (SecCertificate) or identities.
I want to save data including string, number, date and coordinate in a file, and then transmit the file to a server. How to do this using swift?
And I'd like to process these data from the server in the future. What type of file is better to save them?
If i am getting this right you can use NSData
First you have to create a dictionary like this
var dictionary = [String:AnyObject]()
dictionary["age"] = 13
dictionary["name"] = "Mike"
Then you have to transform this dictionary into NSData using nsjsonserialization
if let data = NSJSONSerialization.dataWithJSONObject(dictionary, options:NSJSONWritingOptions(0), error:nil) as NSData? {
request.HTTPBody = data
}
But this is always depend on what the server is able to understand
Hope i helped. Sorry for my english
I am new to Swift and am using Xcode 6.
I am attempting to read data from the app's plist file, but it is not working.
The data.plist file is included in Xcode's Supporting Files group.
I am using the code below:
var dataList = NSDictionary(contentsOfURL:NSBundle.mainBundle().URLForResource("data", withExtension:"plist"))
however the NSURL:
NSBundle.mainBundle().URLForResource("data", withExtension:"plist")
always returns nil.
I don't know what is wrong.
Generally you would want to use this code to create your plist. This finds the the path to your plist and then moves it into the documents directory if it isn't already there. If you don't move it, you are not allowed to write to it, hence this chunk of code is vital. To fetch the information from the plist, use the second bit of code. Obviously if you have an array rather than a dictionary, you would have to alter it to deal with that.
var path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
path = path.stringByAppendingPathComponent("data.plist")
let fileManager = NSFileManager.defaultManager()
if !fileManager.fileExistsAtPath(path) {
let sourcePath = NSBundle.mainBundle().pathForResource("data", ofType: "plist")
fileManager.copyItemAtPath(sourcePath, toPath: path, error: nil)
}
.
let dict = NSMutableDictionary(contentsOfFile: path) as NSMutableDictionary