iOS swift

Value with expiration

@propertyWrapper
struct Expirable<Value> {
    let duration: TimeInterval
    var expirationDate: Date = Date()
    private var innerValue: Value?
   
    var value: Value? {
        get{ return hasExpired() ? nil: innerValue }
        set{
            self.expirationDate = Date().addingTimeInterval(duration)
            self.innerValue = newValue
        }
    }
    init(duration: TimeInterval) {
        self.duration = duration
    }
    private func hasExpired() -> Bool {
        return expirationDate < Date()
    }
}

struct Tokens {
    @Expirable(duration: 3) static var authent: String
}

Tokens.authent = NSUUID().uuidString

sleep(2)
Tokens.authent ?? "token has expired"
sleep(2)
Tokens.authent ?? "token has expired"

Tags: 

Data Compression

let compressed = try data.compressed(using: .zlib)
public enum CompressionAlgorithm: Int {
  case lzfse
  case lz4
  case lama
  case zlib
}

Tags: 

Random in swift 4.2

let double = Double.random(in: -1.2...4.5)
let integer = Int.random(in: .min ... .max)
let unsignedInteger = UInt.random(in: 4...9)
let bool = Bool.random() // false/true

struct SeededRandomNumberGenerator: RandomNumberGenerator {
    init(seed: Int) {
        srand48(seed)
    }
   
    func next() -> UInt64 {
        return UInt64(drand48() * Double(UInt64.max))
    }
}

var seededGenerator = SeededRandomNumberGenerator(seed: 5)
var random = Int.random(in: -5...5, using: &seededGenerator) // 2
random = Int.random(in: -5...5, using: &seededGenerator) // 1
random = Int.random(in: -5...5, using: &seededGenerator) //-3
random = Int.random(in: -5...5, using: &seededGenerator) //-2

View Userdefault

po UserDefaults.standard.dictionaryRepresentation()

Tags: 

++-)

extension Int {
  static postfix func ++ (lhs: inout Int){
    return lhs += 1
  }
}

Tags: 

Random Color with seed

extension UIColor
{
    func randomColor(seed: String) -> UIColor
    {
       
        var total: Int = 0
        for u in seed.unicodeScalars {
            total += Int(UInt32(u))
        }
       
        srand48(total * 200)
        let r = CGFloat(drand48())
        srand48(total)
        let g = CGFloat(drand48())
        srand48(total / 200)
        let b = CGFloat(drand48())
       
        return UIColor(red: r, green: g, blue: b, alpha: 1)
    }
}

let str = "abcd"
let a = UIColor().randomColor(seed: str)
is the same with
let b = UIColor().randomColor(seed: str)
is the same with
let c = UIColor().randomColor(seed: str)
etc etc

Tags: 

price in SKProduct in local currency

func priceStringForProduct(item: SKProduct) -> String? {
        let price = item.price
        if price == 0 {
            return "Free!" //todo: Translate
        } else {
            let numberFormatter = NumberFormatter()
            let locale = item.priceLocale
            numberFormatter.numberStyle = .currency
            numberFormatter.locale = locale
            return numberFormatter.string(from: price)
        }
    }

Tags: 

emitter explosion

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
         createParticles()
    }

    func createParticles() {
        let v = UIView(frame: CGRect(x: 180, y: 220, width: 60, height: 60))
        //v.backgroundColor = .lightGray
        view.addSubview(v)
        let particleEmitter = CAEmitterLayer()
       
        particleEmitter.emitterPosition = CGPoint(x: 30, y: 30)
        particleEmitter.emitterShape = kCAEmitterLayerSphere
        particleEmitter.emitterSize = CGSize(width: 1, height: 1)
       
        let red = makeEmitterCell(color: UIColor.red)
        let green = makeEmitterCell(color: UIColor.green)
        let blue = makeEmitterCell(color: UIColor.blue)
       
        particleEmitter.emitterCells = [red, green, blue]
       
        v.layer.addSublayer(particleEmitter)
        UIView.animate(withDuration: 2.0, animations: {
            v.alpha = 0
        }) { (_) in
            v.layer.sublayers?.removeAll()
        }
    }
   
    func makeEmitterCell(color: UIColor) -> CAEmitterCell {
        let cell = CAEmitterCell()
        cell.birthRate = 2.5
        cell.lifetime = 1.9
        cell.lifetimeRange = 1
        cell.color = color.cgColor
        cell.velocity = 158
        cell.velocityRange = 45
        cell.emissionLongitude = CGFloat.pi
        cell.emissionRange = CGFloat.pi
        cell.spin = 4
        cell.spinRange = 6
        cell.scaleRange = 0.04
        cell.scaleSpeed = 0.3
        cell.xAcceleration = -0.03
        cell.yAcceleration = -0.05
        cell.zAcceleration = 0.2
       
        cell.contents = UIImage(named: "cp")?.cgImage
        return cell
    }
}

Tags: 

version build

if let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString"),
            let build = Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String)
{
     versionLabel.text = "v\(version).\(build)"
}

Tags: 

String contains substring

extension String {
    func contains(find: String) -> Bool{
        return self.range(of: find) != nil
    }
    func containsIgnoringCase(find: String) -> Bool{
        return self.range(of: find, options: .caseInsensitive) != nil
    }
}

Tags: 

Image from UIView

func imageWithView(inView: UIView) -> UIImage? {
    UIGraphicsBeginImageContextWithOptions(inView.bounds.size, inView.isOpaque, 0.0)
    defer { UIGraphicsEndImageContext() }
    if let context = UIGraphicsGetCurrentContext() {
        inView.layer.render(in: context)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        return image
    }
    return nil
}

Tags: 

iPhone x uiviewcontroller

class BaseVC: UIViewController
{
   var shouldHideHomeIndicator     = false
   public let stage                = UIView()

   override func viewDidLoad() {
       super.viewDidLoad()
       HLog.info(function:#function, message: "BaseVC")

       navigationController?.setToolbarHidden(true, animated: false)
       navigationController?.navigationBar.isHidden = true

       setupLayout()
   }


   override func viewDidAppear(_ animated: Bool) {
       super.viewDidAppear(animated)

       self.shouldHideHomeIndicator = true
       if #available(iOS 11.0, *) {
           self.setNeedsUpdateOfHomeIndicatorAutoHidden()
       } else {
           // Fallback on earlier versions
       }
   }

   override var prefersStatusBarHidden: Bool
   {
       return true
   }

   override func preferredScreenEdgesDeferringSystemGestures() ->
UIRectEdge {
       return .top
   }

   override func prefersHomeIndicatorAutoHidden() -> Bool
   {
       return shouldHideHomeIndicator
   }
   //MARK: - Layout
   func setupLayout()
   {
       createStage()
   }

   func createStage()
   {

       let ninesixteen = (sw/9.0*16.0).rounded()
       if ninesixteen <= sh
       {
           stage.frame = Frame(x: 0, y: 0, width: sw, height: ninesixteen)
       }
       else
       {
           stage.frame = Frame(x: 0, y: 0, width: sh/16.0*9.0, height: sh)
       }
       stage.backgroundColor = .clear
       stage.center = view.center
       view.addSubview(stage)
   }

   //MARK: - Helper
   func goto(vc:UIViewController)
   {
       AudioPlayerHelper.play(audioButtonClick)
       UIApplication.shared.keyWindow?.rootViewController = vc.self
   }
}

Tags: 

array with functions

class Bla
{
   let arrayOfFunctions = [function1, function2]

   func function1()
   {
      print("function1")
   }

    func function2() {
        print("function2")
    }

   func useTheFuncs()
   {
    let fn1 = arrayOfFunctions[0]
    fn1(self)()
   }
}

Tags: 

CABasicAnimation

grow shrink, heartbeat?

let img = UIImage(named: "red_star_2")
let imgv = UIImageView(image: img)
let theAnimation = CABasicAnimation()
theAnimation.keyPath = "transform.scale"
theAnimation.duration = 0.7
theAnimation.repeatCount = .infinity
theAnimation.autoreverses = true
theAnimation.fromValue = 1.0
theAnimation.toValue = 1.3
theAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
imgv.layer.add(theAnimation, forKey: "animateOpacity")
imgv.center = CGPoint(x: 50, y: 50)
view.addSubview(imgv)

rotation
let kRotationAnimationKey = "com.myapplication.rotationanimationkey"

let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation")
        rotationAnimation.fromValue = 0.0
        rotationAnimation.toValue = Float(M_PI * 2.0)
        rotationAnimation.duration = 0.2
        rotationAnimation.repeatCount = Float.infinity
        turningStar.layer.add(rotationAnimation, forKey: kRotationAnimationKey)

with completion
import UIKit
import PlaygroundSupport

let viewFrame = CGRect(x: 0, y: 0, width: 500, height: 500)
let view = UIView(frame: viewFrame)
view.backgroundColor = .white
PlaygroundPage.current.liveView = view

let v = UIView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
v.backgroundColor = .red
view.addSubview(v)

CATransaction.begin()
print("start")
let a = CABasicAnimation(keyPath: "position")
a.fromValue = [100, 100]
a.toValue = [200, 200]
a.duration = 2
CATransaction.setCompletionBlock{ print("ended")
}

v.layer.add(a, forKey: nil)
CATransaction.commit()

Tags: 

Link write review in app store

#available(iOS 10, *)!!!

let appID = "959379869"

if let checkURL = URL(string: "http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=\(appID)&pageNumber=0&sortOrdering=2&type=Purple+Software&mt=8") {
    open(url: checkURL)
} else {
    print("invalid url")
}

...

func open(url: URL) {
    if #available(iOS 10, *) {
        UIApplication.shared.open(url, options: [:], completionHandler: { (success) in
            print("Open \(url): \(success)")
        })
    } else if UIApplication.shared.openURL(url) {
            print("Open \(url)")
    }
}

Tags: 

Blurred footprint

extension uiimage

public func modifiedImage(_ draw: (CGContext, CGRect) -> ()) -> UIImage {
       
        // using scale correctly preserves retina images
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        let context: CGContext! = UIGraphicsGetCurrentContext()
        assert(context != nil)
       
        // correctly rotate image
        context.translateBy(x: 0, y: size.height)
        context.scaleBy(x: 1.0, y: -1.0)
       
        let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)
       
        draw(context, rect)
       
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }
public func tintPictogram(with fillColor: UIColor) -> UIImage {
       
        return modifiedImage { context, rect in
            // draw tint color
            context.setBlendMode(.normal)
            fillColor.setFill()
            context.fill(rect)
           
            // mask by alpha values of original image
            context.setBlendMode(.destinationIn)
            context.setAlpha(0.15)
            context.draw(cgImage!, in: rect)
        }
    }

general:
func blurImage(_ image:UIImage) -> UIImage? {
    let context = CIContext(options: nil)
    let inputImage = CIImage(image: image)
    let originalOrientation = image.imageOrientation
    let originalScale = image.scale
   
    let filter = CIFilter(name: "CIGaussianBlur")
    filter?.setValue(inputImage, forKey: kCIInputImageKey)
    filter?.setValue(3.0, forKey: kCIInputRadiusKey)
    let outputImage = filter?.outputImage
   
    var cgImage:CGImage?
   
    if let asd = outputImage
    {
        cgImage = context.createCGImage(asd, from: (inputImage?.extent)!)
    }
   
    if let cgImageA = cgImage
    {
        return UIImage(cgImage: cgImageA, scale: originalScale, orientation: originalOrientation)
    }
   
    return nil
}

use:
if let image = UIImage(named:name)
            {
                 let tintimg = image.tintPictogram(with: .black)
                if let shadowedimage = blurImage(tintimg){
                //...    shadowImages.append(shadowedimage)
                }
               
            }

Tags: 
Subscribe to RSS - iOS swift