Delete number phone Contact - Swift 3 - 4 - ios

I want to delete a contact number, I use ContactsUI
//only do this to the first contact matching our criteria
guard let contact = contacts?.first else{
return
}
let editContact = contact.mutableCopy() as! CNMutableContact
editContact.phoneNumbers[1]..... ?
in editContact.phoneNumbers[1].. I want to eliminate that number that is in that position
to edit it, I edit it in this way. and it works well
editContact.phoneNumbers[1] = CNLabeledValue(label: "home",
value: CNPhoneNumber(stringValue: "1234567"))
but how do I eliminate it

phoneNumbers is an array. Remove the desired element like you would any other array value:
let editContact = contact.mutableCopy() as! CNMutableContact
editContact.phoneNumbers.remove(at: 1)
Of course I'd make sure there are at least 2 phone numbers before doing that.

Related

Coredata relationships how make ordered collection or added in particular index in iOS swift

I am working with core-data relationships add the student in profile entities.
Profile and Student entities are multiple relationship with each others.
Profile entities for create students, it successfully created.
I want to add or append some information that profile entities through student entities its also added.
(Its Like: Profile entities have a array of dictionary of student entities )
But when in display in UItableview added info of student it display in unordered.
I want to display the added student should be display in last or first.
Coredata is unordered collection of set. how to make it order.
Also selected ordered Arrangement. its shows error students not be ordered.
How can achieve this. Help me
Here my code:
func create(record: ProfileModel) {
let cdProfile = CDProfile(context: PersistentStorage.shared.context)
cdProfile.emailID = record.emailID
cdProfile.gender = record.gender
cdProfile.getDate = record.getDate
cdProfile.id = record.id
if(record.toStudent != nil && record.toStudent?.count != 0){
var studentSet = Set<CDStudent>()
record.toStudent?.forEach({ (student) in
let cdStudent = CDStudent(context: PersistentStorage.shared.context)
cdStudent.activity = student.activity
cdStudent.currentPage = Int16(student.currentPage ?? 0)
cdStudent.getPercentage = student.getPercentage
studentSet.insert(cdStudent)
})
cdProfile.toStudent = studentSet
}
PersistentStorage.shared.saveContext()
}
#IBAction func saveBtnClick(_ sender: Any) {
let studentArr = StudentModel(_activity: "S-\(self.sectionString)", _studentComments: self.infotextView.text, _getPercentage: "-", _result: String(self.audioValueKey.count), _sectionID: self.sectionString, _sessionDate: self.convertedDate, _timeSpend: self.timeSpendStr, _currentPage: self.allPageNumber, _selectedValue: self.audioValueKey)
if let getStudentData = userProfileArr![indexNumber].toStudent?.count{
self.personArrCount = getStudentData
let getArr = userProfileArr![indexNumber].toStudent!
if getArr.count == 0{
}else{
for j in 0..<getArr.count{
self.student.append(getArr[j])
// self.student.insert(getArr[j], at: 0)
}
self.student.append(studentArr)
}
}else{
self.personArrCount = 0
self.student.append(studentArr)
print("student-empty",student)
}
let getProfileData = userProfileArr![indexNumber]
let updatePerson = ProfileModel(_id: selectedUserIndex!.id, _profileComments: getProfileData.profileComments!, _emailID: getProfileData.emailID!, _gender: getProfileData.gender!, _profileImage: getProfileData.profileImage!, _getDate: "NO", _studentDOB: getProfileData.studentDOB!, _studentName: getProfileData.studentName!, _toStudent: student)
print("student",self.student)
if(dataManager.update(record: updatePerson))
{
print("Update added")
}else{
print("Not-- added")
}
}
How can i fix this issue help me... Thanks advance.
first of all Core data only provides sorting on parent table only
if you wanna sort data in a subtable you can do as below
First you need to add a field named student_id(int16) in student table
Then you need to assign value as count + 1
As core data does not provide autoincrement field need to manage manually.
Follow the below code to sort data as last to first
// assume you have fetched profile in stud_profile var
if let student_list = stud_profile.toStudent as? Set<CDStudent> {
let arrStudents = Array(student_list).sorted(by: {$0.student_id > $1.student_id})
}
4.You can use arrStudents as it will return sorted [CDStudent]

SQLite.Swift how to get random row never repeating

I'm experimenting with SQlite.Swift in iOS and I'm trying to randomly pick a row from a table in an SQLite database.
The table is movies and its columns are movieID, title genre and seen.
Problem:
Movies should be picked randomly but as soon as I set seen to "yes" they should no longer be picked.
func randomRow() -> Int {
let path = NSSearchPathForDirectoriesInDomains(
.documentDirectory,
.userDomainMask, true)
.first!
let database = try! Connection("\(path)/movies.sqlite3")
var randomRow = Int(arc4random_uniform(UInt32(try!
database.scalar(movies.where(seen != "yes")
.select(movieID.distinct.count)))))
while previousNumber == randomRow {
randomRow = Int(arc4random_uniform(UInt32(try!
database.scalar(movies.where(seen != "yes")
.select(movieID.distinct.count)))))
}
previousNumber = randomRow
return randomRow
}
let destRow = randomRow()
Now I want to use this random row number to be catched from the table to lead the title and genre of the random movie into let ("dispMovie" and "movieGenre") to be output into a UITextField.
let path = NSSearchPathForDirectoriesInDomains(
.documentDirectory,
.userDomainMask, true)
.first!
let database = try! Connection("\(path)/filme.sqlite3")
for movie in try! database.prepare(
self.movies.where(
seen != "yes" && movieID == "\(destRow)")) {
dispMovie = movie[title]
movieGenre = movie[genre]
}
outputTextField.text = "\(dispMovie), \(movieGenre)"
This code works fine. The only problem is that movies I have seen will still be diplayed because I have this .count in the random row function.
I've also tried to call Raw SQLite with this one:
let newMovie = try! database.scalar(
"SELECT title, genre FROM movies WHERE seen != yes
ORDER BY RANDOM() LIMIT 1") as! String
outputTextField.text = newMovie
But this only displays the title and not the genre and looking for the genre in an extra line is not possible because the movie is picked from a random row. I've tried to reference the movie title in the Raw code but that crashes the app.
Thanks for help and hints.
No Christmas 'till this is done!
After days of thinking and running against walls suddenly the good old while loop came to my mind. It turned out working so I'm leaving this as an answer to my own question:
Forget about the randomRow(). No need for this. I focused on the SQLite RAW in the first place and continued with a combination of scalar, where and select from the SQLite.Swift library. That finally got me this:
Posting my whole UIViewController so you can test yourself:
class TestView: UIViewController {
//Table
let movies = Table("movies")
//Expressions
let movieId = Expression<String>("ID")
let movieTitle = Expression<String>("movieTitle")
let genre = Expression<String>("genre")
let seen = Expression<String>("seen")
//to find with database connection
var randomMovie = String()
var movieDetails = [String]()
//Array of all movies seen
var seenMovies = [String]()
//TestLabel to check everything
#IBOutlet weak var testLabel: UILabel!
#IBAction func testButton(_ sender: Any) {
//Open database connection
let path = NSSearchPathForDirectoriesInDomains(
.documentDirectory, .userDomainMask, true
).first!
let database = try! Connection("\(path)/movies.sqlite3")
//Check column "seen" and add all movie Titles to Array seenMovies
for movie in try! database.prepare(self.movies.where(seen == "yes")) {
self.seenMovies.append(movie[movieTitle])
}
//Select random row from movies Table with SQLite RAW as String
self.randomMovie = "\(try! database.scalar("SELECT movieTitle FROM movies WHERE seen != yes ORDER BY RANDOM() LIMIT 1"))"
//Create Array of details for that randomly picked movie
//Use scalar, where and select to find details from the picked movie above
self.movieDetails = ["\(randomMovie!)",
"\(try! database.scalar(movies.where(movieTitle == "\(randomMovie!)").select(genre)))"]
//And here's the "unique" thing...
//while randomMovie is also an element in seenMovies, loop until it's not
while seenMovies.contains("\(randomMovie!)") {
randomMovie = "\(try! database.scalar("SELECT movieTitle FROM movies WHERE seen != yes ORDER BY RANDOM() LIMIT 1"))"
}
//let testLabel show the results and see that no seen movie will be picked
testLabel.text = "\(details)\n\n\(erraten)"
//To prevent the Array from being appended over and over:
self.seenMovies.removeAll()
}
}
Since I still consider myself a beginner (started coding in October '17) please feel free to optimize this if possible. All my tests went very well and no movie was ever repeated when turned to "seen".
Found a solution from SQLite.Swift issue filed in 2016.
let db = Connection(databasePath)
let movies = Table("movies")
let query = movies.order(Expressions<Int>.random()).limit(1)
for row in try! db.prepare(query) {
// handle query result here
}

How can I find a specific Product id by sending Product Name?

I use Firebase For My Store App. I want to find a Product's Details by taking a product name for the user. My JSON format looks like this:
{
product :
electronic =
a = {
pname = "iphone 5"
pprice = "20000"
pdescription = "Details....." }
b = {
pname = "iphone 6"
pprice = "30000"
pdescription = "Details....." }
}
cloths =
a = pname = "shirt"
pprice = "200"
pdescription = "Details....." }
b = {
pname = "pents"
pprice = "300"
pdescription = "Details....." }
}
Now, suppose I have the name iphone 5, then how can I find out the other details of the product?
Try this :-
FIRDatabase.database().reference().child("product/electronic").queryOrderedByChild("pname").queryEqualToValue("iphone 5").observeSingleEventOfType(.Value , withBlock : {(snap) in
if let snapDict = snap.value as? [String:AnyObject]{
for each in snapDict{
print(each.0) // product key
print(each.1) //product details
}
}
})
import Firebase
FIRApp.configure()
ref = FIRDatabase.database().reference()
let prod_query = "iphone 5"
ref.observeSingleEventOfType(.Value, withBlock: { (snapshot) in
let product_enum = snapshot.children
while let product = product_enum.nextObject() as? FDataSnapshot {
product.queryEqualToValue(child:"\(prod_query)").observeSingleEventOfType(.Value, withBlock: { (snap) in
let pid = snap.key as! String
let pprice = snap.value!["pprice"] as! Int
let pdescription = snap.value!["pdescription"] as! String
})
}
})
This implies that you know what the product letter is so that you can pull the correct name, price, and description.
The while loop will iterate through the different types of products (electronics, cloths, etc) and perform a query searching for a product ID that contains the child with the pname you're looking for.
Firebase suggests that instead of using .Value, it's better to use .ChildAdded since it accomplishes the same goal while managing new objects added. But since it appears you are trying to view static data, .Value works just fine.
This should serve as an excellent example as to how you can retrieve data using Firebase. But I suggest checking out the documentation on your own just in case you have further questions.
While I really don't mind looking this information up... this site is used in order to gain a better understanding of code, rather than existing as a collection of personal assistants.
Showing research efforts within your question can go a long way.

Custom labels associated with a contact IOS OS X Contact Framework Swift

How do I access the read-only and/or mutable contact records pertaining to what I believe to be custom labeled relationship contact data?
For instance I have Daughter-In-Law, Husband or Son custom labels associated with a contact Do I need CNLabeledValue CNLabelContactRelationChild? What do I need to read these or get these custom labels from contact data?
Here is what I managed to do in order to assign a relation to a contact and be able to fetch it using the relation
var myNewContact = CNMutableContact()
let myRelation = CNContactRelation(name: "mommy")
let myMom = CNLabeledValue(label: CNLabelContactRelationMother, value: myRelation)
myNewContact.contactRelations.append(myMom)
// add additional info to your contact such as name, email, family
// save your contact
let keysToFetch = [CNContactGivenNameKey, CNContactRelationsKey, CNContactEmailAddressesKey]
let text = "mommy"
let request = CNContactFetchRequest(keysToFetch: keysToFetch)
do {
try store.enumerateContactsWithFetchRequest(request) {
contact, stop in
for var i = 0; i < contact.contactRelations.count; i++ {
if (contact.contactRelations[i].valueForKey("value")?.valueForKey("name")!)! as? String == text
{
print(contact.givenName)
print(contact.identifier)
}
}
}
} catch let err{
print(err)
}
}

Add and Delete CoreData based on attribute value search match

Setup: iOS 9, Swift, XCODE 7.1 Beta
Goal is to build shopping cart functionally for which I need unique values in CoreData.
I have a UITableView in which data (Product name, Cost, Quantity, ID) is uploaded from Parse backend. Each TableView custom cell has a button, tapping which saves the selected row data in CoreData.
I don't want to have duplicate product in the cart, so before saving I want to check if the cart already have the product. If it has, I want to replace the cart with currently selected data. If not, just want to add a new product in the cart.
My CoreData setup is simple.
Entity name = Cart
Attributes = pName(type String), pCost(type
Int), pQuantity(type Int), orderID(type String)
Add product to the Cart button code is as below:
// Product data is retrieved in these variable
var pNam = NSMutableArray()
var pCost = NSMutableArray()
var pQty = NSMutableArray()
var pObjectID = NSMutableArray()
// Add to Cart button ....
let indexPath = NSIndexPath(forRow: sender.tag, inSection: 0)
let cell = tableView.cellForRowAtIndexPath(indexPath) as! ProductMenuTableViewCell! // Custom cell in which the button add to Cart button is placed
let entityDescription = NSEntityDescription.entityForName("Cart", inManagedObjectContext: managedObjectContext!)
let cart = Cart(entity: entityDescription!, insertIntoManagedObjectContext: managedObjectContext)
cart.pName = pNam[indexPath.row].description
cart.pCost = pCst[indexPath.row].integerValue!
cart.pQuantity = pQty[indexPath.row].integerValue!
cart.orderID = pObjectID[indexPath.row].description
var error: NSError?
do {
try managedObjectContext?.save()
} catch let error1 as NSError {
error = error1
}
if let err = error {
print(err.localizedFailureReason)
} else {
print("Saved")
}
Should I directly use cell to add values to CoreData? For ex: cart.pName = cell.pName.text! or there is a better way to do it? Anyone know how to solve this?
Your data setup is absurd. You have 4 arrays for the 4 attributes of n objects. If for any reason the sorting of an array changes, or an element is dropped or added, you have to make sure the same happens with all the other arrays, a maintenance nightmare! How do you expand this model if later you have 15 attributes. Use 15 arrays? This is completely crazy.
Instead, you should have an array of objects - ideally Core Data objects - with the appropriate attributes grouped together. You can always keep a flag to indicate that you want to discard these items later rather then persist them in the database.
Now you do not have to decide to create or update: simply set the delete flag to false.
You need to search for an existing Cart object with the correct name; if there is no matching Cart, then create a new one. Something like this:
var cart : Cart
let requiredName = pNam[indexPath.row].description
let entityDescription = NSEntityDescription.entityForName("Cart", inManagedObjectContext: managedObjectContext!)
let fetchRequest = NSFetchRequest()
fetchRequest.entity = entityDescription!
fetchRequest.predicate = NSPredicate(format:"pName == %#",requiredName)
do {
let results = try self.managedObjectContext?.executeFetchRequest(fetchRequest) as! [Cart]
if results.count == 0 { // not found, so create new...
cart = Cart(entity: entityDescription!, insertIntoManagedObjectContext: managedObjectContext)
cart.pName = requiredName
} else { // found at least one, so use the first...
cart = results[0]
}
// Now update the other attribute values:
cart.pCost = pCst[indexPath.row].integerValue!
cart.pQuantity = pQty[indexPath.row].integerValue!
cart.orderID = pObjectID[indexPath.row].description
} catch {
print("Error fetching")
}
Regarding your secondary question, personally I would use your current approach: use the row as an index on your dataSource arrays, i.e. don't directly use the values from the cell's labels etc.

Resources