Swift3 and addTarget Selector code converter suggestion - swift3

In my old Swift iOS app project I use code like his:
button!.addTarget(self,action:"ratingButtonTapped:",for:.touchDown)
where ratingButtonTapped is a function in the same class
The code converter gives error
"No method declared with Objective-C selector 'ratingButtonTapped:'"
and then suggests this solution
button!.addTarget(self,action:Selector("ratingButtonTapped:"),for:.touchDown)
The only problem is that even after applying the fix, it continues to give warning
"No method declared with Objective-C selector 'ratingButtonTapped:'"
where is then suggest to wrap it in parentheses to hide the warning
...
This is my function declaration in the same classd:
func ratingButtonTapped(_ sender: UIButton) {
}
...
I guess the way I did this dated and wrong in Swift 3 - but what is the correct way then? The class has a function with name ratingButtonTapped

button.addTarget(self, action: #selector(YourClassController. ratingButtonTapped(_:)), for: .touchUpInside)
func ratingButtonTapped(_ sender:UIButton){
}

Related

How to convert a complex UIKit View into a SwiftUI View?

there's a lot of code in here but please be patient I will try to explain my question
so i am trying to convert Apple's AvDepthCapture project which is in UIKit as a SwiftUI project, so i copied all the supporting files, i will attach the image for the same below, the shaders folder contain the metal files for applying filters
so I created a class same as the cameraviewcontroller and added all the properties as follows -
class CameraViewController: UIViewController, AVCapturePhotoCaptureDelegate, AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureDepthDataOutputDelegate, AVCaptureDataOutputSynchronizerDelegate, ObservableObject {
private var previewView: PreviewMetalView!
}
now when i run my app on my device it asks for camera permission but then shows a white screen instead of opening the camera and the PreviewMetalView file that i copied earlier directly from the original UIKit project,
the declaration is causing error
private var previewView: PreviewMetalView!
this line, it quits my app and says unexpectedly found nil when unwrapping an optional value but the code is the same as that of the UIKit project and UIKit project works perfectly fine on my device then why is it throwing this error!?, please help i can provide both the UIKit project and my SwiftUI project file if you want to see i really can't figure it out
there's a lot of code but this specific line is throwing error, I declared a type of PreviewMetalView but now PreviewMetalView has an initialiser which takes in a type NSCoder so what should I write there ??
like I would be declaring my variable as
var previewView = PreviewMetalView(coder: NSCoder)
what to put in place of NSCoder ?
when I opened the original UIKit project the previewView is defined as an IBOutlet to a Container View which is then linked to the CameraViewController but I cannot find where is it initialised please help!

Issue with declaring class variables

I'm implementing Google Maps in my project, because MKLocalSearch doesn't have a complete list of restaurants/bars. I'm following Google's documentation. I believe I've uncovered an issue and seek advice on how to solve.
The fist step is variable declaration at the class level:
var locationManager = CLLocationManager()
var currentLocation: CLLocation?
var mapView: GMSMapView!
var placesClient: GMSPlacesClient!
var zoomLevel: Float = 15.0
After following the remaining instructions, my program keeps failing on the mapView line:
let camera = GMSCameraPosition.camera(withLatitude: defaultLocation.coordinate.latitude,
longitude: defaultLocation.coordinate.longitude,
zoom: zoomLevel)
mapView = GMSMapView.map(withFrame: view.bounds, camera: camera) //Fails here!
The error message in the debugger is: Fatal error: Unexpectedly found Nil while unwrapping optional value.
So the question is why does the Google documentation declare the mapView variable the way it does? Don't all variables that ARE NOT optional have to initialize with a value? Should I declare the variable as Optional? Seems odd to me that Google Documentation would be incorrect.
Thanks.
By declaring an optional with ! you are telling the compiler whenever I access this optional it will have a value. It means you don't have to stick ! at the end everytime you use it. But it does mean if you haven't set the optional to have a value you will get an error when you access it.
An example of using one would a class member of a UIViewController that you setup in viewDidLoad(). You aren't required to setup a separate init() function for the view controller to initialise the variable but you can pretty much guarantee the entry point for your code is viewDidLoad() and any subsequent code run will have a valid version of this class member.
Search for Implicitly Unwrapped Optionals for more details
you should take optional mapView when there is possibility of having mapView or not. You should always take like this
let mapView = GMSMapView(frame: self.view.bounds)

"Expected Declaration" Error on Delegate Function Call

Xcode 8/Swift 3
Can anyone please tell me why I am getting this "expected declaration" error? The use of delegates answered my last question perfectly without getting this error.
Googling other "expected declaration" problems suggests function calls etc being in the wrong place but I don't think thats the case here - I have tried placing delegate?.loadFirstView(viewFromModel: firstView) in a separate function and then calling that function but I just get the same error. See the screenshot below:
Thanks in advance!
P.S: below is a screenshot of when my use of a delegate worked perfectly.
Third Screenshot with delegate call in a separate function:
You have the code (delegate?.loadFirstView(viewFromModel : firstView)) in the wrong place in the class. So move it to any function.
In your working screenshot, the code is written inside the updateClock()method, thus working without any error.
class modelClass{
var delegate : LoadFirstViewProtocol?
let firstView = "First view loaded"
func testing()//Write here user defined method named
{
delegate?.loadFirstView(viewFromModel: firstView)
}
}

AWS and Changes in Swift 3

After the Swift 3 update, I'm having some trouble getting my app to compile. Most of the errors are pretty simple to fix, but I'm running into a few in particular with AWS. Is there some sort of updated AWS SDK for Swift 3? I've tried to look it up, but haven't found one. In any case, the two main errors I'm having trouble resolving are as follows:
"Type 'IdentityProviderManager' does not conform to protocol AWSIdentityProviderManager." This is for a class I created following a tutorial to set up logins through AWS Cognito. The code is:
class IdentityProviderManager: NSObject, AWSIdentityProviderManager{
var tokens : [NSString : NSString]?
init(tokens: [NSString : NSString]) {
self.tokens = tokens
}
#objc func logins() -> AWSTask<AnyObject> {
return AWSTask(result: tokens as AnyObject)
}
}
In the AWS documentation for AWSIdentityProviderManager, it says that the only required function is logins, which I have. Is there a simple way to resolve this that I'm missing?
The other error is in my LoginViewController class: "Type 'LoginViewController' does not conform to protocol 'AWSCognitoIdentityPasswordAuthentication'." Here the issue seems a bit more clear, since the documentation says that getPasswordAuthenticationDetails() is a required method and XCode seems to have changed this method to getDetails() when updating to Swift 3, unless I'm mistaken and it wasn't there to begin with or something. In any case, autocomplete doesn't give me the original method and I can't seem to make the class conform to the protocol.
Apologies if the answer is already in documentation somewhere, but as far as I can tell it seems like the AWS SDK (at least the version that I have) is somehow incompatible with Swift 3. Is there something I can do to resolve these errors?
Nevermind, it turned out XCode just wasn't showing me the option to make the changes I needed. The automatic fix implemented slightly different versions of the required functions and everything ended up working.

Why does dispatch_queue_create give an EXC_BAD_ACCESS error in Swift?

I am porting some code from C++ to Swift that used Grand Central Dispatch, and I am finding a curious error with dispatch_queue_create seemingly not working at all.
For instance, in my C++ base class header, I would declare
dispatch_queue_t m_WorkQ;
and in the initializer, put
m_ResultQ = dispatch_queue_create("com.myapp.mHitsUpdateQueue", 0);
... and everything was glorious.
I've tried this in Swift, in my class, declaring this at class level:
var resultQueue: dispatch_queue_t
... and in the initalizer, I have (among others) the line
resultQueue = dispatch_queue_create("com.myapp.mHitsUpdateQueue", 0)
... and it compiles and starts up fine, but gives me an immediate runtime error of EXC_BAD_ACCESS (code=1, address = 0x37) on the above line
To determine if it's anything else I've done, I created a command line tool application consisting only of the following code:
import Foundation
var thisQueue = dispatch_queue_create("com.myApp.mHitsUpdateQueue", 0)
println(thisQueue.description)
... and sure enough, I get the above error right on the "thisQueue" assignment line. So I'm pretty sure there's something really obvious about Swift and GCD queue creation that I'm missing.
Can anyone please help me out here?
The second argument of dispatch_queue_create() has the type
dispatch_queue_attr_t, which is declared as
typealias dispatch_queue_attr_t = NSObject
You have to pass DISPATCH_QUEUE_SERIAL or nil for a serial queue
(or DISPATCH_QUEUE_CONCURRENT for a concurrent queue):
var thisQueue = dispatch_queue_create("com.myApp.mHitsUpdateQueue", DISPATCH_QUEUE_SERIAL)
In C(++), 0 can be passed instead of a NULL pointer.
The Swift compiler, however, wraps the integer 0 into an NSNumber object
so that it can be passed to the function expecting an NSObject
parameter. That causes the runtime exception because NSNumber is
not a valid attribute. So passing 0 or nil is
significantly different in Swift.