Why is the app crashing when doing a Fetch Request in Core Data - swift

Core Data is crashing when doing a fetch request but I can't understand why. The error is suggesting EXC_BAD_ACCESS but it doesn't always occur for this particular fetch request. Basically when I zoom in and out on the mapView (MKMapKit), it's at that point it crashes.
For my mapView I use the following code:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let userStatus = CoreDataUserLocationManagement().returnUsersLastKnownStatus()
if (annotation is MKUserLocation) && userStatus != 3 {
As you can see from the above, this is when I request the lastKnownStatus, but as mentioned it doesn't always crash.
This fetch crashes here
func returnUsersLastKnownStatus() -> Int16 {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "UsersLocationDetails")
do {
if let fetchResults = try managedObjectContext.fetch(fetchRequest) as? [UsersLocationDetails] {
if fetchResults.count != 0 {
let managedObject = fetchResults[0]
return managedObject.lastKnownStatus
}
}
}
catch {
print("Catch error retrieving last known status to Core Data")
}
return 3
}
The log is:
Printing description of fetchRequest:
(NSFetchRequest) fetchRequest = 0x0000000283a5be20 {
baseNSPersistentStoreRequest#0 = {
baseNSObject#0 = {
isa = NSFetchRequest
}
_affectedStores = 0x0000000000000000
}
_groupByProperties = 0x0000000000000000
_havingPredicate = 0x0000000000000000
_additionalPrivateIvars = 0x0000000281044100
_valuesToFetch = 0x0000000000000000
_entity = 0x0000000282684dc0 {
baseNSObject#0 = {
isa = NSEntityDescription
}
_cd_rc = 12
_snapshotClass = 0x000000028208a760
_versionHashModifier = 0x0000000000000000
_versionHash = some {
some = 0x0000000102faea90 {
baseNSData#0 = {
baseNSObject#0 = {
isa = _PFEncodedData
}
}
_aData = some {
some = 0x00000002811c7e60 {
baseNSData#0 = {
baseNSObject#0 = {
isa = _PFVMData
}
}
_cd_rc = 1732
_length = 40944
_payload = 0x0000000102fac000
}
}
_byteCount = 32
_reserved = 0
}
}
_model = some {
some = 0x00000002832a9400 {
baseNSObject#0 = {
isa = NSManagedObjectModel
}
_dataForOptimization = some {
some = 0x00000002811c7e60 {...}
}
_optimizationHints = 0x0000000102fb5850
_additionalPrivateIvars = 0x00000002811c0120
_entities = some {
some = 0x000000028239f9f0 {
baseNSKnownKeysDictionary1#0 = {
baseNSKnownKeysDictionary#0 = {
baseNSMutableDictionary#0 = {
NSDictionary = {
NSObject = {
isa = NSKnownKeysDictionary2
}
}
}
}
_cd_rc = 0
_count = 14
_keySearch = some {
some = 0x0000000102faeb10 {
baseNSKnownKeysMappingStrategy1#0 = {
baseNSKnownKeysMappingStrategy#0 = {
baseNSObject#0 = {
isa = NSKnownKeysMappingStrategy2
}
}
_cd_rc = -2128839072
_reserved64 = 2
_table = 0x0000000102faeb40
_length = 14
_reserved1 = 0x0000000000000000
_keys = 0x0000000102faec28
}
}
}
_values = {}
}
}
}
_configurations = 0x00000002811c0100 1 key/value pair
_fetchRequestTemplates = 0x0000000000000000
_versionIdentifiers = 0x00000002811c0140 1 element
}
}
_classNameForEntity = some {
some = 0x0000000102fad388 {
base_PFAbstractString#0 = {
baseNSString#0 = {
baseNSObject#0 = {
isa = _PFEncodedString
}
}
}
_cd_rc = 0
_length = 20
_sourceData = some {
some = 0x00000002811c7e60 {...}
}
}
}
_instanceClass = 0x00000002835b9b70
_name = some {
some = 0x0000000102fad388 {...}
}
_rootentity = 0x0000000282684dc0 {...}
_superentity = 0x0000000000000000
_subentities = 0x0000000000000000
_properties = some {
some = 0x00000002835b8720 {
baseNSKnownKeysDictionary1#0 = {
baseNSKnownKeysDictionary#0 = {
baseNSMutableDictionary#0 = {
NSDictionary = {
NSObject = {
isa = NSKnownKeysDictionary2
}
}
}
}
_cd_rc = 0
_count = 9
_keySearch = some {
some = 0x0000000102fb0bf0 {
baseNSKnownKeysMappingStrategy1#0 = {
baseNSKnownKeysMappingStrategy#0 = {
baseNSObject#0 = {
isa = NSKnownKeysMappingStrategy2
}
}
_cd_rc = -2128839072
_reserved64 = 2
_table = 0x0000000102fb0c20
_length = 9
_reserved1 = 0x0000000000000000
_keys = 0x0000000102fb0cd0
}
}
}
_values = {}
}
}
}
_propertyMapping = some {
some = 0x0000000102fb0bf0 {...}
}
_userInfo = 0x0000000000000000
_flattenedSubentities = 0x0000000281ff60d0 1 element
_kvcPropertyAccessors = 0x00000002832a92c0
_modelsReferenceIDForEntity = 13
}
_predicate = 0x0000000000000000
_sortDescriptors = 0x0000000000000000
_batchSize = 0
_fetchLimit = 0
_allocationSize = 0
_relationshipKeyPathsForPrefetching = 0x0000000000000000
}
Also just noticed this in Xcode:
(NSPersistentStoreRequest) CoreData.NSPersistentStoreRequest = <parent failed to evaluate: invalid load address>

So it turns out that it was this piece of code that code that was causing the issue. I have no idea why as the crash wasn't reporting this but as soon as I commented it out, it no longer crashes.
#IBAction func centerUserBtnTapped(_ sender: Any) {
let location = CLLocationCoordinate2D(latitude: locationManager.location?.coordinate.latitude ?? 0.0, longitude: locationManager.location?.coordinate.longitude ?? 0.0)
let span = MKCoordinateSpan.init(latitudeDelta: self.mapView.region.span.latitudeDelta, longitudeDelta: self.mapView.region.span.longitudeDelta)
let region = MKCoordinateRegion(center: location, span: span)
self.mapView.setRegion(region, animated: true)
self.mapView.setUserTrackingMode(.follow, animated: true)
}
Instead I simplified it to the normal approach:
#IBAction func centerUserBtnTapped(_ sender: Any) {
mapView.setUserTrackingMode(.follow, animated: true)
}

Related

Core Data Stack not saving or reverting to default?

I am making a quiz app. I already have a Core Data Stack that is working. However I want to have another Stack to store results and have tried to set it up in same way as first.
It operates across two View Controllers - UnitSelectionController (where 2nd Core Stack should be updating number of attempts, number correct etc.) from the QuizController which is logging attempts, correct etc.
I can see that the logging is working with attempts, correct increasing as the should be. The data is being transferred to the Stack Attribute variables successfully and I the saveContext is firing but changing view controller to load next quiz seems to be losing the data that should have been saved and I'm back where I started with default values.
class CoreDataStackResults {
static let persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "Results")
container.loadPersistentStores { (_, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
return container
}()
static var context: NSManagedObjectContext { return persistentContainer.viewContext }
class func saveContext2 () {
let context = persistentContainer.viewContext
guard context.hasChanges else {
return
}
do {
try context.save()
print("saveContext2 peformed")
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
Then in UnitSelection Controller within viewWillAppear I have:
let fetchResultsRequest: NSFetchRequest<Progression> = NSFetchRequest<Progression>(entityName: "Progression")
do{
let progression = try CoreDataStackResults.context.fetch(fetchResultsRequest)
self.progression = progression
} catch {}
loadResults()
labelResults()
loadResults and labelResults :
func loadResults(){
print("Results being loaded?")
let progression = Progression(context: CoreDataStackResults.context)
unitOneCount = progression.unitOneAttempts
print("unitOneCount = \(unitOneCount)")
unitTwoCount = progression.unitTwoAttempts
unitThreeCount = progression.unitThreeAttempts
unitFourCount = progression.unitFourAttempts
unitFiveCount = progression.unitFiveAttempts
unitSixCount = progression.unitSixAttempts
unitSevenCount = progression.unitSevenAttempts
unitEightCount = progression.unitEightAttempts
unitNineCount = progression.unitNineAttempts
unitOneCountCorrect = progression.unitOneCorrect
unitTwoCountCorrect = progression.unitTwoCorrect
unitThreeCountCorrect = progression.unitThreeCorrect
unitFourCountCorrect = progression.unitFourCorrect
unitFiveCountCorrect = progression.unitFiveCorrect
unitSixCountCorrect = progression.unitSixCorrect
unitSevenCountCorrect = progression.unitSevenCorrect
unitEightCountCorrect = progression.unitEightCorrect
unitNineCountCorrect = progression.unitNineCorrect
}
func labelResults(){
print("Results being labelled?")
UnitOneCountLabel.text = "Attempts: \(unitOneCount)"
UnitTwoCountLabel.text = "Attempts: \(unitTwoCount)"
UnitThreeCountLabel.text = "Attempts: \(unitThreeCount)"
UnitFourCountLabel.text = "Attempts: \(unitFourCount)"
UnitFiveCountLabel.text = "Attempts: \(unitFiveCount)"
UnitSixCountLabel.text = "Attempts: \(unitSixCount)"
UnitSevenCountLabel.text = "Attempts: \(unitSevenCount)"
UnitEightCountLabel.text = "Attempts: \(unitEightCount)"
UnitNineCountLabel.text = "Attempts: \(unitNineCount)"
}
If I change the default value in the Data Stack then the Count variables and Labels change accordingly.
Moving onto QuizController. Within viewWillAppear:
let fetchResultsRequest: NSFetchRequest<Progression> = NSFetchRequest<Progression>(entityName: "Progression")
do{
let progression = try CoreDataStackResults.context.fetch(fetchResultsRequest)
self.progression = progression
} catch {}
let progression = Progression(context: CoreDataStackResults.context)
unitOneCount = progression.unitOneAttempts
print("progression.unitOneAttempts = \(progression.unitOneAttempts)")
unitTwoCount = progression.unitTwoAttempts
unitThreeCount = progression.unitThreeAttempts
unitFourCount = progression.unitFourAttempts
unitFiveCount = progression.unitFiveAttempts
unitSixCount = progression.unitSixAttempts
unitSevenCount = progression.unitSevenAttempts
unitEightCount = progression.unitEightAttempts
unitNineCount = progression.unitNineAttempts
unitOneCountCorrect = progression.unitOneCorrect
unitTwoCountCorrect = progression.unitTwoCorrect
unitThreeCountCorrect = progression.unitThreeCorrect
unitFourCountCorrect = progression.unitFourCorrect
unitFiveCountCorrect = progression.unitFiveCorrect
unitSixCountCorrect = progression.unitSixCorrect
unitSevenCountCorrect = progression.unitSevenCorrect
unitEightCountCorrect = progression.unitEightCorrect
unitNineCountCorrect = progression.unitNineCorrect
Then as questions are answered, the newQuestionCode is used to determine which Unit question came from and starts to count attempts and correct answers for each Unit.
func allocateQuestion(){
questionUnit = Int16(Int(newQuestionCode.prefix(1)) ?? 0)
print ("Question Code = \(Int(newQuestionCode.prefix(1)) ?? 0)")
if (questionUnit == 1) {
unitOneCount += 1 }
if (questionUnit == 2){
unitTwoCount += 1 }
if (questionUnit == 3){
unitThreeCount += 1 }
if (questionUnit == 4){
unitFourCount += 1 }
if (questionUnit == 5){
unitFiveCount += 1 }
if (questionUnit == 6){
unitSixCount += 1 }
if (questionUnit == 7){
unitSevenCount += 1 }
if (questionUnit == 8){
unitEightCount += 1 }
if (questionUnit == 9){
unitNineCount += 1 }
print("Unit One Count = \(unitOneCount)")
print("Unit Two Count = \(unitTwoCount)")
print("Unit Three Count = \(unitThreeCount)")
print("Unit Four Count = \(unitFourCount)")
print("Unit Five Count = \(unitFiveCount)")
print("Unit Six Count = \(unitSixCount)")
print("Unit Seven Count = \(unitSevenCount)")
print("Unit Eight Count = \(unitEightCount)")
print("Unit Nine Count = \(unitNineCount)")
if(allQuestions.list.prefix(prefixNumber).count >= 0){
let progression = Progression(context: CoreDataStackResults.context)
progression.unitOneAttempts = unitOneCount
print("progression.unitOneAttempts = \(progression.unitOneAttempts)")
progression.unitTwoAttempts = unitTwoCount
progression.unitThreeAttempts = unitThreeCount
progression.unitFourAttempts = unitFourCount
progression.unitFiveAttempts = unitFiveCount
progression.unitSixAttempts = unitSixCount
progression.unitSevenAttempts = unitSevenCount
progression.unitEightAttempts = unitEightCount
progression.unitNineAttempts = unitNineCount
CoreDataStackResults.saveContext2()
}
}
func allocateQuestionCorrect(){
questionUnitCorrect = Int16(Int(newQuestionCode.prefix(1)) ?? 0)
print ("Correct Question Code = \(Int(newQuestionCode.prefix(1)) ?? 0)")
if (questionUnitCorrect == 1) {
unitOneCountCorrect += 1 }
if (questionUnitCorrect == 2){
unitTwoCountCorrect += 1 }
if (questionUnitCorrect == 3){
unitThreeCountCorrect += 1 }
if (questionUnitCorrect == 4){
unitFourCountCorrect += 1 }
if (questionUnitCorrect == 5){
unitFiveCountCorrect += 1 }
if (questionUnitCorrect == 6){
unitSixCountCorrect += 1 }
if (questionUnitCorrect == 7){
unitSevenCountCorrect += 1 }
if (questionUnitCorrect == 8){
unitEightCountCorrect += 1 }
if (questionUnitCorrect == 9){
unitNineCountCorrect += 1 }
print("Unit One Correct Count = \(unitOneCountCorrect)")
print("Unit Two Correct Count = \(unitTwoCountCorrect)")
print("Unit Three Correct Count = \(unitThreeCountCorrect)")
print("Unit Four Correct Count = \(unitFourCountCorrect)")
print("Unit Five Correct Count = \(unitFiveCountCorrect)")
print("Unit Six Correct Count = \(unitSixCountCorrect)")
print("Unit Seven Correct Count = \(unitSevenCountCorrect)")
print("Unit Eight Correct Count = \(unitEightCountCorrect)")
print("Unit Nine Correct Count = \(unitNineCountCorrect)")
let progression = Progression(context: CoreDataStackResults.context)
progression.unitOneCorrect = unitOneCountCorrect
print("progression.unitOneCorrect = \(progression.unitOneCorrect)")
progression.unitTwoCorrect = unitTwoCountCorrect
progression.unitThreeCorrect = unitThreeCountCorrect
progression.unitFourCorrect = unitFourCountCorrect
progression.unitFiveCorrect = unitFiveCountCorrect
progression.unitSixCorrect = unitSixCountCorrect
progression.unitSevenCorrect = unitSevenCountCorrect
progression.unitEightCorrect = unitEightCountCorrect
progression.unitNineCorrect = unitNineCountCorrect
CoreDataStackResults.saveContext2()
}
So, I see the unitCount and unitCountCorrect going up when appropriate and I see "saveContext2 peformed" message but when quiz is over and it moves back to UnitSelectionController none of the values have changed and on loading next quiz it is back to original default values (zero) and starts counting fresh.
Key was (eventually) to write the correct code to read my stored data from the Stack.This was placed in viewDidLoad so only runs when App is opening.
let fetchRequest: NSFetchRequest<QuizResults> = NSFetchRequest<QuizResults>(entityName: "QuizResults")
do{
let results = try QuizResultsStack.context.fetch(fetchRequest)
self.results = results
} catch {}
for result in results{
unitOneCount = result.unitOneAttempts
unitTwoCount = result.unitTwoAttempts
unitThreeCount = result.unitThreeAttempts
unitFourCount = result.unitFourAttempts
unitFiveCount = result.unitFiveAttempts
unitSixCount = result.unitSixAttempts
unitSevenCount = result.unitSevenAttempts
unitEightCount = result.unitEightAttempts
unitNineCount = result.unitNineAttempts
unitOneCountCorrect = result.unitOneCorrect
unitTwoCountCorrect = result.unitTwoCorrect
unitThreeCountCorrect = result.unitThreeCorrect
unitFourCountCorrect = result.unitFourCorrect
unitFiveCountCorrect = result.unitFiveCorrect
unitSixCountCorrect = result.unitSixCorrect
unitSevenCountCorrect = result.unitSevenCorrect
unitEightCountCorrect = result.unitEightCorrect
unitNineCountCorrect = result.unitNineCorrect
}
Along the way, I decided it was 'easier' to transfer the values between my two ViewControllers embedded in my override functions:
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
if segue.destination is QuizController{
let gvc = segue.destination as? QuizController
gvc?.unitOneCount = unitOneCount
print(" from UnitSelection Controller to QuizController gvc?.unitOneCount = \(unitOneCount))")
gvc?.unitTwoCount = unitTwoCount
gvc?.unitThreeCount = unitThreeCount
gvc?.unitFourCount = unitFourCount
gvc?.unitFiveCount = unitFiveCount
gvc?.unitSixCount = unitSixCount
gvc?.unitSevenCount = unitSevenCount
gvc?.unitEightCount = unitEightCount
gvc?.unitNineCount = unitNineCount
gvc?.unitOneCountCorrect = unitOneCountCorrect
gvc?.unitTwoCountCorrect = unitTwoCountCorrect
gvc?.unitThreeCountCorrect = unitThreeCountCorrect
gvc?.unitFourCountCorrect = unitFourCountCorrect
gvc?.unitFiveCountCorrect = unitFiveCountCorrect
gvc?.unitSixCountCorrect = unitSixCountCorrect
gvc?.unitSevenCountCorrect = unitSevenCountCorrect
gvc?.unitEightCountCorrect = unitEightCountCorrect
gvc?.unitNineCountCorrect = unitNineCountCorrect
}
And, coming the other way was when I also updated the Core Data Stack:
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
if segue.identifier == "unwindToUnitSelection" {
print("Override segue unwindToUnitSelection")
let usvc = segue.destination as? UnitSelectionController
usvc?.unitOneCount = unitOneCount
print(" usvc?.unitOneCount = \(unitOneCount))")
usvc?.unitTwoCount = unitTwoCount
usvc?.unitThreeCount = unitThreeCount
usvc?.unitFourCount = unitFourCount
usvc?.unitFiveCount = unitFiveCount
usvc?.unitSixCount = unitSixCount
usvc?.unitSevenCount = unitSevenCount
usvc?.unitEightCount = unitEightCount
usvc?.unitNineCount = unitNineCount
usvc?.unitOneCountCorrect = unitOneCountCorrect
usvc?.unitTwoCountCorrect = unitTwoCountCorrect
usvc?.unitThreeCountCorrect = unitThreeCountCorrect
usvc?.unitFourCountCorrect = unitFourCountCorrect
usvc?.unitFiveCountCorrect = unitFiveCountCorrect
usvc?.unitSixCountCorrect = unitSixCountCorrect
usvc?.unitSevenCountCorrect = unitSevenCountCorrect
usvc?.unitEightCountCorrect = unitEightCountCorrect
usvc?.unitNineCountCorrect = unitNineCountCorrect
print("should be updating QuizResultsStack")
let entity = NSEntityDescription.entity(forEntityName: "QuizResults", in: QuizResultsStack.context)
let quizzy = NSManagedObject(entity: entity!, insertInto: QuizResultsStack.context)
quizzy.setValue(unitOneCount, forKey: "unitOneAttempts")
quizzy.setValue(unitTwoCount, forKey: "unitTwoAttempts")
quizzy.setValue(unitThreeCount, forKey: "unitThreeAttempts")
quizzy.setValue(unitFourCount, forKey: "unitFourAttempts")
quizzy.setValue(unitFiveCount, forKey: "unitFiveAttempts")
quizzy.setValue(unitSixCount, forKey: "unitSixAttempts")
quizzy.setValue(unitSevenCount, forKey: "unitSevenAttempts")
quizzy.setValue(unitEightCount, forKey: "unitEightAttempts")
quizzy.setValue(unitNineCount, forKey: "unitNineAttempts")
quizzy.setValue(unitOneCountCorrect, forKey: "unitOneCorrect")
quizzy.setValue(unitTwoCountCorrect, forKey: "unitTwoCorrect")
quizzy.setValue(unitThreeCountCorrect, forKey: "unitThreeCorrect")
quizzy.setValue(unitFourCountCorrect, forKey: "unitFourCorrect")
quizzy.setValue(unitFiveCountCorrect, forKey: "unitFiveCorrect")
quizzy.setValue(unitSixCountCorrect, forKey: "unitSixCorrect")
quizzy.setValue(unitSevenCountCorrect, forKey: "unitSevenCorrect")
quizzy.setValue(unitEightCountCorrect, forKey: "unitEightCorrect")
quizzy.setValue(unitNineCountCorrect, forKey: "unitNineCorrect")
do {
try QuizResultsStack.context.save()
}
catch {
// Handle Error
}
} }

Detect USB when iPhone connect MaOS

This Swift code works great the result is:
Connect iPhone: Event Matched
Disconnect iPhone: Event Terminated
import Darwin
import IOKit
import IOKit.usb
import Foundation
class IOUSBDetector {
enum Event {
case Matched
case Terminated
}
let vendorID: Int
let productID: Int
var callbackQueue: DispatchQueue?
var callback: (
( _ detector: IOUSBDetector, _ event: Event,
_ service: io_service_t
) -> Void
)?
private
let internalQueue: DispatchQueue
private
let notifyPort: IONotificationPortRef
private
var matchedIterator: io_iterator_t = 0
private
var terminatedIterator: io_iterator_t = 0
private
func dispatchEvent (
event: Event, iterator: io_iterator_t
) {
repeat {
let nextService = IOIteratorNext(iterator)
guard nextService != 0 else { break }
if let cb = self.callback, let q = self.callbackQueue {
q.async {
cb(self, event, nextService)
IOObjectRelease(nextService)
}
} else {
IOObjectRelease(nextService)
}
} while (true)
}
init? ( vendorID: Int, productID: Int ) {
self.vendorID = vendorID
self.productID = productID
self.internalQueue = DispatchQueue(label: "IODetector")
guard let notifyPort = IONotificationPortCreate(kIOMasterPortDefault) else {
return nil
}
self.notifyPort = notifyPort
IONotificationPortSetDispatchQueue(notifyPort, self.internalQueue)
}
deinit {
self.stopDetection()
}
func startDetection ( ) -> Bool {
guard matchedIterator == 0 else { return true }
let matchingDict = IOServiceMatching(kIOUSBDeviceClassName)
as NSMutableDictionary
matchingDict[kUSBVendorID] = NSNumber(value: vendorID)
matchingDict[kUSBProductID] = NSNumber(value: productID)
let matchCallback: IOServiceMatchingCallback = {
(userData, iterator) in
let detector = Unmanaged<IOUSBDetector>
.fromOpaque(userData!).takeUnretainedValue()
detector.dispatchEvent(
event: .Matched, iterator: iterator
)
};
let termCallback: IOServiceMatchingCallback = {
(userData, iterator) in
let detector = Unmanaged<IOUSBDetector>
.fromOpaque(userData!).takeUnretainedValue()
detector.dispatchEvent(
event: .Terminated, iterator: iterator
)
};
let selfPtr = Unmanaged.passUnretained(self).toOpaque()
let addMatchError = IOServiceAddMatchingNotification(
self.notifyPort, kIOFirstMatchNotification,
matchingDict, matchCallback, selfPtr, &self.matchedIterator
)
let addTermError = IOServiceAddMatchingNotification(
self.notifyPort, kIOTerminatedNotification,
matchingDict, termCallback, selfPtr, &self.terminatedIterator
)
guard addMatchError == 0 && addTermError == 0 else {
if self.matchedIterator != 0 {
IOObjectRelease(self.matchedIterator)
self.matchedIterator = 0
}
if self.terminatedIterator != 0 {
IOObjectRelease(self.terminatedIterator)
self.terminatedIterator = 0
}
return false
}
// This is required even if nothing was found to "arm" the callback
self.dispatchEvent(event: .Matched, iterator: self.matchedIterator)
self.dispatchEvent(event: .Terminated, iterator: self.terminatedIterator)
return true
}
func stopDetection ( ) {
guard self.matchedIterator != 0 else { return }
IOObjectRelease(self.matchedIterator)
IOObjectRelease(self.terminatedIterator)
self.matchedIterator = 0
self.terminatedIterator = 0
}
}
let test = IOUSBDetector(vendorID: 0x05ac, productID: 0x12a8)
test?.callbackQueue = DispatchQueue.global()
test?.callback = {
(detector, event, service) in
print("Event \(event)")
};
_ = test?.startDetection()
while true { sleep(1) }
This Swift code works great the result is:
Connect iPhone: Event Matched
Disconnect iPhone: Event Terminated
How to : if iPhone is connected then execute some commands
Can you help me write where to put the command?
Commands to get information from iPhone I already have but don't know where to put it
i try replace print("Event (event)") with
if event == Matched {
} else {
}
but not work

realmOC can't update data

addobject is success. but i want to update data. After realm.beginWriteTransaction() executes, breakpoint can't continue execute backup.quanId = 5, it's like just jump over.
class YQQuanBackup: RLMObject {
dynamic var groupId:Int = 0
dynamic var quanId:Int = 0
dynamic var content:String = ""
}
GCDBlock.async(.Default) {
let results:RLMResults = YQQuanBackup.objectsWhere("groupId == %d", self.groupInfo!.groupId)
let quanBackup = results.firstObject() as? YQQuanBackup
guard let backup = quanBackup else { return }
let realm = RLMRealm.defaultRealm()
realm.beginWriteTransaction()
backup.quanId = 5
backup.content = YQRichTextUtil.richTextToPublishText(self.textView.attributedText, uploadedImageUrls: self.uploadedImageUrls)
do {
try realm.commitWriteTransaction()
} catch {
print(error)
}
}

Swift: UIRefreshControl does not pull through when dragging down

I have a working UITableView in which I added a UIRefreshControl like this:
var refresher: UIRefreshControl!
...
// this is ViewDidLoad()
// pull to refresh
refresher = UIRefreshControl()
refresher.tintColor = globalClass.blue
refresher.attributedTitle = NSAttributedString(string: "")
refresher.addTarget(self, action: "loadFriends", forControlEvents: UIControlEvents.ValueChanged)
friendTableView.addSubview(refresher)
This works well on other UITableViews, but not on this one for some reason. The spinner never really spins and just snaps to the top when the dragging stops. What could cause this?
EDIT: loadFriends function
//load friends
func loadFriends() {
globalClass.requestsIn = []
globalClass.requestsOut = []
globalClass.finalSections = []
globalClass.myFriends = []
finalSections = []
sectionsG1 = []
let queryIn1 = PFQuery(className:"Friendship")
queryIn1.whereKey("toUser", equalTo: PFUser.currentUser()!.username!)
let queryOut = PFQuery(className:"Friendship")
queryOut.whereKey("fromUser", equalTo: PFUser.currentUser()!.username!)
let query = PFQuery.orQueryWithSubqueries([queryIn1, queryOut])
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
if objects!.count == 0 {
self.friendtTableView.reloadData()
self.text()
} else {
for object in objects! {
let toUser:String = object["toUser"] as! String
let status:String = object["status"] as! String
if toUser == PFUser.currentUser()?.username {
if status == "pending" {
globalClass.requestsIn.append(object["fromUser"] as! String)
self.update()
} else if status == "approved" {
globalClass.myFriends.append(object["fromUser"] as! String)
globalClass.myFriends = globalClass.myFriends.sorted { $0.localizedCaseInsensitiveCompare($1) == NSComparisonResult.OrderedAscending }
self.update()
}
} else { if status == "pending" || status == "rejected" {
globalClass.requestsOut.append(object["toUser"] as! String)
self.update()
} else if status == "approved" {
globalClass.myFriends.append(object["toUser"] as! String)
globalClass.myFriends = globalClass.myFriends.sorted { $0.localizedCaseInsensitiveCompare($1) == NSComparisonResult.OrderedAscending }
self.update()
}
}
}
}
if self.tableSegment == 1 {
if globalClass.requestsIn.count == 0 {
self.friendTableView.reloadData()
self.text()
} else {
}
} else if self.tableSegment == 2 {
if globalClass.requestsOut.count == 0 {
self.friendTableView.reloadData()
self.text()
} else {
}
} else if self.tableSegment == 0 {
if globalClass.myFriends.count == 0 {
self.friendTableView.reloadData()
self.text()
} else {
}
}
self.refresher.endRefreshing()
} else {
}
}
}

Excess memory usage swift

I'm building a today extension for iOS and I'm confused why this function keeps on using more and more memory.
See the code below:
func loadActivePlayer() {
kodi.getActivePlayer {
(response) in
let result = JSON(response)
let activePlayer = ActivePlayer()
if let playerid = result["result"][0]["playerid"].int {
activePlayer.playerid = playerid
}
if let type = result["result"][0]["type"].string {
activePlayer.type = type
}
if(activePlayer.isEmpty()) {
self.loadActivePlayer()
}
else {
self.enablePlaybackButtons(true)
self.activePlayer = activePlayer
self.kodi.getItem(activePlayer.playerid) {
(response) in
var result = JSON(response)
var item = Item()
if let id = result["result"]["item"]["id"].int {
item.id = id
}
if let type = result["result"]["item"]["type"].string {
item.type = type
}
if let label = result["result"]["item"]["label"].string {
item.label = label
}
if let title = result["result"]["item"]["title"].string {
item.title = title
}
if let season = result["result"]["item"]["season"].int {
item.season = season
}
if let episode = result["result"]["item"]["episode"].int {
item.episode = episode
}
if let showtitle = result["result"]["item"]["showtitle"].string {
item.showtitle = showtitle
}
dispatch_async(dispatch_get_main_queue()) {
self.itemTitleLabel.text = item.title
self.itemShowTitleLabel.text = item.showtitle
self.itemSeasonEpisodeLabel.text = "S\(item.season)E\(item.episode)"
}
self.loadActivePlayer()
}
}
}
When it goes in the if(activePlayer.isEmpty())
the memory usage increases and increases and increases, quite irritating.
But when it goes into the else, the memory usage stays almost the same, it does not increase significantly.
Can anyone help me understand why this is happening?
Thanx in advance!