Search code examples
iosswiftsqliteabaddressbookdispatch-async

How to run code in background ? using dispatch_async how it works?


i'm very new to Swift.I have following code which works perfectly. i.e. I'm fetching contacts from PhoneBook and updating into sqlite successfully.

My requirement

I want to run code in background i.e. in my following code what i'm doing is whenever some contacts added/deleted in Phonebook I'm updating sqlite. This feature continuously i want. It should always run in background.

Here is my code

func getContactNames()
{
    if !self.determineStatus()
    {
        print("not authorized")
        return
    }

    let contactList: NSArray = ABAddressBookCopyArrayOfAllPeople(adbk).takeRetainedValue()
    print("records in the array \(contactList.count)")


    var firstName : String = String()

    var contactNumber : String = String()


    var lastName : String = String()


    var email : String = String()


    var fullName : String = String()


    let db = ContactsDBModel.sharedInstance()


    var  contacts : [ContactsModel!]?


    contacts =  db.selectAllFromContact()

    print(contacts?.count)

    if contacts?.count != contactList.count
    {

        db.deleteAllFromContact()

        for record:ABRecordRef in contactList
        {
            if (ABRecordCopyValue(record,
                kABPersonPhoneProperty) != nil)

            {


                if (ABRecordCopyValue(record,
                    kABPersonFirstNameProperty) != nil)

                {


                    firstName = (ABRecordCopyValue(record, kABPersonFirstNameProperty)?.takeRetainedValue() as? String)!

                    let numbers:ABMultiValue = ABRecordCopyValue(record, kABPersonPhoneProperty).takeRetainedValue()


                    contactNumber = (ABMultiValueCopyValueAtIndex(numbers,0)?.takeRetainedValue() as? String)!
                    // print("first name =\(firstName)")

                   // print("contact number=\(contactNumber)")

                    if (ABRecordCopyValue(record,
                        kABPersonLastNameProperty) != nil)
                    {

                       lastName = (ABRecordCopyValue(record,
                            kABPersonLastNameProperty).takeRetainedValue()as? String)!
                       // print("last name =\(lastName)")
                    }


                    let emails: ABMultiValueRef = ABRecordCopyValue(record, kABPersonEmailProperty).takeRetainedValue()

                    for (var i = 0; i < ABMultiValueGetCount(emails); i++)
                    {
                        email = ABMultiValueCopyValueAtIndex(emails, i).takeRetainedValue() as! String
                      //  print("email of person=\(email)")
                    }

                }

            }

            fullName = firstName + lastName;
            lastName = "";

            print("fullName of person=\(fullName)")
            print("email of person=\(email)")
            print("contact number=\(contactNumber)")


            db.insertIntoContact(contactNumber: contactNumber, contactName: fullName, contactEmail: email)


        }

        contacts =  db.selectAllFromContact()

        print(contacts?.count)

  }


    print(contacts?.count)


} 

The above code i want to run in background.

UPDATE

viewDidLoad

override func viewDidLoad()
{
    super.viewDidLoad()
    var emptyDictionary: CFDictionaryRef?
    var addressBook: ABAddressBookRef?

            func extractABAddressBookRef(abRef: Unmanaged<ABAddressBookRef>!) -> ABAddressBookRef?
            {
                if let ab = abRef
                {
                    return Unmanaged<NSObject>.fromOpaque(ab.toOpaque()).takeUnretainedValue()
                }
                return nil
            }

            if (ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.NotDetermined)
            {
                print("requesting access...")
                var errorRef: Unmanaged<CFError>? = nil
                addressBook = extractABAddressBookRef(ABAddressBookCreateWithOptions(nil, &errorRef))
                ABAddressBookRequestAccessWithCompletion(addressBook, { success, error in
                    if success {
                        self.getContactNames()
                    }
                    else
                    {
                        print("error")
                    }
                })
            }
            else if (ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.Denied || ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.Restricted)
            {
            print("access denied")
            }
            else if (ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.Authorized)
            {
            print("access granted")
            getContactNames()
            }


   }

dispatch_async

 dispatch_async(dispatch_get_global_queue(   DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Thread
 dispatch_async(dispatch_get_main_queue(), ^(void){
    //Run UI Updates
    });
 });

I've heard using dispatch_async we can run code in background.But where to put my above code? what are the scenarios?


Solution

  • We can use dispatch_async for.
    For example this is downloading some image and storing in UserDefaults in background

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) { () -> Void in
                    let imageData = NSData(contentsOfURL: NSURL(string: thankYouImageURL)!)
                    if let data = imageData {
                        print("Success Thanks Image")
                        NSUserDefaults.standardUserDefaults().setObject(data, forKey: "registerThanksImage")
    
                    }else{
                        print("failure thanks image")
                    }
    
                }
    

    General Syntax

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
            // do background task
            dispatch_async(dispatch_get_main_queue()) {
                // update some UI
            }
        }