I get app thread start time via sysctl. Then, when the app starts in the background (such as receiving an incoming call), I calculate the preMain duration of the app. Most of the time, the data is normal (hundreds of milliseconds). But occasionally a very large duration (such as tens of seconds) appears. It feels like restarting the mobile phone test has a higher probability.
// Code in main.swift
let appStartLaunchTime: CFAbsoluteTime = CFAbsoluteTimeGetCurrent()
// Calculate preMain time
var preMain = appStartLaunchTime - appLaunchTime! + kCFAbsoluteTimeIntervalSince1970
public var appLaunchTime: Double? = {
var processInfo = kinfo_proc()
var size = MemoryLayout<kinfo_proc>.stride
var mib: [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()]
guard sysctl(&mib, u_int(mib.count), &processInfo, &size, nil, 0) == 0 else {
return nil
}
let startTime = processInfo.kp_proc.p_starttime
let time = (Int64(startTime.tv_sec) * 1000) + Int64(startTime.tv_usec / 1000)
return Double(time) / 1000.0
}()
Swift 5 iOS 12.x
A stupid question I am sure, but I having a moment.
I got values from -100 to 100. I am interested in the values less than -10 or greater than 10. I wrote this code.
func returnPod() -> String {
defer {
pods.removeAll()
}
var aPitch: Float? = 0
var aRoll: Float? = 0
var aYaw: Float? = 0
for peas in pods {
print("peas \(peas)")
if peas.pitch! < Float(-10) && peas.pitch! > Float(10) {
// capture an average everything below 10, above 10
aPitch = aPitch! + peas.pitch!
aRoll = aRoll! + peas.roll!
aYaw = aYaw! + peas.yaw!
} else {
// drop everything return zero this should happen if pitch is between -10 and 10.
return "#:0:0:0\n"
}
}
return("#:\(String(describing: aRoll!)):\(String(describing: aPitch!)):\(String(describing: aYaw!))")
}
But it doesn't work, it just returns everything... What am I doing wrong.
I've gone over the code for this decoder for elementary h.264 bitstreams a hundred times, tweaking things along the way, with no luck. When I send the output CMSampleBuffers to an AVSampleBufferDisplayLayer, they don't appear, presumably because there's something wrong with how I'm decoding them.
I get no error messages anywhere; the AVSampleBufferDisplayLayer has no error and "status" is "1" (aka .rendering), CMSampleBufferIsValid() returns "true" on the outputted CMSampleBuffers, and I encounter no errors in my decoder either.
I'm stumped and my hope is that a more experienced developer can catch something that I'm missing.
I input raw bytes here (typealias FrameData = [UInt8])
func interpretRawFrameData(_ frameData: inout FrameData) -> CMSampleBuffer? {
let size = UInt32(frameData.count)
var naluType = frameData[4] & 0x1F
var frame: CMSampleBuffer?
// The start indices for nested packets. Default to 0.
var ppsStartIndex = 0
var frameStartIndex = 0
switch naluType {
// SPS
case 7:
print("===== NALU type SPS")
for i in 4..<40 {
if frameData[i] == 0 && frameData[i+1] == 0 && frameData[i+2] == 0 && frameData[i+3] == 1 {
ppsStartIndex = i
spsSize = i - 4 // Does not include the size of the header
sps = Array(frameData[4..<i])
// Set naluType to the nested PPS packet's NALU type
naluType = frameData[i + 4] & 0x1F
break
}
}
// If nested frame was found, fallthrough
if ppsStartIndex != 0 { fallthrough }
// PPS
case 8:
print("===== NALU type PPS")
for i in ppsStartIndex+4..<ppsStartIndex+34 {
if frameData[i] == 0 && frameData[i+1] == 0 && frameData[i+2] == 0 && frameData[i+3] == 1 {
frameStartIndex = i
ppsSize = i - spsSize - 8 // Does not include the size of the header. Subtract 8 to account for both the SPS and PPS headers
pps = Array(frameData[ppsStartIndex+4..<i])
// Set naluType to the nested packet's NALU type
naluType = frameData[i+4] & 0x1F
break
}
}
// If nested frame was found, fallthrough
if frameStartIndex != 0 { fallthrough }
// IDR frame
case 5:
print("===== NALU type IDR frame");
// Replace start code with size
let adjustedSize = size - UInt32(ppsSize) - UInt32(spsSize) - 8
var blockSize = CFSwapInt32HostToBig(adjustedSize)
memcpy(&frameData[frameStartIndex], &blockSize, 4)
if createFormatDescription() {
frame = decodeFrameData(Array(frameData[frameStartIndex...]))
}
// B/P frame
default:
print("===== NALU type B/P frame");
// Replace start code with size
var blockSize = CFSwapInt32HostToBig(size)
memcpy(&frameData[frameStartIndex], &blockSize, 4)
frame = decodeFrameData(Array(frameData[frameStartIndex...]))
break;
}
return frame != nil ? frame : nil
}
And this is where the actual decoding happens:
private func decodeFrameData(_ frameData: FrameData) -> CMSampleBuffer? {
let bufferPointer = UnsafeMutablePointer<UInt8>(mutating: frameData)
let size = frameData.count
var blockBuffer: CMBlockBuffer?
var status = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault,
bufferPointer,
size,
kCFAllocatorNull,
nil, 0, frameData.count,
0, &blockBuffer)
if status != kCMBlockBufferNoErr { return nil }
var sampleBuffer: CMSampleBuffer?
let sampleSizeArray = [size]
status = CMSampleBufferCreateReady(kCFAllocatorDefault,
blockBuffer,
formatDesc,
1, 0, &sampleTimingInfo,
1, sampleSizeArray,
&sampleBuffer)
if let buffer = sampleBuffer, status == kCMBlockBufferNoErr {
let attachments: CFArray? = CMSampleBufferGetSampleAttachmentsArray(buffer, true)
if let attachmentArray = attachments {
let dic = unsafeBitCast(CFArrayGetValueAtIndex(attachmentArray, 0), to: CFMutableDictionary.self)
let key = Unmanaged.passUnretained(kCMSampleAttachmentKey_DisplayImmediately).toOpaque()
let val = Unmanaged.passUnretained(kCFBooleanTrue).toOpaque()
CFDictionarySetValue(dic,
key,
val)
}
print("===== Successfully created sample buffer")
return buffer
}
return nil
}
Other things to note:
The formatDescription contains the correct information (mediaType = "vide", mediaSubType = "avc1", dimensions = "640x480")
The bitstream I'm decoding always groups the SPS, PPS, and IDR frames together and sends them as one big packet every 20 or so frames. Every other time, an individual B/P frame is sent.
Thanks!
That code was pretty ugly so I decided to touch it up a little bit. Turned out that did the trick. Something must have been wrong in there.
Anyways, here's a working version. It sends the decoded & decompressed frame to its delegate. Ideally, whoever calls interpretRawFrameData would be returned a displayable frame, and I'll work on that, but in the meantime this works too.
https://github.com/philipshen/H264Decoder
I need to generate a random number.
It appears the arc4random function no longer exists as well as the arc4random_uniform function.
The options I have are arc4random_stir(), arc4random_buf(UnsafeMutablePointer<Void>, Int), and arc4random_addrandom(UnsafeMutablePointer<UInt8>, Int32).
I can't find any docs on the functions and no comments in the header files give hints.
let randomIntFrom0To10 = Int.random(in: 1..<10)
let randomFloat = Float.random(in: 0..<1)
// if you want to get a random element in an array
let greetings = ["hey", "hi", "hello", "hola"]
greetings.randomElement()
You could try as well:
let diceRoll = Int(arc4random_uniform(UInt32(6)))
I had to add "UInt32" to make it work.
Just call this function and provide minimum and maximum range of number and you will get a random number.
eg.like randomNumber(MIN: 0, MAX: 10) and You will get number between 0 to 9.
func randomNumber(MIN: Int, MAX: Int)-> Int{
return Int(arc4random_uniform(UInt32(MAX-MIN)) + UInt32(MIN));
}
Note:- You will always get output an Integer number.
After some investigation I wrote this:
import Foundation
struct Math {
private static var seeded = false
static func randomFractional() -> CGFloat {
if !Math.seeded {
let time = Int(NSDate().timeIntervalSinceReferenceDate)
srand48(time)
Math.seeded = true
}
return CGFloat(drand48())
}
}
Now you can just do Math.randomFraction() to get random numbers [0..1[ without having to remember seeding first. Hope this helps someone :o)
Update with swift 4.2 :
let randomInt = Int.random(in: 1..<5)
let randomFloat = Float.random(in: 1..<10)
let randomDouble = Double.random(in: 1...100)
let randomCGFloat = CGFloat.random(in: 1...1000)
Another option is to use the xorshift128plus algorithm:
func xorshift128plus(seed0 : UInt64, _ seed1 : UInt64) -> () -> UInt64 {
var state0 : UInt64 = seed0
var state1 : UInt64 = seed1
if state0 == 0 && state1 == 0 {
state0 = 1 // both state variables cannot be 0
}
func rand() -> UInt64 {
var s1 : UInt64 = state0
let s0 : UInt64 = state1
state0 = s0
s1 ^= s1 << 23
s1 ^= s1 >> 17
s1 ^= s0
s1 ^= s0 >> 26
state1 = s1
return UInt64.addWithOverflow(state0, state1).0
}
return rand
}
This algorithm has a period of 2^128 - 1 and passes all the tests of the BigCrush test suite. Note that while this is a high-quality pseudo-random number generator with a long period, it is not a cryptographically secure random number generator.
You could seed it from the current time or any other random source of entropy. For example, if you had a function called urand64() that read a UInt64 from /dev/urandom, you could use it like this:
let rand = xorshift128plus(urand64(), urand64())
for _ in 1...10 {
print(rand())
}
let MAX : UInt32 = 9
let MIN : UInt32 = 1
func randomNumber()
{
var random_number = Int(arc4random_uniform(MAX) + MIN)
print ("random = ", random_number);
}
In Swift 3 :
It will generate random number between 0 to limit
let limit : UInt32 = 6
print("Random Number : \(arc4random_uniform(limit))")
My implementation as an Int extension. Will generate random numbers in range from..<to
public extension Int {
static func random(from: Int, to: Int) -> Int {
guard to > from else {
assertionFailure("Can not generate negative random numbers")
return 0
}
return Int(arc4random_uniform(UInt32(to - from)) + UInt32(from))
}
}
This is how I get a random number between 2 int's!
func randomNumber(MIN: Int, MAX: Int)-> Int{
var list : [Int] = []
for i in MIN...MAX {
list.append(i)
}
return list[Int(arc4random_uniform(UInt32(list.count)))]
}
usage:
print("My Random Number is: \(randomNumber(MIN:-10,MAX:10))")
Another option is to use GKMersenneTwisterRandomSource from GameKit. The docs say:
A deterministic pseudo-random source that generates random numbers
based on a mersenne twister algorithm. This is a deterministic random
source suitable for creating reliable gameplay mechanics. It is
slightly slower than an Arc4 source, but more random, in that it has a
longer period until repeating sequences. While deterministic, this is
not a cryptographic random source. It is however suitable for
obfuscation of gameplay data.
import GameKit
let minValue = 0
let maxValue = 100
var randomDistribution: GKRandomDistribution?
let randomSource = GKMersenneTwisterRandomSource()
randomDistribution = GKRandomDistribution(randomSource: randomSource, lowestValue: minValue, highestValue: maxValue)
let number = randomDistribution?.nextInt() ?? 0
print(number)
Example taken from Apple's sample code: https://github.com/carekit-apple/CareKit/blob/master/CareKitPrototypingTool/OCKPrototyper/CareKitPatient/RandomNumberGeneratorHelper.swift
I'm late to the party 🤩🎉
Using a function that allows you to change the size of the array and the range selection on the fly is the most versatile method. You can also use map so it's very concise. I use it in all of my performance testing/bench marking.
elements is the number of items in the array
only including numbers from 0...max
func randArr(_ elements: Int, _ max: Int) -> [Int] {
return (0..<elements).map{ _ in Int.random(in: 0...max) }
}
Code Sense / Placeholders look like this.
randArr(elements: Int, max: Int)
10 elements in my array ranging from 0 to 1000.
randArr(10, 1000) // [554, 8, 54, 87, 10, 33, 349, 888, 2, 77]
you can use this in specific rate:
let die = [1, 2, 3, 4, 5, 6]
let firstRoll = die[Int(arc4random_uniform(UInt32(die.count)))]
let secondRoll = die[Int(arc4random_uniform(UInt32(die.count)))]
Lets Code with Swift for the random number or random string :)
let quotes: NSArray = ["R", "A", "N", "D", "O", "M"]
let randomNumber = arc4random_uniform(UInt32(quotes.count))
let quoteString = quotes[Int(randomNumber)]
print(quoteString)
it will give you output randomly.
Don't forget that some numbers will repeat! so you need to do something like....
my totalQuestions was 47.
func getRandomNumbers(totalQuestions:Int) -> NSMutableArray
{
var arrayOfRandomQuestions: [Int] = []
print("arraySizeRequired = 40")
print("totalQuestions = \(totalQuestions)")
//This will output a 40 random numbers between 0 and totalQuestions (47)
while arrayOfRandomQuestions.count < 40
{
let limit: UInt32 = UInt32(totalQuestions)
let theRandomNumber = (Int(arc4random_uniform(limit)))
if arrayOfRandomQuestions.contains(theRandomNumber)
{
print("ping")
}
else
{
//item not found
arrayOfRandomQuestions.append(theRandomNumber)
}
}
print("Random Number set = \(arrayOfRandomQuestions)")
print("arrayOutputCount = \(arrayOfRandomQuestions.count)")
return arrayOfRandomQuestions as! NSMutableArray
}
look, i had the same problem but i insert
the function as a global variable
as
var RNumber = Int(arc4random_uniform(9)+1)
func GetCase(){
your code
}
obviously this is not efficent, so then i just copy and paste the code into the function so it could be reusable, then xcode suggest me to set the var as constant so my code were
func GetCase() {
let RNumber = Int(arc4random_uniform(9)+1)
if categoria == 1 {
}
}
well thats a part of my code so xcode tell me something of inmutable and initialization but, it build the app anyway and that advice simply dissapear
hope it helps
Does anyone know how to implement this in swift? The entire function call is
glGetProgramInfoLog(
<#program: GLuint#>,
<#bufsize: GLsizei#>,
<#length: UnsafeMutablePointer<GLsizei>#>,
<#infolog: UnsafeMutablePointer<GLchar>#>)
I understand passing the pointers but not the buffer sizes. Android doesn't even have these parameters at all.
For anyone looking for an answer you can use following code :
Where program is let program = glCreateProgram()
Swift 2
var message = [CChar](count: 256, repeatedValue: CChar(0))
var length = GLsizei(0)
glGetProgramInfoLog(program, 256, &length, &message)
print(String(UTF8String: message))
Swift 3
var message = [CChar](repeating: CChar(0), count: 256)
var length = GLsizei(0)
glGetProgramInfoLog(program, 256, &length, &message)
var s = String.init(utf8String: message)!
if(s.characters.count > 0){print("Shader compile log: \(s)")} //only prints if log isnt empty
Try this:
var message = [CChar](count: 256, repeatedValue: CChar(0))
var length = GLsizei(0)
var log = Array<GLchar>(count: Int(length ), repeatedValue: 0)
log.withUnsafeBufferPointer { logPointer -> Void in
glGetShaderInfoLog(yourProgram, length, &length, UnsafeMutablePointer(logPointer.baseAddress))
NSLog("Shader compile log: \n%#", String(UTF8String: log)!)
}