How to use expectationForPredicate with a XCUIElementQuery UISwitch - uiswitch

How to write a UI Test (XCTestCase) that waits for a UISwitch to be enabled.
I added this code to one of my tests but it timed out:
let firstSwitch = XCUIApplication().switches.elementBoundByIndex(0)
_ = self.expectationForPredicate(
NSPredicate(format: "self.value = %#", enabled),
evaluatedWithObject: firstSwitch,
handler: nil)
self.waitForExpectationsWithTimeout(15.0, handler: nil)

Just replace self.value with self.value.boolValue:
let firstSwitch = XCUIApplication().switches.elementBoundByIndex(0)
_ = self.expectationForPredicate(
NSPredicate(format: "self.value.boolValue = %#", enabled),
evaluatedWithObject: firstSwitch,
handler: nil)
self.waitForExpectationsWithTimeout(15.0, handler: nil)

Related

swift 3 call observer with wrong value

i work with swift 3 for osx
i added this Observer in my MasterViewController: NotificationCenter.default.addObserver(self, selector: #selector(requestData), name: NSNotification.Name(rawValue: "requestData"), object: nil)
my fun requestData in the same MasterViewController:
func requestData(with predicate : NSPredicate? = nil) {
let appdelegate = NSApplication.shared().delegate as! AppDelegate
let context = appdelegate.persistentContainer.viewContext
let request = NSFetchRequest<Person>(entityName: "Person")
request.predicate = predicate
print(predicate)
do {
people = try context.fetch(request)
tableView.reloadData()
} catch { }
}
if i now call this observer from another view controller like this:
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "requestData"), object: nil)
the print result "print(predicate)" will show:
Optional(NSConcreteNotification 0x608000246150 {name = requestData})
but this is wrong.
predicate have to be in this case nil.
what do i wrong?

Swift 2 error handling of audio recording code

can someone please assist me? I have some code (which I know runs properly in Xcode 6) that is having difficulty executing in Xcode 7 (due to the changes in error handling for Swift 2). I tried to convert the code using the latest Swift syntax in Xcode 7, but no recommendations were offered. Any suggestions?
//Setup audio session
var session = AVAudioSession.sharedInstance()
session.setCategory(AVAudioSessionCategoryPlayAndRecord,error: nil)
//Initialize and prepare the recorder
audioRecorder = AVAudioRecorder(URL: filePath, settings: nil, error:nil)
audioRecorder.meteringEnabled = true;
audioRecorder.prepareToRecord()
audioRecorder.record()
}
#IBAction func stopAudio(sender: UIButton) {
recordingInProgress.hidden = true
//TODO: Stop recording the user's voice
audioRecorder.stop()
var audioSession = AVAudioSession.sharedInstance();
audioSession.setActive(false, error:nil)
}
The Error messages are for the following code:
session.setCategory(AVAudioSessionCategoryPlayAndRecord,error: nil)
Extra argument 'error' in call
audioRecorder = AVAudioRecorder(URL: filePath, settings: nil, error:nil)
Cannot find an initializer for type 'AVAudioRecorder' that accepts an argument list of type '(URL: NSURL?, settings: nil, error: nil)'
audioSession.setActive(false, error:nil)
****Extra argument 'error' in call****
try this class ive tested this and it works in the latest version of swift and Xcode
import UIKit
import AVFoundation
class RecordViewController: UIViewController {
required init(coder aDecoder: NSCoder) {
var baseString : String = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as! String
var pathComponents = [baseString, NSUUID().UUIDString + ".m4a"]
self.audioURL = NSURL.fileURLWithPathComponents(pathComponents)!
var session = AVAudioSession.sharedInstance()
session.setCategory(AVAudioSessionCategoryPlayAndRecord, error: nil)
var recordSettings: [NSObject : AnyObject] = Dictionary()
recordSettings[AVFormatIDKey] = kAudioFormatMPEG4AAC
recordSettings[AVSampleRateKey] = 44100.0
recordSettings[AVNumberOfChannelsKey] = 2
self.audioRecorder = AVAudioRecorder(URL: self.audioURL, settings: recordSettings, error: nil)
self.audioRecorder.meteringEnabled = true
self.audioRecorder.prepareToRecord()
// Super init is below
super.init(coder: aDecoder)
}
you will then have to implement your buttons of course
something like this
#IBAction func recordPressed(sender: AnyObject) {
if self.audioRecorder.recording {
self.audioRecorder.stop()
self.recordButton.setTitle("RECORD", forState: UIControlState.Normal)
self.playButton.enabled = true
} else {
var session = AVAudioSession.sharedInstance()
session.setActive(true, error: nil)
self.audioRecorder.record()
self.recordButton.setTitle("PLAY", forState: UIControlState.Normal)
self.playButton.enabled = false
}
}
#IBAction func playPressed(sender: AnyObject) {
self.audioPlayer = AVAudioPlayer(contentsOfURL: self.audioURL, error: nil)
audioPlayer.play()
}
}

Swift "Thread 1: EXC_BAD_INSTRUCTION(code=EXC-I386_INVOP,subcode=0x0)" when using keyBoardWillShow

I am trying to let a user click on a cell in a tale view and it brings them to the DetailViewController. The only problem is that each time I try to do this the error "Thread 1: EXC_BAD_INSTRUCTION(code=EXC-I386_INVOP,subcode=0x0)" comes up.
This is in the DetailViewController:
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyBoardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
//FIRST ERROR HERE
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyBoardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
//SECOND ERROR HERE
/* Setup the contentInsets */
self.tableView.contentInset = UIEdgeInsetsZero
self.tableView.scrollIndicatorInsets = UIEdgeInsetsZero
self.edgesForExtendedLayout = UIRectEdge.None
/* Make sure the content doesn't go below tabbar/navbar */
self.extendedLayoutIncludesOpaqueBars = true
self.automaticallyAdjustsScrollViewInsets = false
/* Setup Map */
let geo = party?.objectForKey("location") as PFGeoPoint
//THIRD ERROR HERE
let coordinate = CLLocationCoordinate2D(latitude: geo.latitude, longitude: geo.longitude)
let reg = MKCoordinateRegionMakeWithDistance(coordinate, 1500, 1500)
self.mapView.setRegion(reg, animated: true)
self.mapView.showsUserLocation = true
if(party?.objectForKey("comments") != nil) {
comments = party?.objectForKey("comments") as? [String]
}
println(party)
println(party?.objectForKey("Name"))
self.nameLabel.text = party?.objectForKey("Name") as? String
// Do any additional setup after loading the view.
}
The other issue is that even after I put // in front of keyBoardWillShow the same error happens for keyBoardWillHide. And if I cover that I get once again the same error trying to setup a map view. As you can probably see, I am just getting into swift, xcode, and Parse and I have no idea what I really and doing. Any help is appreciated.

AVRecorder and AVPlayer in swift

All ,
I need to create a sample audio player and recorder, its not erroring but its not playing and perhaps not recording.. any ideas ?
#IBAction func Play(AnyObject)
{
println ("Play")
let path = NSBundle.mainBundle().pathForResource("171010", ofType:"m4a")
let fileURL = NSURL(fileURLWithPath: path)
player = AVAudioPlayer(contentsOfURL: outputFileURL, error: nil)
player.prepareToPlay()
player.delegate = self
player.play()
}
#IBAction func Record(AnyObject)
{
filename = "171010.m4a"
let paths: NSArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
var pathComponents = [paths.lastObject as String, filename as String]
outputFileURL = NSURL.fileURLWithPathComponents(pathComponents)
settings.setValue(kAudioFormatMPEG4AAC, forKey: AVFormatIDKey)
settings.setValue(44100.0, forKey: AVSampleRateKey)
settings.setValue(2, forKey: AVNumberOfChannelsKey)
recorder = AVAudioRecorder(URL: outputFileURL, settings: settings, error: &error)
recorder.delegate = self;
recorder.prepareToRecord()
recorder.record()
}
#IBAction func Stop(AnyObject)
{
recorder.stop()
println("Stop")
}
and the globals at the top are :
class MainMenu: UIViewController , AVAudioRecorderDelegate , AVAudioPlayerDelegate {
var filename: String!
var outputFileURL: NSURL!
var recorder: AVAudioRecorder!
var error: NSError?
var settings: NSMutableDictionary = NSMutableDictionary()
var player : AVAudioPlayer! = nil
Any ideas ? I don't know if its recording and creating the file. As I am getting URL is nill on the playing function. This is wired up to a storyboard with buttons. Any help within this simple stuff in swift would be brilliant.
I have changed it to this and this should work ? Can anyone advise ?
#IBAction func Play(AnyObject)
{
println ("Play")
var audioPlayer = AVAudioPlayer()
filename = "171010.m4a"
let paths: NSArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
var pathComponents = [paths.lastObject as String, filename as String]
outputFileURL = NSURL.fileURLWithPathComponents(pathComponents)
audioPlayer = AVAudioPlayer(contentsOfURL: outputFileURL, error: nil)
audioPlayer.prepareToPlay()
audioPlayer.delegate = self
audioPlayer.play()
}
#IBAction func Record(AnyObject)
{
filename = "171010.m4a"
let paths: NSArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
var pathComponents = [paths.lastObject as String, filename as String]
outputFileURL = NSURL.fileURLWithPathComponents(pathComponents)
settings.setValue(kAudioFormatMPEG4AAC, forKey: AVFormatIDKey)
settings.setValue(44100.0, forKey: AVSampleRateKey)
settings.setValue(2, forKey: AVNumberOfChannelsKey)
recorder = AVAudioRecorder(URL: outputFileURL, settings: settings, error: &error)
recorder.delegate = self;
recorder.prepareToRecord()
recorder.record()
}
The player needs to be an ivar so it isn't popped off the stack before playing.
Here is a github project with a functioning recorder if you need more info.
Also, the convention is to start function names with a lowercase character.

Can someone explain dispatch_async() for me in this scenario

I had the following method in a separate class:
class API: NSObject {
var data = NSData()
var delegate: APIProtocol?
func getItems(callback: (Array<Image>) -> ()) {
let urlPath: NSString = "http://localhost:3000/files"
let url = NSURL(string: urlPath)
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Accept")
let config = NSURLSessionConfiguration.defaultSessionConfiguration() as NSURLSessionConfiguration
let session = NSURLSession(configuration: config) as NSURLSession
var dataTask = NSURLSessionDataTask()
dataTask = session.dataTaskWithRequest(request) { (data, response, error) in
if (error == nil) {
println("API at URL \(url)")
let responseArray = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: nil) as NSArray
var images = Image[]()
for item: AnyObject in responseArray {
var location = Image(dict: item as NSDictionary)
images.append(location)
}
var img = images[0] as Image
callback(images)
//self.delegate?.didReceiveResponse(responseArray)
}
}
dataTask.resume()
}
}
I couldn't get my tableView to reload when calling self.tableView.reloadData() inside the callback() until I added the dispatch_async() around it.
My questions are:
1) Why wouldn't it work without it and is it the proper thing for me to do now that it's refreshing the tableView correctly?
2) Is there another way to get it working without having to add the dispatch on the main queue?
api.getItems() { (theArray) in
dispatch_async(dispatch_get_main_queue(), {
self.images = theArray
self.tableView.reloadData()
if (viaPullToRefresh) {
self.refreshControl.endRefreshing()
}
})
}
When creating a NSURLSession you can specify the delegate/completion queue. If you don't specify a queue
the session creates a serial operation queue for performing all
delegate method calls and completion handler calls.
So this means that your callbacks are called on a private serial queue. Now, all UI must be updated on the main queue, this is why tableView.reloadData() wasn't working.
To remove the dispatch call to the main_queue create the session like this
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: nil, delegateQueue: NSOperationQueue.mainQueue())

Resources