Swift - Write Image from URL to Local File - json

I've been learning swift rather quickly, and I'm trying to develop an OS X application that downloads images.
I've been able to parse the JSON I'm looking for into an array of URLs as follows:
func didReceiveAPIResults(results: NSArray) {
println(results)
for link in results {
let stringLink = link as String
//Check to make sure that the string is actually pointing to a file
if stringLink.lowercaseString.rangeOfString(".jpg") != nil {2
//Convert string to url
var imgURL: NSURL = NSURL(string: stringLink)!
//Download an NSData representation of the image from URL
var request: NSURLRequest = NSURLRequest(URL: imgURL)
var urlConnection: NSURLConnection = NSURLConnection(request: request, delegate: self)!
//Make request to download URL
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: { (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
if !(error? != nil) {
//set image to requested resource
var image = NSImage(data: data)
} else {
//If request fails...
println("error: \(error.localizedDescription)")
}
})
}
}
}
So at this point I have my images defined as "image", but what I'm failing to grasp here is how to save these files to my local directory.
Any help on this matter would be greatly appreciated!
Thanks,
tvick47

In Swift 3:
Write
do {
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let fileURL = documentsURL.appendingPathComponent("\(fileName).png")
if let pngImageData = UIImagePNGRepresentation(image) {
try pngImageData.write(to: fileURL, options: .atomic)
}
} catch { }
Read
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let filePath = documentsURL.appendingPathComponent("\(fileName).png").path
if FileManager.default.fileExists(atPath: filePath) {
return UIImage(contentsOfFile: filePath)
}

The following code would write a UIImage in the Application Documents directory under the filename 'filename.jpg'
var image = .... // However you create/get a UIImage
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
let destinationPath = documentsPath.stringByAppendingPathComponent("filename.jpg")
UIImageJPEGRepresentation(image,1.0).writeToFile(destinationPath, atomically: true)

In swift 2.0, stringByAppendingPathComponent is unavailable, so the answer changes a bit. Here is what I've done to write a UIImage out to disk.
documentsURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
if let image = UIImage(data: someNSDataRepresentingAnImage) {
let fileURL = documentsURL.URLByAppendingPathComponent(fileName+".png")
if let pngImageData = UIImagePNGRepresentation(image) {
pngImageData.writeToURL(fileURL, atomically: false)
}
}

UIImagePNGRepresentaton() function had been deprecated. try image.pngData()

#IBAction func savePhoto(_ sender: Any) {
let imageData = UIImagePNGRepresentation(myImg.image!)
let compresedImage = UIImage(data: imageData!)
UIImageWriteToSavedPhotosAlbum(compresedImage!, nil, nil, nil)
let alert = UIAlertController(title: "Saved", message: "Your image has been saved", preferredStyle: .alert)
let okAction = UIAlertAction(title: "Ok", style: .default)
alert.addAction(okAction)
self.present(alert, animated: true)
}
}

Update for swift 5
just change filename.png to something else
func writeImageToDocs(image:UIImage){
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let destinationPath = URL(fileURLWithPath: documentsPath).appendingPathComponent("filename.png")
debugPrint("destination path is",destinationPath)
do {
try image.pngData()?.write(to: destinationPath)
} catch {
debugPrint("writing file error", error)
}
}
func readImageFromDocs()->UIImage?{
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let filePath = URL(fileURLWithPath: documentsPath).appendingPathComponent("filename.png").path
if FileManager.default.fileExists(atPath: filePath) {
return UIImage(contentsOfFile: filePath)
} else {
return nil
}
}

Related

SwiftUI local JSON save string value

I created a local json. I change the value of the name key in the json and when I close and open the application, it says "Test" again. How can I save the change I made on the Json file?
Why can't I save the string value? I shared all the codes with you. If you want I can share the project.
Local JSON File
{
"person": {
"name": "Test"
}
}
Model
struct PersonContainer: Codable {
var person: Person?
}
struct Person: Codable {
var name: String?
}
JSON Provider
class JSONProvider: ObservableObject {
#Published var personContainer: PersonContainer = PersonContainer()
var fm = FileManager.default
var fresult: Bool = false
#Published var subUrl: URL? = URL(string: "")
var mainUrl: URL? = Bundle.main.url(forResource: "test", withExtension: "json")
func getData() {
do {
let documentDirectory = try fm.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
subUrl = documentDirectory.appendingPathComponent("test.json")
loadFile(mainPath: mainUrl!, subPath: subUrl!)
} catch {
print(error)
}
}
func loadFile(mainPath: URL, subPath: URL){
if fm.fileExists(atPath: subPath.path){
decodeData(pathName: subPath)
if ((personContainer.person) != nil) {
decodeData(pathName: mainPath)
}
}else{
decodeData(pathName: mainPath)
}
}
func decodeData(pathName: URL){
do{
let jsonData = try Data(contentsOf: pathName)
let decoder = JSONDecoder()
let personContainer = try decoder.decode(PersonContainer.self, from: jsonData)
self.personContainer = personContainer
} catch {}
}
func writeToFile(location: URL) {
do{
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let JsonData = try encoder.encode(personContainer)
try JsonData.write(to: location)
} catch {
}
}
}
ContentView
struct ContentView: View {
#State var text: String = ""
#ObservedObject var jsonProvider: JSONProvider = JSONProvider()
var body: some View {
VStack {
TextField("Placeholder", text: $text)
.padding()
.background(Color(UIColor.secondarySystemBackground))
.cornerRadius(15)
.padding(.horizontal)
Text("Hello, world! \(jsonProvider.personContainer.person?.name ?? "")")
.padding()
Button(action: {
jsonProvider.personContainer.person?.name = text
jsonProvider.writeToFile(location: jsonProvider.subUrl!)
}) {
Text("Button")
}
}
.onAppear {
jsonProvider.getData()
}
}
}
Looks like you were on the right track, but there were a few things missing.
Since the original main bundle's test.json should only be loaded if the file in the documents directory doesn't exist, a lot of the logic can be simplified. For example, you can remove the #Published subUrl, since it never gets changed and isn't observed by the View.
Make sure that you call the writeToFile when the button is pressed.
Also, it's always a good idea to do something (like printing the error) inside the catch blocks in case something has gone wrong.
class JSONProvider: ObservableObject {
#Published var personContainer: PersonContainer = PersonContainer()
private var fm = FileManager.default
private let mainUrl: URL = Bundle.main.url(forResource: "test", withExtension: "json")!
func getData() {
if fm.fileExists(atPath: documentDirectoryJSONURL().path) {
decodeData(fromURL: documentDirectoryJSONURL())
} else {
decodeData(fromURL: mainUrl)
}
}
func documentDirectoryJSONURL() -> URL {
do {
let documentDirectory = try fm.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
return documentDirectory.appendingPathComponent("test.json")
} catch {
fatalError("Couldn't create URL")
}
}
func decodeData(fromURL url: URL){
do{
let jsonData = try Data(contentsOf: url)
let decoder = JSONDecoder()
let personContainer = try decoder.decode(PersonContainer.self, from: jsonData)
self.personContainer = personContainer
} catch {
print(error)
assertionFailure("Error decoding JSON")
}
}
func writeToFile() {
do{
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let jsonData = try encoder.encode(personContainer)
try jsonData.write(to: documentDirectoryJSONURL())
} catch {
print(error)
}
}
}
struct ContentView: View {
#State var text: String = ""
#ObservedObject var jsonProvider: JSONProvider = JSONProvider()
var body: some View {
VStack {
TextField("Placeholder", text: $text)
.padding()
.background(Color(UIColor.secondarySystemBackground))
.cornerRadius(15)
.padding(.horizontal)
Text("Hello, world! \(jsonProvider.personContainer.person?.name ?? "")")
.padding()
Button(action: {
jsonProvider.personContainer.person?.name = text
jsonProvider.writeToFile()
}) {
Text("Write")
}
}
.onAppear {
jsonProvider.getData()
}
}
}

WKwebview is blank white screen when returning from cam scanner SDK in iOS Swift?

I have loaded iframe form into wkwebview and its working fine. When the tap scanner button inside an iframe and it opens the camera to scan the document, after document uploaded to the server it will return to wkweb view but here wkweb view is not refreshed and showing a blank white screen.
Here is my code for wkweb view:
private func loadWebView(){
webView.uiDelegate = self
webView.allowsBackForwardNavigationGestures = true
do {
guard let filePath = Bundle.main.path(forResource: "index", ofType: "html")
else {
// File Error
print ("File reading error")
return
}
let contents = try String(contentsOfFile: filePath, encoding: .utf8)
let baseUrl = URL(fileURLWithPath: "https://url")
DispatchQueue.main.async {
self.webView.loadHTMLString(contents as String, baseURL: baseUrl)
}
}
catch {
print ("File HTML error")
}
webView.configuration.preferences.javaScriptEnabled = true
webView.configuration.userContentController.add(self, name: "jsHandler")
webView.configuration.userContentController.add(self, name: "saveHandler")
webView.configuration.userContentController.add(self, name: "openCamera")
}
func makeSaveForm(ProcessInstanceId: String, FullFormKey: String, TaskIdValue: String, FormValues: String) -> saveFormModel {
let newForm = saveFormModel()
newForm.ProcessInstanceId = ProcessInstanceId
newForm.FullFormKey = FullFormKey
newForm.TaskIdValue = TaskIdValue
newForm.FormValues = FormValues
return newForm
}
func ProcessInstanceIDApiCall(ProcessInstId: String){
let authToken = UserDefaults.standard.string(forKey: "authToken")
print("id for process instance", ProcessInstId)
let bearerToken: String = "Bearer " + (authToken ?? "")
print("baearer token::\(bearerToken)")
let headers:HTTPHeaders = ["Content-Type":"Application/json",
"Authorization": "Bearer " + (authToken ?? ""),
"Accept":"application/json"]
AF.request("https://api url/process-instance/\(ProcessInstId)/variables", method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers).responseJSON { (response:AFDataResponse<Any>) in
print("process instance id api",response.result)
switch response.result {
case .success:
print("instance response", response.value )
guard let data = response.value else {
// print("request failed \(error)")
return
}
self.anyValueJson = response.value
self.jsonStringProcessInstanceID = self.JSONStringify(value: data as AnyObject)
print("raw response: \(String(describing: self.jsonStringProcessInstanceID))")
case .failure(let error):
print("Error:", error)
}
}
}//api call end
public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "jsHandler" {
// print(message.body)
} else if message.name == "saveHandler" {
let values = message.body
print(values)
let jsonString = JSONStringify(value: values as AnyObject)
print(jsonString)
formValues = jsonString
let newSaveForm = self.makeSaveForm(ProcessInstanceId: self.processInstanceId ?? "", FullFormKey: self.fullFormKey ?? "", TaskIdValue: self.taskIdValue ?? "", FormValues: jsonString )
//realm create/update saveform based task id
let realm = try! Realm()
if realm.object(ofType: saveFormModel.self, forPrimaryKey: newSaveForm.TaskIdValue) != nil {
try! realm.write {
print("already exist")
//.all is equivalent to true and .error is equivalent to false
realm.add(newSaveForm, update: .all)
}
} else {
try! realm.write {
print("new document written")
realm.add(newSaveForm) //RLMException occurs here
}
}
} else if message.name == "openCamera" {
print("open camera",message.body)
let base64Encoded = message.body
let jsonString = JSONStringify(value: base64Encoded as AnyObject)
do{
if let json = jsonString.data(using: String.Encoding.utf8){
if let jsonData = try JSONSerialization.jsonObject(with: json, options: .allowFragments) as? [String:AnyObject]{
let id = jsonData["scannerData"] as! String
print("scanner data ::", id)
let vc1 = ScannerViewController()
let v = vc1.scanParameters(scannerDataBase64: id)
print("v", v)
let newVC = A8Scan(self)
newVC.showScanner()
}
}
}catch {
print(error.localizedDescription)
}
func loadFormView(){
let setPath = "https://api url/\(formKey ?? "")/index.html";
let js = "setFrame('" + setPath + "')";
print("js::\(js)")
webView.evaluateJavaScript(js) { (r, error) in
if error == nil {
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0){
print(r ?? "empty")
let realm = try! Realm()
let object = realm.object(ofType: saveFormModel.self, forPrimaryKey: self.taskIdValue)
print("object", object ?? "")
print("json api string", self.jsonStringProcessInstanceID ?? "")
let authValue = "Bearer \(self.authTokenValue ?? "")"
if object?.FullFormKey != nil {
if let jsonStr = self.jsonStringProcessInstanceID {
let l = "loadform('\(object?.FullFormKey ?? "")', '\(authValue)', '\(object?.ProcessInstanceId ?? "")', \(object?.FormValues ?? ""), \(jsonStr))"
self.webView.evaluateJavaScript(l, completionHandler: nil)
}
} else {
if let jsonStr = self.jsonStringProcessInstanceID {
print("json str::::", jsonStr)
let l = "loadform('\(self.fullFormKey ?? "")', '\( authValue)', '\(self.processInstanceId ?? "")', \(jsonStr))"
self.webView.evaluateJavaScript(l, completionHandler: nil)
}
}
self.tapCallback = {
print("tap called save")
// let s = "submitEvent('\(self.saveArg)')"
let save = "submitEvent('save');"
self.webView.evaluateJavaScript(save, completionHandler: nil)
}
}
} else {
print("web view didfinish loading error",error)
}
}
}
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("Web View didFinish Loading");
loadFormView()
}
My issue when I'm returning to wkweb view after from scanner SDK it shows a blank white screen. How to refresh the screen when I return to the web view each time scanner SDK close?
Any help much appreciated, please...
The problem is being caused by AVG AntiVirus's webshield. For some reason AVG webshield treats all network communication from the simulator as fraudulent.
The following screenshot shows the safari app running on simulator. It says that www.apple.com is not safe or any other website.
The following screenshot is from system.log showing errors with webkit.
You can replicate this problem by installing AVG antivirus and turning on the webshield. WKWebview in your App(On the simulator) wouldn't load anything.
taken from here

Save JSON response as JSON file

I want to save my JSON response to a JSON file in document or any other directory.
Earlier I was trying to save the response in coreData but that was a heavy and slow task.
//API Manager function
func loadEmployees(urlString: String, completion: #escaping ((Any?,Error?) -> ())){
guard let url = URL(string: urlString) else { return }
var request = URLRequest(url: url)
request.httpMethod = RequestMethod.get.rawValue
let session = URLSession.shared
let sessionTask = session.dataTask(with: request) { (data, response, error) in
if error == nil {
let result = try? JSONDecoder().decode([EmployeeDetails].self, from: data!)
completion(result, nil)
}
else {
completion(nil, ServiceError.customError("Please check your internet connection"))
}
}
sessionTask.resume()
}
//I am calling it in my View Controller
NetworkManager.sharedInstance.loadEmployees(urlString: EMPLOYEEBASEURL, completion: { (data, responseError) in
if let error = responseError {
self.showToast(controller: self, message: error.localizedDescription, seconds: 1.6)
}else{
if data != nil {
DispatchQueue.global().async {
self.employeeListArray = data as! [EmployeeDetails]
self.filteredEmployeeArray = self.employeeListArray
DispatchQueue.main.async {
self.loader.isHidden = true
self.employeeTableView.reloadData()
}
}
}
}
})
//My model
struct EmployeeDetails: Decodable {
let id: String?
let name: String?
let salary: String?
let age: String?
let profileImage: String?
enum CodingKeys: String, CodingKey {
case id = "id"
case name = "employee_name"
case salary = "employee_salary"
case age = "employee_age"
case profileImage = "profile_image"
}
}
Now Instead of parsing it directly I want to save the response in a json file and parse from the file.
I can install any pods if required, my Project is in Swift 5.0 so newer methods are also acceptable.
To save:-
func saveJsonFile(_ name:String, data:Data) {
// Get the url of File in document directory
guard let documentDirectoryUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
let fileUrl = documentDirectoryUrl.appendingPathComponent(name + ".json")
// Transform array into data and save it into file
do {
//let data = try JSONSerialization.data(withJSONObject: list, options: [])
try data.write(to: fileUrl, options: .completeFileProtection)
} catch {
print(error)
}
}
Retrive:-
func retrieveFromJsonFile(_ name:String) -> [JSONObject]? {
// Get the url of File in document directory
guard let documentsDirectoryUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return nil}
let fileUrl = documentsDirectoryUrl.appendingPathComponent(name + ".json")
// Check for file in file manager.
guard (FileManager.default.fileExists(atPath: fileUrl.path))else {return nil}
// Read data from .json file and transform data into an array
do {
let data = try Data(contentsOf: fileUrl, options: [])
guard let list = try JSONSerialization.jsonObject(with: data, options: []) as? [JSONObject] else { return nil}
//print(list)
return list
} catch {
print(error)
return nil
}
}
Delete json file:-
func removeFile(with name: String){
// Path for the file.
guard let documentsDirectoryUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return}
let fileUrl = documentsDirectoryUrl.appendingPathComponent(name + ".json")
if (FileManager.default.fileExists(atPath: fileUrl.absoluteString)){
do{
try FileManager.default.removeItem(at: fileUrl)
}catch{
print(error.localizedDescription)
}
}
}
where JSONObject:- [String: Any]

How to modify the video format after the download in swift

I have a problem in modifying the video format after downloading from videoplayback to mp4 and save to camera.
This is my download code, but I downloaded some video with a different format example : "videoplayback". I can't save to camera because I want to change format video to mp4.
func SessionDownload(URLSession : String) {
MBProgressHUD.hideAllHUDs(for: view, animated: true)
let hud = MBProgressHUD.showAdded(to: self.view, animated: true)
// Set the bar determinate mode to show task progress.
progress = 0.0
hud?.mode = MBProgressHUDMode.determinateHorizontalBar
hud?.isUserInteractionEnabled = true;
hud?.labelText = NSLocalizedString("Downloading...", comment: "HUD loading title")
DispatchQueue.global(qos: .default).async(execute: {() -> Void in
// Do something useful in the background and update the HUD periodically.
self.doSomeWorkWithProgress()
DispatchQueue.main.async(execute: {() -> Void in
//hud?.hide(true)
hud?.labelText = NSLocalizedString("Just Wait...", comment: "HUD loading title")
})
})
let videoPath = URLSession
print(videoPath)
let s = videoPath
let url = NSURL(string:s)!
let req = NSMutableURLRequest(url:url as URL)
let config = URLSessionConfiguration.default
let task = self.session.downloadTask(with: req as URLRequest)
self.task = task
task.resume()
}
//MARK:- share video
func doSomeWorkWithProgress() {
// This just increases the progress indicator in a loop.
while progress < 1.0 {
DispatchQueue.main.async(execute: {() -> Void in
print(self.progress)
MBProgressHUD(for: self.view).progress = self.progress
})
usleep(50000)
}
}
//MARK:- URL Session delegat
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
print("downloaded \(100*totalBytesWritten/totalBytesExpectedToWrite)")
taskTotalBytesWritten = Int(totalBytesWritten)
taskTotalBytesExpectedToWrite = Int(totalBytesExpectedToWrite)
percentageWritten = Float(taskTotalBytesWritten) / Float(taskTotalBytesExpectedToWrite)
print(percentageWritten)
let x = String(format:"%.2f", percentageWritten)
print(x)
self.progress = Float(x)!
print(progress)
}
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64) {
// unused in this example
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
print("completed: error: \(error)")
}
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
print("Finished downloading!")
let fileManager = FileManager()
// this can be a class variable
let directoryURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
print(directoryURL)
let docDirectoryURL = NSURL(fileURLWithPath: "\(directoryURL)")
print(docDirectoryURL)
//Save To Photos
PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL:directoryURL)
}) { saved, error in
if saved {
let alertController = UIAlertController(title: "Your video was successfully saved", message: nil, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
}
}
let destinationFilename = downloadTask.originalRequest?.url?.lastPathComponent
print(destinationFilename!)
// append that to your base directory
let destinationURL = docDirectoryURL.appendingPathComponent("\(destinationFilename!)")
print(destinationURL!)
/* check if the file exists, if so remove it. */
if let path = destinationURL?.path {
if fileManager.fileExists(atPath: path) {
do {
try fileManager.removeItem(at: destinationURL!)
} catch let error as NSError {
print(error.debugDescription)
}
}
}
do
{
try fileManager.copyItem(at: location, to: destinationURL!)
}
catch {
print("Error while copy file")
}
DispatchQueue.main.async(execute: {() -> Void in
MBProgressHUD.hide(for: self.view, animated: true)
})
// let videoLink = NSURL(fileURLWithPath: filePath)
let objectsToShare = [destinationURL!] //comment!, imageData!, myWebsite!]
let activityVC = UIActivityViewController(activityItems: objectsToShare , applicationActivities: nil)
activityVC.setValue("Video", forKey: "subject")
//New Excluded Activities Code
if #available(iOS 9.0, *) {
activityVC.excludedActivityTypes = [UIActivity.ActivityType.airDrop, UIActivity.ActivityType.addToReadingList, UIActivity.ActivityType.assignToContact, UIActivity.ActivityType.copyToPasteboard, UIActivity.ActivityType.mail, UIActivity.ActivityType.message, UIActivity.ActivityType.openInIBooks, UIActivity.ActivityType.postToTencentWeibo, UIActivity.ActivityType.postToVimeo, UIActivity.ActivityType.postToWeibo, UIActivity.ActivityType.print]
} else {
// Fallback on earlier versions
activityVC.excludedActivityTypes = [UIActivity.ActivityType.airDrop, UIActivity.ActivityType.addToReadingList, UIActivity.ActivityType.assignToContact, UIActivity.ActivityType.copyToPasteboard, UIActivity.ActivityType.mail, UIActivity.ActivityType.message, UIActivity.ActivityType.postToTencentWeibo, UIActivity.ActivityType.postToVimeo, UIActivity.ActivityType.postToWeibo, UIActivity.ActivityType.print ]
}
if let popoverController = activityVC.popoverPresentationController {
popoverController.sourceView = self.BtnDownloadVideo
popoverController.sourceRect = self.BtnDownloadVideo.bounds
}
self.present(activityVC, animated: true, completion: nil)
}
I'm assuming when you download a file from the internet, you are sure you are downloading a video in this circumstance? And what you are really wanting is just to change the format, i.e. PathExtension such as .mp4, .png, jpeg, etc.
Iff (if and only if) this is the case, then you can add a file extension on to the path component.
let destinationURL = docDirectoryURL.appendingPathComponent("\(destinationFilename!)").appendingPathExtension("mp4")
Now, when you check your saved files, it will include the ".mp4"
Again, I'm assuming you are 110% confident you are downloading a ".mp4" from the interwebs.

Xcode func used in another View Controller

I have this func in a Swift file, and it returns the value of the data in the database and prints it out in the counsel.
I want to use the value in the other View Controller but I can't get this to work, so I hope somebody can help me.
It is the nameUser, statusUser and pointUser I like to use in other View Controller.
import Foundation
import UIKit
var code = "100"
var getStatusUSer = ""
class getJSON: NSObject, URLSessionDataDelegate
{
//properties
var data : NSMutableData = NSMutableData()
func downloadItems()
{
let url = NSMutableURLRequest(url: NSURL(string: "http://www.hholm.dk/time_app/qrcode4.php")! as URL)
url.httpMethod = "POST"
let postString = "username=\(code)"
url.httpBody = postString.data(using: String.Encoding.utf8)
print(url.httpBody = postString.data(using: String.Encoding.utf8))
var session: URLSession!
let configuration = URLSessionConfiguration.default
session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
let task = session.dataTask(with: url as URLRequest)
task.resume()
}
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
{
self.data.append(data as Data);
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
{
if error != nil
{
print("Not Found", error)
}
else
{
print("Ok")
self.parseJSON()
}
}
func parseJSON()
{
var jsonResult: NSArray = NSArray()
do
{
jsonResult = try JSONSerialization.jsonObject(with: self.data as Data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray
print("jsonResult.count",jsonResult.count)
}
catch let error as NSError
{
print("jsonResult: ", error)
}
var jsonElement: NSDictionary = NSDictionary()
var contador = 0
for i in (0..<jsonResult.count)
{
jsonElement = jsonResult[i] as! NSDictionary
if let nameUser = jsonElement["name"] as? String,
let pointUser = jsonElement["point"] as? String,
let statusUser = jsonElement["status"] as? String
{
getStatusUSer = statusUser
print("Name: ", nameUser)
print("Status: ", statusUser)
print("Point: ", pointUser)
}
}
}
}
Hi Woof this is what i have in my viewcontroler:
import UIKit
class inputcodeViewController: UIViewController {
#IBOutlet weak var input: UITextField!
#IBAction func but(_ sender: Any) {
downloadItems()
}
func downloadItems(){
let getJson = GetJSON()
//setting the delegate
getJson.delegate = self
//starting download
getJson.downloadItems()
}
}
extension inputcodeViewController: GetJSONDelegate {
func didReceiveValues(name: String, status: String, point: String){
//now you can use values in your view controller
}
}
how can i print the values
You can use protocol to return those values:
import Foundation
import UIKit
var code = "100"
var getStatusUSer = ""
//define the protocol
protocol GetJSONDelegate {
func didReceiveValues(name: String, status: String, point: String)
}
//I've changed the first char of the class name to uppercase
class GetJSON: NSObject, URLSessionDataDelegate{
//properties
var data : NSMutableData = NSMutableData()
//delegate
var delegate: GetJSONDelegate?
func downloadItems(){
let url = NSMutableURLRequest(url: NSURL(string: "http://www.hholm.dk/time_app/qrcode4.php")! as URL)
url.httpMethod = "POST"
let postString = "username=\(code)"
url.httpBody = postString.data(using: String.Encoding.utf8)
print(url.httpBody = postString.data(using: String.Encoding.utf8))
var session: URLSession!
let configuration = URLSessionConfiguration.default
session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
let task = session.dataTask(with: url as URLRequest)
task.resume()
}
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
{
self.data.append(data as Data);
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
{
if error != nil
{
print("Not Found", error)
}
else
{
print("Ok")
self.parseJSON()
}
}
func parseJSON()
{
var jsonResult: NSArray = NSArray()
do
{
jsonResult = try JSONSerialization.jsonObject(with: self.data as Data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray
print("jsonResult.count",jsonResult.count)
}
catch let error as NSError
{
print("jsonResult: ", error)
}
var jsonElement: NSDictionary = NSDictionary()
var contador = 0
for i in (0..<jsonResult.count)
{
jsonElement = jsonResult[i] as! NSDictionary
if let nameUser = jsonElement["name"] as? String,
let pointUser = jsonElement["point"] as? String,
let statusUser = jsonElement["status"] as? String
{
getStatusUSer = statusUser
print("Name: ", nameUser)
print("Status: ", statusUser)
print("Point: ", pointUser)
//here we will return received data to the delegate
self.delegate?.didReceiveValues(name: nameUser, status: statusUser, point: pointUser)
}
}
}
}
Now we need to set your controller as a delegate for that protocol:
//this is an example, you need to add the methods described in your controller where you want to use those values
class YourViewController: UIViewController{
// the method that is called by you to get values
func downloadItems(){
let getJson = GetJSON()
//setting the delegate
getJson.delegate = self
//starting download
getJson.downloadItems()
}
}
//defining protocol methods in the extension of the view controller
extension YourViewController: GetJSONDelegate {
func didReceiveValues(name: String, status: String, point: String){
//now you can use values in your view controller
}
}