I have a phonelist application that loads employees from a database and lets users search through them. They have an option to add the contact to their phone. Currently I can add all of the data to the phone as a CNMutableContact(), but if I open up my iOS contact application the image data only works the first time I open the application. If I open it later the images are gone, but all of the other information is correct. Is there something I need to do for saving the image? Does the image need to be stored locally aside from saving it through the save request? The CNMutableContact uses a Data object for the image data. Using Swift 4, iOS target 9.0+
let contact = CNMutableContact()
contact.givenName = givenName
contact.familyName = familyName
contact.imageData = UIImagePNGRepresentation(image)
let store = CNContactStore()
let saveRequest = CNSaveRequest()
saveRequest.add(contact, toContainerWithIdentifier: nil)
do {
try store.execute(saveRequest)
} catch let error {
print(error)
}
Related
I am using Xcode and swift. I am trying to create an app that automates receipt documentation instead of traditionally filling in the information in a spreadsheet.
I have used the vision framework to pull data about the receipt and classify it. I was able to classify the essential information (Price, Date, etc), but I'm struggling with how I can store and display the data in a file.
I have looked into the different databases I could use, but I was wondering if there is a short way to upload this data from the app directly to Google Spreadsheets using swift. In short, even if I will go with the database approach, I would still need to display the data in an Excel or CSV way, and I'm unsure of what would be a good approach for that. Any ideas?
You can use sql database but Core Data is very great too if you need to store datas. Specially if you need to sync them with iCloud.
In the past i have always use sql but now i find CoreData just better, more clean and more easy (after some time to learn how to use it).
About CSV you can export your datamodel with this sample of code:
// MARK: - Exoprt to CSV
#IBAction func selectorexport(toCSV sender: Any) {
let docPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).map(\.path)[0]
let filePath = URL(fileURLWithPath: docPath).appendingPathComponent("file.csv").path
let contents = String(repeating: "\0", count: 0)
//fill contents with data in csv format
// ...
//var error: Error?
do {
try contents.write(
toFile: filePath,
atomically: true,
encoding: .utf8)
} catch {
}
// check for the error
let fileUrl = URL(fileURLWithPath: filePath)
let activityItems = ["file.csv", fileUrl] as [Any]
let activityViewController = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
if let popoverController = activityViewController.popoverPresentationController {
popoverController.barButtonItem = btShare
popoverController.permittedArrowDirections = []
}
// Present action sheet.
present(activityViewController, animated: true)
}
I'm trying to save images using their file paths but every time that I kill the Xcode simulator and restart it, the location of the images changes and my imageView is blank. I know for a fact that the location changes because I print out the file path when I try to pick an image from the photo library and it's different each time.
I access the URL of the UIImage
let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
let url = info[UIImagePickerController.InfoKey.imageURL] as! URL
After which I save the URL as a string to my realm database. I've tried converting it to string via all of these
let imageFilePath = url.relativeString
let imageFilePath = url.absoluteString
let imageFilePath = url.relativePath
but none of them worked. I'm a newbie to Swift so let me know if I've missed any key details needed.
At my project i need to send user id's to widget in iOS. But for do that, my user needs to open application once. Without opening, information stays only 1 day, after that it vanishes and widget stops showing information and await for opening application.
For do that i used appGroup.
What is the correct way to use transfer data from my project to widget?
Swift 5
Follow these steps to pass data from the host app to extensions.
Select project target > Capabilities > add new app group (if you have enabled permissions for your developer account otherwise enable that first)
Select the extension target and repeat the same.
if let userDefaults = UserDefaults(suiteName: "group.com.yourAppgroup") {
createEventDic.removeAll()
let eventDic = NSMutableDictionary()
eventDic.setValue("YourString", forKey: "timeFontName")
createEventDic.append(eventDic)
let resultDic = try? NSKeyedArchiver.archivedData(withRootObject: createEventDic, requiringSecureCoding: false)
userDefaults.set(resultDic, forKey: "setWidget")
userDefaults.synchronize()
} else {
}
Now go to your app extension and do these steps to get the passed data.
if let userDefaults = UserDefaults(suiteName: "group.com.yourAppGroup") {
guard let testcreateEvent = userDefaults.object(forKey: "testcreateEvent") as? NSData else {
print("Data not found in UserDefaults")
return
}
do {
guard let eventsDicArray = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(testcreateEvent as Data) as? [NSMutableDictionary] else {
fatalError("loadWidgetDataArray - Can't get Array")
}
for eventDic in eventsDicArray {
let timeFontName = eventDic.object(forKey: "timeFontName") as? String ?? ""
}
} catch {
fatalError("loadWidgetDataArray - Can't encode data: \(error)")
}
}
Hopefully, it will help. Cheers!
For do that i used appGroup.
What is the correct way to use transfer data from my project to
widget?
What you did so far (App Grouping) is one of the steps that you should follow. Next, as mentioned in App Extension Programming Guide - Sharing Data with Your Containing App:
After you enable app groups, an app extension and its containing app
can both use the NSUserDefaults API to share access to user
preferences. To enable this sharing, use the initWithSuiteName: method
to instantiate a new NSUserDefaults object, passing in the identifier
of the shared group.
So, what you have to do so far is to let the data to be transferred by the UserDefautls. For instance:
if let userDefaults = UserDefaults(suiteName: "group.com.example.myapp") {
userDefaults.set(true, forKey: "myFlag")
}
thus you could pass it to the widget:
if let userDefaults = UserDefaults(suiteName: "group.com.example.myapp") {
let myFlag = userDefaults.bool(forKey: "myFlag")
}
And you follow the same approach for passing the data vise-versa (from the widget to the project).
In Xamarin Forms, we need to use DI to pass the data to the ios project then we can put it into NSUserDefaults
Info: Grouping application is mandatory
Xamarin iOS project - Putting Data into NSUserDefaults
var plist = new NSUserDefaults("group.com.test.poc", NSUserDefaultsType.SuiteName);
plist.SetBool(true, "isEnabled");
plist.Synchronize();
Today Extension - Getting data from NSUserDefaults
var plist = new NSUserDefaults("group.com.test.poc", NSUserDefaultsType.SuiteName);
var result = plist.BoolForKey("isEnabled");
Console.WriteLine($"The result of NSUserdefaults: logesh {result}");
I create/update contacts, using CNMutableContact.
I can set new image via imageData property, but I need to set custom crop information for creating thumbnail. Property thumbnailImageData is read-only.
Code:
let cnContact = CNMutableContact()
cnContact.imageData = imageData //created before
How to add custom thumbnailImage crop?
It seems that setting a thumbnail is not possible in iOS. However, by definition, a thumbnail of an image is the same image cropped to a smaller dimension. Hence iOS will auto generate the thumbnail from the image data set on the contact while saving the contact.
If you want to setup a different images for thumbnail and actual contact image, iOS will not allow you to do this.
Problem I have:
Before adding a new contact (CNMutableContact reference) in the user's contacts, I want to display the contact to the user. I can use the imageData to setup the new contact's image. However, when using CNContactViewController to display this new contact, the image is not cropped as per thumbnail. The thumbnail image showed looks super weird and scaled. How to resolve this?
Solution:
This occurs because the thumbnailImageData property on the CNMutableContact object is nil. This property cannot be set by the developers. This property can only be set by iOS internals and is auto generated by iOS while saving the contact.
So, before displaying the CNMutableContact object, you should save it to the users contacts, to kick in the auto-thumbnail-generation, and then immediately delete the contact.
The following extension on CNMutableContact depicts what you can do to achieve this.
extension CNMutableContact {
func generateThumbnailImage() {
if self.thumbnailImageData != nil {
return
}
// contact.thumbnailImageData is nil
// First save the contact for the thumbnail to be generated
let saveRequest = CNSaveRequest()
saveRequest.add(self, toContainerWithIdentifier: nil)
do {
try CNContactStore().execute(saveRequest)
} catch let error {
print("Error occurred while saving the request \(error)")
}
// self.thumbnailImageData is not nil. Contact Store will generate the thumbnail for this contact with the imageData provided.
// Now delete the contact
let deleteRequest = CNSaveRequest()
deleteRequest.delete(self)
do {
try CNContactStore().execute(deleteRequest)
} catch let error {
print("Error occurred while deleting the request \(error)")
}
// The contact is removed from the Contact Store
// However, the contact.thumbnailImageData is not nil anymore. Contacts Store has generated the thumbnail automatically with the imageData provided.
}
}
I want to upload Images, Videos and some PList files on iCloud on Button Click event. I did following code but there are some issues.
(Q.1) It takes too much time to upload data on iCloud Dashboard http://icloud.developer.apple.com/dashboard/.
(Q.2) Sometime Dashboard shows data and sometimes not.
(Q.3) One important question: right now its data shows in iCloud Dashboard, after app go live will it be visible to user's iCloud drive? because I need to this: data will visible to user's iCloud drive in a folder.
(Q.4) As I want to upload images, video and plist files, so my following coding approach is correct or not? else I need to use Key-Value storage or iCloud-Document upload or iCloud Drive upload? (right now i am using iCloud Drive upload method)
Below is my code:
private let pathsForDocDir = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let DOCUMENT_DIRECTORY: AnyObject = pathsForDocDir[0]
let filePath = DOCUMENT_DIRECTORY.stringByAppendingPathComponent("image1.png")
let File : CKAsset? = CKAsset(fileURL: NSURL(fileURLWithPath: filePath))
let newRecord:CKRecord = CKRecord(recordType: "album")
newRecord.setValue(File, forKey: "ImageOrVideo")
let privateDB = CKContainer.defaultContainer().privateCloudDatabase
privateDB.saveRecord(newRecord) { (record : CKRecord?, error : NSError?) in
if error != nil {
print(error?.localizedDescription)
} else {
dispatch_async(dispatch_get_main_queue()) {
print("finished")
}
}
}
I am using this code in For loop because I have multiple files to upload.
(Q.5) And also I need to click on "Add Record ID Query Index" on iCloud Dashboard. you can see the screenshot of iCloud Dashboard.