How can my OS X app accept drag-and-drop of picture files from Desk in Cocoa? - swift

I got an error when I drag files to my macOS app,
[sandbox] Failed to get a sandbox extension,when i set App Sandboxvalue boolean no,it is ok,but i want put my app to appstore,I must set App Sandbox YES, how can I do?
class FYOpenDragFileView: NSView{
override func draggingEnded(_ sender: NSDraggingInfo) {
print("松手了")
setupWithActive(active: false)
}
override func draggingExited(_ sender: NSDraggingInfo?) {
isDraging = false
setupWithActive(active: false)
print("draggingExited 进去又出来")
}
override func updateDraggingItemsForDrag(_ sender: NSDraggingInfo?) {
guard let next = delegate else {
return;
}
next.fileDraging()
print("更新拖动文件")
}
override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
guard let items = sender.draggingPasteboard.pasteboardItems else{
return false
}
var datas = [Data]()
for i in 0..<items.count{
let item = items[i] .string(forType: .fileURL)
if item != nil {
// this have an error
//[sandbox] Failed to get a sandbox extension
let da = try? Data(contentsOf: URL(string: item!)!)
guard let next = da else {
continue
}
datas.append(next)
}
}
QiniuUploadManger.uploadImage(nil, data: datas)
return true
}
}

With sandboxing, you'll have to set the appropriate "entitlements" for your app to receive drag-&-dropped files, which is probably why you're getting this error.
The entitlements file should already have been generated for you when you enabled Sandboxing. See this Apple documentation for details.

Related

Eureka in swift List Selection Selected Value Automatically Deselect when navigating away

I am implementing Eureka list selection. On the language selections, there are 7 values to choose from. Value 1 to 6 is good. But when the last one selected and user navigates away from the VC, it's deselected automatically. I wonder if there is something wrong with my code. I have tried to "hardcode" the last selection on viewWillAppear just so the app goes smoothly and yes it is. But it's a little weird because none of the selection selected. I am a beginner to programming and greatly appreciated any help. Thank you
import Eureka
class ListSectionsController: FormViewController {
let defaults = UserDefaults.standard
var languageSelected = "English (default)"
override func viewDidAppear(_ animated: Bool) {
defaults.set(languageSelected, forKey: "LanguageSelection")
}
override func viewWillAppear(_ animated: Bool) {
if let language = defaults.string(forKey: "LanguageSelection") {
if language == "Korean 한국어" {
languageSelected = language
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
let languageSelections = ["English (default)", "Spanish", "Japanese 日本語", "Chinese Mandarin 普通话", "Indonesian", "Dutch - het Nederlands", "Korean 한국어"]
form +++ SelectableSection<ImageCheckRow<String>>() { section in
section.header = HeaderFooterView(title: "Language Selection")
}
for option in languageSelections {
if let language = self.defaults.string(forKey: "LanguageSelection") {
self.form.setValues([language : language])
} else {
self.form.setValues([languageSelected : languageSelected])
}
form.last! <<< ImageCheckRow<String>(option){ lrow in
lrow.title = option
lrow.selectableValue = option
lrow.value = nil
}
}
}
override func valueHasBeenChanged(for row: BaseRow, oldValue: Any?, newValue: Any?) {
if row.section === form[0] {
if let selected = (row.section as! SelectableSection<ImageCheckRow<String>>).selectedRow()?.baseValue {
print("Selected: \(selected)")
languageSelected = selected as! String
defaults.set(languageSelected, forKey: "LanguageSelection")
}
} else if row.section === form[1] {
print("Mutiple Selection:\((row.section as! SelectableSection<ImageCheckRow<String>>).selectedRows().map({$0.baseValue}))")
}
}
}

Give a new url to the browser with Swift macOS

I could find a way to open a specific browser (with macOS and Swift):
#IBAction func frx(_ sender: NSButton) {
NSWorkspace.shared.open(URL(fileURLWithPath: "/Applications/Firefox.app"))
}
Is it possible to give to that Firefox window a new url in a posterior moment and reload the page? (Give the address not when I launch the application but later)
struct Firefox {
static func open(path: String) {
let ff_url = NSURL(fileURLWithPath: "/Applications/Firefox.app", isDirectory: true) as URL
if let www_url = URL(string: path) {
NSWorkspace.shared.open([www_url], withApplicationAt: ff_url, configuration: NSWorkspace.OpenConfiguration()) { app, error in
if let error = error {
// handle error
}
if let _ = app {
// handle success
}
}
} else {
// handle error
}
}
}

Can't get QuickLook to work when trying to preview files

I am writing a macOS application with Swift using story boards. I have a NSTableView which contains files that I want the user to be able to preview via QuickLook.
I seemingly have everything in place and my code looks very similar to what has been described here: QuickLook consumer as a delegate from an NSViewController, but I keep getting the error
-[QLPreviewPanel setDataSource:] called while the panel has no controller - Fix this or this will raise soon.
See comments in QLPreviewPanel.h for -acceptsPreviewPanelControl:/-beginPreviewPanelControl:/-endPreviewPanelControl:.
I've been trying to adapt the solution of above post to my situation with Swift and story boards.
The main pieces are:
import Quartz
class ViewController: NSViewController, QLPreviewPanelDataSource, QLPreviewPanelDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let windowNextResponder = self.view.window?.nextResponder
self.view.window?.nextResponder = self
self.nextResponder = windowNextResponder
}
// *** Quicklook stuff ***
#IBAction func quickLookButtonAction(_ sender: Any) {
guard qlPanel != nil else {
return
}
if qlPanel!.currentController == nil {
print ("No controller")
//qlPanel!.windowController = self.view.window?.windowController
// qlPanel!.updateController()
} else {
print (qlPanel!.currentController)
}
qlPanel!.delegate = self
qlPanel!.dataSource = self
qlPanel!.makeKeyAndOrderFront(self)
}
func numberOfPreviewItems(in panel: QLPreviewPanel!) -> Int {
return CSVarrayController.selectedObjects.count
}
func previewPanel(_ panel: QLPreviewPanel!, previewItemAt index: Int) -> QLPreviewItem! {
let file = CSVarrayController.selectedObjects[index] as! CSVfile
return file.url as NSURL
}
override func acceptsPreviewPanelControl(_ panel: QLPreviewPanel!) -> Bool {
return true
}
override func beginPreviewPanelControl(_ panel: QLPreviewPanel!) {
panel.dataSource = self
panel.delegate = self
}
override func endPreviewPanelControl(_ panel: QLPreviewPanel!) {
panel.dataSource = nil
panel.delegate = nil
}
}
With or without messing with the responder chain I get the error.
The delegate functions all get called as expected as well.
Remove
qlPanel!.delegate = self
qlPanel!.dataSource = self
in quickLookButtonAction, the viewcontroller isn't in control yet. Wait for beginPreviewPanelControl.
From the documentation for currentController:
You should never change the preview panel’s state (its delegate, datasource, and so on) if you are not controlling it.
From comments in QLPreviewPanel.h for -beginPreviewPanelControl::
Sent to the object taking control of the Preview Panel.
The receiver should setup the preview panel (data source, delegate, binding, etc.) here.

Basic Sinch Sample in Swift - but no Sound

first of all thank you for reading my lines.
For an idea I'm currently trying to dive into the Swift world (I only have very basic programming knowledge - no Objective C knowledge
).
I tried to set up the following lines to create a very basic app-to-app sample in Sinch. After my code I let you know what the issues are.
import UIKit
import Sinch
var appKey = "APP_KEY_FROM_MY_ACCOUNT"
var hostname = "clientapi.sinch.com"
var secret = "SECRET_FROM_MY_ACCOUNT"
class CViewController: UIViewController, SINCallClientDelegate, SINCallDelegate, SINClientDelegate {
var client: SINClient?
var call: SINCall?
var audio: SINAudioController?
//Text field in the main storyboard
#IBOutlet weak var userNameSepp: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.initSinchClient()
}
//initialize and start the client as a fixed "userA"
func initSinchClient() {
client = Sinch.client(withApplicationKey: appKey, applicationSecret: secret, environmentHost: hostname, userId: "userB")
client?.call().delegate = self
client?.delegate = self
client?.startListeningOnActiveConnection()
client?.setSupportCalling(true)
client?.start()
}
//Did the Client start?
func clientDidStart(_ client: SINClient!) {
print("Hello")
}
//Did the Client fail?
func clientDidFail(_ client: SINClient!, error: Error!) {
print("Good Bye")
}
//Call Button in the main.storyboard ... if call==nil do the call ... else hangup and set call to nil
//the background color changes are my "debugging" :D
#IBAction func callSepp(_ sender: Any) {
if call == nil{
call = client?.call()?.callUser(withId: userNameSepp.text)
//for testing I change to callPhoneNumber("+46000000000").
// the phone call progresses (but I hear nothing),
// the phonecall gets established (but I hear nothing)
// and the phonecall gets ended (but of course I hear nothing)
self.view.backgroundColor = UIColor.red
call?.delegate = self
audio = client?.audioController()
}
else{
call?.hangup()
self.view.backgroundColor = UIColor.blue
call = nil
}
}
func callDidProgress(_ call: SINCall?) {
self.view.backgroundColor = UIColor.green
client?.audioController().startPlayingSoundFile("/LONG_PATH/ringback.wav", loop: true)
print("Call in Progress")
}
//I know that this works but I don't hear anything
func callDidEstablish(_ call: SINCall!) {
client?.audioController().stopPlayingSoundFile()
print("Call did Establish")
}
func callDidEnd(_ call: SINCall!) {
print("Call did end")
}
// this works fine
#IBAction func hangUpSepp(_ sender: Any) {
call?.hangup()
self.view.backgroundColor = UIColor.red
call = nil
}
// i work in a "sub view controller" - so i navigate here back to the main view controller
#IBAction func goBackMain(_ sender: Any) {
call?.hangup()
dismiss(animated: true, completion: nil)
client?.stopListeningOnActiveConnection()
client?.terminateGracefully()
client = nil
}
}
So I can call my private phone number or if I change to callUser I can call another app but I don't hear anything. What do I miss? It must have to do with the SINAudioController and the client's method audioController() but I don't know what I'm doing wrong. Thank you for your help.

Swift App Auto-Login not working

I followed this tutorial here to create an auto-login feature for ma Swift app: https://theswiftdev.com/2015/09/17/first-os-x-tutorial-how-to-launch-an-os-x-app-at-login/
The tutorial is pretty straightforward - the only problem is that I simply can not make it work with my app - it just doesn't work.
I have created a new project for the auto-login with the identifier "com.sascha-simon.com.NetWorkerAutoStarter".
func applicationDidFinishLaunching(_ aNotification: Notification)
{
let mainIdentifier = "com.sascha-simon.Mac.NetWorker"
let running = NSWorkspace.shared().runningApplications
var alreadyRunning = false
for app in running
{
if app.bundleIdentifier == mainIdentifier
{
alreadyRunning = true
break
}
}
if !alreadyRunning
{
DistributedNotificationCenter.default().addObserver(self, selector: #selector(AppDelegate.terminate), name: NSNotification.Name("killme"), object: mainIdentifier)
let path = Bundle.main.bundlePath as NSString
var components = path.pathComponents
components.removeLast()
components.removeLast()
components.removeLast()
components.append("MacOS")
components.append("NetWorker")
let newPath = NSString.path(withComponents: components)
NSWorkspace.shared().launchApplication(newPath)
}
else
{
self.terminate()
}
}
func applicationWillTerminate(_ aNotification: Notification)
{
// Insert code here to tear down your application
}
func terminate()
{
NSApp.terminate(nil)
}
My Main-App has the identifier "com.sascha-simon.NetWorker"
AppDelegate:
func applicationDidFinishLaunching(_ aNotification: Notification)
{
let starterIdentifier = "com.sascha-simon.NetWorkerAutoStarter"
var startedAtLogin = false
for app in NSWorkspace.shared().runningApplications
{
if app.bundleIdentifier == starterIdentifier
{
startedAtLogin = true
break
}
}
if startedAtLogin
{
DistributedNotificationCenter.default().post(name: NSNotification.Name("killme"), object: Bundle.main.bundleIdentifier!)
}
}
I have a NSPopup with a checkbox to enable the auto login:
#IBAction func startOSCheckedChange(_ sender: NSButton)
{
let value = sender.state == 1
SMLoginItemSetEnabled("com.sascha-simon.NetWorkerAutoStarter" as CFString, value)
}
The method returns true. I have exported the developer-id signed app, started it, enabled the auto login, logged out...and the app didn't start.
I have set an alert to the auto start project and the problem is, that it seems that the project is not started (and therefore the main project isn't started).
First I thought that I have to add a storyboard/MainMenu.xib file to the project (and add the key to the info.plist) but that didn't help either.
What could I have forgotten?