I am creating EKEvent, saving it and saving its identifier as well. I wanna access this identifier and delete the specific Event. I am able to retrieve the proper Identifier from database. However, the Event isn't getting deleted from my Device's calendar.
My code to delete the event :
`NSError* err;
EKEvent *myEvent = [EKEvent eventWithEventStore:homeobj.eventDB];
myEvent = [homeobj.eventDB eventWithIdentifier:[dbObj selectEventIdentifier:mypass]];
[homeobj.eventDB removeEvent:myEvent span:EKSpanThisEvent commit:YES error:&err];
`
For deleting use this code
-(void)removeMeWithIndex:(int)index
{
EKEvent* eventToRemove = [eventStore eventWithIdentifier:[arrayofEventId objectAtIndex:index]];
if (eventToRemove != nil) {
NSError* error = nil;
[eventStore removeEvent:eventToRemove span:EKSpanThisEvent error:&error];
}
}
-(IBAction)remove
{
[self removeMeWithIndex:0];
}
I have updated my code to check if id exists or not as
-(void)removeMeWithIndex:(int)index
{
NSLog(#"id is %#",[[NSUserDefaults standardUserDefaults] valueForKey:#"id"]);
EKEvent* eventToRemove = [eventStore eventWithIdentifier:[[NSUserDefaults standardUserDefaults] valueForKey:#"id"]];
if (eventToRemove != nil) {
NSError* error = nil;
[eventStore removeEvent:eventToRemove span:EKSpanThisEvent error:&error];
}
}
output after deletion is ...
2013-06-26 18:51:43.999 CARL[674:907] id is 7AFE7AC2-111A-446F-86E6-8D69AD38F1AF:CA946E83-BE08-44AB-8834-06E1E4BFF7E8
your id is something like this ?
After creation of event check in calendar app in device.
After deleting event completion screenshot is :--
Here you can get sample project.
Related
I have a dynamic array (named "items") of users I follow:
["user5#t.co", " user6#t.co"]
and I'm essentially retrieving these user's posts using:
for i in 0..< items.count{
db.collection("users").document("\(items[i])").collection("posts").addSnapshotListener { (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
print("No documents")
return
}
self.posts = documents.map { QueryDocumentSnapshot -> Post in
let longitudeVar = data["longitude"] as? String ?? ""
let latitudeVar = data["latitude"] as? String ?? ""
return Post(id: .init(), longitudeVAR: longitudeVAR, latitudeVAR: latitudeVAR)
}
}
}
I'm trying to draw information from both users at the same time but the issue I'm having is that this only draws post information (longitudeVar & latitudeVar) for ONE user OR the other- and it seems to randomly pick between user5#t.co and user6#t.co. Any suggestions? Also I apologize if this is a basic question or if my code isn't well written- I'm just trying to get this to work. Thanks!
If you want to loop database fetches and coordinate their returns into a single task then you should use a DispatchGroup. It's a very simple API that will simply record how many calls you make to Firestore and give you a completion handler to execute when that many returns eventually come in (at the end of the last one).
Don't use a snapshot listener here because those are for streams of data—all you want is a one-time document grab. If there are lots of documents to parse and they are relatively big then I would consider using a background queue so the UI doesn't stutter when this is going on.
var posts = [Post]()
let dispatch = DispatchGroup() // instantiate dispatch group outside loop
for item in items {
dispatch.enter() // enter on each iteration
// make a get-documents request, don't add a continuously-updating snapshot listener
db.collection("users").document(item).collection("posts").getDocuments { (querySnapshot, error) in
if let documents = querySnapshot?.documents {
// fill a local array, don't overwrite the target array with each user
let userPosts = documents.map { QueryDocumentSnapshot -> Post in
let longitudeVar = data["longitude"] as? String ?? ""
let latitudeVar = data["latitude"] as? String ?? ""
return Post(id: .init(), longitudeVAR: longitudeVAR, latitudeVAR: latitudeVAR)
}
self.posts.append(userPosts) // append local array to target array
} else if let error = error {
print(error)
}
dispatch.leave() // always leave, no matter what happened inside the iteration
}
}
/* this is the completion handler of the dispatch group
that is called when all of the enters have equaled all
of the leaves */
dispatch.notify(queue: .main) {
self.tableView.reloadData() // or whatever
}
I have my device working on both a simulator and on my test iPhone. I want to save a new record to to the Cloudkit database. I can create records on the physical test device, but not in the simulator. When I submitted it for Apple's review they rejected it because of that as well. Both devices are signed into iCloud. This is confirmed right before saving the record with this code:
CKContainer.default().accountStatus { (accountStatus, error) in
switch accountStatus {
case .available:
print("iCloud Available")
case .noAccount:
print("No iCloud account")
case .restricted:
print("iCloud restricted")
case .couldNotDetermine:
print("Unable to determine iCloud status")
}
}
The code I use to make the save is pretty straight forward and it works without any issues on real devices:
static func saveUser(user: UserElement, completion: #escaping (Result<UserElement, Error>) ->
()) {
let itemRecord = CKRecord(recordType: "userInfo")
itemRecord["uniqueID"] = user.bossID as CKRecordValue
itemRecord["screenName"] = user.screenName as CKRecordValue
itemRecord["shareCode"] = user.shareCode as CKRecordValue
itemRecord["subscribedBosses"] = user.subscribedBosses as CKRecordValue
let container = CKContainer(identifier: "iCloud.Caz4Short.WatChaDoin")
container.publicCloudDatabase.save(itemRecord) { (record, err) in
DispatchQueue.main.async {
if let err = err {
print("error on run")
completion(.failure(err))
return
}
guard let record = record else {
print("record")
completion(.failure(CloudKitHelperError.recordFailure))
return
}
let id = record.recordID
guard let boss = record["uniqueID"] as? String else {
print("record ID")
completion(.failure(CloudKitHelperError.recordIDFailure))
return
}
guard let name = record["screenName"] as? String else {
print("screenname")
completion(.failure(CloudKitHelperError.castFailure))
return
}
guard let bossCode = record["shareCode"] as? String else {
print("Code")
completion(.failure(CloudKitHelperError.castFailure))
return
}
guard let subs = record["subscribedBosses"] as? [String] else {
completion(.failure(CloudKitHelperError.castFailure))
return
}
let element = UserElement(recordID: id, bossID: boss, screenName: name, shareCode: bossCode, subscribedBosses: subs)
completion(.success(element))
}
}
}
The code fails at "Error On Run" with the resulting error message
Error saving record <CKRecordID: 0x9t83ecb31790; recordName=8AB667FA-0D8F-4B72-8B90-C694AB960EFF, zoneID=_defaultZone:defaultOwner> to server: CREATE operation not permitted
I get a similar error when I try to modify a record except it says WRITE instead of CREATE. I am able to read records without a problem though. This made me think I forgot to set the Security Roles for that zone, but that is not the case. Authenticated users & have READ, CREATE, and WRITE selected for all zones. Creator also has READ and WRITE. I've also signed into iCloud on a computer and accepted the terms and conditions for the iCloud account a long time ago so its not like its a new account that needs to be setup. Any ideas would be greatly appreciated so it doesn't get rejected again!
Alright so i'm starting to get a headache here... Once my user sign onto my app i create a new class on parse with the name PFUser.Current()?.objectId! Within this class i store all the users information, and the user can acces it from any device since his user ID never changes. One of the things i store in the user class is an array which leads me to my question: I want to be able to acces this array but the only way this can be done is by using:
var query = PFQuery(className: "\(PFUser.current()?.objectId!)") // Calling the user class
query.getObjectInBackground(withId: "") { (object: PFObject?, error: Error?) in
if error != nil {
print(error)
} else {
print(object)
}
}
The Problem is that i do not know how to retrieve the objectID from within the class UserObjectID.
I found some code that lets me retrieve my user list and append usernames and iDs to an array:
var query = PFUser.query()
query?.findObjectsInBackground { (objects, error) in
if let users = objects {
for object in users {
if let user = object as? PFUser {
self.usernames.append(user.username!)
self.userids.append(user.objectId!)
}
}
}
}
How can i do a similar search, and find all the objectIDs within my individual userClass instead of the superUser class?
Are you sure you want to create a new class for each user? you going to end up with an enormous amount of tables with 1 row in each. Best to add your array as a column in the current _User table or create a new table and save all user arrays in it with a pointer.
That being said if do and your new table is named from the objectId of the user then you should be able to query that class with:
var userId: String = ""
let userClassName = PFUser.current()!.objectId!
let query = PFQuery(className: userClassName)
// as there is only 1 row get the first
query.getFirstObjectInBackground { (object, error) in
if error != nil || object == nil {
print("nothing here try again")
} else {
userId = object?.objectId
}
}
If you have a table with many users and a pointer then use the following lines as a guide
let userObjectId = PFUser.current()!.objectId!
query.whereKey("yourPointerName", equalTo: PFObject(outDataWithClassName: "theClassYouWantToQuery", objectId: userObjectId))
I have a problem with Sqlite in Swift. Every time I run my app on simulator and insert a new record, then after insert successfully, I can not insert or update, delete any records, it's like database changed to read-only. But if I run my app without inserting a new record, then update, delete statements work totally fine.
I do open and then close the connection to database each time execute any SQL statements.
Here's my insert function :
func insertJobToDatabase(label: String, startTime: NSDate, finishTime: NSDate, startDay: NSDate, finishDay: NSDate, color: String){
let db = connectDatabase("TimeTable.sqlite")
// Set date formatter
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy HH:mm"
//Insert string of interting new job
let insertStatementString = "INSERT INTO Jobs VALUES (\"\(label)\",'\(dateFormatter.stringFromDate(startTime))','\(dateFormatter.stringFromDate(finishTime))','\(dateFormatter.stringFromDate(startDay))','\(dateFormatter.stringFromDate(finishDay))',\"\(color)\", \(Int(self.getMaxIdOfTable(db)+1)));"
//compile Insert string
var insertStatement: COpaquePointer = nil
if sqlite3_prepare_v2(db, insertStatementString, -1, &insertStatement, nil) == SQLITE_OK {
//Execute Insert string
if sqlite3_step(insertStatement) == SQLITE_DONE {
print("Successfully inserted row.")
} else {
print("Could not insert row.")
}
} else {
print("INSERT statement could not be prepared.")
}
// 5
sqlite3_finalize(insertStatement)
if sqlite3_close_v2(db) == SQLITE_OK{
print("closed")
}
}
update function :
func updateDatabase(updateStatementString: String){
let db = connectDatabase("TimeTable.sqlite")
var updateStatement: COpaquePointer = nil
if sqlite3_prepare(db, updateStatementString, -1, &updateStatement, nil) == SQLITE_OK{
if sqlite3_step(updateStatement) == SQLITE_DONE{
print("Successfully update row.")
}
else{
print("Could not update row.")
}
}
else{
print("UPDATE statement could not be prepared")
}
sqlite3_finalize(updateStatement)
if sqlite3_close_v2(db) == SQLITE_OK{
print("closed")
}
}
Delete function :
func deleteInDatabase(id: Int){
let db = connectDatabase("TimeTable.sqlite")
let deleteStatementString = "DELETE FROM Jobs WHERE id = \(id)"
var deleteStatement: COpaquePointer = nil
if sqlite3_prepare(db, deleteStatementString, -1, &deleteStatement, nil) == SQLITE_OK{
if sqlite3_step(deleteStatement) == SQLITE_DONE{
print("Successfully deleted row.")
}
else{
print("Could not delete row.")
}
}
else{
print("DELETE statement could not be prepared")
}
sqlite3_finalize(deleteStatement)
if sqlite3_close_v2(db) == SQLITE_OK{
print("closed")
}
}
connectDatabase function :
func connectDatabase(fileName: String) -> COpaquePointer {
var db: COpaquePointer = nil
//Searching for path of database
let documentsURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
let fileURL = documentsURL.URLByAppendingPathComponent(fileName)
let dbPath: String = fileURL!.path!
let fileManager = NSFileManager.defaultManager()
if !fileManager.fileExistsAtPath(dbPath){ //If database not exist then...
let documentURL = NSBundle.mainBundle().resourceURL
let fromPath = documentURL!.URLByAppendingPathComponent(fileName) //Get database path from projects location
var error: NSError?
do {
try fileManager.copyItemAtPath(fromPath!.path!, toPath: dbPath) //Try to copy database from projects location to applications documents location
} catch let error1 as NSError{
error = error1
}
let alert: UIAlertView = UIAlertView()
if(error != nil){
alert.title = "Error Occured"
alert.message = error?.localizedDescription //If database is not exist in projects location then pop out error alert
}
else {
alert.title = "Successfully Copy" //Notify by an alert if copy successfully
alert.message = "Your database copy successfully"
if sqlite3_open(dbPath, &db) == SQLITE_OK {
print("Successfully opened connection to database") //Open database just copied
} else {
print("Unable to open database")
}
}
alert.delegate = nil
alert.addButtonWithTitle("Ok")
alert.show()
}
else{
print("Database already exist in \(dbPath)") //Notify by an alert if there's already a database in applications documents location
if sqlite3_open(dbPath, &db) == SQLITE_OK {
print("Successfully opened connection to database") //Open database without copy
} else {
print("Unable to open database")
}
}
return db
}
I'm sure that my app connected to database and there's nothing wrong with update, delete statements because I'm still able to update, delete records if it's not insert any records yet.
A couple of thoughts:
If sqlite3_open fails, you should examine the numeric return code. If another SQLite call fails, I'd suggest examining the result of sqlite3_errmsg. Using those, you can diagnose why it's failing.
Having done that, you informed us that it reported "database is locked".
That is generally a result of trying to perform a query while another is still in progress. I don't see anything here, but I wonder if you have some other code that does a SELECT for which you may have neglected to finalize/close (or perhaps you're in the middle of a SELECT and then trying to do one of these update statements).
I'd suggest putting a log statement in connectDatabase and again everywhere you close the database, and I bet you'll find some sequence where you try to open a database prior to seeing the close of the prior call.
Regardless, this "database is locked" has been discussed extensively on Stack Overflow, so see that for more information.
Currently trying to save objects to parse database, when i println the objects they contain the new array that i wanted inside the array field but for some reason it won't save to table been on this a while any ideas?
The array needs to add a new integer value for each one corresponding to each the queries,the "test" array archives this but saving each object to the USER class seems to be a problem
func taskAllocation(){
// var query = PFQuery(className: "Tasks")
var query = PFUser.query()
// let user = PFUser()
var posts:[PFUser] = []
query.whereKey("Year", equalTo: yearTextField.text.toInt())
query.whereKey("Class", equalTo: classTextField.text.toInt())
query.whereKey("Keystage", equalTo: keystageTextField.text.toInt())
// query.limit = 10
query.findObjectsInBackgroundWithBlock { (objects: [AnyObject]!, error: NSError!) -> Void in
if error != nil {
println(error)
} else {
if objects.isEmpty {
println("empty query")
}
else {
for object in objects as [PFUser] {
var test:[Int] = object["taskIDs"] as [Int]
test.append(self.getIndex)
println(test)
object.setValue(test, forKey: "taskIDs")
object["tasksCorrect"] = "hello"
posts.append(object)
}
println(posts)
PFUser.saveAllInBackground(posts)
}}}
I assume you want to save these components to your "Tasks" class and not your User class. PFUser Query is just for the "_User" class which does not have the tasks in it.
var tasks:PFObject = PFObject(className: "Tasks")
// Make sure in your parse data table you have the columns created as type String or Int
item["Year"] = yearTextField.text.toInt()
item["Keystage"] = keystageTextField.text.toInt()
item["Class"] = classTextField.text.toInt())
// Save the task to a user, make sure you create a Username column in your data table
item["Username"] = PFUser.currentUser().username
// save it
item.saveInBackgroundWithTarget(nil , selector: nil)
Your code is a little clunky so I made assumptions on what your trying to do. It might be beneficial taking a screen shot of your task class.