I have a timer set up and it downloads the source of a text file for a phone number. No matter what I change the text in the text file on the server to it always stays the same phone number. How can I get it to download the latest string?
func scheduledTimerWithTimeInterval(){
// Scheduling timer to Call the function **Countdown** with the interval of 1 seconds
timer = Timer.scheduledTimer(timeInterval: 1/5, target: self, selector: #selector(self.updateCounting), userInfo: nil, repeats: true)
}
func updateCounting()
{
view.window?.level = Int(CGShieldingWindowLevel()) + 1
if (currentNumber == "")
{
resizeSmall()
}
else{
resizeLarge()
}
// let urls = URL(string : "http://www.xxxxxxxxx.net/CallerID/" + accountID + "/phone.txt")
guard var urls = URL(string : "http://www.xxxxxxxxx.net/CallerID/" + accountID + "/phone.txt")
else {
print("Error: doesn't seem to be a valid URL")
return
}
do{
var phonenumber = try String(contentsOf: urls, encoding: .ascii)
if (phonenumber != "" && !NumberList.contains(phonenumber))
{
NumberList.append(phonenumber)
print(phonenumber)
TableView.reloadData()
urls.removeAllCachedResourceValues()
}
}catch{
}
}
It always returns the same phone number even though I constantly change it
Related
This question already has answers here:
UIDocumentPickerViewController is not working when testing with my iPad but fine with simulators
(2 answers)
Closed 12 months ago.
Update: This code works in the simulator, but not on my device. Obviously, I'm needing it to work on both.
I've followed the tutorials, yet I cannot seem to get this feature to work. When the user selects the barButtonItem, DocumentPicker opens allowing the user to select a .txt file. I then take the URL to the selected file and attempt to return a string from it; however, I'm getting the following error: "The file “Test.txt” couldn’t be opened because you don’t have permission to view it." What am I missing? Did I fail to ask for permission somewhere? I've tried cleaning the build folder - didn't work.
#IBAction func importFileBtnTapped(_ sender: Any) {
selectFiles()
}
func selectFiles() {
let types = UTType.types(tag: "txt",
tagClass: UTTagClass.filenameExtension,
conformingTo: nil)
let documentPickerController = UIDocumentPickerViewController(forOpeningContentTypes: types)
documentPickerController.delegate = self
self.present(documentPickerController, animated: true, completion: nil)
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let myURL = urls.first else {
let alert = SCLAlertView()
alert.showError("ERROR", subTitle: "Unable to retrieve document.")
return
}
let text = createStringFromSelectedFile(fileURL: myURL)
if text == "error" {
print("ERROR creating a string from the selected file.")
return
}
let separatedStrings = decipherString(text: text)
if separatedStrings.first == "error" {
print("ERROR deciphering the string in ClaimInfoViewController")
return
}
for string in separatedStrings {
print("\(string)")
}
print("import result: \(myURL)")
}
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
dismiss(animated: true, completion: nil)
}
func createStringFromSelectedFile(fileURL: URL) -> String {
var text = String()
do {
text = try String(contentsOf: fileURL)
}
catch {
print("ERROR in the createStringFromSelectedFile function in ClaimInfoViewController")
print("The error: \(error.localizedDescription)")
let alert = SCLAlertView()
alert.showError("ERROR", subTitle: "Unable to read the file. Please try again.")
return "error"
}
return text
}
func decipherString(text: String) -> [String]{
let newText = text
let startIndexes = ["<Claim#",
"<File#",
"<DateOfLoss:"
]
var claimNumber = String()
var fileNumber = String()
var dateOfLoss = String()
for indexValue in startIndexes {
guard let index = newText.firstIndex(of: ">") else { return ["error"] }
let newString = String(newText[..<index])
if indexValue == "<Claim#" {
claimNumber = newString
}
else if indexValue == "<File#" {
fileNumber = newString
}
else if indexValue == "<DateOfLoss:" {
dateOfLoss = newString
}
}
let finalText = [claimNumber, fileNumber, dateOfLoss]
return finalText
}
Thanks to matt, who commented above, I was able to find out that it's a security issue. Adding this simple code resolved the issue:
let shouldStopAccessing = pickedFolderURL.startAccessingSecurityScopedResource()
defer {
if shouldStopAccessing {
pickedFolderURL.stopAccessingSecurityScopedResource()
}
}
I added it right before this line of code that can be seen above:
let text = createStringFromSelectedFile(fileURL: myURL)
I got this code from here: StackOverflow Post
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 trying to download information from a Firebase Firestore document that is then appended to an array in realtime. Everytime I add a document, delete or edit a document I would like the app to update and sync the array to match the data. I was able to retrieve the data with the following code:
database.collection("_Products").getDocuments(completion: { (snapshot, error) in
if error != nil {
print(error as Any)
}else{
for document in (snapshot?.documents)! {
let Name = document.data()["Item Name"] as! String
let Price = document.data()["Item Price"] as! String
let Number = document.data()["Item Number"] as! String
let Brand = document.data()["Item Brand"] as! String
let Quantity = document.data()["Quantity"] as! String
let Category = document.data()["Item Category"] as! String
DispatchQueue.main.async {
if instoreCheckOutArray.contains(where: {$0.Number == Number && $0.Brand == Brand}){
return
}else{
instoreCheckOutArray.append(checkOutArrayInfo(Brand: Brand, Name: Name, Number: Number, Price: Price, Quantity: Quantity, Category: Category))
self.searchForCoupon()
}
}
}
}
})
I then use the following code to run the function every second to fetch the data from the database:
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateCart), userInfo: nil, repeats: true)
Running the previous code perfectly fetches me new data but I cannot get the app to update the existing array to match the database and when I remove a document from the database it stays in the array.
Thank you in advanced.
1.Declare scrollingTimer variable
var scrollingTimer = Timer()
2.Initialize scrollingTimer with your function
scrollingTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateCart), userInfo: nil, repeats: true)
3.Fire the scrollingTimer(fire any where you want)
scrollingTimer.fire()
To stop the scrolling timer use the below line(Stop any where you want)
scrollingTimer.invalidate()
If any Please refer the link (DevelopersDocument)
I am new to swift Programming and FireBase,I have Implemented Chat Application,Which I stored the Message Count using sender and Receiver ID ,In receiver side getting count Perfectly,But when new count is added in FireBase I want to get that new count, for that I used timer to call a function every 10 seconds,i am getting count perfectly ,But My problem is Timer running continuously, App getting Hang and slow,After sometimes I doesn't response, can anyone suggest me how to call the function every 10 seconds or how to use timer.
Here I have tried this code,
var timer = Timer()
override func viewWillAppear(_ animated: Bool) {
MessageCountingFunction()
}
func MessageCountingFunction(){
//getting count details
keyvalue.removeAllObjects()
countarray.removeAllObjects()
let ref = FIRDatabase.database().reference()
ref.child("CountDetails").child(AuthManager.User.id.value).observeSingleEvent(of: FIRDataEventType.value, with: { (snapshot) in
if let cakeSnapshot = snapshot.children.allObjects as? [FIRDataSnapshot] {
for cakes in cakeSnapshot {
print(cakes)
if let cakeDictionary = cakes.value as? Dictionary <String, Any> {
print(cakeDictionary)
let count = cakeDictionary["Count"]
let key = cakes.key as String
//your class that takes a key as String and a Dictionary
print(count as Any)
print(key)
self.keyvalue.add(key)
self.countarray.add(count!)
}
}
DispatchQueue.global().sync {
print(self.keyvalue)
print(self.countarray)
self.tableView.reloadData()
}
}
})
DispatchQueue.main.async {
self.timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(self.MessageCountingFunction), userInfo: nil, repeats: true)
}
}
My json data structure for new message is :-
{ "status" : "sent", "sender" : "ayush ", "timeStamp" :
1525760473513 }
we are maintaining the status key for checking new message. after reading we are updating value of status key to read and looking for sent status for new message.
var channelRef: DatabaseReference = Database.database().reference().child(FIREBASE_CONSULTATION_DBKEY)
channelRef.child("channelKey").observe(DataEventType.value, with: { (snapshot) -> Void in // 1
if let channelData = snapshot.value as? Dictionary<String, AnyObject>{ // 2
let id = snapshot.key
self.chatMessageArray.removeAll()
for (key,obj) in channelData{
if status == "Sent"{
}
}
}
}
}
When I send data from a timer on the Apple Watch, it keeps sending 1 instead of sending the actual number in "message": timerCount. How can I ensure the right number is being sent back to the phone, instead of 1. I am not sure where it is pulling the 1 from. When I print timerCount, it returns the same number as on the timer.
let myInterval: TimeInterval = 0.0
var timerCount: Int = 0
var timer = Timer()
func stopPlay() {
let startTime = Date.timeIntervalSinceReferenceDate
print(timerCount) //this prints the actual time
let data: Dictionary<String, AnyObject> = [ "startTime": startTime as AnyObject, "message": timerCount as AnyObject]
if session.isReachable {
session.sendMessage(data, replyHandler: nil, errorHandler: nil)
} else {
let action1 = WKAlertAction(title: "OK", style: .default, handler: stopPlay)
presentAlert(withTitle: "Workout Complete", message: "Connect to your iPhone", preferredStyle: .actionSheet, actions: [action1])
}
}
#IBAction func start_button() {
if isStarted == false {
self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.update), userInfo: nil, repeats: true)
self.startStopButton.setTitle("Stop")
isStarted = true
} else if isStarted == true {
self.timer.invalidate()
self.startStopButton.setTitle("Resume")
isStarted = false
}
}
func update() {
internalDuration -= 1
totalTimeCounter += 1
timerCount += 1
self.elapsedLabel.setText(timeString(time: totalTimeCounter))
}