Use of Timer and Url downloading web source not working - swift

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

How to Read Data from Text File iOS 15 [duplicate]

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

IOS Swift WebRtc insertDtmf issue

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

Realtime update array from Firestore

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)

How to get Count values when changes Happen in FireBase DataBase using Swift?

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"{
}
}
}
}
}

Sending time from Apple Watch to Phone is not returning the correct number

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))
}