Are you over 18 and want to see adult content?
More Annotations
A complete backup of https://balkanje.com/latino-serije/sestre-2010/
Are you over 18 and want to see adult content?
A complete backup of https://balkanje.com/turske-serije/ime-mi-je-sreca/
Are you over 18 and want to see adult content?
A complete backup of https://balkanje.com/turske-serije/bez-daha-2018/
Are you over 18 and want to see adult content?
A complete backup of https://balkanje.com/latino-serije/velvet-2016/
Are you over 18 and want to see adult content?
A complete backup of https://balkanje.com/turske-serije/dvoriste-2018/
Are you over 18 and want to see adult content?
A complete backup of https://balkanje.com/latino-serije/telenovela-2016/
Are you over 18 and want to see adult content?
A complete backup of https://balkanje.com/turske-serije/7-lica-2017/
Are you over 18 and want to see adult content?
A complete backup of https://balkanje.com/latino-serije/kandidat-2020/
Are you over 18 and want to see adult content?
Favourite Annotations
A complete backup of mygenerator.com.au
Are you over 18 and want to see adult content?
A complete backup of xn--pionenfamilia-jkb.com
Are you over 18 and want to see adult content?
A complete backup of homeboxoffice.com
Are you over 18 and want to see adult content?
A complete backup of becauseimawhore.com
Are you over 18 and want to see adult content?
A complete backup of mariuszrokicki.pl
Are you over 18 and want to see adult content?
A complete backup of jasuemfan.tumblr.com
Are you over 18 and want to see adult content?
Text
ABOUT | BENCODING
Hello, I’m Ben Bahrenburg. Ben Bahrenburg is an author, blogger, and technologist in PricewaterhouseCoopers’s International Assignment Services (IAS) practice. Over the last decade Ben has design and implemented innovative enterprise scale solutions to meet numerous Fortune 100 organizations’ global mobility challenges. He specializes in building enterprise solutions using CrossOSX | BENCODING
Posts about OSX written by Ben Bahrenburg. I think everyone, at least developers, have at least one iCloud account which is linked to an oldemail address.
OBJECTIVE-C
Change are if you are using Swift for more then “Hello World” you will need to interact with existing Objective-C libraries such as FMDB, FCModel, MMWormhole, or something similar. Although Apple has come great documentation and there is a WWDC video discussing this I thought it might be helpful to walk through my experiences as someonenew to Swift.
UIWEBVIEW BACKGROUND EXPERIMENTS UIWebView is one of the most useful controls in UIKit and has almost a limitless amount of options you can configure. My use case isn’t all that unique I’m simply displaying snippets of HTML email messages in a full screen UIViewController. The need to set the background color of the UIWebView is the only thing that makes this more than just a simple drag and drop in Interface Builder. MAILKIT CONVERTING A INTERNETADDRESSLIST TO A If you need to work with email in a .NET environment I highly recommend checking out MailKit by Jeffrey Stedfast. MailKit provides a higher level abstraction working across the different email protocols, which is a massive time saver. MailKit has its own classes for handling Email Addresses. Most notability the MailboxAddress and InternetAddressList classes are returned FIXING THE HP Z BOOK FUNCTION KEYS The HP Z Book is a great development laptop for anyone that needs to build using the Windows stack. There is one minor annoyance, by default the function keys are not mapped to your standard F1 through F12. To fix this, press fn+ctrl+shift. The FORCING ICLOUD LOGOUT ON YOUR MAC I think everyone, at least developers, have at least one iCloud account which is linked to an old email address. To address this I've been migrating mine over to another domain. The process is extremely easy, just visit appleid.apple.com and change your Apple ID email address. Although easy, this can be a real pain as SETTING YOUR LOCATION IN THE IOS 5.0 SIMULATOR After upgrading my development tools to XCode 4.2 and iOS 5, I started to run into location unavailable errors when running in the iOS Simulator. Having battled with the Android Emulator over the years, I figured there was a new location services setting I missed. After a quick look at the iOS Simulator’s debug menu ADDING A SWIFT BRIDGE HEADER MANUALLY The first step in creating the bridging header is to add a header file to your project. This is just like adding any other header file, just using the -Bridging-Header.h naming contention. If you haven’t done this before, in Xcode select File –> New –> File from the menu then select Header File as shown below. BENCODING | CONSOLE.LOG("HELLO WORLD"); console.log("Hello World"); With every release of Xcode it seems to eat more and more space. I was thrilled to find the XcodeCleaner project from Baye on Github.. This is a great project that allows you to tailor the space Xcode uses.ABOUT | BENCODING
Hello, I’m Ben Bahrenburg. Ben Bahrenburg is an author, blogger, and technologist in PricewaterhouseCoopers’s International Assignment Services (IAS) practice. Over the last decade Ben has design and implemented innovative enterprise scale solutions to meet numerous Fortune 100 organizations’ global mobility challenges. He specializes in building enterprise solutions using CrossOSX | BENCODING
Posts about OSX written by Ben Bahrenburg. I think everyone, at least developers, have at least one iCloud account which is linked to an oldemail address.
OBJECTIVE-C
Change are if you are using Swift for more then “Hello World” you will need to interact with existing Objective-C libraries such as FMDB, FCModel, MMWormhole, or something similar. Although Apple has come great documentation and there is a WWDC video discussing this I thought it might be helpful to walk through my experiences as someonenew to Swift.
UIWEBVIEW BACKGROUND EXPERIMENTS UIWebView is one of the most useful controls in UIKit and has almost a limitless amount of options you can configure. My use case isn’t all that unique I’m simply displaying snippets of HTML email messages in a full screen UIViewController. The need to set the background color of the UIWebView is the only thing that makes this more than just a simple drag and drop in Interface Builder. MAILKIT CONVERTING A INTERNETADDRESSLIST TO A If you need to work with email in a .NET environment I highly recommend checking out MailKit by Jeffrey Stedfast. MailKit provides a higher level abstraction working across the different email protocols, which is a massive time saver. MailKit has its own classes for handling Email Addresses. Most notability the MailboxAddress and InternetAddressList classes are returned FIXING THE HP Z BOOK FUNCTION KEYS The HP Z Book is a great development laptop for anyone that needs to build using the Windows stack. There is one minor annoyance, by default the function keys are not mapped to your standard F1 through F12. To fix this, press fn+ctrl+shift. The FORCING ICLOUD LOGOUT ON YOUR MAC I think everyone, at least developers, have at least one iCloud account which is linked to an old email address. To address this I've been migrating mine over to another domain. The process is extremely easy, just visit appleid.apple.com and change your Apple ID email address. Although easy, this can be a real pain as SETTING YOUR LOCATION IN THE IOS 5.0 SIMULATOR After upgrading my development tools to XCode 4.2 and iOS 5, I started to run into location unavailable errors when running in the iOS Simulator. Having battled with the Android Emulator over the years, I figured there was a new location services setting I missed. After a quick look at the iOS Simulator’s debug menu ADDING A SWIFT BRIDGE HEADER MANUALLY The first step in creating the bridging header is to add a header file to your project. This is just like adding any other header file, just using the -Bridging-Header.h naming contention. If you haven’t done this before, in Xcode select File –> New –> File from the menu then select Header File as shown below. BENCODING | CONSOLE.LOG("HELLO WORLD"); console.log("Hello World"); With every release of Xcode it seems to eat more and more space. I was thrilled to find the XcodeCleaner project from Baye on Github.. This is a great project that allows you to tailor the space Xcode uses.PUBLICATIONS
Author of: Technical Reviewer on: Recent Posts. Fixing the HP Z Book Function Keys; MailKit Converting a InternetAddressList to a MailAddressCollectionTOOLS | BENCODING
Open terminal. Type appc logout, this will logout the Appcelerator CLI. Type appc login, then enter your Appcelerator credentials. If you are using the CLI most likely will never see the above but for those of us that like to use Appcelerator Studio might find this little trick helpful. iOS, Swift, Tools. JAVASCRIPT | BENCODING Posts about JavaScript written by Ben Bahrenburg. Recent Posts. Fixing the HP Z Book Function Keys; MailKit Converting a InternetAddressList to a MailAddressCollection BENCODING | CONSOLE.LOG("HELLO WORLD"); | PAGE 3 The handling for prompts for network, location, and other settings is fairly common when building apps. I think we have all written code that verifies a network connection and then prompts the user to check their network settings. SIMPLIFYING USING KEYCHAIN ACCESS GROUPS Keychain sharing is an easy and secure way to share information between apps on the same device. This is even more useful when you think about sharing information between an app and it’s extensions. In my opinion Keychain is just as easy as using NSUserDefaults but provides a greater level of security.. Although Keychain sharing is easy to use, I found the use of Access Groups or USING OPENURL TO LAUNCH LINKS IN A UIWEBVIEW UIWebView in great for displaying HTML formatting information in your app. In many cases you might be displaying fragments you didn’t create opening the door for links your user might action. By default your embedded UIWebView will follow the link which can lead to an odd user experience. There are several options for handling this SENTIMENT ANALYSIS USING SWIFT Sentiment Analysis using Swift. Lately I’ve been working on several projects using conversational UI or “Bot” interactions. A key interaction pattern when designing “Bots” you must listen to both the intent and sentiment of the text the user is providing. Through the use of sentiment analysis you can help determine the mood of theuser.
SWIFT | BENCODING | PAGE 2 Recently I’ve been exploring Swift and really been enjoying both the syntax and extension points. Although still getting my legs under mewith Swift
SETTING YOUR LOCATION IN THE ANDROID EMULATOR It seems almost all of the Apps I write these days are location aware in some regard. I’ve written here about the new iOS Simulator’s location setting and wanted to show the same for the Android Emulator. There are several different ways to sent the emulator’s location information. Since I use a few different developmentSkip to content
Primary Menu
BENCODING
* Home
* About
* Publications
Search for:
CATEGORIES
Categories Select Category .NET (1) Android (16) Geo Location (1) iOS (56) JavaScript (2) macOS (1) NLP (1) Node.JS (1) Objective-C (3) OSX (2) Review (1) Swift (20) Titanium (57) Tools (12) Windows (1)Xcode (3)
RECENT POSTS
* Fixing the HP Z Book Function Keys * MailKit Converting a InternetAddressList to a MailAddressCollection * Swift Trimming Trailing Punctuation * Freeing the space used by Xcode with XcodeCleaner * Sentiment Analysis using SwiftBOOK
Appcelerator Titanium Business Application Development CookbookSkip to content
BENCODING
CONSOLE.LOG("HELLO WORLD");Windows
FIXING THE HP Z BOOK FUNCTION KEYS Posted on April 13, 2019by Ben Bahrenburg
The HP Z Book is a great development laptop for anyone that needs to build using the Windows stack. There is one minor annoyance, by default the function keys are not mapped to your standard F1 throughF12.
To fix this, press fn+ctrl+shift. The standard function key behavior will then be active..NET
MAILKIT CONVERTING A INTERNETADDRESSLIST TO A MAILADDRESSCOLLECTION Posted on February 6, 2019February 7, 2019by Ben Bahrenburg
If you need to work with email in a .NET environment I highly recommend checking out MailKit by Jeffrey Stedfast . MailKit provides a higher level abstraction working across the different email protocols, which is a massive time saver. MailKit has its own classes for handling Email Addresses. Most notability the MailboxAddressand
InternetAddressList
classes are returned when parsing a message envelope. foreach (var summary in inbox.Fetch(0, -1, MessageSummaryItems.UniqueId | MessageSummaryItems.BodyStructure)){
var tos = summary.Envelope.To; var replyToList = summary.Envelope.ReplyTo;}
view raw
MailKitReadMessageEnvelop.cs hosted with by GitHub As powerful as the MailKit constructs are, I typically like to convert any 3rd party types into their .NET framework equivalents. The below extension method adds a ToMailAddressCollection method to MailKit’sInternetAddressList
class.
public static class MailKitExts{
public static MailAddressCollection ToMailAddressCollection(this InternetAddressList addressList){
if(addressList == null){
return new MailAddressCollection();}
return addressList.Mailboxes.Aggregate(new MailAddressCollection(), (c, r) => { c.Add(new MailAddress(r.Address, r.Name)); return c; });}
}
view raw
MailKitExts.cs
hosted with by GitHubNLP , Swift
SWIFT TRIMMING TRAILING PUNCTUATION Posted on February 3, 2019by Ben Bahrenburg
Lately, I’ve been working on a project that requires some basic MLP text processing to be performed on device. A component of our text processing involved removing any trailing punctuation, no matter thelanguage.
I’ve found the below String Extension is a good balance between effectiveness, performance, and readability. Especially if you are collecting input from users prone to excessive punctuation.extension String {
func trimTrailingPunctuation() -> String { return self.trimmingCharacters(in: .whitespacesAndNewlines) .trimmingCharacters(in: .punctuationCharacters) .trimmingCharacters(in: .whitespacesAndNewlines)}
}
view raw
String+NLP.swift
hosted with by GitHub let example1 = "How are you???".trimTrailingPunctuation()>>> How are you
let example2 = "Hi!!!!".trimTrailingPunctuation()>>> Hi
let example3 = "Act limited time offer now!".trimTrailingPunctuation() >>> Act limited time offer nowview raw
zoutput-example.txt
hosted with by GitHubiOS , Tools
, Xcode
FREEING THE SPACE USED BY XCODE WITH XCODECLEANER Posted on December 31, 2017January 1, 2018by Ben Bahrenburg
With every release of Xcode it seems to eat more and more space. I was thrilled to find the XcodeCleaner project from Baye on Github . This is a great project that allows you to tailor the space Xcode uses. I’ve been able to free up an easy 12GB without any issues. I highly recommend checking out the project on GitHub at XcodeCleaner . You can build the project from source or download from the macOS App Store for $0.99.Swift
SENTIMENT ANALYSIS USING SWIFT Posted on July 6, 2017February 3, 2019by
Ben Bahrenburg
Lately I’ve been working on several projects using conversational UI or “Bot” interactions. A key interaction pattern when designing “Bots” you must listen to both the intent and sentiment of the text the user is providing. Through the use of sentiment analysisyou can help
determine the mood of the user. This can be an important tool in determining when to offer help or involve a human. You might think of this as the “help representative” moment we are all familiar with. Using sentiment analysisyou can try to
offer help before that moment occurs. There are several great sentiment analysisnode.js packages
but nothing I could find to run offline in Swift. A majority of the node.js projects seem to be a forks of the Sentiment package. The Sentiment-v2package worked best
for many of my cases and became my starting point. A majority of the sentiment analysispackages
available through NPM use the same scoring approach. First they parse a provided phrase into individual words. For example “Cats are amazing” would be turned into an array ofwords, ie .
Next a dictionary of keywords and associated weights are created. These scoring dictionary is created using the AFINN wordlist and Emoji Sentiment Ranking.
In a nutshell, words like “amazing” would have a positive weight whereas words like “bad” would have a negative weight. The weight of each word in the provided phrase is added together to get the total weight of the phrase. If the phrase has a negative weight, chances are your user is starting to get frustrated or at least talking about anegative subject.
Using this approach I created the SentimentlySwift playgroundto demonstrate
how this can be done on device using Swift. This playground uses thesame FINN wordlist
and Emoji Sentiment Rankingweights
to determine a sentiment analysisscore without the
network dependency. To make comparisons easier, I tried to mirror the Sentiment package API as must as possible. The below demonstrates the output for a few of the test phrases included with Sentiment.
let sentiment = Sentimently() print(sentiment.score("Cats are stupid.")) analysisResult(score: -2, comparative: -0.66666666666666663, positive: , negative: , wordTokens: ) print(sentiment.score("Cats are very stupid.")) analysisResult(score: -3, comparative: -0.75, positive: , negative: , wordTokens: ) print(sentiment.score("Cats are totally amazing!")) analysisResult(score: 4, comparative: 1.0, positive: , negative: , wordTokens: )var testInject = ()
testInject.append(sentimentWeightValue(word: "cats", score: 5)) testInject.append(sentimentWeightValue(word: "amazing", score: 2)) print(sentiment.score("Cats are totally amazing!", addWeights:testInject))
analysisResult(score: 7, comparative: 1.75, positive: , negative: , wordTokens: )view raw
Sentimently-output.swift hosted with by GitHub Although the APIs are similar there is one important difference between the two approaches. The SentimentlySwift playground uses NSLinguisticTagger to tokenize the provided phrase. Using NSLinguisticTagger, SentimentlySwift first parsers each word into a series of word slices. Each slice is a word tokenized using the options provided to the NSLinguisticTagger. Next the slides are enumerated and an optional “tag” or word stem is calculated. For example, in the phrase “cats are amazing”, the “amazing” word generates a word stem of “amaze”. A better example would be the word “hiking” produces the word stem of “hike”. The following snippet shows an example on how this can be implemented. public struct wordToken {let word: String
let wordStem: String? init(word: String, wordStem: String?) {self.word = word
self.wordStem = wordStem}
}
func lemmatize(_ text: String) -> { let text = text.lowercased() let options: NSLinguisticTagger.Options = let tagger = NSLinguisticTagger(tagSchemes: NSLinguisticTagger.availableTagSchemes(forLanguage: "en"), options: Int(options.rawValue)) tagger.string = textvar tokens: =
tagger.enumerateTags(in: NSMakeRange(0, text.characters.count), scheme: NSLinguisticTagSchemeLemma, options: options) { tag,tokenRange, _, _ in
let word = (text as NSString).substring(with: tokenRange) tokens.append(wordToken(word: word, wordStem: tag))}
return tokens
}
view raw
lemmatize.swift
hosted with by GitHub You might be asking why this is important? By implementingLemmatisation you
increase your AFINN hit rate and improve your overall analysisscoring.
This is one trick I’ve found for improving or at least monitoring your conversational UI or “Bot” interactions.iOS , Tools
, Xcode
FASTLANE: SOLVING THE WATCHKIT CFBUNDLEVERSION MATCHING PROBLEM Posted on March 13, 2017March 12, 2017by Ben Bahrenburg
Fastlane is one of the tools that a developer shouldn’t live without. At this point it must have saved me hundreds of hours. As great as fastlane is out of the box it has a few rough edges when you introduce a WatchKitapp.
Recently I added a WatchKit app into one of my projects and started getting the below error: ERROR: THE VALUE OF CFBUNDLEVERSION IN YOUR WATCHKIT APP’S INFO.PLIST (262) DOES NOT MATCH THE VALUE IN YOUR COMPANION APP’S INFO.PLIST (263). THESE VALUES ARE REQUIRED TO MATCH. In a nutshell, Apple requires that your WatchKit app and it’s companion app share the same version. If your fastlane build includes INCREMENT_BUILD_NUMBER these will never match by default. Solving this problem is pretty easy, although alittle more involved then just changing your versioning system like in your core app. Hopefully the below will help people Googling for this error in thefuture.
STEP 1: UPDATE YOUR WATCH APP’S VERSIONING CONFIGURATIONS The first thing you will need to do is update the versioning configuration for your Watch App’s target. * In Xcode click on your Watch App’s target * Go to the Build Settings tab * Scroll (or search) for the Versioning section * Update the “Current Project Version” to match your core app target’s version. It is important you get this correct the firsttime.
* Switch the “Versioning System” to “Apple Generic” With these changes in place fastlane increment your Watch App’s CURRENT PROJECT VERSION every time INCREMENT_BUILD_NUMBER is called. This will work just like it does in your core app target. STEP 2: UPDATE YOUR WATCH APP’S EXTENSION CONFIGURATION Just like step 1, you will need to update the versioning configuration for your Watch App’s extension target. * In Xcode click on your Watch App’s Extension target * Go to the Build Settings tab * Scroll (or search) for the Versioning section * Update the “Current Project Version” to match your core app target’s version. It is important you get this correct the firsttime.
* Switch the “Versioning System” to “Apple Generic” This again let’s fastlane increment your Watch App’s Extension when INCREMENT_BUILD_NUMBER is called. STEP 3: KEEPING YOUR CFBUNDLEVERSION IN SYNC If you run your fastlane build process now you will notice you still get an error that your CFBundleVersion information does not match. Whereas fastlane is updating the CURRENT PROJECT VERSION in both your Watch App and Watch App Extension it doesn’t update their CFBundleVersion value. The best way I’ve found to do this is to use PlistBuddy and update the CFBundleVersion as part of the fastlane build process. Below is a small convenience function created to manage the process of updating the build numbers. def setBuildNumberOnExtension(build_number) raise if build_number.nil? puts "Setting Extension to build number #{build_number}" sh("/usr/libexec/PlistBuddy -c 'Set CFBundleVersion #{build_number}' ../myWatchApp/Info.plist") sh("/usr/libexec/PlistBuddy -c 'Set CFBundleVersion #{build_number}' ../myWatchAppExtension/Info.plist")end
view raw
fastlane-setBuildNumberOnExtension.rb hosted with by GitHub For my workflow I’ve incorporated the SETBUILDNUMBERONEXTENSION helper function into my BUILD method that is called as part of my deployment, testing, or CI process.desc "Create ipa"
lane :build do
increment_build_number setBuildNumberOnExtension(get_build_number
)
gym(scheme: "TestApp", workspace: "TestApp.xcworkspace", output_directory: "../../../Builds/TestApp", clean:true, silent: true, export_method: "enterprise")end
view raw
fastlane-build.rb
hosted with by GitHub The same approach should work for all extensions. Even if you only have a “Today Extension” I’d recommend keeping the version numbers in sync with your core app. This will make life easier whenyou are debugging.
Check of the fastlane examples for more ideas on how to create extensions to improve your workflow.iOS , Swift
THINKING ABOUT MEMORY: CONVERTING UIIMAGE TO DATA IN SWIFT Posted on March 7, 2017February 3, 2019by Ben Bahrenburg
How often do you convert a UIImage into a Data object? Seems like a relatively straight forward task, just use UIImageJPEGRepresentationand
your done.
After doing this I started seeing memory spikes and leaks appear which got me thinking on how I can better profile different options for performing this conversion. If you want to follow along you can create your own Swift Playground using this gist.
APPROACHES
The first step was looking at the different ways you can convert a UIImage into Data. I settled on the following three approaches. UIIMAGEJPEGREPRESENTATION Out of all the options this is the most straightforward and widely used. If you look at the testing blocks later in the post you can see I’m simply inlined the UIImageJPEGRepresentation with the test suite compression ratio. UIImageJPEGRepresentation(image, compressionRatio)view raw
UIImageJPEGRepresentation.swift hosted with by GitHub UIIMAGEJPEGREPRESENTATION WITHIN AN AUTORELEASE POOL Out of the box UIImageJPEGRepresentation provides everything we need. In some cases I’ve found it holds onto memory after execution. To determine if wrapping UIImageJPEGRepresentation in a autoreleasepool has any benefit I created the convenience method UIImageToDataJPEG2. This simply wraps UIImageJPEGRepresentation into a autoreleasepool closure as shown below. We later use UIImageToDataJPEG2 within our tests. func UIImageToDataJPEG2(image: UIImage, compressionRatio: CGFloat)-> Data? {
return autoreleasepool(invoking: { () -> Data? in return UIImageJPEGRepresentation(image, compressionRatio)})
}
view raw
UIImageToDataJPEG2.swift hosted with by GitHub USING THE IMAGEIO FRAMEWORK The ImageIO framework gives us a lower level APIs for working with images. Typically ImageIO has better CPU performance than using UIKit and other approaches. NSHipster has a great article with details here . I was interested to see if there was a memory benefit as well. The below helper function wraps the ImageIO functions into an API similar to UIImageJPEGRepresentation.
This makes testing much easier. Keep in mind you’ll need to have image orientation yourself. For this example we just use Top, Left. If you are implementing yourself you’ll want read the API documentation available here.
func UIImageToDataIO(image: UIImage, compressionRatio: CGFloat, orientation: Int = 1) -> Data? { return autoreleasepool(invoking: { () -> Data in let data = NSMutableData() let options: NSDictionary = let imageDestinationRef = CGImageDestinationCreateWithData(data as CFMutableData, kUTTypeJPEG, 1, nil)! CGImageDestinationAddImage(imageDestinationRef, image.cgImage!,options)
CGImageDestinationFinalize(imageDestinationRef)return data as Data
})
}
view raw
UIImageToDataIO.swift hosted with by GitHub WHAT ABOUT UIIMAGEPNGREPRESENTATION? UIImagePNGRepresentation is great when you need the highest quality image. The side effect of this is it has a largest Data size and memory footprint. This disqualified UIImagePNGRepresentation as an option for these tests.TESTING SCENARIOS
For my scenarios it was important to understand how memory is impacted based on the following: * Number of executions, i.e. what is the memory impact for calling an approach on one or many images. * How the Compression ratio impacts memory usage. Image quality is an important aspect of my projects, so the tests where performed using the compression ratios of 1.0 and 0.9. These compression ratios where then run using 1, 2, 14, 20, and 50 executions. These frequencies demonstrate when image caching and Autorelease Pool strategies start to impact results. TESTING EACH APPROACH I test each of the above mentioned approaches using the template outlined below. See the gist of the details for each approach. * At the top of the method a memory sample is taken * The helper method for converting a UIImage to a Data object iscalled in a loop.
* To make sure we are measure the same resulting data across tests, we record the length of the first Data conversion. * When the loop has completed the proper number of iterations the memory is again sampled and the delta is recorded. There is some variability on how each approach is tested. The implementation for each approach is slightly different, but the same iteration and compression ratios are used to keep the outcome as comparative as possible. Below is an example the strategy used to test the JPEGRepresentation with Autorelease Pool approach. func Test_JPEGRepresentation_AutoRelease(iterations: Int, compressionRatio: CGFloat,image: UIImage) { //Gather the initial information let startReading = report_memory() print("Memory at start: \(startReading / 1024 / 1024) mb") //Loop through the number of test iterations specified for index in 1...iterations { if let data = UIImageToDataJPEG2(image: image, compressionRatio:compressionRatio) {
//Sample the length of the first result to make sure we are comparing the same sizeif index == 1 {
//Report out results let dataSize = Int(data.count / 1024 / 1024) print("Data Length: \(dataSize) mb")}
}
}
let endReading = report_memory() print("Memory at finish: \(Int(endReading / 1024 / 1024)) mb") let delta = (Int(Int(endReading) - Int(startReading)) / 1024 /1024)
print("Memory delta: \(delta) mb")}
view raw
Test_JPEGRepresentation_AutoRelease.swift hosted with by GitHubTEST RESULTS
Below is the result broken down by iteration. RESULTS FOR 1 ITERATION RESULTS FOR 2 ITERATIONS RESULTS FOR 14 ITERATIONS RESULTS FOR 20 ITERATIONS RESULTS FOR 50 ITERATIONSCONCLUSION
I am sure there is a ton of optimizations that could be made to bring these numbers down. Overall the usage of UIImageJPEGRepresentationwrapped
within
an Autorelease Pool looks to be the best approach. There is more work to be done on why the compression ratio has an inconsistent impact, my guess is this is a result to caching within the test. Although the ImageIO strategy was better in a single execution scenario I question if the proper handling of image orientation would reduce or eliminate any of your memory savings.CAVEATS
There are more comprehensive approaches out there. This is just an experiment using Playgrounds and basic memory sampling. It doesn’t take into account any memory spikes that happen outside of the two sampling points or any considerations around CPU utilization.RESOURCES
* Gist of the Swift Playground is available herePOSTS NAVIGATION
Older posts
Create a website or blog at WordPress.combencoding
Create a website or blog at WordPress.comPost to
Cancel
* Follow
*
* bencoding
* Customize
* Follow
* Sign up
* Log in
* Report this content * Manage subscriptions* Collapse this bar
Details
Copyright © 2024 ArchiveBay.com. All rights reserved. Terms of Use | Privacy Policy | DMCA | 2021 | Feedback | Advertising | RSS 2.0