I'm having trouble with In-App Purchases. The app is crashing in the following case:
Opening the view from NavController
Requesting the 2 SKProducts
Showing price of products on the labels
Closing View by going back in NavController
Opening the view from NavController again
Requesting the 2 SKProducts
Showing price of products on the labels
Buying one product with SKPaymentQueue.default().add(payment)
Crash with EXC_BAD_ACCESS
I've checked that the payment isn't nil. If I buy the product on the first open everything is working as it should. Any tips why it crashes only in this case?
Here is the code:
override func viewDidLoad() {
super.viewDidLoad()
SKPaymentQueue.default().add(self)
if SKPaymentQueue.canMakePayments(){
print("Enabled, Loading...")
let productId: NSSet = NSSet(objects: unlockPremiumId, disableAdsId)
let request: SKProductsRequest = SKProductsRequest(productIdentifiers: productId as! Set<String>)
request.delegate = self
request.start()
} else {
print("Please Enable IAP")
}
}
var SKProductList = [SKProduct]()
var currentSKProduct = SKProduct()
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
let myProducts = response.products
for product in myProducts {
if product.productIdentifier == unlockPremiumId {
if let productPrice = priceStringForProduct(item: product) {
premiumFeaturesBtn.setTitle(selectedLanguage.IAPPurchase + productPrice, for: .normal)
}
}
if product.productIdentifier == disableAdsId {
if let productPrice = priceStringForProduct(item: product) {
disableAdsBtn.setTitle(selectedLanguage.IAPPurchase + productPrice, for: .normal)
}
}
SKProductList.append(product)
}
disableAdsBtn.isEnabled = true
premiumFeaturesBtn.isEnabled = true
restoreBtn.isEnabled = true
}
#IBAction func disableAdsTapped(_ sender: UIButton) {
disableAdsBtn.isEnabled = false
for product in SKProductList {
let ProdId = product.productIdentifier
if ProdId == disableAdsId {
buyProduct(skpayment:SKPayment(product: product))
}
}
}
func buyProduct(skpayment:SKPayment) {
SKPaymentQueue.default().add(product)
}
Here is the Stack Trace, sorry for the formatting:
thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x18)
frame #0: 0x00000001108c394b libobjc.A.dylibobjc_msgSend + 11
frame #1: 0x000000011011b4cc StoreKit__NotifyObserverAboutChanges + 66
frame #2: 0x000000011289b268 CoreFoundationCFArrayApplyFunction + 72
frame #3: 0x000000011011b473 StoreKit-[SKPaymentQueue _notifyObserversAboutChanges:sendUpdatedDownloads:] + 148
frame #4: 0x0000000110119951 StoreKit`-[SKPaymentQueue addPayment:] + 313
frame #5: 0x000000010f57c2a8 AnatomyQuizzSettingsInAppPurchasesTableViewController.buyProduct(product=0x00006040000086c0, self=0x00007fbcbb090e00) at SettingsInAppPurchasesTableViewController.swift:114
frame #6: 0x000000010f57b9ac AnatomyQuizzSettingsInAppPurchasesTableViewController.disableAdsTapped(sender=0x00007fbcba473700, self=0x00007fbcbb090e00) at SettingsInAppPurchasesTableViewController.swift:88
frame #7: 0x000000010f57bc3c AnatomyQuizz#objc SettingsInAppPurchasesTableViewController.disableAdsTapped(_:) at SettingsInAppPurchasesTableViewController.swift:0
frame #8: 0x0000000114a57972 UIKit-[UIApplication sendAction:to:from:forEvent:] + 83
frame #9: 0x0000000114bd6c3c UIKit-[UIControl sendAction:to:forEvent:] + 67
frame #10: 0x0000000114bd6f59 UIKit-[UIControl _sendActionsForEvents:withEvent:] + 450
frame #11: 0x0000000114bd5e86 UIKit-[UIControl touchesEnded:withEvent:] + 618
frame #12: 0x0000000115047bad UIKit_UIGestureEnvironmentSortAndSendDelayedTouches + 5560
frame #13: 0x0000000115041a4d UIKit_UIGestureEnvironmentUpdate + 1506
frame #14: 0x000000011504141f UIKit-[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:] + 484
frame #15: 0x00000001150404cb UIKit-[UIGestureEnvironment _updateGesturesForEvent:window:] + 288
frame #16: 0x0000000114acef14 UIKit-[UIWindow sendEvent:] + 4102
frame #17: 0x0000000114a72365 UIKit-[UIApplication sendEvent:] + 352
frame #18: 0x00000001153bea1d UIKitdispatchPreprocessedEventFromEventQueue + 2809
frame #19: 0x00000001153c1672 UIKit__handleEventQueueInternal + 5957
frame #20: 0x00000001128f0101 CoreFoundation__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17
frame #21: 0x000000011298ff71 CoreFoundation__CFRunLoopDoSource0 + 81
frame #22: 0x00000001128d4a19 CoreFoundation__CFRunLoopDoSources0 + 185
frame #23: 0x00000001128d3fff CoreFoundation__CFRunLoopRun + 1279
frame #24: 0x00000001128d3889 CoreFoundationCFRunLoopRunSpecific + 409
frame #25: 0x00000001192c99c6 GraphicsServicesGSEventRunModal + 62
frame #26: 0x0000000114a565d6 UIKitUIApplicationMain + 159
frame #27: 0x000000010f6ac0f7 AnatomyQuizzmain at AppDelegate.swift:15
frame #28: 0x0000000117907d81 libdyld.dylibstart + 1
frame #29: 0x0000000117907d81 libdyld.dylib`start + 1
Related
I am trying to implement a table view that displays books information in every cell. I get this information from the API. Here is my code:
class ViewController: UIViewController {
#IBOutlet weak var allBooksTable: UITableView!
var bookList:myList? = nil {
didSet {
allBooksTable.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.allBooksTable.dataSource = self
self.allBooksTable.delegate = self
let url = URL(string: "https://ipvefa0rg0.execute-api.us-east-1.amazonaws.com/dev/books?lang=fr&term=self")!
var request = URLRequest(url: url)
request.setValue(
"jFXzWHx7SkK6",
forHTTPHeaderField: "api-key"
)
request.httpMethod = "GET"
let session = URLSession.shared
let task = session.dataTask(with: request) { (data, response, error) in
if let error = error {
print(error.localizedDescription)
} else if let data = data {
do {
let decodedData = try JSONDecoder().decode(myList.self,
from: data)
self.bookList = decodedData
print("user: ", decodedData.list[0].imageLinks.thumbnail)
print("===================================")
} catch let DecodingError.dataCorrupted(context) {
print(context)
} catch let DecodingError.keyNotFound(key, context) {
print("Key '\(key)' not found:", context.debugDescription)
//print("codingPath:", context.codingPath)
} catch let DecodingError.valueNotFound(value, context) {
print("Value '\(value)' not found:", context.debugDescription)
print("codingPath:", context.codingPath)
} catch let DecodingError.typeMismatch(type, context) {
print("Type '\(type)' mismatch:", context.debugDescription)
print("codingPath:", context.codingPath)
} catch {
print("error: ", error)
}
} else {
// Handle unexpected error
}
}
task.resume()
}
}
extension ViewController: UITableViewDataSource , UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 200
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell") as! bookTableViewCell
cell.bookName.text = bookList?.list[indexPath.row].title
if bookList?.list[indexPath.row].imageLinks.smallThumbnail != nil{
//cell.img.load(url: (bookList?.list[indexPath.row].imageLinks.smallThumbnail)!)
print((bookList?.list[indexPath.row].imageLinks.smallThumbnail)!)
cell.img.downloaded(from: (bookList?.list[indexPath.row].imageLinks.smallThumbnail)!)
}
return cell
}
}
extension UIImageView {
func downloaded(from url: URL, contentMode mode: UIView.ContentMode = .scaleAspectFit) {
contentMode = mode
URLSession.shared.dataTask(with: url) { data, response, error in
guard
let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
let data = data, error == nil,
let image = UIImage(data: data)
else { return }
DispatchQueue.main.async() { [weak self] in
self?.image = image
}
}.resume()
}
func downloaded(from link: String, contentMode mode: UIView.ContentMode = .scaleAspectFit) {
guard let url = URL(string: link) else { return }
downloaded(from: url, contentMode: mode)
}
}
When I run the app, it only shows my the first book and then crashes with the following error.
2020-10-15 23:12:00.953424+1100 MSA[50129:2517792] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff2043a126 __exceptionPreprocess + 242
1 libobjc.A.dylib 0x00007fff20177f78 objc_exception_throw + 48
2 CoreAutoLayout 0x00007fff58010d41 -[NSISEngine tryToOptimizeReturningMutuallyExclusiveConstraints] + 0
3 CoreAutoLayout 0x00007fff58010fcd -[NSISEngine withBehaviors:performModifications:] + 25
4 UIKitCore 0x00007fff24ac64ad -[UIView(AdditionalLayoutSupport) _recursiveUpdateConstraintsIfNeededCollectingViews:forSecondPass:] + 112
5 UIKitCore 0x00007fff24ac6136 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededCollectingViews:forSecondPass:] + 827
6 UIKitCore 0x00007fff24ac6a08 __100-[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededWithViewForVariableChangeNotifications:]_block_invoke + 85
7 UIKitCore 0x00007fff24ac6594 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededWithViewForVariableChangeNotifications:] + 154
8 UIKitCore 0x00007fff24ac7482 -[UIView(AdditionalLayoutSupport) _updateConstraintsAtEngineLevelIfNeededWithViewForVariableChangeNotifications:] + 393
9 UIKitCore 0x00007fff24ba9ad6 -[UIView _updateConstraintsAsNecessaryAndApplyLayoutFromEngine] + 275
10 UIKitCore 0x00007fff24bbda37 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2979
11 QuartzCore 0x00007fff27a3dd87 -[CALayer layoutSublayers] + 258
12 QuartzCore 0x00007fff27a44239 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 575
13 UIKitCore 0x00007fff24ba8fe9 -[UIView(Hierarchy) layoutBelowIfNeeded] + 573
14 UIKitCore 0x00007fff24bb0479 +[UIView(Animation) performWithoutAnimation:] + 84
15 UIKitCore 0x00007fff248954d0 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 1300
16 UIKitCore 0x00007fff2485e8bb -[UITableView _updateVisibleCellsNow:] + 2942
17 UIKitCore 0x00007fff2487e6e6 -[UITableView layoutSubviews] + 237
18 UIKitCore 0x00007fff24bbd9ce -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2874
19 QuartzCore 0x00007fff27a3dd87 -[CALayer layoutSublayers] + 258
20 QuartzCore 0x00007fff27a44239 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 575
21 QuartzCore 0x00007fff27a4ff91 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 65
22 QuartzCore 0x00007fff27990078 _ZN2CA7Context18commit_transactionEPNS_11TransactionEdPd + 496
23 QuartzCore 0x00007fff279c6e13 _ZN2CA11Transaction6commitEv + 783
24 QuartzCore 0x00007fff279c7616 _ZN2CA11Transaction14release_threadEPv + 210
25 libsystem_pthread.dylib 0x00007fff5dcda054 _pthread_tsd_cleanup + 551
26 libsystem_pthread.dylib 0x00007fff5dcdc512 _pthread_exit + 70
27 libsystem_pthread.dylib 0x00007fff5dcd9ddd _pthread_wqthread_exit + 77
28 libsystem_pthread.dylib 0x00007fff5dcd8afc _pthread_wqthread + 481
29 libsystem_pthread.dylib 0x00007fff5dcd7b77 start_wqthread + 15
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Could you please help me to understand what's going on here? I have looked over for similar threads, but most of the solutions are specific to the question.
if a UIElement getting update in background thread thats why applications getting crashed so whenever you want to update UI you need to update that UI Element in main thread, and your session data task is running in background thread and there you set the value bookList but when bookList is set there is an property observer which is reload the tableview in background thread so there is two solutions.
inside your api calling functions you need to set the property in main thread like this:-
DispatchQueue.main.async {
self.bookList = decodedData
}
inside your property observer you need to do like that
var bookList:myList? = nil {
didSet {
DispatchQueue.main.async {
allBooksTable.reloadData()
}
}
}
Enjoy:-
The issue is that you set bookList from a background thread (since URLSession.dataTask calls its completion on a background thread) and in the didSet of bookList, you update the UI. You should dispatch the UI update to the main thread.
var bookList:myList? = nil {
didSet {
DispatchQueue.main.async {
allBooksTable.reloadData()
}
}
}
You can set the bookList on main thread like below...
DispatchQueue.main.async {
self.bookList = decodedData
}
I run a mobile app project using Swift, SwiftUI and Cloud Firestore where I need to find users based on their different settings/preferences. I have solved this by using a collectionGroup query. But sometimes (maybe 1 out of 10 times) the query crashes without any (for me) understandable error message. The composite indexes have been created using the http links provided from XCode.
This is the function I use:
func getUsersFromActivityPrefs(genders:[String], activities:[Int],skillScore_min:Int, skillScore_max:Int,completion:#escaping ([String]) -> ()) {
var matchUsers = [String]()
var count = 0
let db = Firestore.firestore()
for gender in genders {
for activity in activities {
let dbRef = db.collectionGroup("activity_preferences")
.whereField("gender", isEqualTo: gender)
.whereField("activityid", isEqualTo: activity)
.whereField("status", isEqualTo: true)
.whereField("skill_score", isGreaterThanOrEqualTo: skillScore_min)
.whereField("skill_score", isLessThanOrEqualTo: skillScore_max)
.limit(to: 100)
dbRef.getDocuments {( snap, err) in
count+=1
if err != nil {
print(err!.localizedDescription)
}
for i in snap!.documentChanges{
let uid = i.document.get("uid") as? String ?? ""
if uid != "" && !matchUsers.contains(uid) {
matchUsers.append(uid)
if matchUsers.count == 100 {
count = genders.count * activities.count
completion(matchUsers) //escaping completion handler
return
}
}
}
if count == genders.count * activities.count {
completion(matchUsers)
return
}
}
}
}
}
I have attached the trace log and the crash message from XCode. Im using the latest version of Firebase SDK and deployment target is iOS14.
This is the trace log I get:
thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x4f)
frame #0: 0x00007fff4b80dd66 AttributeGraphAG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 322 frame #1: 0x00007fff4b81f1a5 AttributeGraphAGGraphGetValue + 203
frame #2: 0x00007fff55e7ffab SwiftUISwiftUI.DynamicBody.phase.getter : SwiftUI._GraphInputs.Phase + 27 frame #3: 0x00007fff55e80176 SwiftUISwiftUI.DynamicBody.updateValue() -> () + 294
frame #4: 0x00007fff55b9583a SwiftUIpartial apply forwarder for implicit closure #2 (Swift.UnsafeMutableRawPointer, __C.AGAttribute) -> () in implicit closure #1 (A1.Type) -> (Swift.UnsafeMutableRawPointer, __C.AGAttribute) -> () in closure #1 () -> (Swift.UnsafeMutableRawPointer, __C.AGAttribute) -> () in closure #1 (Swift.UnsafePointer<A1>) -> AttributeGraph.Attribute<A> in AttributeGraph.Attribute.init<A where A == A1.Value, A1: AttributeGraph.StatefulRule>(A1) -> AttributeGraph.Attribute<A> + 26 frame #5: 0x00007fff4b808d03 AttributeGraphAG::Graph::UpdateStack::update() + 505
frame #6: 0x00007fff4b809199 AttributeGraphAG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335 frame #7: 0x00007fff4b80d8e8 AttributeGraphAG::Graph::value_ref(AG::AttributeID, AGSwiftMetadata const*, bool*) + 130
frame #8: 0x00007fff4b81f1f3 AttributeGraphAGGraphGetValue + 281 frame #9: 0x00007fff561aeeb7 SwiftUISwiftUI.GraphHost.updatePreferences() -> Swift.Bool + 39
frame #10: 0x00007fff55c9a8cf SwiftUISwiftUI.ViewGraph.updateOutputs(at: SwiftUI.Time) -> () + 95 frame #11: 0x00007fff5611310c SwiftUIclosure #1 () -> () in (extension in SwiftUI):SwiftUI.ViewRendererHost.render(interval: Swift.Double, updateDisplayList: Swift.Bool) -> () + 1308
frame #12: 0x00007fff56112327 SwiftUI(extension in SwiftUI):SwiftUI.ViewRendererHost.render(interval: Swift.Double, updateDisplayList: Swift.Bool) -> () + 343 frame #13: 0x00007fff55ba07de SwiftUIclosure #1 () -> () in SwiftUI._UIHostingView.requestImmediateUpdate() -> () + 62
frame #14: 0x00007fff562739ae SwiftUIreabstraction thunk helper from #escaping #callee_guaranteed () -> () to #escaping #callee_unowned #convention(block) () -> () + 14 frame #15: 0x0000000112ebd8ac libdispatch.dylib_dispatch_call_block_and_release + 12
frame #16: 0x0000000112ebea88 libdispatch.dylib_dispatch_client_callout + 8 frame #17: 0x0000000112eccf23 libdispatch.dylib_dispatch_main_queue_callback_4CF + 1152
frame #18: 0x00007fff203a8276 CoreFoundation__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9 frame #19: 0x00007fff203a2b06 CoreFoundation__CFRunLoopRun + 2685
frame #20: 0x00007fff203a1b9e CoreFoundationCFRunLoopRunSpecific + 567 frame #21: 0x00007fff2b773db3 GraphicsServicesGSEventRunModal + 139
frame #22: 0x00007fff24660af3 UIKitCore-[UIApplication _run] + 912 frame #23: 0x00007fff24665a04 UIKitCoreUIApplicationMain + 101
frame #24: 0x000000010db84a5b Sparringmain at AppDelegate.swift:14:7 frame #25: 0x00007fff20257415 libdyld.dylibstart + 1
Attachments:
Crash in XCode 1
Composite index 2
func getUsersFromActivityPrefs(genders: [String], activities: [Int], skillScore_min: Int, skillScore_max: Int, completion: #escaping ([String]) -> Void) {
var matchUsers = [String]()
var count = 0
let db = Firestore.firestore()
let dispatch = DispatchGroup() // instantiate dispatch group outside loop
for gender in genders {
for activity in activities {
dispatch.enter() // enter group on each iteration
let dbRef = db.collectionGroup("activity_preferences")
.whereField("gender", isEqualTo: gender)
.whereField("activityid", isEqualTo: activity)
.whereField("status", isEqualTo: true)
.whereField("skill_score", isGreaterThanOrEqualTo: skillScore_min)
.whereField("skill_score", isLessThanOrEqualTo: skillScore_max)
.limit(to: 100)
dbRef.getDocuments {( snap, err) in
if let snap = snap {
count += 1
for doc in snap.documents {
if let uid = doc.get("uid") as? String,
!matchUsers.contains(uid) {
matchUsers.append(uid)
}
}
} else if let err = err {
print(err)
}
dispatch.leave() // always leave no matter what the db returned
}
}
}
/*
this is the group's completion handler and it's only
called once after all groups have entered and left
*/
dispatch.notify(queue: .main) {
completion(matchUsers)
}
}
I'm trying to create an app that:
Records my microphone and saves the output to a file
Plays the last recorded file
The playback should be manipulated with effects such as pitch-shift
So far I've got 1+2 down, but when I try to assign the AudioKit.output to my timePitch (or PitchShifter for that matter), I get an exception (see below). Can anyone help me out? Seems like if I set output to anything else than player, it crashes..
Disclaimer: I'm new to Swift, so please go easy on me and forgive my bad code
2017-11-08 16:39:58.637075+0100 mysoundplayer[41113:759865] *** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'player started when in a disconnected state'
*** First throw call stack:
(
0 CoreFoundation 0x0000000108a3c1ab __exceptionPreprocess + 171
1 libobjc.A.dylib 0x00000001047ddf41 objc_exception_throw + 48
2 CoreFoundation 0x0000000108a41372 +[NSException raise:format:arguments:] + 98
3 AVFAudio 0x000000010b3bb00e _Z19AVAE_RaiseExceptionP8NSStringz + 158
4 AVFAudio 0x000000010b4131ce _ZN21AVAudioPlayerNodeImpl9StartImplEP11AVAudioTime + 204
5 AVFAudio 0x000000010b412482 -[AVAudioPlayerNode playAtTime:] + 82
6 AudioKit 0x0000000103a2270d _T08AudioKit13AKAudioPlayerC4playySo11AVAudioTimeCSg2at_tFTf4gn_n + 1933
7 AudioKit 0x0000000103a1c78d _T08AudioKit13AKAudioPlayerC5startyyF + 45
8 mysoundplayer 0x00000001035dd3b8 _T010mysoundplayer14ViewControllerC14playLoadedFileyyF + 1832
9 mysoundplayer 0x00000001035dca1e _T010mysoundplayer14ViewControllerC4playySo8UIButtonCF + 46
10 mysoundplayer 0x00000001035dca6c _T010mysoundplayer14ViewControllerC4playySo8UIButtonCFTo + 60
11 UIKit 0x000000010507c275 -[UIApplication sendAction:to:from:forEvent:] + 83
12 UIKit 0x00000001051f94a2 -[UIControl sendAction:to:forEvent:] + 67
13 UIKit 0x00000001051f97bf -[UIControl _sendActionsForEvents:withEvent:] + 450
14 UIKit 0x00000001051f81e7 -[UIControl touchesBegan:withEvent:] + 282
15 UIKit 0x00000001050f1916 -[UIWindow _sendTouchesForEvent:] + 2130
16 UIKit 0x00000001050f32de -[UIWindow sendEvent:] + 4124
17 UIKit 0x0000000105096e36 -[UIApplication sendEvent:] + 352
18 UIKit 0x00000001059d9434 __dispatchPreprocessedEventFromEventQueue + 2809
19 UIKit 0x00000001059dc089 __handleEventQueueInternal + 5957
20 CoreFoundation 0x00000001089df231 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
21 CoreFoundation 0x0000000108a7ee41 __CFRunLoopDoSource0 + 81
22 CoreFoundation 0x00000001089c3b49 __CFRunLoopDoSources0 + 185
23 CoreFoundation 0x00000001089c312f __CFRunLoopRun + 1279
24 CoreFoundation 0x00000001089c29b9 CFRunLoopRunSpecific + 409
25 GraphicsServices 0x000000010cc289c6 GSEventRunModal + 62
26 UIKit 0x000000010507a5e8 UIApplicationMain + 159
27 mysoundplayer 0x00000001035e12a7 main + 55
28 libdyld.dylib 0x000000010aa49d81 start + 1
29 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Source code:
import AudioKit
import AudioKitUI
import UIKit
class ViewController: UIViewController {
var micMixer: AKMixer!
var recorder: AKNodeRecorder!
var player: AKAudioPlayer!
var tape: AKAudioFile!
var timePitch: AKTimePitch!
var pitchShifter: AKPitchShifter!
var mainMixer : AKMixer!
var loadedFile: AKAudioFile!
let mic = AKMicrophone()
var state = State.readyToRecord
enum State {
case readyToRecord
case recording
case readyToPlay
case playing
}
#IBAction func toggleRecord(_ sender: UIButton) {
switch state {
case .recording:
sender.setTitle("record", for: .normal)
state = .readyToRecord
do {
try player.reloadFile()
} catch {
print("Error reloading!")
}
let recordedDuration = player != nil ? player.audioFile.duration : 0
if recordedDuration > 0.0 {
recorder.stop()
let randomfilename:String = NSUUID().uuidString + ".m4a"
print("Filename: \(randomfilename)")
player.audioFile.exportAsynchronously(name: randomfilename, baseDir: .documents, exportFormat: .m4a, callback: {file, exportError in
if let error = exportError {
print("Export failed \(error)")
} else {
print("Export succeeded")
self.loadedFile = file
}
})
}
case .readyToRecord:
do {
try recorder.record()
sender.setTitle("stop", for: .normal)
state = .recording
} catch { print("Error recording!") }
default:
print("no")
}
}
#IBAction func play(_ sender: UIButton) {
playLoadedFile()
}
#IBAction func valueChanged(_ sender: UISlider) {
timePitch.pitch = Double(sender.value)
}
func playLoadedFile() {
do {
try player.replace(file: loadedFile)
player.start()
} catch { print("Error playing!") }
}
func exportedAudioFile(filename: String) {
print("yay")
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
AKAudioFile.cleanTempDirectory()
AKSettings.bufferLength = .medium
AKSettings.defaultToSpeaker = true
//inputPlot.node = mic
micMixer = AKMixer(mic)
mainMixer = AKMixer(player,timePitch)
pitchShifter = AKPitchShifter(player)
timePitch = AKTimePitch(player)
recorder = try? AKNodeRecorder(node: micMixer)
if let file = recorder.audioFile {
player = try? AKAudioPlayer(file: file)
}
AudioKit.output = timePitch // works with player
AudioKit.start()
print("mainMixer status: \(mainMixer.isStarted)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
It looks like mainMixer isn't connected to anything. Try changing AudioKit.output = timePitch to AudioKit.output = mainMixer.
As for best practices, get rid of any try?s. Use a do try catch and at least print the error.
if let file = recorder.audioFile {
do{
player = try AKAudioPlayer(file: file)
} catch {
print(error)
}
}
You’re attaching the player to the mixer before you create it. At the time where you give player to AKMixer(), it is nil. Move the mixer creation after the player assignment.
I am trying to add a new child to my node in firebase using this code:
#IBAction func likeButtonOnTouch(_ sender: Any) {
if ViewController.usersUid.count > 0 {
self.update()
}
}
func update() {
let child1: String = (FIRAuth.auth()?.currentUser?.uid)!
let ref = FIRDatabase.database().reference().child(child1).child("following")
let data1: [String:String] = [ViewController.usersUid[self.currentUser]: "true"]
ref.setValue(data1)
}
But when I press the button, my app crashes with this error:
thread 1 exc_bad_instruction (code=1 subcode=0x100ef5c78)
on this line:
ref.setValue(data1)
I have no idea what this means and how to fix it. The most interesting thing that the value has successfully added to my DB (!!!), but app crashes. Please give me an advice.
P.S. crash report:
* thread #1: tid = 0xb503, 0x0000000100f11c78 libdispatch.dylib`dispatch_group_leave + 76, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x100f11c78)
frame #0: 0x0000000100f11c78 libdispatch.dylib`dispatch_group_leave + 76
frame #1: 0x00000001000a36f8 Elite Club`thunk + 68 at ViewController.swift:0
frame #2: 0x00000001001bf8a4 Elite Club`__43-[FValueEventRegistration fireEvent:queue:]_block_invoke.57((null)=<unavailable>) + 88 at FValueEventRegistration.m:60 [opt]
frame #3: 0x0000000100f0d258 libdispatch.dylib`_dispatch_call_block_and_release + 24
frame #4: 0x0000000100f0d218 libdispatch.dylib`_dispatch_client_callout + 16
frame #5: 0x0000000100f12280 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 1200
frame #6: 0x000000019376e810 CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
frame #7: 0x000000019376c3fc CoreFoundation`__CFRunLoopRun + 1660
frame #8: 0x000000019369a2b8 CoreFoundation`CFRunLoopRunSpecific + 444
frame #9: 0x000000019514e198 GraphicsServices`GSEventRunModal + 180
frame #10: 0x00000001996e17fc UIKit`-[UIApplication _run] + 684
frame #11: 0x00000001996dc534 UIKit`UIApplicationMain + 208
frame #12: 0x00000001000c04b8 Elite Club`main + 140 at AppDelegate.swift:15
frame #13: 0x000000019267d5b8 libdyld.dylib`start + 4
if ViewController.usersUid[self.currentUser] does not exist please crash
Could you Try this way :
let data1: [String:String] = [(ViewController.usersUid[self.currentUser] ?? "") : "true"]
ref.setValue(data1) { (error, ref) -> Void in
}
more cleaner way :
if let currentuser = ViewController.usersUid[self.currentUser] {
let data1: [String:String] = [currentuser : "true"]
ref.setValue(data1) { (error, ref) -> Void in
}
}
After a day of working, I've figured out. First, you should sign out, and then sign in one more time. Here is my final code:
func update() {
do {
let ref = try FIRAuth.auth()?.signOut()
}
catch {}
let preferences = UserDefaults.standard
FIRAuth.auth()?.signIn(withEmail: preferences.object(forKey: "userName") as! String, password: preferences.object(forKey: "userPassword") as! String) { (user, error) in
if error == nil {
LoggingIn.userUID = (user?.uid)!
print(user?.uid ?? "not found")
print("You have successfully logged in")
let child1: String = (FIRAuth.auth()?.currentUser?.uid)!
let ref = FIRDatabase.database().reference().child(child1).child("following")
let data1: [String:String] = [ViewController.usersUid[self.currentUser] : "true"]
ref.setValue(data1) { (error, ref) -> Void in
}
} else {
}
}
}
I am new in Swift and I need your help.
lazy var profileImageView: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "Userprofile")
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFill
var tap = UITapGestureRecognizer(target: self, action: Selector(("handleSelectProfileImageView")))
imageView.addGestureRecognizer(tap)
imageView.isUserInteractionEnabled = true
return imageView
}()
func handleSelectProfileImageView() {
let picker = UIImagePickerController()
picker .delegate = self
picker.sourceType = UIImagePickerControllerSourceType.photoLibrary
self.present(picker, animated: true)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
profileImageView.image = image
}else
{
//ERROR
}
self.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
print("canceled picker")
dismiss(animated: true, completion: nil)
}
}
And then I get this error:
017-01-04 19:39:18.889 ChatUp[7484:136643] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ChatUp.LoginController handleSelectProfileImageView]: unrecognized selector sent to instance 0x7fe94cc0c0c0'
* First throw call stack:
(
0 CoreFoundation 0x000000010a41ad4b exceptionPreprocess + 171
1 libobjc.A.dylib 0x0000000109e7c21e objc_exception_throw + 48
2 CoreFoundation 0x000000010a48af04 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
3 CoreFoundation 0x000000010a3a0005 ___forwarding_ + 1013
4 CoreFoundation 0x000000010a39fb88 _CF_forwarding_prep_0 + 120
5 UIKit 0x000000010b48d409 -[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:] + 57
6 UIKit 0x000000010b4951a8 _UIGestureRecognizerSendTargetActions + 109
7 UIKit 0x000000010b492c77 _UIGestureRecognizerSendActions + 227
8 UIKit 0x000000010b491f03 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 891
9 UIKit 0x000000010b47df7e _UIGestureEnvironmentUpdate + 1395
10 UIKit 0x000000010b47d9c3 -[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:] + 521
11 UIKit 0x000000010b47cba6 -[UIGestureEnvironment _updateGesturesForEvent:window:] + 286
12 UIKit 0x000000010afc2c1d -[UIWindow sendEvent:] + 3989
13 UIKit 0x000000010af6f9ab -[UIApplication sendEvent:] + 371
14 UIKit 0x000000010b75c72d dispatchPreprocessedEventFromEventQueue + 3248
15 UIKit 0x000000010b755463 __handleEventQueue + 4879
16 CoreFoundation 0x000000010a3bf761 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17
17 CoreFoundation 0x000000010a3a498c __CFRunLoopDoSources0 + 556
18 CoreFoundation 0x000000010a3a3e76 __CFRunLoopRun + 918
19 CoreFoundation 0x000000010a3a3884 CFRunLoopRunSpecific + 420
20 GraphicsServices 0x000000010e329a6f GSEventRunModal + 161
21 UIKit 0x000000010af51c68 UIApplicationMain + 159
22 ChatUp 0x000000010845d42f main + 111
23 libdyld.dylib 0x000000010d1c368d start + 1
24 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)