Argument labels '(withReadPermission:, from:, handler:)' do not match any available overloads - facebook-graph-api

Just converted a project to Swift 3 and can't figure out the following error. And I don't know where is the mistake with message:
Argument labels '(withReadPermission:, from:, handler:)' do not match
any available overloads
FBManager.shared.logIn(
withReadPermission: ["public_profile", "email"],
from: self,
handler: { (result, error) in
if (error == nil) {
elf.fbLoginSuccess = true
}

First you need to update your pods to swift 3+ branch as it introduced argument labels (_) , and use this
let facebookLogin = FBSDKLoginManager()
facebookLogin.logIn(withReadPermissions: ["public_profile","email", "user_friends"], from:self, handler:
{
(facebookResult, facebookError) -> Void in
})

Related

swift - AWS S3 uploading image and then crashing

I'm using the following code to upload data (image) so amazon s3
func uploadData(data: Data, fileExtension: String, completion: #escaping (_ success: Bool, _ filename: String, _ url: String) -> ()) {
if let documentsDirectoryPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first {
let userId = 1
let fileName = "\(userId)_\(self.randomString()).\(fileExtension)"
let url = NSURL(fileURLWithPath: "\(documentsDirectoryPath)/\(fileName)")
let networkURLString = "\(appDel.assetAddress)/\(fileName)"
do {
try data.write(to: url as URL, options: .atomic)
} catch {
print("S3 Upload Error")
completion(false, "", "")
}
let uploadRequest: AWSS3TransferManagerUploadRequest = AWSS3TransferManagerUploadRequest()
uploadRequest.bucket = appDel.S3BucketName
uploadRequest.key = fileName
uploadRequest.body = url as URL!
let transferManager = AWSS3TransferManager.default()
let task = transferManager?.upload(uploadRequest)
task?.continue({ (task) -> Any? in
let success = (task.error == nil) && (task.result != nil)
if(!success){
print("S3 Upload Error: \(task.error)")
completion(false, "", "")
} else {
completion(success, fileName, networkURLString)
}
return nil
})
} else {
completion(false, "", "")
}
}
The image gets uploaded successfully; however, after returning completion of success with the filename and the url string... at around the line where it returns nil, the app takes a long time in the background doing AWS cleanup and all of a sudden gives an exception.
I'm trying to push a controller to the navigation bar on completion and it goes through that code but does nothing... as it's doing things in the background... although the image was already uploaded.
Nothing descriptive when it crashes that could help us find the issue.. any ideas?
Edit: Stack trace
2017-02-09 15:37:06.453327 HighThere[2021:526754] *** Assertion failure in void _UIPerformResizeOfTextViewForTextContainer(NSLayoutManager *, UIView<NSTextContainerView> *, NSTextContainer *, NSUInteger)(), /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIFoundation/UIFoundation-491.4/UIFoundation/TextSystem/NSLayoutManager_Private.m:1577
2017-02-09 15:37:06.462391 HighThere[2021:526754] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Only run on the main thread!'
*** First throw call stack:
(0x18d7e91b8 0x18c22055c 0x18d7e908c 0x18e2a1098 0x1935c33d4 0x1935c30b8 0x1935f2b90 0x1935f5ea8 0x19361a3a8 0x193619ab4 0x19374c8b8 0x19374c79c 0x1000e54d0 0x1000e0a98 0x1000e1390 0x1000e001c 0x1000e00f0 0x19369e924 0x1936b64b4 0x19383e5b4 0x193756e74 0x193756adc 0x193756a40 0x19369ba80 0x190b499d8 0x190b3e4cc 0x190b3e38c 0x190abb3e0 0x190ae2a68 0x190ae2f34 0x18c87bfbc 0x18c87bce4 0x18c87b378 0x18c87ad8c)
libc++abi.dylib: terminating with uncaught exception of type NSException
Great. I just needed to push the controller to the navigation controller on the main thread... brilliant. goodbye 2 hours
DispatchQueue.main.async(execute: {
self.navigationController?.pushViewController(vcIntro(), animated: true)
})

Problems with migration to Swift3, compilation error with URLSession.GET

I'm trying to migrate from Swift2 to Swift3 and I'm having an issue with URLSession.GET
I went through the migration tool provided by XCode, and changed my "NSURLSession" calls into "URLSession" but I keep having this error message:
"Use of Instance member 'GET' on type 'URLSession'; did you mean to use a value of type 'URLSession' instead?"
Here is my code:
open static func getData() -> Promise<[Station]> {
return URLSession.GET("http://api.xxx.gov/api/").asDataAndResponse().then { (data: NSData, _) -> [Station] in
var stations = [Station]()
// rest of the code to retrieve the data
...
...
return stations
}
}
Update:
After some digging a found a solution, see answer below for more details and helpful links
After some more digging I found a solution :
First I have to init URLSession with a configuration:
let URLSession1 = URLSession(configuration: .default)
Then I can call the 'GET' method and I had to use (data,_ ) instead of (data:NSData,_ ):
open static func getData() -> Promise<[Station]> {
return URLSession1.GET("http://api.xxx.com/api/").asDataAndResponse().then { (data, _) -> [Station] in
var stations = [Station]()
// rest of the code to retrieve the data
...
...
return stations
}
}
Some helpful StackOverflow links that helped me find the solution:
NSURLSession dataTaskForRequest:completion: unrecognized selector sent to instance

Swift 3 FileManagerDelegate: shouldRemoveItemAt compiler error

While using Xcode 8 and Swift 3, I am trying to implement the following method for the FileManagerDelegate protocol:
private func fileManager(_ fileManager: FileManager, shouldRemoveItemAt URL: URL) -> Bool {
var shouldDelete = true
let urlString = URL.absoluteString
if urlString?.range(of: "keepfiles") != nil {
shouldDelete = false
}
return shouldDelete
}
the compiler shows the following error:
Use of undeclared type: 'URL'
but it does not offer any solution to fix it. Because of this I cannot test the selective deletion. If I change the URL type declaration to NSURL, the error goes away, but the delegate never gets called and all the files get deleted.
Does anyone know why this is happening and how I can fix it?
You were trying to get the absoluteString from the type URL instead of instance url. Change your parameter name into a more readable format and do like this, the error will go away.
private func fileManager(_ fileManager: FileManager, shouldRemoveItemAt url: URL) -> Bool {
var shouldDelete = true
let urlString = url.absoluteString
if urlString?.range(of: "keepfiles") != nil {
shouldDelete = false
}
return shouldDelete
}

Error after updating to xcode 7 : Cannot invoke initializer for type 'NSRegularExpression' with an argument list of type

Get following error after updating xcode:
"Cannot invoke initializer for type 'NSRegularExpression' with an argument list of type '(pattern: String, options: NilLiteralConvertible, error: NilLiteralConvertible)'"
Following is code which cause error:
func applyStylesToRange(searchRange: NSRange) {
let normalAttrs = [NSFontAttributeName : UIFont.preferredFontForTextStyle(UIFontTextStyleBody)]
// iterate over each replacement
for (pattern, attributes) in replacements {
let regex = NSRegularExpression(pattern: pattern, options: nil, error: nil)!
regex.enumerateMatchesInString(backingStore.string, options: nil, range: searchRange) {
match, flags, stop in
// apply the style
let matchRange = match.rangeAtIndex(1)
self.addAttributes(attributes, range: matchRange)
// reset the style to the original
let maxRange = matchRange.location + matchRange.length
if maxRange + 1 < self.length {
self.addAttributes(normalAttrs, range: NSMakeRange(maxRange, 1))
}
}
}
error is at this line:- let regex = NSRegularExpression(pattern: pattern, options: nil, error: nil)!
please suggest me how to resolve it.
The initalizer is now throwable and needs an option:
do {
let regex = try NSRegularExpression(pattern: "YouPattern", options: NSRegularExpressionOptions.CaseInsensitive)
} catch {
print(error)
}
Check out a new initialiser
public init(pattern: String, options: NSRegularExpressionOptions) throws
It means now you must pass an options argument and be ready to catch an error. Example:
do {
let regex = try NSRegularExpression(pattern: "pattern", options: .CaseInsensitive)
} catch {
print(error)
}

if let nil in swift 2.0 is not working as expected

"if let nil" check is not working in Swift 2.0, but was working fine in Swift 1.2.
In the below code, "fetchNumbersFromCoreDataDB" function returns nil. In getDatabaseDate function, I have a condition "if let date = dbDate". This condition ideally should fail and go to else block. But in Swift 2.0, it is going inside the if block. In Swift 1.2, same code is going to else block. I am confused here. What is the difference here?
func getDatabaseDate() {
let dbDate : NSDate? = ((self.fetchNumbersFromCoreDataDB(“123456”) as DBNumbers!).dbDate)
if let date = dbDate {
print(“\(date)”)
}
else {
print(“No Date”)
}
}
func fetchNumbersFromCoreDataDB(Number:String) -> DBNumbers? {
var numArray = coreDataInterface.fetchAllObjectsFromEntity(info, withAttributeValues: [“No” : Number]) as! [DBNumbers]
return numArray.count>0 ? numArray[0] : nil
}
Note: "dbDate" is NSDate type in Coredata table
The let dbDate line is very oddly constructed and would raise an exception if your fetchNumbersFromCoreDataDB were returning nil. Therefore your fetchNumbersFromCoreDataDB is not returning nil.
Your line:
let dbDate : NSDate? = ((self.fetchNumbersFromCoreDataDB(“123456”) as DBNumbers!).dbDate)
as DBNumbers! says to convert from DBNumbers? to DBNumbers!. So you've got an optional that is implicitly unwrapped.
Hence .dbDate says to unwrap the return result of fetchNumbersFromCoreDataDB and get the dbDate property from it. Had fetchNumbersFromCoreDataDB returned nil, the attempt to unwrap would raise an exception.
What you probably wanted was:
let dbDate = self.fetchNumbersFromCoreDataDB(“123456”)?.dbDate
Which says "if the optional returned by fetchNumbersFromCoreDataDB is not nil then get its dbDate property; otherwise get nil".
If you really need to convince yourself empirically, open a playground and try this:
class DBNumbers {
var dbDate: NSDate?
}
func fetchNumbersFromCoreDataDB(Number:String) -> DBNumbers? {
return nil
}
let dbDate : NSDate? = (fetchNumbersFromCoreDataDB("123456") as DBNumbers!).dbDate
You'll get an EXC_BAD_INSTRUCTION on the last line.