Issue with code for connecting to VPN - ios

I am creating an app the allows you to connect to a VPN at the tap of a button. I've been experimenting with the code, and I receive an error Use of unresolved identifier 'getPasscodeNSData'. I Googled everywhere but I could not find a way to solve this. Thank you in advance, I will leave the chunk of code below.
func initVPN() {
let manager: NEVPNManager = NEVPNManager.sharedManager()
let p = NEVPNProtocolIPSec()
p.username = "vpnUser"
p.passwordReference = getPasscodeNSData("vpnPassword")
p.serverAddress = "vpnIP"
p.authenticationMethod = NEVPNIKEAuthenticationMethod.SharedSecret
p.sharedSecretReference = getPasscodeNSData("vpnSharedSecret")
p.useExtendedAuthentication = true
p.disconnectOnSleep = false
}

Probably you copied this code from someone. getPasscodeNSData is a function that this person wrote. You need to copy that function too.

Related

iOS VPN auto disconnected after sometime

I'm working on a VPN application, VPN working fine but after 15-20 minutes, its automatically disconnected.
Here is configuration I'm using
let vpnProtocol = NEVPNProtocolIKEv2()
vpnProtocol.username = CredentialsManager.shared.accessToken
vpnProtocol.localIdentifier = CredentialsManager.shared.accessToken
print("VPN Connecting to \(self.region.name ?? "Error! Must be a valid region name!")")
if let region = self.region {
f
vpnProtocol.serverAddress = region.serverAddress
vpnProtocol.remoteIdentifier = region.serverAddress
}
let encodedIdentifier = "Secret Password".data(using: .utf8)!
let item = [kSecClass: kSecClassGenericPassword,
kSecAttrGeneric: encodedIdentifier,
kSecAttrAccount: encodedIdentifier,
kSecMatchLimit: kSecMatchLimitOne,
kSecReturnPersistentRef: kCFBooleanTrue as Any,
kSecAttrService: "XYZ"] as [CFString : Any]
var passwordReference: CFTypeRef?
SecItemCopyMatching(item as CFDictionary, &passwordReference)
vpnProtocol.passwordReference = passwordReference as? Data
vpnProtocol.authenticationMethod = .none
vpnProtocol.useExtendedAuthentication = true
vpnProtocol.ikeSecurityAssociationParameters.encryptionAlgorithm =
.algorithmAES256GCM
vpnProtocol.ikeSecurityAssociationParameters.integrityAlgorithm = .SHA384
vpnProtocol.ikeSecurityAssociationParameters.diffieHellmanGroup = .group14
vpnProtocol.childSecurityAssociationParameters.encryptionAlgorithm = .algorithmAES256GCM
vpnProtocol.childSecurityAssociationParameters.integrityAlgorithm = .SHA384
vpnProtocol.childSecurityAssociationParameters.diffieHellmanGroup = .group14
vpnProtocol.disconnectOnSleep = false
self.vpnManager.protocolConfiguration = vpnProtocol
let connectRule = NEOnDemandRuleConnect()
connectRule.interfaceTypeMatch = .any
self.vpnManager.onDemandRules = [connectRule]
self.vpnManager.isOnDemandEnabled = self.connectOnDemand
self.vpnManager.localizedDescription = "XYZ VPN"
self.vpnManager.isEnabled = true
Please help me out, how to identify problem that causing auto disconnect.
change your VPN protocol with this: NEVPNProtocolIPSec
maybe it will help you.
You have configured "connect on demand", so it will connect back automatically when you will access resource next time. That is how VPN on iOS works, it will always close connection on idle.

AWS DynamoDB updateItem problems in Swift 4

I am trying to update an item in my dynamoDB noSQL database. Having some troubles implementing this in swift as there is no swift documentation yet.
I was able to create an item in the database successfully, updating an item seems to be a whole other monster.
Swift Code:
var updatedValue: AWSDynamoDBAttributeValue = AWSDynamoDBAttributeValue()
updatedValue.s = self.UserID
let dynamo: AWSDynamoDB = AWSDynamoDB()
let AddToHistory = Users()
AddToHistory?._campany = self.CompanyTextBox.text!
AddToHistory?._personalSite = self.PersonalTitleTextBox.text!
AddToHistory?._facebook = self.FacebookTextBox.text!
AddToHistory?._linkedIn = self.LinkedInTextBox.text!
AddToHistory?._title = self.TitleTextBox.text!
AddToHistory?._bio = self.BioTextBox.text!
let updateInput: AWSDynamoDBUpdateItemInput = AWSDynamoDBUpdateItemInput()
updateInput.tableName = "myTableName"
updateInput.key = ["_userId": updatedValue]
let updatedCompany = AWSDynamoDBAttributeValue()
updatedCompany?.s = AddToHistory?._campany
let updatedFacebook = AWSDynamoDBAttributeValue()
updatedFacebook?.s = AddToHistory?._facebook
let updatedLinkedIn = AWSDynamoDBAttributeValue()
updatedLinkedIn?.s = AddToHistory?._linkedIn
let updatedPersonalSite = AWSDynamoDBAttributeValue()
updatedPersonalSite?.s = AddToHistory?._personalSite
let updatedTitle = AWSDynamoDBAttributeValue()
updatedTitle?.s = AddToHistory?._title
let updatedBio = AWSDynamoDBAttributeValue()
updatedBio?.s = AddToHistory?._bio
updateInput.expressionAttributeValues = [
"_campany" : updatedCompany!,
"_facebook" : updatedFacebook!,
"_linkedIn" : updatedLinkedIn!,
"_personalSite" : updatedPersonalSite!,
"_title" : updatedTitle!,
"_bio" : updatedBio!,
]
updateInput.returnValues = AWSDynamoDBReturnValue.updatedNew
dynamo.updateItem(updateInput).continueOnSuccessWith(block: { (task:AWSTask!) -> AnyObject! in
if (task.error == nil) {
}
return nil
}
)
Not getting any warnings or errors in the editor, however when I run the app and press the button which runs this code, I get this exception thrown:
Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason: '- init is not a valid
initializer. Use + defaultDynamoDB or + DynamoDBForKey: instead.'
Not sure what I am missing here, it must be something to do with the way I am initializing the dynamoDB object. Tried accessing a default method for init, but there is no such method. :(
Any help would be greatly appreciated, thanks in advance!
Thanks to Jake.lange's comment, I realized I could have used the object mapper that i used to create items to update them as well. Heres the code incase others run into this problem :)
//db connection mapper
let objectMapper = AWSDynamoDBObjectMapper.default()
//new instancer of User class
let itemToUpdate:CheckaraUsers = CheckaraUsers()
//populate
itemToUpdate._userId = UserID
itemToUpdate._firstName = FirstName
itemToUpdate._lastName = LastName
itemToUpdate._campany = AddToHistory?._campany
itemToUpdate._facebook = AddToHistory?._facebook
itemToUpdate._linkedIn = AddToHistory?._linkedIn
itemToUpdate._personalSite = AddToHistory?._personalSite
itemToUpdate._title = AddToHistory?._title
itemToUpdate._bio = AddToHistory?._bio
//save to dynamoDB
objectMapper.save(itemToUpdate, completionHandler:{(error: Error?) -> Void in
if let error = error {
print("Amazon DynamoDB Save Error: \(error)")
}
print("Saved Information!!!")
})
Your definition was wrong.
Change this:
let dynamo: AWSDynamoDB = AWSDynamoDB()
to:
let dynamo: AWSDynamoDB = AWSDynamoDB.default()

Create Entity programmatically (Core Data)

Is there a way to create a Entity programmatically on Core Data with swift2?
I searched for it, but I doesn't found something.
There are only a few tutorials on the Web (possibly only one).
I am not a fan of Xcode's GUI tools (Nibs, Storyboards, XCDataModeld, etc), so creating everything (from DB to UI) in code is usual thing for me.
The article referenced by #Lubos (2 minutes after I added a link to it in comments, hmm...) is written in ObjC.
So, here is a Swift code:
internal var _model: NSManagedObjectModel {
let model = NSManagedObjectModel()
// Create the entity
let entity = NSEntityDescription()
entity.name = "DTCachedFile"
// Assume that there is a correct
// `CachedFile` managed object class.
entity.managedObjectClassName = String(CachedFile)
// Create the attributes
var properties = Array<NSAttributeDescription>()
let remoteURLAttribute = NSAttributeDescription()
remoteURLAttribute.name = "remoteURL"
remoteURLAttribute.attributeType = .StringAttributeType
remoteURLAttribute.optional = false
remoteURLAttribute.indexed = true
properties.append(remoteURLAttribute)
let fileDataAttribute = NSAttributeDescription()
fileDataAttribute.name = "fileData"
fileDataAttribute.attributeType = .BinaryDataAttributeType
fileDataAttribute.optional = false
fileDataAttribute.allowsExternalBinaryDataStorage = true
properties.append(fileDataAttribute)
let lastAccessDateAttribute = NSAttributeDescription()
lastAccessDateAttribute.name = "lastAccessDate"
lastAccessDateAttribute.attributeType = .DateAttributeType
lastAccessDateAttribute.optional = false
properties.append(lastAccessDateAttribute)
let expirationDateAttribute = NSAttributeDescription()
expirationDateAttribute.name = "expirationDate"
expirationDateAttribute.attributeType = .DateAttributeType
expirationDateAttribute.optional = false
properties.append(expirationDateAttribute)
let contentTypeAttribute = NSAttributeDescription()
contentTypeAttribute.name = "contentType"
contentTypeAttribute.attributeType = .StringAttributeType
contentTypeAttribute.optional = true
properties.append(contentTypeAttribute)
let fileSizeAttribute = NSAttributeDescription()
fileSizeAttribute.name = "fileSize"
fileSizeAttribute.attributeType = .Integer32AttributeType
fileSizeAttribute.optional = false
properties.append(fileSizeAttribute)
let entityTagIdentifierAttribute = NSAttributeDescription()
entityTagIdentifierAttribute.name = "entityTagIdentifier"
entityTagIdentifierAttribute.attributeType = .StringAttributeType
entityTagIdentifierAttribute.optional = true
properties.append(entityTagIdentifierAttribute)
// Add attributes to entity
entity.properties = properties
// Add entity to model
model.entities = [entity]
// Done :]
return model
}
This code is equal to this CD model (created in Xcode's GUI):
Creating models in code is much more complicated than using GUI.
But, IMO, it is faster and safer than loading CoreData model file to get your model (what if no file exists? or the file is damaged?).
By 'safer' I mean that you don't have to handle disk IO errors related to reading CoreData model from disk (your model is in code, there is no need in model file). Average CoreData user just don't want to handle these errors because its easier to terminate an application
It is possible to define core data model programmatically. I found a good example, though it is written in Objective C. I am sure it is working also for Swift 2. You just need to rewrite it. Should take a few minutes.
https://www.cocoanetics.com/2012/04/creating-a-coredata-model-in-code/

How do I save dictionary (map object) to DynamoDB using Swift

I’m trying to save a dictionary to my DynamoDB table field using low-level API. I couldn’t figure out how to do it with object mapper. There is no example for this in AWS iOS documentation and I’ve tried to research and implement Java / .NET examples of the same subject unsuccessfully.
I want to update only the dictionary field in the row using updateExpression.
I stumbled to this question while searching for answer, but it didn't help: Best way to make Amazon AWS DynamoDB queries using Swift?
Here’s the function to update dynamoDB-table:
func saveMapToDatabase(hashKey:Int, rangeKey:Double, myDict:[Int:Double]){
let nsDict:NSDictionary = NSDictionary(dictionary: myDict)
var dictAsAwsValue = AWSDynamoDBAttributeValue();dictAsAwsValue.M = nsDict as [NSObject : AnyObject]
let updateInput:AWSDynamoDBUpdateItemInput = AWSDynamoDBUpdateItemInput()
let hashKeyValue:AWSDynamoDBAttributeValue = AWSDynamoDBAttributeValue();hashKeyValue.N = String(hashKey)
let rangeKeyValue:AWSDynamoDBAttributeValue = AWSDynamoDBAttributeValue(); rangeKeyValue.N = String(stringInterpolationSegment: rangeKey)
updateInput.tableName = "my_table_name"
updateInput.key = ["db_hash_key" :hashKeyValue, "db_range_key":rangeKeyValue]
//How I usually do low-level update:
//let valueUpdate:AWSDynamoDBAttributeValueUpdate = AWSDynamoDBAttributeValueUpdate()
//valueUpdate.value = dictAsAwsValue
//valueUpdate.action = AWSDynamoDBAttributeAction.Put
//updateInput.attributeUpdates = ["db_dictionary_field":valueUpdate]
//Using the recommended way: updateExpression
updateInput.expressionAttributeValues = ["dictionary_value":dictAsAwsValue]
updateInput.updateExpression = "SET db_dictionary_field = :dictionary_value"
self.dynamoDB.updateItem(updateInput).continueWithBlock{(task:BFTask!)->AnyObject! in
//do some debug stuff
println(updateInput.aws_properties())
println(task.description)
return nil
}
}
I solved it, the problem was that AWS requires dictionary keys to always be in the form of String, any other type is not allowed.
The working solution snippet:
...
updateInput.tableName = "my_table_name"
updateInput.key = ["db_hash_key" :hashKeyValue, "db_range_key":rangeKeyValue]
let dictionaryInRightFormat:NSDictionary = ["stringKey":dictAsAwsValue]
updateInput.expressionAttributeValues = updateInput.updateExpression = "SET db_dictionary_field = :stringKey"

How to send all traffic over a VPN connection?

I am creating an application to connect to a VPN server.
I have worked out how to do this, but need to be able to send all traffic over the connection.
Is there any code which can do this?
So far I have tried:
let manager: NEVPNManager = NEVPNManager.sharedManager()
var p = NEVPNProtocolIPSec()
manager.`protocol` = p
let pw = ""
println(manager.connection.status)
p.username = ""
p.passwordReference = pw.dataUsingEncoding(NSUTF8StringEncoding)
p.serverAddress = ""
p.authenticationMethod = NEVPNIKEAuthenticationMethod.SharedSecret
//p.sharedSecretReference = getPasscodeNSData("vpnSharedSecret")
p.useExtendedAuthentication = true
p.disconnectOnSleep = false
No, I don't think there is any way to switch all system IP traffic over a VPN connection. Apple doesn't let apps muck around with the OS like that.

Resources