I need to convert to swift 5, because my project is deprecated and I need to update this function ... any ideas?
Due to Apple's policies, which start in December ... The logic I had in the project using the Alamofire swift 4 library passed to Swift 5 and I have problems adapting this function due to the non-existent delegate.
func acceptInvalidSSLCerts() {
let manager = Alamofire.SessionManager.default
manager.delegate.sessionDidReceiveChallenge = { session, challenge in
var disposition: URLSession.AuthChallengeDisposition = .performDefaultHandling
var credential: URLCredential?
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
disposition = .useCredential
credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
} else {
if challenge.previousFailureCount > 0 {
disposition = .cancelAuthenticationChallenge
} else {
credential = manager.session.configuration.urlCredentialStorage?.defaultCredential(for: challenge.protectionSpace)
if credential != nil {
disposition = .useCredential
}
}
}
return (disposition, credential)
}
}
Related
I am using reward admob ad in my project with latest sdk. How can i get proper callback that the user has closed the ad in between. I know there is a delegate method of fullscreencontentdelegate which has a function adDidDismiss but in that function i am doing some code block which i perform when i complete watching the ad and it just works fine but what if i closed the ad in between, because what happens is that whether i see the whole ad or not this delegate function gets called and there is no way to differentiate how would i proceed with complete and incomplete ad. Please help me with this.
video link
as in the video first time i am not watching the whole ad and i just close it then also the scratch card popup comes because of the delegate method being called, which i dont want to open and then i just watch the whole ad and get my reward which is working fine
My code snippet:
enum RewardAdType {
case avatar, freeChips, scratchCard, chips250
}
typealias AD_COMPLETION_BLOCK = (_ success: Bool) -> ()
class RewardAdManager : NSObject
{
//MARK: - PROPERTIES
var rewardBasedVideoAd : GADRewardedAd? = nil
var rewardValue = ""
var type: RewardAdType? = nil
}
//MARK: - HELPERS
extension RewardAdManager
{
func loadRewardedAd(vc: UIViewController, userId: String, type: RewardAdType, imageName: String? = nil, chipsCoin: String? = nil, completion: #escaping AD_COMPLETION_BLOCK)
{
self.type = type
let adUnit = self.type == .avatar ? Constants.REWARD_AD_AVATAR_LIVE_ID : Constants.REWARD_AD_WINCHIPS_LIVE_ID
let request = GADRequest()
GADRewardedAd.load(withAdUnitID: adUnit, request: request) { [weak self] ad, error in
guard let self = self, error == nil else {
Helpers.hidehud()
self?.type = nil
self?.rewardBasedVideoAd = nil
return
}
let serverSideVerificationOptions = GADServerSideVerificationOptions()
serverSideVerificationOptions.userIdentifier = userId
if type == .scratchCard {
self.rewardValue = self.generateRandomRewardValue()
serverSideVerificationOptions.customRewardString = self.rewardValue
} else if type == .avatar {
serverSideVerificationOptions.customRewardString = imageName
} else if type == .freeChips {
serverSideVerificationOptions.customRewardString = chipsCoin
} else if type == .chips250 {
serverSideVerificationOptions.customRewardString = "250"
}
self.rewardBasedVideoAd = ad
self.rewardBasedVideoAd?.serverSideVerificationOptions = serverSideVerificationOptions
self.rewardBasedVideoAd?.fullScreenContentDelegate = self
self.showRewardedAd(viewController: vc, type: type, completion: completion)
}
}
func showRewardedAd(viewController: UIViewController, type: RewardAdType? = nil, completion: #escaping AD_COMPLETION_BLOCK)
{
Helpers.hidehud()
if let ad = self.rewardBasedVideoAd {
self.type = type
DispatchQueueHelper.delay {
ad.present(fromRootViewController: viewController) {}
}
completion(true)
} else {
self.type = nil
self.checkForSavedLanguage(viewController: viewController)
}
}
func checkForSavedLanguage(viewController: UIViewController)
{
let lang = LanguageCode(rawValue: Defaults[.LangCode]) ?? .english
viewController.showToast(msg: Constants.NO_ADS_MESSAGE.localizeString(string: lang))
}
func generateRandomRewardValue() -> String
{
var val = 0
let random = Double.random(in: 0.1...1.0)
if random < 0.20 {
val = 150
} else if random < 0.50 {
val = 200
} else if random < 0.70 {
val = 250
} else {
val = 350
}
return val.toString()
}
}
//MARK: - GADFullScreenContentDelegate
extension RewardAdManager : GADFullScreenContentDelegate {
func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error)
{
self.type = nil
Helpers.hidehud()
let lang = LanguageCode(rawValue: Defaults[.LangCode]) ?? .english
let userInfo = ["msg":Constants.NO_ADS_MESSAGE.localizeString(string: lang)]
NotificationCaller.shared.showLeaveMsg(userInfo: userInfo)
}
func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd)
{
guard let type = self.type else { return }
self.rewardBasedVideoAd = nil
let userInfo: [String:RewardAdType] = ["type":type]
NotificationCaller.shared.showRewardTypePopup(userInfo: userInfo)
}
}
I am building an app that works with janus gateway via websocket and webrtc. everything works fine, I can send and receive voice calls successfully but insertDtmf metod doesnt send my dtmf to other peer.
Same account and same codes in android works fine.
Here is where I prepare webrtc
private func prepareWebRtc( callbacks:PluginHandleWebRTCCallbacksDelegate) {
if (pc != nil) {
if (callbacks.getJsep() == nil) {
createSdpInternal(callbacks: callbacks, isOffer: isOffer)
} else {
let jsep = callbacks.getJsep()!
let sdpString:String = jsep["sdp"] as! String
let type:RTCSdpType = RTCSessionDescription.type(for: jsep["type"] as! String)
let sdp:RTCSessionDescription = RTCSessionDescription.init(type: type, sdp: sdpString)
pc.setRemoteDescription(sdp) { (err) in}
}
} else {
trickle = callbacks.getTrickle() != nil ? callbacks.getTrickle()! : false
streamsDone(webRTCCallbacks: callbacks)
}
}
private func streamsDone(webRTCCallbacks:PluginHandleWebRTCCallbacksDelegate) {
let rtcConfig = RTCConfiguration.init()
rtcConfig.iceServers = server.iceServers
rtcConfig.bundlePolicy = RTCBundlePolicy.maxBundle
rtcConfig.rtcpMuxPolicy = RTCRtcpMuxPolicy.require
rtcConfig.continualGatheringPolicy = RTCContinualGatheringPolicy.gatherContinually
rtcConfig.sdpSemantics = .planB
let source :RTCAudioSource = sessionFactory.audioSource(with: audioConstraints)
let audioTrack:RTCAudioTrack? = sessionFactory.audioTrack(with: source, trackId: AUDIO_TRACK_ID)
let stream:RTCMediaStream? = sessionFactory.mediaStream(withStreamId: LOCAL_MEDIA_ID)
if (audioTrack != nil){
stream!.addAudioTrack(audioTrack!)
myStream = stream
}
if (stream != nil){
onLocalStream(stream: stream!)
}
// pc.addTrack(audioTrack, mediaStreamLabels);
pc = sessionFactory.peerConnection(with: rtcConfig, constraints: audioConstraints, delegate: nil)
if (myStream != nil){
pc.add(myStream)
}
if let obj:[String:Any] = webRTCCallbacks.getJsep(){
let sdp:String = obj["sdp"] as! String
let type:RTCSdpType = RTCSessionDescription.type(for: obj["type"] as! String)
let sessionDescription:RTCSessionDescription = RTCSessionDescription(type: type, sdp: sdp)
print(" STREAMS DONE JSEP NULL DEĞİL")
// pc.setRemoteDescription(WebRtcObserver(webRTCCallbacks), sessionDescription);
pc.setRemoteDescription(sessionDescription) { (err) in
}
}else{
createSdpInternal(callbacks: webRTCCallbacks, isOffer: isOffer)
print(" STREAMS DONE JSEP NULL ");
}
/* } catch (Exception ex) {
webRTCCallbacks.onCallbackError(ex.getMessage());
}*/
}
and here where I try to send dtmf
public func insertDTMF(_ tone:String){
if(pc != nil){
if let dtmfSender = pc.senders.first?.dtmfSender{
dtmfSender.insertDtmf(tone, duration: 200, interToneGap: 70)
}
//Here the timers are in ms
}
}
In my case, this is how I have handled insert DTMF functionality.
a - First filter out audio RTCRtpSender track:
var audioSender: RTCRtpSender?
for rtpSender in pc.senders {
if rtpSender.track?.kind == "audio" {
audioSender = rtpSender
}
}
b - And then use the same filtered audioSender object to insert the tone using OperationQueue
if let audioSender = audioSender {
let queue = OperationQueue()
queue.addOperation({
audioSender.dtmfSender?.insertDtmf(dtmfTone, duration: TimeInterval(0.1),interToneGap: TimeInterval(0.5))
})
}
Note: you can modify duration and interToneGap as per your requirement.
Hope this solution works for you as well.
The original answer can be found here: https://stackoverflow.com/a/60148372/4515269
I am new in Swift. Since I update podfile I am facing issue in AWSS3
Cannot find type 'AWSS3TransferManagerUploadRequest' in scope
Cannot find type 'AWSS3TransferManagerDownloadRequest' in scope
There is also import AWSS3 in ViewController.
I am not understanding the problem. Did someone face the same issue?
I also check this https://stackoverflow.com/questions/32659346/awss3transfermanageruploadrequest-in-xcode-7
But it does not help.
var uploadRequests = Array<AWSS3TransferManagerUploadRequest?>()
var uploadFileURLs = Array<URL?>()
var downloadRequests = Array<AWSS3TransferManagerDownloadRequest?>()
func download(_ downloadRequest: AWSS3TransferManagerDownloadRequest) {
switch (downloadRequest.state) {
case .notStarted, .paused:
let transferManager = AWSS3TransferManager.default()
transferManager.download(downloadRequest).continueWith(block: { (task) -> AWSTask<AnyObject>? in
if let error = task.error {
if error.domain == AWSS3TransferManagerErrorDomain as String
&& AWSS3TransferManagerErrorType(rawValue: error.code) == AWSS3TransferManagerErrorType.paused {
print("Download paused.")
} else {
print("download failed: [\(error)]")
}
} else if let exception = task.error {
print("download failed: [\(exception)]")
} else {
DispatchQueue.main.async(execute: { () -> Void in
print("downloaded file url: \(downloadRequest.downloadingFileURL)")
// if let index = self.indexOfDownloadRequest(self.downloadRequests, downloadRequest: downloadRequest) {
// self.downloadRequests[index] = nil
// self.downloadFileURLs[index] = downloadRequest.downloadingFileURL
//
// let indexPath = NSIndexPath(forRow: index, inSection: 0)
// self.collectionView.reloadItemsAtIndexPaths([indexPath])
// }
})
}
return nil
})
break
default:
break
}
}
func downloadAll() {
for (_, value) in self.downloadRequests.enumerated() {
if let downloadRequest = value {
if downloadRequest.state == .notStarted
|| downloadRequest.state == .paused {
self.download(downloadRequest)
}
}
}
// self.collectionView.reloadData()
}
func listObjects() {
let s3 = AWSS3.default()
let listObjectsRequest = AWSS3ListObjectsRequest()
listObjectsRequest?.bucket = "dice-ios"
s3.listObjects(listObjectsRequest!).continueWith { (task) -> AnyObject? in
if let error = task.error {
print("listObjects failed: [\(error)]")
}
if let exception = task.error {
print("listObjects failed: [\(exception)]")
}
if let listObjectsOutput = task.result {
if let contents = listObjectsOutput.contents {
for s3Object in contents {
let downloadingFileURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("download").appendingPathComponent(s3Object.key!)
let downloadingFilePath = downloadingFileURL.path
if FileManager.default.fileExists(atPath: downloadingFilePath) {
self.downloadRequests.append(nil)
self.downloadFileURLs.append(downloadingFileURL)
} else {
let downloadRequest = AWSS3TransferManagerDownloadRequest()
downloadRequest?.bucket = "dice-ios"
downloadRequest?.key = s3Object.key
downloadRequest?.downloadingFileURL = downloadingFileURL
self.downloadRequests.append(downloadRequest)
self.downloadFileURLs.append(nil)
}
}
DispatchQueue.main.async(execute: { () -> Void in
// self.collectionView.reloadData()
})
}
}
return nil
}
}
My code is like this I am getting issue since I update the podfile.I am facing issue in AWS3 as it is updated. I need to know what to replace.
I coped with the same problem when I was integrating the pod named AWSS3.
I fixed it by installing the specific version of these pods.
Please check this URL
https://cocoapods.org/pods/AWSS3#changelog
In my case, I installed the v2.16.0.
I think it is concerning with the Xcode version.
pod 'AWSS3', '~> 2.16.0'
I hope this helps you.
You need to downgrade your AWSS3 pod version. Check the pod folder to see if the tool you're using is there (In my case, AWSS3TransferManager.h was missing from current version, downgraded to a version that had it).
I tried everything, read everywhere, but I'm unable to make a shared record editable by the user who received the link
Everything works fine except the edit performed by the invited user
here's the sharing code (like the WWDC16 video):
let sharingController = UICloudSharingController { (controller, preparationCompletionHandler) in
let share = CKShare(rootRecord: record)
share.publicPermission = .readWrite
share[CKShareTitleKey] = "Help me to improve data" as CKRecordValue
share[CKShareTypeKey] = "com.company.AppName" as CKRecordValue
let modifyRecordsOperation = CKModifyRecordsOperation( recordsToSave: [record, share], recordIDsToDelete: nil)
modifyRecordsOperation.modifyRecordsCompletionBlock = { (records, recordIDs, error) in
if let errorK = error {
print(errorK.localizedDescription)
}
preparationCompletionHandler(share, CKContainer.default(), error)
}
CKContainer.default().privateCloudDatabase.add(modifyRecordsOperation)
}
sharingController.availablePermissions = [.allowPublic, .allowPrivate, .allowReadWrite]
sharingController.delegate = self
controller.present(sharingController, animated: true)
The console always print:
PrivateDB can't be used to access another user's zone
thank you
when you retrive the shared record you need to add the operation to the sharedDatabase:
func fetchShare(_ metadata: CKShareMetadata) {
debugPrint("fetchShare")
let operation = CKFetchRecordsOperation(recordIDs: [metadata.rootRecordID])
operation.perRecordCompletionBlock = { record, _, error in
if let errore = error { debugPrint("Error fetch shared record \(errore.localizedDescription)") }
if let recordOk = record {
DispatchQueue.main.async() {
self.storage.append(recordOk)
}
}
}
operation.fetchRecordsCompletionBlock = { (recordsByRecordID, error) in
if let errore = error { debugPrint("Error fetch shared record \(errore.localizedDescription)") }
}
CKContainer.default().sharedCloudDatabase.add(operation)
}
but now there is a problem when you try to update the record, you need to know who is the owner, if the owner is the one who shared the record you need to save to the private db, if the owner is another person you need to save to the shared db... so:
func updateOrSaveRecord(_ record:CKRecord, update:Bool) {
var db : CKDatabase
if update == true {
guard let creatorUserID = record.creatorUserRecordID else { return }
if record.share != nil && creatorUserID.recordName != CKCurrentUserDefaultName {
debugPrint("record shared from another user")
db = CKContainer.default().sharedCloudDatabase
} else {
debugPrint("private record")
db = CKContainer.default().privateCloudDatabase
}
} else { db = CKContainer.default().privateCloudDatabase }
db.save(record) { (savedRecord, error) in
if let errorTest = error {
print(errorTest.localizedDescription)
} else {
if let recordOK = savedRecord {
DispatchQueue.main.async {
if update == false {
self.storage.append(recordOK)
} else {
self.dettCont?.updateScreen()
}
self.listCont?.tableView.reloadData()
}
}
}
}
}
to know if the record was created by the current user the trick is to compare against CKCurrentUserDefaultName
I have initialized the credentials provider per this AWS Developer Guide. I'm not sure if it worked, and how to check. I can't seem to find any documentation on how to use Cognito with Swift. I'm running it as a unit test, and the test passes and the line print("identityId", identityId) outputs:
identityId <AWSTask: 0x17d5fde0; completed = NO; cancelled = NO; faulted = NO;>
However, during debug the property identityProvider.identityId is nil.
Here are my files:
// MyAuth.swift
import Foundation
import AWSCognito
class MyAuth {
func getUnauthCognitoId()->Bool {
let identityProvider = MyIdentityProvider()
let credentialsProvider = AWSCognitoCredentialsProvider(regionType: AWSRegionType.USEast1, identityProvider: identityProvider, unauthRoleArn: Constants.ARNUnauth.value, authRoleArn: Constants.ARNAuth.value)
let defaultServiceConfiguration = AWSServiceConfiguration(region: .USEast1, credentialsProvider: credentialsProvider)
AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = defaultServiceConfiguration
if let identityId = identityProvider.getIdentityId() {
print("identityId", identityId)
return true
} else {
return false
}
}
}
And
// MyIdentityProvider.swift
import Foundation
import AWSCognito
class MyIdentityProvider: AWSAbstractCognitoIdentityProvider {
var _token: String!
var _logins: [ NSObject : AnyObject ]!
// Header stuff you may not need but I use for auth with my server
/*let acceptHeader = "application/vnd.exampleapp-api+json;version=1;"
let authHeader = "Token token="
let userDefaults = NSUserDefaults.standardUserDefaults()
let authToken = self.userDefaults.valueForKey("authentication_token") as String*/
// End point that my server gives amazon identityId and tokens to authorized users
let url = "https://api.myapp.com/api/amazon_id/"
func authenticatedWithProvider()->Bool {
if let logins = _logins {
return logins["ProviderName"] == nil
}
else {
return false
}
}
override var token: String {
get {
return _token
}
}
override var logins: [ NSObject : AnyObject ]! {
get {
return _logins
}
set {
_logins = newValue
}
}
override func getIdentityId() -> AWSTask! {
if self.identityId != nil {
return AWSTask(result: self.identityId)
}
else if(!self.authenticatedWithProvider()) {
return super.getIdentityId()
}
else{
return AWSTask(result: nil).continueWithBlock({ (task) -> AnyObject! in
if self.identityId == nil {
return self.refresh()
}
return AWSTask(result: self.identityId)
})
}
}
override func refresh() -> AWSTask! {
let task = AWSTaskCompletionSource()
if(!self.authenticatedWithProvider()) {
return super.getIdentityId()
}
else {
// TODO: Authenticate with developer
return task.task
}
/*let request = AFHTTPRequestOperationManager()
request.requestSerializer.setValue(self.acceptHeader, forHTTPHeaderField: "ACCEPT")
request.requestSerializer.setValue(self.authHeader+authToken, forHTTPHeaderField: "AUTHORIZATION")
request.GET(self.url, parameters: nil, success: { (request: AFHTTPRequestOperation!, response: AnyObject!) -> Void in
// The following 3 lines are required as referenced here: http://stackoverflow.com/a/26741208/535363
var tmp = NSMutableDictionary()
tmp.setObject("temp", forKey: "ExampleApp")
self.logins = tmp
// Get the properties from my server response
let properties: NSDictionary = response.objectForKey("properties") as NSDictionary
let amazonId = properties.objectForKey("amazon_identity") as String
let amazonToken = properties.objectForKey("token") as String
// Set the identityId and token for the ExampleAppIdentityProvider
self.identityId = amazonId
self._token = amazonToken
task.setResult(response)
}, failure: { (request: AFHTTPRequestOperation!, error: NSError!) -> Void in
task.setError(error)
})*/
return task.task
}
}
And
import XCTest
#testable import My
class MyTests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measureBlock {
// Put the code you want to measure the time of here.
}
}
func testGetUnauthCognitoId() {
let myAuth = MyAuth()
XCTAssertTrue(myAuth.getUnauthCognitoId())
}
}
It turns out that if you create a default service configuration within the application:didFinishLaunchingWithOptions: application delegate method in your app delegate file as described here:
let credentialsProvider = AWSCognitoCredentialsProvider(
regionType: AWSRegionType.USEast1, identityPoolId: cognitoIdentityPoolId)
let defaultServiceConfiguration = AWSServiceConfiguration(
region: AWSRegionType.USEast1, credentialsProvider: credentialsProvider)
AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = defaultServiceConfiguration
The SDK will use an unauthenticated identity whenever you try to use any of the AWS services, and you don't necessarily need to create a cognitoIdentity object.
getIdentityId returns an AWSTask. Since AWSTask is essentially BFTask with a different name, you can get the identityId using the continueWithBlock syntax shown on the BFTask page. Something like:
credentialProvider.getIdentityId().continueWithBlock {
(task: AWSTask!) -> AWSTask in
if task.error() {
// failed to retrieve identityId.
} else {
print("identityId", task.result())
}