This question is also, here, one StackOverflow. But it's only gotten 8 views, and I am stuck till I find out what am I doing wrong.
I am able to create a URLSesion, build a request with a file to upload and successfully call it from my app. On my server side, the proper script is called, uploaded file is saved, etc,. However, I am not receiving the HTTP responses, data, etc.
Actually had this working without the delegate, when the HTTP response functions were within the task itself. But am now trying to expand functionality and am missing something while trying implement the delegate.
The trimmed code is below, and it all works, with the exception of setting up UIViewController as the URLSession delegate. Just trying to figure out why my UIViewController is not receiving the HTTP responses.
Below is the code for:
UIViewController
Class which creates the upload session (UploadService)
Extension for UIViewController which I want to use to process the responses
How the previous task looked, when it worked. Before I tried to implement the delegate.
UIViewController
class UploadInv : UIViewController {
var xFile : XFile?
...create UI....
let uploadService = UploadService()
lazy var uploadSession: URLSession = {
let configuration = URLSessionConfiguration.default
return URLSession(configuration: configuration, delegate: self, delegateQueue: .main)
}()
override func viewWillAppear(_ animated: Bool) {
...
}
override func viewDidLoad() {
super.viewDidLoad()
uploadService.uploadSession = uploadSession
... code the lays out all buttons, labels, etc...
}
@objc func buttonAction(sender: UIButton!) {
guard let theButton = sender else { return}
let myTag = theButton.tag
switch myTag {
//button to start upload
case ButtType.up.rawValue:
uploadService.start(upFile: xFile!, script: "uploadOrig.pl", upLoadInvClass: self)
uploadService.task?.resume()
//button to select file to upload
case ButtType.file.rawValue:
... file xFile with file info
}
}
UploadService
class UploadService {
var task: URLSessionUploadTask?
var uploadSession = URLSession.shared
func start(upFile: XFile, script: String, upLoadInvClass: UploadInv) {
var request = upFile.makeUrlReq(upFile: upFile, script: script)
self.task = uploadSession.uploadTask(with: request, from: request.httpBody! )
}
}
extension
extension UploadInv: UIDocumentPickerDelegate, URLSessionDelegate {
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
... file xFile info for upload ....
... http request created ....
}
// Below are the three simple functions which I would handle
// responses the server, but these never seem to get called.
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
if let err = error {
print("Error: \(err.localizedDescription)")
}
}
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: (URLSession.ResponseDisposition) -> Void) {
print("didReceive response")
completionHandler(URLSession.ResponseDisposition.allow)
}
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
print("didReceive data")
if let responseText = String(data: data, encoding: .utf8) {
print(responseText)
}
}
}
Pre-Delegate model which worked
class UploadService {
var uploadSession = URLSession.shared
func start(upFile: XFile, script: String, upLoadInvClass: UploadInv) {
var request = upFile.makeUrlReq(upFile: upFile, script: script)
uploadSession.uploadTask(with: request, from: request.httpBody )
{ (data, response, error) in
if let response = response {
upLoadInvClass.upResp(resp: response)
}
if let error = error {
upLoadInvClass.upErr(error: error)
}
if let data = data {
upLoadInvClass.upData(data: data)
}
}.resume()
}
}
Post
Replies
Boosts
Views
Activity
From a tutorial I pulled the extension below to allow the enduser to select a file off of the iPhone's storage system.
Everything works fine.
However I noticed that in the delegate that "dismiss" is only being called if the user chooses cancel. While the view does disappear when a file is selected, I am not sure that the view is being properly dismissed internally by Swift.
Since I do call present, am I responsible for dismissing it when the user chooses a file as well?
let supportedTypes: [UTType] = [UTType.item]
let pickerViewController = UIDocumentPickerViewController(forOpeningContentTypes: supportedTypes)
pickerViewController.delegate = self
pickerViewController.allowsMultipleSelection = false
present(pickerViewController, animated: true, completion: nil)
extension uploadFile: UIDocumentPickerDelegate {
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
for url in urls {
guard url.startAccessingSecurityScopedResource() else {
print ("error")
return
}
...save chosen file url here in an existing structre
do { url.stopAccessingSecurityScopedResource() }
}
}
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
controller.dismiss(animated: true, completion: nil)
}
}
I have the following structure :
struct XFile : Codable {
...variables here
init(fileUrl: URL, key: String) {
...
}
Then in another class I am trying the following:
class UploadTask {
var xfile: XFile
var inProgress = false
init(file: URL) {
xFile = XFile(fileUrl: file, key: "filename")
}
}
If typed as above Xcode gives me the following error:
Cannot find 'xFile' in scope
If I remove the xFile= part,
Xcode give me the following warning and error:
Result of 'XFile' initializer is unused
Return from initializer without initializing all stored properties
Obviously I am breaking some rule, just not sure what it is.
I realize I could declare a global var, such as:
var mySpecialSubClass : MySpecialSubClass?
..and then check if it is defined.
Don't know of any reason to do one way or another, but I was wondering if there was a search for an instance of "MySpecialSubClass" function or method available?
Can I have multiple extensions for the same class? Obviously I have already tried it and it works. But that doesn't make it right?
So want to make sure this doesn't blowup in my face at a later date.
p.s I keep typing "****-up" as two separate words but the size changes the b word to "****" what's up with that?
Yes, still learning Swift, and no, am not lazy, but I do have some sort of reading problem.
In code block below, what do the < and > represent?
let requestedComponents: Set<Calendar.Component> = [
.year,
.month,
.day,
.hour,
.minute,
.second
]
Am trying to add a file uploader to my iPhone app in Swift, and need help as am unsure how to save the data from returned from the UIDocumentPickerViewController.
My whole document picking code works, and ends with this line of code:
let data = try Data.init(contentsOf: url)
The thing is I don't do my uploading till the user clicks another button, so I need to save that data. but am unsure how to cast a variable to hold it, then release the original data, and then finally free the copy.
I thought this would work
var dataToSend : AnyObject?
but it doesn't
Yes, still have casting issues to learn in Swift
Xcode 13.3
Whenever I hit enter on Xcode, it starts off the new line with an indentation. It doesn't matter if I am creating a new line, or moving lines down, it always start the new line, or the moved line with an indentation.
This happens when I have:
Prefer Indent Using set to Tabs
regardless if I have
Syntax-Aware Indenting: Return checked or unchecked
Any thoughts?
Update, now somehow it does that auto indent on every line no matter whether I set it tabs or spaces. It's as if I broke it. Very annoying, please help!
I posted this question below on StackOverflow, and when someone pointed out .partialCurl, I tried different modalTransitionStyles, and the code doesn't crash.
Is anyone aware of "known" issues with partialCurl from Apple?
original post on StackOverflow
Within my root UIViewController I call up a submenu, second UIViewController, with the following code:
within root UIViewController
let myInvMenu = InvMenuCtrl()
myInvMenu.modalPresentationStyle = .fullScreen
myInvMenu.modalTransitionStyle = .partialCurl
present(myInvMenu, animated: false)
Within the new screen, I have a back button, I want dismiss it, and return to the original UIViewController.
dismiss(animated: false)
In this post, I have the animation set to false, because that works fine. But if I set it to true, I crash on the dismissal.
From the docs, below I assumed that I didn't have to handle anything myself, but obviously if someone could tell me where my misunderstanding is:
The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, UIKit asks the presenting view controller to handle the dismissal.
I have a function in my UIView extension and I can call it both ways
This way:
func anchorSizePercent(to view: UIView, sFactor: CGSize) {
...
}
myHeader.anchorSizePercent(to: myView, sFactor: CGSize(width: 0.8, height: 0.2))
As well, I can call it without the to, such as:
func anchorSizePercent(view: UIView, sFactor: CGSize) {
...
}
myHeader.anchorSizePercent(view: myView, sFactor: CGSize(width: 0.8, height: 0.2))
May I ask what the difference is?
Xcode updated yesterday, and am now at
Xcode Version 13.3 (13E113)
Since then, whenever I debug my app the the simulator, I get the message below. Am curious if I should be concerned.
If it makes a difference: Yes, I have an IBM keyboard attached via USB.
Also this does not happen when I debug the app on the iPhone itself.
2022-03-15 14:50:45.745237-0400 Hello World[48883:648134] [HardwareKeyboard] -[UIApplication getKeyboardDevicePropertiesForSenderID:shouldUpdate:usingSyntheticEvent:], failed to fetch device property for senderID (778835616971358211) use primary keyboard info instead.
Closing because again I asked a stupid question
Below is my very simple code, where I programmatically create another UIViewController. My only problem is that it pops up as a view that can be swiped away. I want this to be its own UIViewController that takes the entire screen, and cannot be just shipped away.
Is that possible?
import UIKit
class ViewController: UIViewController {
lazy var mainMenu = MainMenuCtrl()
private let myView : UIView = {
let myView = UIView()
myView.translatesAutoresizingMaskIntoConstraints = false
myView.backgroundColor = .gray
return myView
}()
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
view.backgroundColor = bgColor
view.addSubview(myView)
addContraints()
present(mainMenu, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
}
override var prefersStatusBarHidden: Bool {
return false
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .darkContent
}
func addContraints() {
var constraints = [NSLayoutConstraint]()
constraints.append(myView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 5))
constraints.append(myView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -5))
constraints.append(myView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -5))
constraints.append(myView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor,constant: +5))
NSLayoutConstraint.activate(constraints)
}
}
Stupid question, could a moderator please delete this embarrassing post on my part?
I was looking up removing the Main storyboard, and am a little confused. Everywhere in my app, I'm supposed to remove "Main." But I can't find where ViewController.swift is called.
So am trying to figure that part out, who calls whom? Because if I add a background color to ViewController, and a label to the Main storyboard, both show up.
I'm just trying to figure out how both are called.
Working on a recording app. So I started from scratch, and basically jump right into recording. I made sure to add the Privacy - Microphone Usage Description string.
What strikes me as odd, is that the app launches straight into recording. No alert comes up the first time asking the user for permission, which I thought was the norm.
Have I misunderstood something?
override func viewDidLoad() {
super.viewDidLoad()
record3()
}
func record3() {
print ("recording")
let node = audioEngine.inputNode
let recordingFormat = node.inputFormat(forBus: 0)
var silencish = 0
var wordsish = 0
makeFile(format: recordingFormat)
node.installTap(onBus: 0, bufferSize: 8192, format: recordingFormat, block: {
[self]
(buffer, _) in
do {
try audioFile!.write(from: buffer);
x += 1;
if x > 300 {
print ("it's over sergio")
endThis()
}
} catch {return};})
audioEngine.prepare()
do {
try audioEngine.start()
} catch let error {
print ("oh catch \(error)")
}
}
Am working on a recording app from scratch and it just has the basics. Within my info.plist I do set Privacy - Microphone Usage Description
Still, I always want to check the "privacy permission" on the microphone because I know people can hit "No" by accident.
However, whatever I try, the app keeps running without waiting for the iOs permission alert to pop up and complete.
let mediaType = AVMediaType.audio
let mediaAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: mediaType)
switch mediaAuthorizationStatus {
case .denied:
print (".denied")
case .authorized:
print ("authorized")
case .restricted:
print ("restricted")
case .notDetermined:
print("huh?")
let myQue = DispatchQueue(label: "get perm")
myQue.sync
{
AVCaptureDevice.requestAccess(for: .audio, completionHandler: { (granted: Bool) in
if granted {
} else {
}
})
}
default:
print ("not a clue")
}