Alamofire support for ios14 - alamofire

I have a method headerParameters() which returns [String: String]? when I tried migrating code to swift 5 to support iOS14 I tried upgrading the Alamofire version and getting an error as "Cannot find 'SessionManager' in scope" can someone help me with this.
func headerParameters() -> [String: String]? {
return SessionManager.defaultHTTPHeaders
}

Alamofire 5 renamed SessionManager to Session and moved the defaultHTTPHeaders to the HTTPHeaders.default value.

Related

Ktor - post unhanldled error with coroutines

I a new to Kotlin and Ktor in particular, so I have tried to do simple post request. As you can see below, there is nothing special.
routing {
post("/articles/add"){
val post = call.receive<ArticleRequest>()
println(post)
}
Error shown in logs is below and I don't understand why I should use here coroutines.
ERROR Application - Unhandled: POST - /articles/add
java.lang.IllegalStateException: Using blocking primitives on this dispatcher is not allowed. Consider using async channel instead or use blocking primitives in withContext(Dispatchers.IO) instead.
I am using 1.4.2 version. I would appreciate any help.
If you are using Jackson this is a bug and there is a suggested workaround:
routing {
post("/articles/add") {
with(Dispatchers.IO) {
val post = call.receive<ArticleRequest>()
println(post)
}
}
}
Or you can rollback to 1.4.1 until the bug is solved.
I've experienced the same issue after upgrading to ktor 1.4.2 and Kotlin 1.4.20, and I used both Moshi and Gson on this specific project but I don't believe they are causing this issue.
If you have a 'gradle.properties' file, add these ( or whatever version you wish to use ) :
ktor_version=1.3.2
kotlin_version=1.3.70.
Otherwise, in your 'build.gradle' file, create variables for different version :
buildscript {
ext.kotlin_version = '1.3.70'
ext.ktor_version = '1.3.2'
repositories {
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Then sync your gradle, run project.. all should be good.
However if you still experience some gradle-related issue, try this :
go to gradle (folder) -> wrapper -> open gradle_wrapper.properties and make sure the url has version 6.x.x or 5.x.x.
Mine looks like this currently:
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

Getting a NoClassDefFoundError when calling a kotlin extension function

I'm using the Android Studio 3.0 Beta 2 Canary Preview, and am calling a Kotlin extension function from Java:
The Kotlin code:
fun Metadata.validate(context: Context) {
validateInnerList(context)
// other validation functions
}
private fun Metadata.validateInnerList(context: Context) {
taskGroupList.removeIf { !it.isDataValid() } // error goes here
}
the java code:
metadataDecoratorKt.validate(metadata, context);
The code compiles fine, but during runtime calling it gives me a - java.lang.NoClassDefFoundError
Am I doing something wrong? is there an error on Intellij's side?
If more information is needed please say so.

Realm throws exception with empty unit test

In an Objective-C project, we started writing our new Unit Tests in Swift. I'm just now trying to create our first Unit Test of successfully saving the results of a parsed JSON. However, the test already fails during setup() due to the following error:
[ProjectTests.Project testInitializingOverlayCollectionCreatesAppropriateRealmObjects] : failed: caught "NSInvalidArgumentException", "+[RLMObjectBase ignoredProperties]: unrecognized selector sent to class 0x759b70
So apparently it tries to execute ignoredProperties on the RLMObjectBase class, and that method isn't implemented yet. Not sure how this happens, because I have yet to initialise anything, beyond creating a RLMRealms object with a random in-memory identifier.
ProjectTests.swift
import XCTest
class ProjectOverlayCollectionTests: XCTestCase {
var realm: RLMRealm!
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
let realmConfig = RLMRealmConfiguration()
realmConfig.inMemoryIdentifier = NSUUID().UUIDString
do {
realm = try RLMRealm(configuration: realmConfig) // <-- Crashes here.
}
catch _ as NSError {
XCTFail()
}
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testInitializingOverlayCollectionCreatesAppropriateRealmObjects() {
XCTAssertTrue(true)
}
}
Project-Bridging-Header.h
#import <Realm/Realm.h>
Podfile
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '7.1'
def shared_pods
pod 'Realm', '0.95.0'
end
target 'Project' do
shared_pods
end
target 'ProjectTests' do
shared_pods
end
As mentioned in the Realm documentation;
Avoid Linking Realm and Tested Code in Test Target
Remove the Realm pod from the ProjectTests target and all is right with the world.
Update: This answer is outdated. As #rommex mentions in a comment, following the current Realm installation documentation should link it to both your module and test targets without problems. However, I have not checked this.

How to best modify error messages from -validate method on Alamofire

I have this small snippet that makes a request to a login endpoint and it works fine.
public func loginWithEmail(email: String, password: String, completionHandler: Result<String, NSError> -> Void) {
Alamofire.request(AuthenticationRouter.Login(email: email, password: password))
.validate()
.responseString { response in
completionHandler(response.result)
}
}
My question is: when the user inputs invalid credentials the server returns 403 which due to validate will generate a Result<NSError>. What is the best way to modify the error description / failure reason in this error?
Should I create my own error? Is there a way to modify it for all the requests?
Alamofire validate func snippet for reference:
public func validate<S: SequenceType where S.Generator.Element == Int>(statusCode acceptableStatusCode: S) -> Self {
return validate { _, response in
if acceptableStatusCode.contains(response.statusCode) {
return .Success
} else {
let failureReason = "Response status code was unacceptable: \(response.statusCode)"
return .Failure(Error.errorWithCode(.StatusCodeValidationFailed, failureReason: failureReason))
}
}
}
The easiest way would be to act on the error once it reaches your app code. You probably don't want to create a custom validate method that overrides the default Alamofire behavior because your case is VERY specific.
In general, you would set your acceptable status codes and use the validate(statusCodes:) method. Then in your response logic in your app code, switch on the error and create custom app representations of each case. In this case, a 403 means that the incorrect credentials were used which only your application knows. Hence, it should live in your app code, not in an Alamofire validation extension. My two cents...

Attempting to port face books login button to swift

Everything seems to be going well, I am following this tutorial: http://www.brianjcoleman.com/tutorial-facebook-login-in-swift/#prettyPhoto
However within this function I am filled with errors, I am not sure if this is because of swift 2.0 or not but I am running Xcode 7.0.1
The two errors I am getting below are
Objective-C method 'application:openURL:sourceApplication:annotation:' provided by method 'application(_:openURL:sourceApplication:annotation:)' conflicts with optional requirement method 'application(_:openURL:sourceApplication:annotation:)' in protocol 'UIApplicationDelegate'
on the first line
as well as this error below on the second to last line of the function
Cannot invoke 'handleOpenURL' with an argument list of type '(NSURL, sourceApplication: NSString?)'
_
func application(application: UIApplication, openURL url: NSURL, sourceApplication: NSString?, annotation: AnyObject) -> Bool{
var wasHandled:Bool = FBAppCall.handleOpenURL(url, sourceApplication: sourceApplication)
return wasHandled
}
I would also like to mention that I do not understand Objective-C at all
Try this (directly from Facebook's walkthrough of integrating their login button, and what I use in one of my apps that uses Facebook login)
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
}