Can I turn a string into a block of code in swift? - ios

Is there any way to turn a string into a block of code? I'm making an Ajax request to a website of mine that has an endpoint that returns some swift code as a string. I can get that code back as a string, but I can't run that code because it doesn't know that it is code.

As others have pointed out, if you are creating an iOS app (especially for distribution on the app store), you can not do this. However, if you are writing Swift code for an OS X machine AND you know that XCode is installed on the machine, you can run your Swift code string by running the command-line Swift compiler. Something like this (with proper error checking, of course):
var str = "let str = \"Hello\"\nprintln(\"\\(str) world\")\n"
let task = Process()
task.launchPath = "/usr/bin/swift"
let outpipe = Pipe()
let inpipe = Pipe()
inpipe.fileHandleForWriting.write(str.data(using: String.Encoding.utf8, allowLossyConversion: true)!)
task.standardInput = inpipe
task.standardOutput = outpipe
task.launch()
task.waitUntilExit()
task.standardInput = Pipe()
let data = outpipe.fileHandleForReading.readDataToEndOfFile()
let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue)! as String
Again, this is probably not recommended in nearly all real-world cases, but is a way you can execute a String of Swift code, if you really need to.

No, you can't do that. Swift is a compiled language, not interpreted like Ajax.
The Swift compiler runs on your Mac, not on the iOS device. (The same is true for Objective-C).
Plus, Apple's app store guidelines forbid delivering executable code to your apps, so even if you figured out a way to do it, your app would be rejected.
Edit:
Note that with the advent of Swift playgrounds, it is possible to run the Swift compiler on an iPad. Recent high-end iPhones are probably also up to the job, but you'd have to figure out how to get it installed.
As stated above though, Apple's app store guidelines forbid you from delivering code to your apps at runtime.

Related

AES encryption not working properly on iOS 13.4

My iOS application creates a key using AES encryption and send it with all the APIs , and it is being decrypted at the server end, now after the update of OS 13.4 the key created from the device(not the simulator) is in incorrect and the following error is thrown by the server :
"Padding is invalid and cannot be removed."
It is working perfectly in the devices below 13.4 OS version , we are using CommonCrypto to encrypt the key at our end , following are the details :
let ivData = "passpharse".data(using:String.Encoding.utf8)!
let cryptLength = size_t(data.count + kCCBlockSizeAES128)
var cryptData = Data(count:cryptLength
let keyLength = size_t(kCCKeySizeAES128)
let options = CCOptions(kCCOptionPKCS7Padding)
var numBytesEncrypted :size_t = 0
The surprising part is that the key is being correctly generated for some API calls although same method is used for key generation.
Users with iOS - OS less than 13.4 are not facing any issue, If anyone have came across the same situation please guide.
thanks in advance.
After much research I made it work on all the versions.
if in the above code “passphrase” is shorted than 16 bytes, it uses whatever's in-memory past the end.
It seems like improper use of the CommonCrypto APIs was the issue here. Really don’t know why this worked before, but maybe we got lucky with the memory layout but the issues above need to be remedied before this will function as expected.

Operations on xml file using Swift for mobile

I have to do some operations in my xml file in project
Operations like -
Inserting the records
Writing the records
Deleting the records at specific location(with index).
NSXMLDocument is for Mac OS
Can any one help me with some sample code to understand and to implement the operations on the Xml file without using the third party frameworks.
For iOS Apple provides an XMLParser api for swift and NSXMLParser for Objective C. You can check out this tutorial for reference.
You can use following code to read a file in iOS
let bundle = NSBundle.mainBundle()
let path = bundle.pathForResource("data", ofType: "json")
let content = NSString.stringWithContentsOfFile(path) as String
then pass the string to XMLParser and implement its delegate methods.
Hope this helps.

Looking for Xcode Swift examples to decompress gzipped Json data

I am trying to decompressed a Json data stream. I've found various decompression solutions, the native zlib seems easier, the other cocoa pod solutions produced new problems. The setting advised in native zlib inflate/deflate for swift3 on iOS seems working, the problem is what's next. I've thoroughly searched the net, only found C or Obj-C example codes but not Swift's. Thanks.
Another solution I tried was with https://github.com/mw99/DataCompression. But I had problem trying to set it up according to the instruction so look into the short codes and took out the part that I think should work for me, hard-coded some of the options. But no matter which algorithm I tried, perform() return nil.
I also tried unzip(), it failed at guard header >> 8 & 0b1111 == 0b1000. The web address automatic download a gzip file which can be decompressed into a Json file.
var routeFile: JsonRouteFile?
UIApplication.shared.isNetworkActivityIndicatorVisible = true
let urlRoute:URL = URL(string: "http://data.taipei/bus/ROUTE")!
DispatchQueue.global().async {
do {
let data:Data = try Data(contentsOf: urlRoute)
routeFile = try JSONDecoder().decode(JsonRouteFile?.self, from: data.decompress()!)
`
https://github.com/1024jp/GzipSwift works.
I didn't go through the enter installation though. Just dragged the file over.

I received a URL from a server with a unicode é in it (\U00e9). How do I create an NSURL with it?

Whenever I try to create an NSURL from it, I always receive nil back. How do I make it work?
Small example:
let str = "https://montr\\U00e9al.ca".stringByRemovingPercentEncoding!
NSURL(string: str)
Which always gives me nil back. Even if I replace the \u00e9 with é it still returns nil.
How should I be doing this?
You should make unicode in braces and add percent for it like this:
let str = "https://www.montr\u{00e9}al.ca".stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
First, if you have any control over the server, you should fix the server to provide proper URLs. If you don't have control over it, but can choose a different service, do so. There's no guarantee that improperly encoded URLs will be the only problem coming from that server.
If you can't switch servers, you may need to do something like this:
let percentEncodedURLString = NSURL(dataRepresentation: str.dataUsingEncoding(NSUTF8StringEncoding)!, relativeToURL: nil).relativeString
This is the Swift version of what Apple recommends in the Foundation release notes. I strongly recommend that you read that section to understand the issues with other approaches.

Using reopened standard file descriptors in an iOS app with background capabilities?

I would like to be able to redirect my logging statements to a file so that I can retrieve them when my app runs standalone (i.e. is not attached to Xcode). I have discovered (thank you Stackoverflow) that freopen can be used to accomplish this.
If I create a new Xcode project and add the code to redirect stderr then everything works as expected.
However, when I add the redirection code to my existing, bluetooth project I am having trouble. The file is being created and I can retrieve it using iTunes or Xcode's Devices window, but it is of size 0. If I explicitly close the file then the text that I wrote actually makes it into the file. It is as though iOS is not flushing the file when the app is terminated. I suspect that the trouble stems from the fact that I have enabled background processing. Can anyone help me to understand this?
Here is my code:
let pathes = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true);
let filePath = NSURL(fileURLWithPath: pathes[0]).URLByAppendingPathComponent("Test.log")
freopen(filePath.path!, "a", stderr);
fputs("Hello, Samantha!\r\n", stderr);
struct StderrOutputStream: OutputStreamType {
static let stream = StderrOutputStream()
func write(string: String) {fputs(string, stderr)}
}
var errStream = StderrOutputStream.stream
print("Hello, Robert", toStream: &errStream)
fclose(stderr) // Without this the text does not make it into the file.
I'd leave this as a comment, but have you looked into NSFileHandle? It sounds like you just need a way to append data to the end of a text file, correct?
Once you have a handle with something like NSFileHandle(forWritingToURL:), you can use .seekToEndOfFile() and .writeData(_:). As a side note, you'll need to convert your String to Data before writing it.
Admittedly, this will probably end up being more lines of code, and you'll almost certainly need to take threading into consideration.

Resources