I need help Debugging/Fixing this code, by the way this is in Xcode, I am using the OpenAI Package by adamrushy - xcode

I am having an issue, I don't know if it related to the package but it probably is so here is my code. This is the package I used; https://github.com/adamrushy/OpenAISwift
// Send query to OpenAI
openAI.send(prompt: query) { [weak self] (response, error) in
guard let self = self else { return }
if let error = error {
print("Error: \(error.localizedDescription)")
self.startListening()
return
}
if let response = response {
// Use Text to Speech to speak response
let synthesizer = AVSpeechSynthesizer()
let utterance = AVSpeechUtterance(string: response.text)
synthesizer.speak(utterance)
}
By the way the below Bugs are on this line "openAI.send(prompt: query) { [weak self] (response, error) in"
Bug 1: Unable to infer type of closure parameter 'error' in the current context
Bug 2: Unable to infer type of a closure parameter 'response' in the current context
Bug 3: Value of type 'OpenAI' has no member 'send'
I tried removing the error thing itself, it gave more issues. I tried changing 'send' to other things, it just kept giving the same error. And I could not touch 'response' as it is important.

Related

How to port a network extension NEPacketTunnelProvider class from Obj-C/Swift to Xamarin C#?

I'm trying to figure out how to make a network extension so that my iOS app can programmatically open an custom VPN tunnel in C#, but looking at some similar Obj-C projects I'm not sure if it's possible in Xamarin (as I don't see a network extension project in Visual Studio) and how to port a what I gather is a required PacketTunnelProvider class which I think must be present and listed as an extension in the plist.info first...I'm in particular having most trouble in how to port the parts of that class which appear at the end as an extension and some event handlers named like this func Adapter(adapter: Adapter, configureTunnelWithNetworkSettings networkSettings: NEPacketTunnelNetworkSettings, completionHandler: #escaping (AdapterPacketFlow?) -> Void) and func Adapter(adapter: Adapter, handleEvent event: AdapterEvent, message: String?) as they both have a different signature than an event handler in C# which accepts sender and eventArgs (or something derived)…if anyone did this in C# I'd like to know at least if it's possible if not how to port such a class?
I've found this one project https://github.com/ss-abramchuk/OpenVPNAdapter (since it seems to do most of what I want) that I managed to translate into a Xamarin binding library but I'm unsure how and if to incorporate its PacketTunnelProvider class in Xamarin (as that is what the readme says you should use to incorporate something like that adapter)...I gather one should add to plist.info something like this first:
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.networkextension.packet-tunnel</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).PacketTunnelProvider</string>
</dict>
but where do you go from there to use the binding library? This is the Obj-C code that says and seemingly does what I want to do to after i.e. add that custom VPN protocol tunnel to an app using the library:
import NetworkExtension
import OpenVPNAdapter
class PacketTunnelProvider : NEPacketTunnelProvider
{
lazy var vpnAdapter: OpenVPNAdapter = {
let adapter = OpenVPNAdapter()
adapter.delegate = self
return adapter
}
()
let vpnReachability = OpenVPNReachability()
var startHandler: ((Error?) -> Void)?
var stopHandler: (() -> Void)?
override func startTunnel(options: [String: NSObject]?, completionHandler: #escaping (Error?) -> Void)
{
// There are many ways to provide OpenVPN settings to the tunnel provider. For instance,
// you can use `options` argument of `startTunnel(options:completionHandler:)` method or get
// settings from `protocolConfiguration.providerConfiguration` property of `NEPacketTunnelProvider`
// class. Also you may provide just content of a ovpn file or use key:value pairs
// that may be provided exclusively or in addition to file content.
// In our case we need providerConfiguration dictionary to retrieve content
// of the OpenVPN configuration file. Other options related to the tunnel
// provider also can be stored there.
guard
let protocolConfiguration = protocolConfiguration as? NETunnelProviderProtocol,
let providerConfiguration = protocolConfiguration.providerConfiguration
else
{
fatalError()
}
guard let ovpnFileContent: Data = providerConfiguration["ovpn"] as? Data else
{
fatalError()
}
let configuration = OpenVPNConfiguration()
configuration.fileContent = ovpnFileContent
configuration.settings = [
// Additional parameters as key:value pairs may be provided here
]
// Apply OpenVPN configuration
let properties: OpenVPNProperties
do
{
properties = try vpnAdapter.apply(configuration: configuration)
}
catch
{
completionHandler(error)
return
}
// Provide credentials if needed
if !properties.autologin {
// If your VPN configuration requires user credentials you can provide them by
// `protocolConfiguration.username` and `protocolConfiguration.passwordReference`
// properties. It is recommended to use persistent keychain reference to a keychain
// item containing the password.
guard let username: String = protocolConfiguration.username else
{
fatalError()
}
// Retrieve a password from the keychain
guard let password: String = ... {
fatalError()
}
let credentials = OpenVPNCredentials()
credentials.username = username
credentials.password = password
do
{
try vpnAdapter.provide(credentials: credentials)
}
catch
{
completionHandler(error)
return
}
}
// Checking reachability. In some cases after switching from cellular to
// WiFi the adapter still uses cellular data. Changing reachability forces
// reconnection so the adapter will use actual connection.
vpnReachability.startTracking { [weak self] status in
guard status != .notReachable else { return }
self?.vpnAdapter.reconnect(interval: 5)
}
// Establish connection and wait for .connected event
startHandler = completionHandler
vpnAdapter.connect()
}
override func stopTunnel(with reason: NEProviderStopReason, completionHandler: #escaping () -> Void)
{
stopHandler = completionHandler
if vpnReachability.isTracking {
vpnReachability.stopTracking()
}
vpnAdapter.disconnect()
}
}
extension PacketTunnelProvider: OpenVPNAdapterDelegate {
// OpenVPNAdapter calls this delegate method to configure a VPN tunnel.
// `completionHandler` callback requires an object conforming to `OpenVPNAdapterPacketFlow`
// protocol if the tunnel is configured without errors. Otherwise send nil.
// `OpenVPNAdapterPacketFlow` method signatures are similar to `NEPacketTunnelFlow` so
// you can just extend that class to adopt `OpenVPNAdapterPacketFlow` protocol and
// send `self.packetFlow` to `completionHandler` callback.
func openVPNAdapter(_ openVPNAdapter: OpenVPNAdapter, configureTunnelWithNetworkSettings networkSettings: NEPacketTunnelNetworkSettings, completionHandler: #escaping (OpenVPNAdapterPacketFlow?) -> Void)
{
setTunnelNetworkSettings(settings) {
(error) in
completionHandler(error == nil ? self.packetFlow : nil)
}
}
// Process events returned by the OpenVPN library
func openVPNAdapter(_ openVPNAdapter: OpenVPNAdapter, handleEvent event: OpenVPNAdapterEvent, message: String?)
{
switch event {
case .connected:
if reasserting {
reasserting = false
}
guard let startHandler = startHandler else { return }
startHandler(nil)
self.startHandler = nil
case .disconnected:
guard let stopHandler = stopHandler else { return }
if vpnReachability.isTracking {
vpnReachability.stopTracking()
}
stopHandler()
self.stopHandler = nil
case .reconnecting:
reasserting = true
default:
break
}
}
// Handle errors thrown by the OpenVPN library
func openVPNAdapter(_ openVPNAdapter: OpenVPNAdapter, handleError error: Error)
{
// Handle only fatal errors
guard let fatal = (error as NSError).userInfo[OpenVPNAdapterErrorFatalKey] as? Bool, fatal == true else
{
return
}
if vpnReachability.isTracking {
vpnReachability.stopTracking()
}
if let startHandler = startHandler {
startHandler(error)
self.startHandler = nil
} else
{
cancelTunnelWithError(error)
}
}
// Use this method to process any log message returned by OpenVPN library.
func openVPNAdapter(_ openVPNAdapter: OpenVPNAdapter, handleLogMessage logMessage: String)
{
// Handle log messages
}
}
// Extend NEPacketTunnelFlow to adopt OpenVPNAdapterPacketFlow protocol so that
// `self.packetFlow` could be sent to `completionHandler` callback of OpenVPNAdapterDelegate
// method openVPNAdapter(openVPNAdapter:configureTunnelWithNetworkSettings:completionHandler).
extension NEPacketTunnelFlow: OpenVPNAdapterPacketFlow {}
How do I port to C# then or maybe I'm doing it all wrong (because of the comment bellow - the binding dll is bigger than 15MB - or is that limit in regard to use of memory which isn't related to file size)? Should I actually be just referencing the custom VPN library to open up a VPN tunnel from code directly and go on from there like it's business as usual (as I also found a project/app https://github.com/passepartoutvpn which uses a TunnelKit cocoapod, but that app's lib won't work with sharpie to make the binding library, and if so would the app like that even be admissible to the AppStore)? Thank you for any help in advance.
Per #SushiHangover advice, I've tried binding TunnelKit, as that project seemed smaller, and succeeded, partially... I've managed to build ~3MB dll, which seems much smaller than 21MB OpenVPNAdapter, and I think I'm almost there with the NetworkExtension project...I've got just to figure out the did I do ok with #escaping completionHandler and how to get some group constants which I guess should be set within the Host app somehow?
public override void StartTunnel(NSDictionary<NSString, NSObject> options, Action<NSError> completionHandler)
{
//appVersion = "\(GroupConstants.App.name) \(GroupConstants.App.versionString)";
//dnsTimeout = GroupConstants.VPN.dnsTimeout;
//logSeparator = GroupConstants.VPN.sessionMarker;
base.StartTunnel(options, completionHandler);
}
I've commented out the groupcontants for now but at least I'm hoping that's good enough porting of Swift3's:
override func startTunnel(options: [String : NSObject]?, completionHandler: #escaping (Error?) -> Void) {
appVersion = "\(GroupConstants.App.name) \(GroupConstants.App.versionString)"
dnsTimeout = GroupConstants.VPN.dnsTimeout
logSeparator = GroupConstants.VPN.sessionMarker
super.startTunnel(options: options, completionHandler: completionHandler)
}
If anyone else knows about the group constants and how to get them I'd be grateful (but I should also note that sharpie pod didn't give/expose any of those fields I should be assigning. Maybe I did it wrong as that's TunnelKit is a completely Swift3 project unlike the OpenVPNAdapter :/
Should I actually be just using the a custom VPN library to open up a VPN tunnel and go from there, but would the app then be admissible to the AppStore?
For iOS 12+, you absolutely have to use the Network Extension framework to be Store eligible.
The Xamarin.iOS build task (ValidateAppBundle) correctly identifies com.apple.networkextension.packet-tunnel as a valid extension (.appex) so yes you can build an NEPacketTunnelProvider extension.
You are correct the VS does not have build-in templating for Network Provider .appex's for tunnels, dns proxy, filter control|data, proxy types, but that does not mean you can not just use another one of the templates (or create the project from scratch) and modify it (I create an Xcode iOS project and start adding extension targets and just mirror those changes in VS).
(FYI: That is Swift code in your example, not ObjC...)
Now due to limitations in .appex size (and performance issues in some cases), a lot of extensions are very difficult to do via Xamarin.iOS. Most devs that encounter this, go native using ObjC/Swift for at least the appex development...

Generic parameter 'Element' could not be inferred?

"Generic parameter 'Element' could not be inferred" - this error comes as I write guard statement - what is inside guard statement which causes error that element could not be inferred.
static func makeTokenForCard(with cardinfo: CardInfo) -> Single<String> {
return Single.create {
single in guard let ck = try CheckoutKit.getInstance("pk_123456789876543234567, env: Environment.SANDBOX, debug: true)
else {
let descr = "Unexpectedly Checkout got invalid private key. You may need to update the app."
single(.error(NSError.recreate(error: CheckoutError.invalidPK as NSError, description: descr)))
return
}
single(.success("123456"))
return Disposables.create()
}
}
When I remove this Guard statement - it returns simple String and errors in Single.
Edit :
After getting more into error, I found that its due to throws.
open class func getInstance(_ pk: String, env: Environment, debug: Bool) throws -> CheckoutKit? {
In Simple Guard & wrapping its fine.
So, How to call a method in Single when it has throws some expected error
?
This isn't RxSwift related but more Swift and handling errors.
The simplest answer to your question is to use try? instead try. This will fix the issue.
You can read more about error handling here https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html

Swift 2: Can't call createDirectoryAtUrl with definition

I am currently developing an application on xCode7 beta 2 using Swift 2 (it is a requirement at the moment).
Here is what I am trying to call:
let fileManager = NSFileManager.defaultManager()
let tempDirectoryURL = NSURL(string: NSTemporaryDirectory())!
let directoryURL = tempDirectoryURL.URLByAppendingPathComponent("com.test.manager/multipart.form.data")
var error: NSError?
if fileManager.createDirectoryAtURL(directoryURL, createIntermediates: true, attributes: nil) {
...
}
Here is the error I am getting:
Cannot invoke 'createDirectoryAtURL' with an argument list of type
'(NSURL, createIntermediates: Bool, attributes: nil)'
Which is confusing because the definition for createDirectoryAtURL I am getting when I right click and "view definition" is:
func createDirectoryAtURL(
url: NSURL,
withIntermediateDirectories createIntermediates: Bool,
attributes: [String : AnyObject]?
) throws
The only only paramater that doesn't match verbatim is the last parameter "attributes", which the documentation (and all example usage) explicitly states can accept the value nil.
Apple's Documentation:
If you specify nil for this parameter, the directory is created
according to the umask(2) Mac OS X Developer Tools Manual Page of the
process.
Two problems here:
You've switched an parameter label for its internal name. The second parameter's label — part of the function name, required for calling it — is withIntermediateDirectories. The implementor of that function refers to that parameter's value as createIntermediates. So your call should look like this:
fileManager.createDirectoryAtURL(directoryURL, withIntermediateDirectories: true, attributes: nil)
Note the signature you quoted:
func createDirectoryAtURL( ... ) throws
You're using this call as the condition of an if statement — that means you need a function that returns Bool. The compiler is trying to satisfy the requirement of the if statement by looking for a function called createDirectoryAtURL whose type signature is (NSURL, Bool, [String : AnyObject]?) -> Bool, and complaining because it only sees one whose signature is (NSURL, Bool, [String : AnyObject]?) throws -> Void.
The error handling system in Swift 2 takes ObjC methods that return BOOL and have an NSError out parameter and turns them into throwing methods with no return type (that is, they return Void). So, if you're looking at Swift 1.x code that uses such methods, or porting ObjC code, you need to change patterns like the following:
var error: NSError?
if fileManager.createDirectoryAtURL(directoryURL, withIntermediateDirectories: true, attributes: nil, error: &error) {
// all good
} else {
// handle error
}
And use patterns like this instead:
do {
try fileManager.createDirectoryAtURL(directoryURL, withIntermediateDirectories: true, attributes: nil)
// if here, all is good
} catch {
// handle error
}

Parse query returning nothing from findObjectsInBackgroundWithBlock

EDIT:
I changed the question title.
and I changed the function to findObjectsInBackgroundWithBlock -
override func viewDidAppear(animated: Bool) {
let predicate = NSPredicate(format: "username != '"+userName+"'")
var query = PFQuery(className: "_User", predicate: predicate)
var objects = query.findObjectsInBackgroundWithBlock({
(objects:[AnyObject]!, error: NSError!) in
if(error == nil){
for object in objects {
self.resultsUsernameArray.append(object.username)
self.resultsProfileNameArray.append(object.email)
self.resultsImageFiles.append(object["photo"] as PFFile)
self.resultsTable.reloadData()
}
}else{
println("error in quert execution \(error)")
}
})
}
There is one warning [variable 'objects' inferred to have type 'Void', which may be unexpected], and the code still returns nothing. I have 3 users in my Parse account for this app.
There's no error anymore, I guess that's good at least?
I'm new to xcode, and can't find how to search for this function. I'm having the same issue with Parse that others have had. My find query worked twice, and now (with no changes to the code) it stops returning anything. I want to do as suggested and 'Break on warnBlockingOperationOnMainThread() to debug,' but the only project search feature I can find (right clicking the project and doing 'Find in selected groups') doesn't bring anything up.
So, how do I find this function to add a breakpoint? Or, better yet, why did this query stop working?
override func viewDidAppear(animated: Bool) {
let predicate = NSPredicate(format: "username != '"+userName+"'")
var query = PFQuery(className: "_User", predicate: predicate)
var objects = query.findObjects()
for object in objects {
self.resultsUsernameArray.append(object.username)
self.resultsProfileNameArray.append(object.email)
self.resultsImageFiles.append(object["photo"] as PFFile)
self.resultsTable.reloadData()
}
}
Thanks!
From: https://developer.apple.com/library/mac/recipes/xcode_help-breakpoint_navigator/articles/adding_a_symbolic_breakpoint.html
In the bottom-left corner of the breakpoint navigator, click the Add button.
Choose Add Symbolic Breakpoint.
Enter the symbol name in the Symbol field.
If the symbol is declared in more than one library, enter the name of the appropriate library in the Module field.
To specify that program execution be suspended only if an expression evaluates to true, enter the expression in the Condition field.
Click Done.

fatal error: unexpectedly found nil while unwrapping an Optional value in Swift when tried to parse JSON

I've tried to build up a document-based Cocoa app and when I tried to parse JSON in readFromData: ofType: error: method, I got an error: fatal error: unexpectedly found nil while unwrapping an Optional value. The actual line that caused the error is the following:
override func readFromData(data: NSData?, ofType typeName: String?, error outError: NSErrorPointer) -> Bool {
var error: NSErrorPointer!
var loadedDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error: error) as? NSDictionary // this causes an error
return true
}
It looks like the NSJSONSerialization.JSONObjectWithData() method caused the error, but why did it issue it?
I changed options: argument to either nil or 0, and also changed error: argument to nil, but nothing solved the issue.
I also ensured that data is not nil.
So what am I missing? I think the JSON method tried to force unwrapping within it, but how can I know that? And how can I escape the fatal error and have my app run properly?
I use Xcode6-beta 3 on Yosemite beta3.
Most likely the problem is that you have data that isn't actually JSON, so the deserialisation will return nil, or the data is an array, and converting it to a dictionary will obviously crash.
You don't seem to understand some of the basics. What do you think AllowFragments is going to achieve? And why did you change error to nil? Do you understand what the error variable is there for? It's there to tell you what errors the JSON parser found. By setting the variable to nil, you prevent it from helping you.
If the data does not contain a valid JSON object, the JSONObjectWithData function will return a nil, so you need to do a conditional unwrapping as follows:
if let dict = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: jsonError) as? NSDictionary {
println("Dictionary: \(dict)")
} else {
println("nil")
let resultString = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Flawed JSON String: \(resultString)")
}
I hope it helps..... e
In this case outError is supplied as an argument so you should use it (I overlooked that).
Looks like this function's purpose is to check whether data is valid JSON.
Then your funciton should be:
override func readFromData(data: NSData?, ofType typeName: String?, error outError: NSErrorPointer) -> Bool {
if let loadedDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error: outError) as? NSDictionary {
return true
} else {
return false
}
}
Now this function:
write error to where the caller specified in ourError should error occur
return wheter the data is valid JSON as NSDictionary
FYI I happened to write a JSON handler, too.
https://github.com/dankogai/swift-json/
Which includes NSJSONSerialization.JSONObjectWithData.

Resources