Swift CSVImporter Cannot use instance member path within property - swift

I am currently trying to import a CSV file using CSVImporter. The github repo says that it is up to date with the current Swift version 3.0. However I am getting an error which I couldn't find a solution to on the internet.
This is the error: http://imgur.com/imhSoQi
This is the github repo: https://github.com/Flinesoft/CSVImporter
I would gladly provide anymore information if needed.

These errors are unrelated to the CSVImporter library.
The first error happens because you are referring one ivar from another. Essentially this is not valid in Swift:
class ABC {
let hello = "Hello"
let hello_world = hello + " World" // references 'hello'
}
The second error happens because you directly put code into your class. Code in Swift lives in methods or in initialisers, but not directly in a class.
I think this may be what you want:
class ViewController {
let path = "/tmp/blub.csv"
func load() {
let importer = CSVImporter<[String]>(path: path)
importer.startImportingRecords ... {
...
}
}
}
And if this is part of a VC (e.g. you might want to display the CSV in a tableview), you probably want to load the data off the main queue, not in init().
P.S.: Do not only send image links to source code. Copy/paste the relevant source code into the question.

Related

Get the user's home directory from XPC

My (non-sandboxed) app has an embedded XPC helper which runs as root.
I would like to reference the (real) user's home directory from inside my helper, but these usual suspects simply return /var/root:
FileManager.default.homeDirectoryForCurrentUser
NSHomeDirectory()
I can't simply pass Users/bob to my helper for security reasons — if an exploit managed to call my helper method with any URL it wished, and my helper did things based on that as root, I fear bad things could be achieved.
As vadian commented there are fundamental conceptual issues with what you're asking. What you probably actually want to do is be sure the process communicating with your helper tool is in fact trusted.
To do that you need to use SecCodeCreateWithXPCMessage and then use the resulting SecCode instance to validate the caller. For an example of how to do that, take a look at the acceptMessage function in the SecureXPC framework.
EDIT: Turns out there is a way to do this that does work from a Command Line Tool such as one installed with SMJobBless. This answer is adapted from Apple's Technical Q&A QA1133.
If you for whatever reason want to ignore the above, there's an approach you can take which may produce unexpected results if multiple users have active consoles. From Apple's documentation for SCDynamicStoreCopyConsoleUser: "Note that this function only provides information about the primary console. It does not provide any details about console sessions that have fast user switched out or about other consoles."
import SystemConfiguration
extension FileManager {
var homeDirectoryForConsoleUser: URL? {
var homeDirectory: URL?
if let consoleUser = SCDynamicStoreCopyConsoleUser(nil, nil, nil) as String?,
consoleUser != "loginwindow" {
homeDirectory = URL(fileURLWithPath: "/Users/\(consoleUser)")
}
return homeDirectory
}
}
And then you can make use of this anywhere in your helper tool:
if let homeDirectory = FileManager.default.homeDirectoryForConsoleUser {
// Do something useful here
}

What is the correct way to open a file from line arguments in an NSDocument application in Swift?

I'm working on a MacOS Document based application that opens a certain file type. What I want to do is write some UI tests for this application, but I want to load some mock data for these UI tests. From what I understand, I should actually use launchArguments or launchEnvironment variables to load this mock data.
So, it sounds to me like the correct thing to do is create some test data files, and open those files at the launch of the application using something like this:
let app = XCUIApplication()
app.launchArguments.append("-url")
app.launchArguments.append($PATH)
app.launch()
Now my question is, where should I add the code for opening a file during launch? Is there a method that NSDocumentDelegate has that I should override? Should I call openDocument(withContentsOf:display:completionHandler:) or just set the fileURL or something else entirely?
Right now my application opens the last opened file or opens a new document. I could try to override makeUntitledDocument(ofType typeName: String) or func restoreWindow(withIdentifier identifier: NSUserInterfaceItemIdentifier, state: NSCoder, completionHandler: #escaping (NSWindow?, Error?) -> Void) but I don't feel like either of those is the correct option.
So I guess I have two questions: 1) what is the correct way to pass mock data for UI testing of an NSDocument based application. 2) what is the correct way to open a file on launch of an application using a line argument.
1) what is the correct way to pass mock data for UI testing of an NSDocument based application?
What I do is the following:
1) To open a new document I call makeUntitledDocument(ofType typeName: String). There is no need to override it at all. You can then set up the document as you wish with the returned value of this API.
2) To open a previously saved document I call indeed openDocument(withContentsOf:display:completionHandler:)
Using pseudo-code would be something like this, where you can pass any URL with the mock data:
func openDocument(itemData:ItemData) {
let controller = NSDocumentController.shared
controller.openDocument(withContentsOf: itemData.url, display: true)
{ (_, _, error:Error?) in
if error != nil {
handleError(.unableToOpenDocument(itemData.url))
}
}
}
Once again, there is no need to override openDocument(withContentsOf:display:completionHandler:).
2) what is the correct way to open a file on launch of an application using a line argument?
I would use a bash script for that using:
open -a $APP_PATH $DOCUMENT_PATH
This will mimic what the Finder does, but if you don't like that option, then you can always try what they propose in the answers to this question here.

Value of type 'MSTable?' has no member 'pullWithQuery'

I tried to change client page size in Azure server
it's default is 50 and I want to make it bigger
so i use Microsoft tutorial in this link
https://learn.microsoft.com/en-us/azure/app-service-mobile/app-service-mobile-ios-how-to-use-client-library#querying
var client : MSClient?
let client = MSClient(applicationURLString: "AppUrl")
let table = client.tableWithName("TodoItem")
let query = table.query()
let pullSettings = MSPullSettings(pageSize: 3000)
but when I write
table.pullWithQuery(query, queryId:nil, settings: pullSettings) { (error) in
if let err = error {
print("ERROR ", err)
}
}
there are error "Value of type 'MSTable?' has no member 'pullWithQuery'"
what is the problem ?
is the function name changed ?
Two problems:
The documentation has not been updated for current versions of Swift
(an update request has been filed). The correct function name in modern Swift is pull rather than pullWithQuery.
The pullWithQuery function is on MSSyncTable, not MSTable. Pull is part of the offline sync system. The MSTable analog is read.
More details:
The SDK itself defines the function as MSSyncTable.pullWithQuery, but one of the features of Swift 3.0 is that it renames Objective C methods when it projects them into Swift to remove redundant arguments from the name, so verbWithX(X) becomes just verb(with:x) and pullWithQuery (MSQuery) becomes pull(with:MSQuery).
For more information on Swift 3 changes please see https://swift.org/blog/swift-3-0-released/ . I believe this particular change is SE-0005: Better Translation of Objective-C APIs Into Swift
If you download the Swift quickstart from your Azure Portal then you’ll get the correct modern pattern there:
self.table!.pull(with: self.table?.query(), queryId: "AllRecords")
or with your arguments:
self.table!.pull(with: self.table?.query(), queryId: nil, settings: pullSettings)

Import SQLClient into existing Xcode (Swift) project

I've never messed with iOS so this is all new to me. I'm trying to import SQLClient into an an existing Xcode project. (I need to fire off an INSERT from the iOS app.)
https://github.com/martinrybak/SQLClient
I've tried both installation methods listed by Martin via cocoapods and manual but I can't get either to work.
For option #1) everything worked fine until I tried pod install and was met with
Analyzing dependencies
[!] The dependency SQLClient (~> 0.1.3) is not used in any concrete target.
I was expecting the command to produce a file named SQLClient.xcworkspace. I wasn't sure if this new xcworkspace file was meant to replace my main project xcode file. But since it didn't work, I moved onto option #2.
For option #2 I wasn't sure where to put the contents. (Does Martin mean /SQLClient/SQLClient/SQLClient/SQLClient or /SQLClient/SQLClient/SQLClient?)
Was I supposed to copy just the files or the whole folder?
Do the contents go into my project at the same level as my original xcode project file or in a subfolder?
I've tried a couple variations but I admittedly don't know where the SQLClient files/folders should be placed in relation to my other project files.
I've tried messing with my bridge file as well but I've been unable to properly load it.
I have some time (2 days) to figure this out so I'm willing to learn but I need some guidance.
Here's a pic of my existing Xcode project and latest attempt to import SQLClient.
It looks like you have all the files in your project correctly.
Things to check.
If you said yes to create the bridge file when you dragged the object-c file into the project then you just need to add #import "SQLClient.h" to the bridge file. If you created the bridge file manually make sure it is added to Build Settings - Objective-C Bridging Header.
Make sure in your target - general - linked framework and libraries you have libiconv.tb and libfreetds.a
Swift 3
class testViewController: UIViewController, SQLClientDelegate {
// Handles errors from the SQLClient
func error(_ error: String!, code: Int32, severity: Int32) {
print("\(error!) \(code) \(severity)")
}
//MARK: Lifecyle
override func viewDidLoad() {
super.viewDidLoad()
let client = SQLClient.sharedInstance()!
client.delegate = self
client.connect("ServerNameOrIP", username: "cool", password: "cool", database: "database") { success in
client.execute("SELECT * FROM table", completion: { (_ results: ([Any]?)) in
for table in results as! [[[String:AnyObject]]] {
for row in table {
for (columnName, value) in row {
print("\(columnName) = \(value)")
}
}
}
client.disconnect()
})
}
}
}
Created a sample project here
I was able to get installation option #1 working after changing the pod file to include a target.
target "TargetName" do
pod 'SQLClient', '~> 0.1.3'
end
I downloaded SQLClient manually and it worked for me.You will get the steps to connect from swift project from here - https://github.com/salmasumona/Call-SP-from-iOS-project-using-SQLClient
SWIFT 5
enter image description hereThe best way to use Obj-C in a Swift project is to use a bridging header file, what I did with SQLCLient was to drag and drop the files from SQL client and then Xcode will ask if you want to create a bridging header file, select yes.
Inside the bridging header file, import "SQLClient.h", from here you can build the project and everything should compile. You can then create a SQLClient object like you did above and inside the .connect you make the sure the completion handler checks if it was successful then inside the closure you can call client.execute and from here if you put a SQL command as a string and use data as a variable inside the .execute completion block, if you print this data variable you will return all of the data from the SQL Server. It returns in JSON, so from here you can convert using JSON Serialization.
If you have any questions, please feel free to message me and I will return a screenshot of what my code looked like so that it may help you!

methodAccessException when passing variables from ViewModel to ViewModel on WP7 using anonymous object (MVVMCross)

I've created an app using MVVMCross, the IOS and Android versions are working but when I tried to "port" to WP7 and I ran into the following problem:
throw methodAccessException.MvxWrap("Problem accessing object - most likely this is caused by an anonymous object being generated as Internal - please see http://stackoverflow.com/questions/8273399/anonymous-types-and-get-accessors-on-wp7-1");
As mentioned in the answer to my other question about this (on Android) you have to set an InternalsVisibleTo attribute in the AssemblyInfo.cs for WP7. So I did:
[assembly: InternalsVisibleTo("Cirrious.MvvmCross.WindowsPhone")]
But this doesn't make any difference. I use the following code to send two variables form my BeckhoffViewModel to my BeckhoffSensorViewModel.
BeckhoffViewModel:
public IMvxCommand BeckhoffSensor1
{
get
{
return new MvxRelayCommand(kvpSens1);
}
}
private void kvpSens1()
{
RequestNavigate<BeckhoffSensorViewModel>(new { VarType = "short", Variable = ".countertest" });
}
BeckhoffSensorViewModel:
public BeckhoffSensorViewModel(string VarType, string Variable)
{
_vartype = VarType;
_variable = Variable;
}
Anything I'm overlooking? I also looked at the other stackoverflow topic mentioned in the exception but couldn't really understand it.
The anonymous class will most definitely be created as internal by the compiler - which is why you need the line [assembly: InternalsVisibleTo("Cirrious.MvvmCross.WindowsPhone")]
Can you check that the AssemblyInfo.cs file definitely being linked into the project (and that this is the project containing the ViewModel/anonymous-class code)?
If that is the case, can you check the methodAccessException to see what the message is?
If that doesn't help, can you use a tool like Reflector to check the internalVisible attribute is actually present on the core/application assembly?