Swift if condition fails - ios

Swift if statement works fine on all other devices but the iPhone 4S with iOS 9.2.1.
This is the set of code I am using:
I am printing a bool value above, before applying the condition, and it prints 0, but the compiler jumps directly to the else part, failing the if statement.
print(NSNumber.init(value: socketListener!.isConnected)) //prints 0
if socketListener!.isConnected == false {
// skipped
} else {
// executed
}

I would suggest you go the long, but the correct one, by unwrapping your socket listener optional, or you can even go directly with the long unwrapping:
guard let isConnected = socketListener.isConnected else { return }
print(NSNumber.init(value: isConnected)) //prints 0
if isConnected == false {
// Your code
} else {
// Your code
}

Related

Problems with list manipulation in Swift after iOS update 14.4.2

For some years, I use this simple code to read and manipulate a list in Swift:
if (Helper.hasSubscription()) {
self.allVisitedTrackHandles = Database.getAllCompletedTrackHandles(withDeleted: false, userid: self.userid)
if (self.allVisitedTrackHandles.count > 0) {
var counter = 0
for th: TrackHandle in self.allTrackHandles {
if self.allVisitedTrackHandles.contains(where: { $0.trackid == th.trackid }) {
for thv: TrackHandle in self.allVisitedTrackHandles {
if thv.trackid == th.trackid {
self.allTrackHandles[counter].date_in_milliseconds = thv.date_in_milliseconds
break
}
}
self.allTrackHandles[counter].visited = 1
}
counter += 1
}
}
}
After updating my iOS device to iOS 14.4.2, app is crashing on this line:
for th: TrackHandle in self.allTrackHandles
Only feedback Xcode gives me is this: Thread 79: EXC_BAD_ACCESS (code=1, address=0x12f100010)
I don't know why that line would suddenly start crashing; There is nothing in the code shown that would cause the crash. Are you updating the array somewhere else? Is this, perhaps, a threading issue?
You can refactor this code to make it simpler, clearer and more efficient. This may help;
if Helper.hasSubscription() {
self.allVisitedTrackHandles = Database.getAllCompletedTrackHandles(withDeleted: false, userid: self.userid)
if !self.allVisitedTrackHandles.isEmpty {
for index in 0..<self.allTrackHandles.count {
if let visited = self.allVisitedTrackHandles.first { $0.track id == self.allTrackHandles[index].track id } {
self.allTrackHandles[index].date_in_milliseconds = visited.date_in_milliseconds
}
self.allTrackHandles[index].visited = 1
}
}
}

iOS baresip with SIP Calling

I am trying to develop an application which provides Audio and Video calling, Now I am following baresip library for the same.
and I wrote following code on button Click :
#IBAction func btnCallClick(_ sender: Any) {
guard libre_init() == 0 else { return }
// Initialize dynamic modules.
mod_init()
// Make configure file.
if let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first {
conf_path_set(path)
}
guard conf_configure() == 0 else { return }
// Initialize the SIP stack.
guard baresip_init(conf_config(), 0) == 0 else { return }
guard ua_init("SIP", 1, 1, 1, 0) == 0 else { return }
// Load modules.
guard conf_modules() == 0 else { return }
let addr = "sip:101#xxx.xxx.com:port;auth_pass=aaaa;transport=udp;answermode=auto"
// Start user agent.
guard ua_alloc(&agent, addr) == 0 else { return }
// Make an outgoing call.
guard ua_connect(agent, nil, nil, "sip:100#xxx.xxx.com", VIDMODE_OFF) == 0 else { return }
// Start the main loop.
re_main(nil)
}
Now, I am getting a call from one device to another device but it hangs my view, Why it's hanging view? I spent lots of time, anyone can help me?
I think the real problem is your re_main() function on the last line of the function. It is starting the loop execution of the thread. so untill an unless you call the re_cancel() function your execution of the process will remain in the thread.
Solution:
Putting your re_main() function on user initiated global thread will solve your problem. it will start all another process on user initiated global queue and the main thread will be free for your UI Interaction purpose.
DispatchQueue.global(qos: .userInitiated).async {
re_main(nil)
}

Driving activity confidence is low all time in iOS 11

I've an application which detects user driving and do some process internally. After the iOS update from iOS-10 to iOS-11, the application stops working. Still the application works great in iOS 10, but fails in iOS 11.
After debugging I found that the CMMotionActivityManager had the issue. The confidence of the automotive activity is low (0) at most of the time even though the user is actually driving.
Since this I can't identify the complete driving behaviour of the user.
Here is the sample code I'm using.
if CMMotionActivityManager.isActivityAvailable() {
motion.startActivityUpdates(to: OperationQueue.current!, withHandler: {
activityData
in
self.handleActivityData(activityData!)
})
}
func handleActivityData(_ activityData: CMMotionActivity) {
let rawConfidence = activityData.confidence.rawValue
// Confidence = 2 -> high
// Confidence = 0 -> low
if rawConfidence > 0 {
if activityData.automotive {
drivingActivity = true
Log.info("Activity : Automotive")
} else {
drivingActivity = false
var text = "Empty"
if activityData.walking {
text = "Walking"
} else if activityData.running {
text = "Running"
} else if activityData.stationary {
text = "Stationary"
} else if activityData.cycling {
text = "Cycling"
} else if activityData.unknown {
text = "Unknown"
}
}
}
}
Do anyone face the same issue?
Any help is appreciated.

SocketScan Getting the Battery Level in Swift

Whatever I seem to try I cannot currently get back the Battery level from the iOS/SocketScan API. I am using version 10.3.36, here is my code so far:
func onDeviceArrival(result: SKTRESULT, device deviceInfo: DeviceInfo!) {
print("onDeviceArrival:\(deviceInfo.getName())")
scanApiHelper.postGetBattery(deviceInfo, target: self, response: #selector(onGetBatteryInfo))
}
func onGetBatteryInfo(scanObj: ISktScanObject) {
let result:SKTRESULT = scanObj.Msg().Result()
print("GetBatteryInfo status:\(result)")
if (result == ESKT_NOERROR) {
let batterylevel = scanObj.Property().getUlong()
print("Battery is:\(batterylevel)")
} else {
print("Error GetBatteryInfo status:\(result)")
}
However, the values I get back are:
GetBatteryInfo status:0
Battery is:1677741312
If my code is correct then how do I make the Battery result I get back a meaningful result, like a percentage? If I'm way off then how do I get back info like the battery level, firmware version etc?
Thanks
David
EDIT: SKTBATTERY_GETCURLEVEL isn't supported in Swift. However, the docs explain that the battery level response includes the min, current and max levels encoded in the first, second and third bytes, respectively.
The following is equivalent to using SKTBATTERY_GETCURLEVEL
Swift
func onGetBatteryInfo(scanObj: ISktScanObject) {
let result:SKTRESULT = scanObj.Msg().Result()
if(SKTSUCCESS(result)){
let batteryInfo = scanObj.Property().getUlong();
let batteryMin = ((batteryInfo >> 4) & 0xff);
let batteryCurrent = ((batteryInfo >> 8) & 0xff);
let batteryMax = ((batteryInfo >> 12) & 0xff);
let batteryPercentage = batteryCurrent / (batteryMax - batteryMin);
print("Battery is:\(batteryPercentage)")
self.setBatteryLevel = batteryPercentage
self.tableView.reloadData
} else {
print("Error GetBatteryInfo status:\(result)")
}
}
Objective-C
-(void) onGetBatteryInfo:(ISktScanObject*)scanObj {
SKTRESULT result=[[scanObj Msg]Result];
if(SKTSUCCESS(result)){
long batteryLevel = SKTBATTERY_GETCURLEVEL([[scanObj Property] getUlong]);
NSLog(#"BatteryInfo %ld", batteryLevel);
[self setBatteryLevel:batteryLevel];
[self.tableView reloadData];
} else {
NSLog(#"Error GetBatteryInfo status: %ld",result);
}
}
Here's code I use. Theres a variable defined in appDelegate for the batteryPercentage, and that is read when the v value is needed. The value is updated each 120 seconds by a timer, this way actions can occur as the level drops etc.
func onBatteryLevel (scanObj: ISktScanObject) {
let result: SKTRESULT = scanObj.Msg().Result()
if (SKTRESULT(result) > -1) {
let property: ISktScanProperty = scanObj.Property()
var batteryLevel = property.getUlong()
#if arch(x86_64) || arch(arm64)
batteryLevel = (batteryLevel<<(48))>>(56)
#else
batteryLevel = (batteryLevel<<(48-32))>>(56-32)
#endif
batteryPercentage = Int(batteryLevel)
} else {
debug ("data error \(result)")
}
}
For Swift 4 I just came across this problem and came up with the following solution.
var lastDeviceConnected : CaptureHelperDevice? {
didSet {
guard let lastDevice = self.lastDeviceConnected else { return }
lastDevice.getBatteryLevelWithCompletionHandler { result, batteryLevel in
guard result == SKTResult.E_NOERROR, let batteryLevel = batteryLevel else { return }
let minimum = SKTHelper.getMinimumLevel(fromBatteryLevel: Int(batteryLevel))
let maximum = SKTHelper.getMaximumLevel(fromBatteryLevel: Int(batteryLevel))
let current = SKTHelper.getCurrentLevel(fromBatteryLevel: Int(batteryLevel))
print("minimum: \(minimum)")
print("maximum: \(maximum)")
print("current: \(current)")
// current is out battery level in %
// minimum and maximum could for example be used for
// for a slider or something that visually presents
// the battery status
}
}
}
In my example I'm not handling the case that there could be no device or that the battery status might not have been retrieved as expected. I simply guard / return. In your example you might want to handle the issue.

streamStatus as NSStreamStatusAtEnd

What may be the reason for getting streamStatus as NSStreamStatusAtEnd for NSOutputStream?
if(self.outputStream.streamStatus == NSStreamStatusAtEnd)
{
// why this condition is true?
}

Resources