Native framework for copying file on macOS [closed] - macos

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 2 years ago.
Improve this question
Is there a framework in macOS that I can use to programmatically copy files and get a progress bar the same as copying files from Finder?
Alternatively, I can do the copy using cp or filesystem APIs and use NSProgressIndicator to implement the progress bar.

You can use copyFile.
Here is example of copyfile with Progress Callback.

I had the same problem, but I needed it in swift.
But great Project Parag it really help me!
Thats my Copy Function.
func createCopy(of:URL, to:URL,skip:Bool) throws {
if !skip {
if FileManager.default.fileExists(atPath: to.path) {
print("\n\n did not copy \n\(of.lastPathComponent.utf8CString) \nto \n\(to.path)\n\n")
return
}
}
//open window
let copyStoryboard = NSStoryboard.init(name: "copyProgessWindow", bundle: nil)
self.progressWindowConrtoller = copyStoryboard.instantiateController(withIdentifier: "CopyProgressWindow") as! NSWindowController
let application = NSApplication.shared
//set Up view
let viewController = self.progressWindowConrtoller!.contentViewController as! CopyViewController
viewController.path_copyFrom.url = of
viewController.path_copyTo.url = to
DispatchQueue.global(qos: .userInteractive).async{
do{
let bufferSize:Int = 64*1024;
var buffer = [Int32](repeating: 0, count: Int(bufferSize))
let open_source = open(of.path, O_RDONLY);
let open_target = open(to.path, O_RDWR | O_CREAT | O_TRUNC, S_IWUSR | S_IRUSR);
let attrSource = try FileManager.default.attributesOfItem(atPath: of.path)
let sourceFileSize = attrSource[FileAttributeKey.size] as! UInt64
var bytes_read = 0;
bytes_read = read(open_source, &buffer, bufferSize);
while(bytes_read > 0){
write(open_target, &buffer, bufferSize);
if FileManager.default.fileExists(atPath: to.path) {
let attrTarget = try FileManager.default.attributesOfItem(atPath: to.path)
let targetFileSize = attrTarget[FileAttributeKey.size] as! UInt64
DispatchQueue.main.async {
viewController.progressbar_progBar.doubleValue = self.progressProcent
}
self.progressProcent = Double(targetFileSize)/Double(sourceFileSize)
print(self.progressProcent)
}
bytes_read = read(open_source, &buffer, bufferSize);
}
// copy is done, or an error occurred
close(open_source);
close(open_target);
sleep(2)
DispatchQueue.main.async {
application.abortModal()
self.progressWindowConrtoller!.close()
}
}
catch{
print(error)
}
}
application.runModal(for: self.progressWindowConrtoller!.window!)
}
I have a storyboard file called 'copyProgessWindow.storyboard' and important is the storyboardID set to 'CopyProgressWindow'. and it looks like this:
storyboardCopyProgress
Thats my ViewController for the view you see:
class CopyViewController: NSViewController {
#IBOutlet weak var path_copyFrom: NSPathControl!
#IBOutlet weak var path_copyTo: NSPathControl!
#IBOutlet weak var label_remaindingTime: NSTextField!
#IBOutlet weak var progressbar_progBar: NSProgressIndicator!
override func viewDidLoad() {
super.viewDidLoad()
}
}

Related

How to fetch using string in swift

I was just wondering how would I be able to use a searched barcode to fetch using Core Data in Swift. I'm basically passing a barcode to a static func method, but how would I be able to use that to fetch the data from the Core Data?
Here is the barcode when detected:
func barcodeDetected(code: String) {
// Let the user know we've found something.
let alert = UIAlertController(title: "Found a Barcode!", message: code, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Search", style: UIAlertActionStyle.Destructive, handler: { action in
// Remove the spaces.
let trimmedCode = code.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
// EAN or UPC?
// Check for added "0" at beginning of code.
let trimmedCodeString = "\(trimmedCode)"
var trimmedCodeNoZero: String
if trimmedCodeString.hasPrefix("0") && trimmedCodeString.characters.count > 1 {
trimmedCodeNoZero = String(trimmedCodeString.characters.dropFirst())
// Send the doctored barcode
ProductDetailsViewController.searchCode(trimmedCodeNoZero)
} else {
// Send the doctored barcode
ProductDetailsViewController.searchCode(trimmedCodeString)
}
self.navigationController?.popViewControllerAnimated(true)
}))
self.presentViewController(alert, animated: true, completion: nil)
}
My Product Class:
import UIKit
import Foundation
import CoreData
class ProductDetailsViewController: UIViewController, NSFetchedResultsControllerDelegate {
#IBOutlet weak var productLabel: UILabel!
#IBOutlet weak var priceLabel: UILabel!
#IBAction func addProduct(sender: AnyObject) {
let AppDel = UIApplication.sharedApplication().delegate as? AppDelegate
let context:NSManagedObjectContext = (AppDel?.managedObjectContext)!
let ent = NSEntityDescription.entityForName("Products", inManagedObjectContext: context)
var newProduct = ProductItem(entity: ent!, insertIntoManagedObjectContext: context)
newProduct.title = productLabel.text
//newProduct.price = priceLabel.text
/*context.save(nil)
print(newProduct)
print("Object Saved")*/
}
private(set) var PRODUCT_NAME = ""
private(set) var PRODUCT_PRICE = ""
private var menuItems:[ProductItem] = []
static func searchCode(codeNumber: String) -> String{
let barcodeNumber = codeNumber
return barcodeNumber
}
deinit{
NSNotificationCenter.defaultCenter().removeObserver(self)
}
override func viewDidLoad() {
super.viewDidLoad()
productLabel.text = "Scan a Product"
priceLabel.text = ""
NSNotificationCenter.defaultCenter().addObserver(self, selector: "setLabels:", name: "ProductNotification", object: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
I already added the items into Core Data successfully and was able to load all items into a table in my app. Now with the barcode scanned I want to be able to just load the products with the barcode and i'm stuck on that part. As you can see my static fun searchCode is receiving the barcode from barcodeDetected but what should I do next to fetch it? Thanks.
EDIT:
Core Data Entity
import Foundation
import CoreData
#objc(ProductItem)
class ProductItem: NSManagedObject{
#NSManaged var barcodeNum:String?
#NSManaged var box_height:NSNumber?
#NSManaged var box_length:NSNumber?
#NSManaged var box_width:NSNumber?
#NSManaged var price:NSNumber?
#NSManaged var sku:String?
#NSManaged var weight:NSNumber?
#NSManaged var title:String?
}
To fetch the correct ProductItem, you need to use a predicate (see the Apple Documentation here). In your case, you could use something like this:
let AppDel = UIApplication.sharedApplication().delegate as? AppDelegate
let context:NSManagedObjectContext = (AppDel?.managedObjectContext)!
let fetchRequest = NSFetchRequest(entityName: "ProductItem")
fetchRequest.predicate = NSPredicate(format: "barcodeNum == %#",codeNumber)
let results = try! context.executeFetchRequest(fetchRequest) as! [ProductItem]
if results.count > 0 { // great, you found (at least one) matching item
let scannedProduct = results[0]
// from here you can access the attributes of the product
// such as title, price, sku, etc.
...
} else { // not found
...
}
Note that I've use try! for brevity, but in practice you should use proper do ... catch syntax and handle any errors.
I'm not clear why you are using a static func in the ProductDetailsViewController; a common approach would be to use the above fetch within your barcodeDetected method, and then to segue to the ProductDetailsViewController passing the relevant ProductItem for display/editing or whatever. Or to display an alert view if the product was not found.

How can I rename label with another class attribute?

So, here is the part of class OnboardingViewController, where declared and initialized reviewConsentStep.
class OnboardingViewController: UIViewController {
// MARK: IB actions
#IBAction func joinButtonTapped(sender: UIButton) {
let consentDocument = ConsentDocument()
let consentStep = ORKVisualConsentStep(identifier: "VisualConsentStep", document: consentDocument)
let healthDataStep = HealthDataStep(identifier: "Health")
let signature = consentDocument.signatures!.first!
let reviewConsentStep = ORKConsentReviewStep(identifier: "ConsentReviewStep", signature: signature, inDocument: consentDocument)
reviewConsentStep.text = "Review the consent form."
reviewConsentStep.reasonForConsent = "Consent to join the Developer Health Research Study."
let passcodeStep = ORKPasscodeStep(identifier: "Passcode")
passcodeStep.text = "Now you will create a passcode to identify yourself to the app and protect access to information you've entered."
let completionStep = ORKCompletionStep(identifier: "CompletionStep")
completionStep.title = "Welcome aboard."
completionStep.text = "Thank you for joining this study."
let orderedTask = ORKOrderedTask(identifier: "Join", steps: [consentStep, reviewConsentStep, healthDataStep, passcodeStep, completionStep])
let taskViewController = ORKTaskViewController(task: orderedTask, taskRunUUID: nil)
taskViewController.delegate = self
presentViewController(taskViewController, animated: true, completion: nil)
}
I want to use reviewConsentStep.signature?.givenName and reviewConsentStep.signature?.familyName here:
#IBOutlet var applicationNameLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
applicationNameLabel.text = reviewConsentStep.signature?.givenName/////////... here
If it possible, please tell me how can I do it?

Sent email, without confirmation using swift (OSX)

I cannot manage to send an email using Swift on OSX.
Its almost do the work, but don't sent the email, and on my personal computer, its opening Google Chrome for some raison.
Here is my code
import Cocoa
class ViewController: NSViewController, NSSharingServiceDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
#IBAction func mag(sender: AnyObject) {
let body = "BODY EMAIL"
let shareItems = [body] as NSArray
var service = NSSharingService(named: NSSharingServiceNameComposeEmail)
service?.delegate = self
service?.recipients = ["email#address.com"]
let subject = "Subject!"
service?.subject = subject
service?.performWithItems(shareItems as [AnyObject])
}
}

Using xcode 6 and Swift, how can I grab all objectIds from a class on parse and put them into an array?

I am making a tiny quiz app to help my students study for tests. I have the questions on parse.com and successfully can query objects by their ID one at a time, but I end up having to hard code all the objectIds, and what I would like to do is grab the objectIds, put them into an array, and then pull a random question/objectID from that array as the students click through the questions.
I'm a novice, so ... while I may be able to understand the logic, I'm not sure how to write the code.
Here is the code I'm currently using ... but it doesn't include my failed attempts to put the object IDs in an array. I've been trying to add a function CallIDs() with a parse query to get them all, but so far ... no luck. Any ideas?
import UIKit
import Parse
class ViewController: UIViewController {
var ObjectIDs : [String]!
var Question : String!
var Answers : [String]!
var Answer : String!
#IBOutlet var QuestionLabel: UILabel!
#IBOutlet var Button1: UIButton!
#IBOutlet var Button2: UIButton!
#IBOutlet var Button3: UIButton!
#IBOutlet var Button4: UIButton!
#IBOutlet var AnswerResult: UILabel!
#IBOutlet var Next: UIButton!
#IBOutlet var QuizInstructions: UILabel!
var RandomID = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
Hide()
CallData()
}
func GetRandomObjectID() {
ObjectIDs = ["jr92lfjbQc","r0C8oC4aJ6","XbTTX8xBRf","cjV2z4PSvV","wATbbu0JoX","9Y6HzfeeoD","mNHCMaao41","5qRcqyyXOL","JaLCoeyA1T","nrnifGOP1T","aDAQ6t3saJ","jKF0ZhmPxh"]
RandomID = Int (arc4random_uniform(UInt32(ObjectIDs.count)))
}
func CallData() {
GetRandomObjectID()
var query : PFQuery = PFQuery(className: "QuestionsandAnswers")
query.getObjectInBackgroundWithId(ObjectIDs[RandomID]) {
(ObjectHolder : PFObject!, error : NSError!) -> Void in
if (error == nil) {
self.Question = ObjectHolder ["Question"] as String!
self.Answers = ObjectHolder ["Answers"] as Array!
self.Answer = ObjectHolder ["Answer"] as String!
if (self.Answers.count > 0) {
self.QuestionLabel.text = self.Question
self.Button1.setTitle(self.Answers[0], forState: UIControlState.Normal)
self.Button2.setTitle(self.Answers[1], forState: UIControlState.Normal)
self.Button3.setTitle(self.Answers[2], forState: UIControlState.Normal)
self.Button4.setTitle(self.Answers[3], forState: UIControlState.Normal)
}
} else {
NSLog("Something is wrong, dude. Sorry.")
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func Hide() {
AnswerResult.hidden = true
Next.hidden = true
}
func UnHide() {
AnswerResult.hidden = false
Next.hidden = false
}
#IBAction func Button1Action(sender: AnyObject) {
UnHide()
if (Answer == "0") {
AnswerResult.text = "Woot! That's correct!"
} else {
AnswerResult.text = "Nope. Try Again."
}
}
#IBAction func Button2Action(sender: AnyObject) {
UnHide()
if (Answer == "1") {
AnswerResult.text = "Woot! That's correct!"
} else {
AnswerResult.text = "Nope. Try Again."
}
}
#IBAction func Button3Action(sender: AnyObject) {
UnHide()
if (Answer == "2") {
AnswerResult.text = "Woot! That's correct!"
} else {
AnswerResult.text = "Nope. Try Again."
}
}
#IBAction func Button4Action(sender: AnyObject) {
UnHide()
if (Answer == "3") {
AnswerResult.text = "Woot! That's correct!"
} else {
AnswerResult.text = "Nope. Try Again."
}
}
#IBAction func Next(sender: AnyObject) {
CallData()
Hide()
}
}
///// well ... here is the function I attempted to code, but it isn't working:
func CallIDs() {
var query = PFQuery(className: “QuestionsandAnswers”) 
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]!, error: NSError!) -> Void in 
for object in objects {
self.objectIdsArray.append(object.objectId)
  }
}
}
I think the underlying misunderstanding in this question is that objects are to be retrieved using their ids. The requirement is for a random object, and that can be achieved better by knowing only the count of the objects stored on the server.
Getting the count we can select a random object by setting a random skip for a query. So, in the completion block of countObjectsInBackgroundWithBlock, get a random number up to that count like this:
let randomSkip = arc4random_uniform(count)
Now we're ready to do a query with no object id, setting query.skip = randomSkip, and query.limit = 1.
EDIT - If I were to build this in Objective-C, I would do it as follows:
- (void)randomQuestion:(void (^)(NSString *question, NSArray *answers))completion {
PFQuery *countQuery = [PFQuery queryWithClassName:#"QuestionsandAnswers"];
[countQuery countObjectsInBackgroundWithBlock:^(int count, NSError *error) {
NSInteger randomSkip = arc4random_uniform(count);
PFQuery *query = [PFQuery queryWithClassName:#"QuestionsandAnswers"];
query.skip = randomSkip;
query.limit = 1;
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
if (objects.count) {
PFObject *questionAndAnswerObject = objects[0];
NSString *question = questionAndAnswerObject[#"Question"];
NSArray *answers = questionAndAnswerObject[#"Answers"];
completion(question, answers);
} else {
NSLog(#"no error, but no Q&A objects found");
}
} else {
NSLog(#"there was an error %#", error);
completion(nil, nil);
}
}];
}];
}
I am not sure where you declare the array objectIdsArray. I was unable to find it. However the reason you may be having trouble replacing an existing array is because the function you are calling, findObjectsInBackgroundWithBlock does not run on the main thread. The code will continue to execute rather then waiting for the objectIds to download.
In order to make sure that you have downloaded the objectIds first before you try to use them, you may want to use the following code:
func CallIDs() {
var query = PFQuery(className: “QuestionsandAnswers”)
query.selectKeys(["objectId"])
self.objectIdsArray = query.findObjects()
}
Note: When run, you should see the following message:
Warning: A long-running operation is being executed on the main thread.
However I have not yet found this to be a problem. If the download is quick, it should not be noticeable. If it is taking a considerable amount of time, you can add in a UIActivityIndicatorView.

Share variables between functions in Swift

I started Swift today.
I have no idea how to share variables between functions. Does anyone have an idea?
#IBAction func function1(sender : NSButton) {
var variable1 = 1
}
#IBAction func function2(sender: NSButton) {
println(variable1)
}
I googled about this, but I couldn't find the solution.
I'm using Xcode6 beta6.
----EDITED----
The specific thing I wanted to do was the code below.
var files: [AnyObject] = [AnyObject]()
#IBAction func selectFiles(sender : NSButton) {
let openDlg = NSOpenPanel()
openDlg.allowsMultipleSelection = true
openDlg.canChooseFiles = true
openDlg.canChooseDirectories = true
if openDlg.runModal() == NSOKButton{
var files = openDlg.URLs
}
}
#IBAction func startScript(sender: NSButton) {
for var i = 0; i < files.count; i++ {
var fileName:AnyObject = files[i];
println(files[i])
}
}
In fact, I wanted to open a dialog to select files, and log the paths of those files.
No error occurs in this code, but nothing is printed. How can I do so?
Why are you not declaring variable1 outside and then use it in both of your functions as shown below:
var variable1 = 0
#IBAction func function1(sender : NSButton) {
variable1 = 1
}
#IBAction func function2(sender: NSButton) {
println(variable1)
}
EDIT:
Based on the new code you posted, you are doing
var files = openDlg.URLs
Here, you are declaring a local variable and not using your global one.
Remove the var from here and keep only
files = openDlg.URLs

Resources