Huffman Coding API in Swift

This question is a follow up question to: this post

I’d love some advice on my implementation and the API of the Huffman class.

I’m also not sure how to test if my implementation is actually resulting in less bytes than a string. It seems that encoded.count (as a Data) is larger than word.utf8.count (as a String). Maybe I’m just not testing on large enough strings?

Also any thoughts on HuffData storing the code ex. ["00","01"] and the frequencyTable instead of the tree.

Here’s an example of how the API is used:

let word = "MISSISSIPPI_RIVER!" let encoded = try? Huffman.encode(word) let decoded = try? Huffman.decode(encoded!) XCTAssertEqual(decoded, word) 

Here’s the code:

import Foundation  struct HuffData: Codable {     var code: [String]     var frequencyTable: [String: String] }  class Huffman {     static func decode(_ data: Data) throws -> String {         do {             let huff = try JSONDecoder().decode(HuffData.self, from: data)             let reverseTable = Dictionary(uniqueKeysWithValues: zip(huff.frequencyTable.values, huff.frequencyTable.keys))             return huff.code.compactMap({ reverseTable[$  0]}).joined()         }         catch let error {             throw error         }     }      static func encode(_ input: String) throws -> Data {         let frequencyTable = Huffman.buildFrequencyTable(for: input)         let code = input.compactMap({frequencyTable[String($  0)]})         let huff = HuffData(code: code, frequencyTable: frequencyTable)         do {             let data = try JSONEncoder().encode(huff)             return data         }         catch let error {             throw error         }     }      static private func buildFrequencyTable(for input: String) -> [String: String] {         // count letter frequency         let sortedFrequency = input.reduce(into: [String: Int](), { freq, char in             freq[String(char), default: 0] += 1         })         // create queue of initial Nodes         let queue = sortedFrequency.map{ Node(name: $  0.key, value: $  0.value)}         // generate key by traversing tree         return Huffman.generateKey(for: Huffman.createTree(with: queue), prefix: "")     }      static private func generateKey(for node: Node, prefix: String) -> [String: String] {         var key = [String: String]()         if let left = node.left, let right = node.right {             key.merge(generateKey(for: left, prefix: prefix + "0"), uniquingKeysWith: {current,_ in current})             key.merge(generateKey(for: right, prefix: prefix + "1"), uniquingKeysWith: {current,_ in current})         }else {             key[node.name] = prefix         }         return key     }      static private func createTree(with queue: [Node]) -> Node {         // initialize queue that sorts by decreasing count         var queue = PriorityQueue(queue: queue)         // until we have 1 root node, join subtrees of least frequency         while queue.count > 1 {             let node1 = queue.dequeue()             let node2 = queue.dequeue()             let rootNode = Huffman.createRoot(with: node1, and: node2)             queue.enqueue(node: rootNode)         }         return queue.queue[0]     }      static private func createRoot(with first: Node, and second: Node) -> Node {         return Node(name: "\(first.name)\(second.name)", value: first.value + second.value, left: first, right: second)     }  }  struct PriorityQueue {     var queue: [Node]     var count: Int {         return queue.count     }     mutating func enqueue(node: Node) {         queue.insert(node, at: queue.index(where: {$  0.value <= node.value}) ?? 0)     }     mutating func dequeue() -> Node {         return queue.removeLast()     }     init(queue: [Node]){         // assumes queue will always be sorted by decreasing count         self.queue = queue.sorted(by: {$  0.value > $  1.value})     } }  class Node: CustomStringConvertible {     var description: String {         return "\(name): \(value)"     }     let name: String     let value: Int     let left: Node?     let right: Node?      init(name: String, value: Int, left: Node? = nil, right: Node? = nil) {         self.name = name         self.value = value         self.left = left         self.right = right     } } 

ios – Swift 4: How to remove UIImageViews when UIImageView.animationImages is finished?

I am using .animationImages for UIImageViews in my project (it’s a game). When the user presses a hint button I programmatically create a variable number of UIImageViews that will appear on screen and play the same image sequence once. I need to remove the UIImageViews from the view when the animation has stopped but I can’t figure out how to do this.

I’ve been through the swift documentation for both .animationImages and .startAnimating but it’s literally one paragraph and one line, neither of which is in relation to a completion or finish notifications etc. Any help will be much appreciated.

private func hideAnswerButtonsHint() {      // Clear all of the answer boxes that aren't hint locked     resetAnswerBoxes()      var imageArray = [UIImage]()     var remainingLetters = [String]()      for imageCount in 1...8 {         let imageName = "green_smoke_puff_0\(imageCount)"         let image = UIImage(named: imageName)!         imageArray.append(image)     }      for answerBox in answerBoxArray where answerBox.hintLock == false {         if let letter = answerBoxDict[answerBox.tag] {             remainingLetters.append(letter)         }     }      for answerButton in answerButtonArray where answerButton.hintLock == false {         if let index = remainingLetters.index(of: answerButton.titleText) {             answerButton.decompress()             remainingLetters.remove(at: index)         } else {             let frame = answerButton.superview?.convert(answerButton.frame.origin, to: nil)              let imageView = UIImageView()             imageView.animationImages = imageArray             imageView.animationDuration = 0.5             imageView.animationRepeatCount = 1             imageView.frame = CGRect(x: frame!.x, y: frame!.y, width: answerButton.frame.width, height: answerButton.frame.height)              view.addSubview(imageView)             imageView.startAnimating()              answerButton.compress()             answerButton.hintLock = true         }     } } 

Integrate Google Map in Swift

I’m trying to integrate Google Map in swift, I’ve used following code for integration and result is shown in the screenshot. I’ve already installed the Cocoapods for google map, I’ve followed this link. still not getting the result.. what I’m actually trying to do is create multiple static markers on clicking of those markers I need to redirect to view controller which show complete details about that particular marker..but what I’m getting is only one marker nothing else..

  let camera = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 0.0)      let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)     view = mapView      // Creates a marker in the center of the map.     let marker = GMSMarker()     marker.position = CLLocationCoordinate2D(latitude: -33.86, longitude: 151.20)     marker.title = "Sydney"     marker.snippet = "Australia"     marker.map = mapView 

enter image description here

Error Fix Xcode 10, Swift 4 initializer for conditional must have optional.

So I’m working on a savings app using a table view controller. I ran into an error, and I couldn’t find a fix.

if let sourceViewController = sender.source as? SavingsTableViewController, let saving = sourceViewController.savings {         let newIndexPath = IndexPath(row: saving.count, section: 0)         saving.append(saving)         SavingsTableViewController.insertRows(at: [newIndexPath], with: .automatic)     } 

The error shows up as Initializer for conditional binding must have Optional type, not ‘[Savings]’

Thanks for the help!

How UUID is generated in Objective C or Swift

I understand that UUID is generated based on bits given by timestamp.

For instance, if two iOS devices at the exact same time executes the following statement then what possibility is there that it will generate same uuid?

let uuid = NSUUID().uuidString 

If uuid is combination of more than just timestamp, what is the internal logic using which UUID is generated?

Is there is any way either in Obj c or swift, to alter the background so nicely that one could feel the person must be in the image

I just want to know is it possible..to alter the background image so nicely that one could feel the person must be in the picture..if yes then please let me know any tutorial regarding this..or any kind of help. both obj c or swift language code will be helpfull..thanks in advance