I have a private/public key pair and I'm trying to encrypt a String with either of them. The code is running on OSX 10.11 and Xcode 7.2
func encryptMessageWithKey(message: String, keyType: KeyType,
withCompletionBlock: (success: Bool, data: NSData?, error: AsymCryptoExceptions.Exceptions?)
-> Void) {
let uintData = [UInt8](message.utf8)
let sourceData = CFDataCreate(kCFAllocatorDefault, uintData, uintData.count)
let privKey = self.getPrivateKeyReference()!
var errorRef: Unmanaged<CFError>?
let encoder = SecEncryptTransformCreate(privKey, &errorRef)
SecTransformSetAttribute(encoder,
kSecPaddingKey,
kSecPaddingPKCS1Key,
&errorRef)
SecTransformSetAttribute(encoder,
kSecTransformInputAttributeName,
sourceData,
&errorRef)
var encryptedData = SecTransformExecute(encoder, &errorRef)
if (errorRef != nil) {
let error = errorRef!.takeRetainedValue()
print(error)
}
}
The above is failing miserably, causing the app to crash at runtime with EXEC_BAD_ACCESS. No errors, nothing.
My research has shown that there might be a bug related to explicitly specifying kSecPaddingPKCS1Key as opposed to NULL which will set the padding to PKCS1 by default. However, I wasn't able to set this value to NULL since Swift has replaced that with nil and that can't be used in this spot.
Even though this is a pretty old question, I will answer it to maybe save someone else some time :)
I had the same problem where SecTransformExecute gave an EXC_BAD_ACCESS error. I noticed that the error would only occur when I changed or cleaned the project and rebuilt the app, but not when I would run the same debug build.
In the end, signing the application with a development certificate is what solved it for me, since before the app could not use the key due to the different automatic signing identities provided by Xcode.
Related
I have tested with the debugger and both the Dictionary and the value I am interested in are not nil. When I enable the App Sandbox the app crashes, but when I disable it everything works ok. Is there something to do when using UserDefaults with Sandbox enabled?
Code where the crash occurs:
func getPreferenceSettings(_ aKey: String) -> Bool
{
var lastPreferenceSetting: Bool!
if let currentSetting: Dictionary<String, Bool> = UserDefaults.standard.object(forKey: "defaultValues") as? Dictionary<String,Bool>{
lastPreferenceSetting = currentSetting[aKey]! //crash at this line
}else{
//show error to the user
}
return lastPreferenceSetting
}
I am using Xcode 9.4
You have to check if both keys defaultValues and aKey exist. As the return value is non-optional return false as default value.
This code uses the dedicated method dictionary(forKey
func getPreferenceSettings(_ aKey: String) -> Bool
{
if let currentSetting = UserDefaults.standard.dictionary(forKey: "defaultValues"),
let lastPreferenceSetting = currentSetting[aKey] as? Bool {
return lastPreferenceSetting
} else {
//show error to the user
}
return false
}
The key value was nil (i was using the Release schemes instead of the Debug, that is why i was not able to see its value and assumed it was not nil). Also with the help of the debugger i was able to see that the key was never saved in the dictionary. The strange thing is that when disabling the Sandbox the crash doesn't occur. I have modified the method in the following way so it returns an optional and then the caller checks with optional binding if there is a key or not.
func getPreferenceSettings(_ aKey: String) -> Bool?
{
var lastPreferenceSetting: Bool?
if let currentSetting: Dictionary<String, Bool> = UserDefaults.standard.object(forKey: "defaultValues") as? Dictionary<String,Bool>{
lastPreferenceSetting = currentSetting[aKey]
}else{
//show error to the user
}
return lastPreferenceSetting
}
EDIT
#vadian
I was reading when to use correctly the ? type and it's commonly used to indicate the absence of a value for example the mid name of a Person. But in this case the preference property is always present in the project because it's hard coded by the developer (except, like happened to me when i forgot to add it to the UserDefaults and had first to clear it before update the dictionary with the new key ). If i understand correctly, from what you have write, i should return an Bool? value and then check with optional binding in the caller method if it's nil or not; this should be done not only for the mid name case for the user side but also for the developer side because there could be another developer that could pass a wrong aKey, right?
Also is it correct to declare the lastPreferenceSetting as ?, because if i use a default value and the if let evaluate to false, the function could return not the expected value.
I'm making an app to track your sleep by getting any movement of the iPhone. I searched everywhere and there are many ways you can get data from this but non worked. Here's my code.
func startManager() {
let manager = CMMotionManager()
manager.startAccelerometerUpdates()
let accelerometer = manager.accelerometerData
}
But manager.accelerometerData is nil. I also tried it with DeviceMotion, Gyro and UserAcceleration, non of them worked. I also tried this.
print(manager.isAccelerometerActive)
It printed false so I think this is the problem but I still cannot make it active.
I tried putting the let manager = CMMotionManager() to the top and it still won't work.
I tried putting manager.startAccelerometerUpdates() in the ViewDidLoad and still doesn't work.
I also tried another way which is this.
manager.startAccelerometerUpdates(to: OperationQueue.main) { (data : CMAccelerometerData, error : Error) in
print(data)
}
but it gave me an error saying that I have to add as! CMAccelerometerHandler but after I added that it tell me to add it again.
I want to get raw value from the Accelerometer as x, y and z
(I imported CoreMotion)
I'm doing this using Swift 3 on XCode 8.2.1 and testing it on iPhone 6s.
In Swift3, you should use optional parameters in the handler
motionManager.startAccelerometerUpdates(
to: OperationQueue.main ,
withHandler:{ (data : CMAccelerometerData?, error : Error?) in
print(data)
})
I've got a simple class that uses an NSURLSession.
class test {
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration());
func f() {
dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_UTILITY.value), 0), { () -> Void in
var task = self.session.dataTaskWithRequest(request, completionHandler: { (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
if error != nil {
// cry
return;
}
var error: NSError? = nil;
var dict = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &error) as! Dictionary<String, String>;
// use dict
});
task.resume();
});
}
When I try to deserialize the data as JSON, the application crashes.
I've determined that the data seems to be of the right length but the content looks like garbage in the debugger, so it seems to me that the data object passed in is broken. Furthermore, I suspect some stack smashing as I can step through this completion handler and see that it's the attempt to deserialize the data that's crashing, but when the actual crash occurs, the stack in the debugger mentions nothing about the completion handler or any of my code.
I've seen several samples of using NSURLSession that look pretty much exactly like mine that just work. I tried using the shared session instead of making a new one, but that did not help either.
What is causing this crash?
Seems that the JSON was not actually all strings- I brainfarted and one of them was actually a number.
The real problem in the question is that Swift is completely worthless when handling the problem of force casts failing. Not only do you not get any kind of useful error at runtime that you could handle or recover from, but the debugging information presented when it occurs is completely misleading and points to totally the wrong place. You simply get a trap in a function without symbols with the wrong callstack.
Trying to follow along and code the Smashtag project while watching the Lecture 10 iTunes video.
When I add the dowloaded Twitter package to my Smashtag project, XCode couldn't find the Tweet class when I made reference to it in the TweetTableViewController.
Because of the problem described above, I added the four classes belonging to the Twitter package individually to the project. XCode found the four classes but adding them in this manner generated 11 compile errors.
I'm using XCode Version 6.3 (6D570) which is subsequent to the iOS 8.3 release.
Has anyone else encountered this issue?
Thank you for reading my question.
~ Lee
Possibly not the most-correct (read: best practice) way to do this, but I'm going to chalk it up to doing what it takes to finish the course.
I just went through the list of compile errors and changed the relevant properties to var instead of let. Constants can't be changed and in the new version of Swift they can only be instantiated once. So for the sake of not rewriting too much code, I chose to make certain properties vars instead of lets.
Other bugs I found following the iTunes U course:
The named ‘handler:’ argument needs the name explicitly in a few places.
The simulator will show "TwitterRequest: Couldn\'t discover Twitter account type.” until you go to Settings (inside the simulator) and set the Twitter account. At this point I had to reboot the device, as the call is made in the ViewDidLoad, and thus is only called the first time the view loads. (Alternatively, you could close out the app from the app switcher in the simulator and relaunch that way.)
Here is a gist with corrected code that you can use as a Twitter package that will work with the course and has fixes for the aforementioned bugs, minus the Twitter account setting:
https://gist.github.com/mattpetters/ccf87678ccce0c354398
As Christian R. Jimenez said, "I went to Settings in the Simulated iphone and add my Twitter Account. And everything works perfect." in http://cs193p.m2m.at/cs193p-lecture-10-table-view-winter-2015/. I just added my Twitter Account and tested it, it works!
I had similar problems with the Twitter packages using Swift 2.0 and Xcode 7.2
I'm very new to Swift, so there is a good chance the changes I made are not best practices, but the updated files do work: https://gist.github.com/awaxman11/9c48c0b4c622bffb879f.
For the most part I used Xcode's suggested changes. The two larger changes I made were:
In Tweet.swift I updated the the IndexedKeyword struct's init method to use advanceBy() instead of advance()
In TwitterRequest.swift I updated the signature of NSJSONSerialization to conform to the new error handling system
I've just had a big session fixing the Twitter package files for this same version of Xcode.
It seems that what has broken is that in this version of Swift, constants ('let x...') may only be initialized once, so if a constant is given a value in the declaration ('let x = false'), it may not be changed in the init() function. The Twitter package gives some constants initial values, but then changes the values in the init() function.
My solution to this was to follow the styles suggested in the current version of the Apple Swift language book: declare (many of) the constants as implicitly unwrapped optionals, unconditionally assign a value to them in the init() function (which value may be nil), then test whether any of them are nil, and, if so, return nil from init().
See https://developer.apple.com/library/mac/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html, click "On This Page" and choose "Failable Initializers"
Also, in TwitterRequest.swift, I needed to add the parameter name 'handler:' in a couple of calls to performTwitterRequest(request, handler: handler).
As an example of constant initialization, in MediaItem.swift:
<< Original Code >>
...
public let aspectRatio: Double = 0
...
init?(data: NSDictionary?) {
var valid = false
if let urlString = data?.valueForKeyPath(TwitterKey.MediaURL) as? NSString {
if let url = NSURL(string: urlString) {
self.url = url
let h = data?.valueForKeyPath(TwitterKey.Height) as? NSNumber
let w = data?.valueForKeyPath(TwitterKey.Width) as? NSNumber
if h != nil && w != nil && h?.doubleValue != 0 {
aspectRatio = w!.doubleValue / h!.doubleValue
valid = true
}
}
}
if !valid {
return nil
}
}
...
<< Updated code >>
...
public let aspectRatio: Double
...
init?(data: NSDictionary?) {
if let urlString = data?.valueForKeyPath(TwitterKey.MediaURL) as? NSString {
if let url = NSURL(string: urlString as String) {
self.url = url
let h = data?.valueForKeyPath(TwitterKey.Height) as? NSNumber
let w = data?.valueForKeyPath(TwitterKey.Width) as? NSNumber
if h != nil && w != nil && h?.doubleValue != 0 {
aspectRatio = w!.doubleValue / h!.doubleValue
return
}
}
}
return nil
}
...
My class has a property
var activeSquares = Dictionary <String, SKShapeNode> ()
I try to add and update values in the dictionary using
let squareNode = SKShapeNode(rectOfSize: CGSizeMake(80, 80), cornerRadius: 8)
activeSquares.updateValue(squareNode, forKey: "someUniqueDescription")
I also get the same crash if I use
activeSquares["someUniqueDescription"] = squareNode
But it is causing a crash when compiling
1. While emitting IR SIL function #_TFC14gamename9GameScene11addedSquarefS0_FCS_6SquareT_ for 'addedSquare' at /.../gamename/gamename/GameScene.swift:30:5
<unknown>:0: error: unable to execute command: Segmentation fault: 11
<unknown>:0: error: swift frontend command failed due to signal (use -v to see invocation)
Command /Applications/Xcode6-Beta2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 254
How do I properly use updateValue to add/update key/value pairs to my dictionary?
No sure if my solution fits here, but it could help. Seems there's something weird with subscription for NSDictionary. Not sure why, but it's defined as:
func objectForKeyedSubscript(key: NSCopying!) -> AnyObject!
so, if I'm not wrong it returns implicitly unwrapped optional, but should return optional, as far as there could be no value for a key. If you try to write:
if(dictionary["key"] != nil)
you'll get a compile error "AnyObject is not convertible to UInt8" while if you write:
if(dictionary["key"])
you don't get one.
The way I solved this issue was using optional unwrapping, so:
if(someBool && dictionary["key"]) // fine in beta 2, crash in beta 3-4
// turned to:
var hasValueForKey = false
if dictionary["key"]
{
hasValueForKey = true
}
if(someBool && hasValueForKey) // fine in beta 4
and:
var someArray : NSArray? = dictionary["key"]? as? NSArray // note ? after []
I guess there could be something with optionals and stuff for setting an object via subscript, it's defined as:
func setObject(obj: AnyObject!, forKeyedSubscript key: NSCopying!)
Maybe playing with optional unwrapping could help here as well.