Swift: How to Fully Strip Internal/Inline Symbols

Swift: how to fully strip internal/inline symbols?

I have investigated this again, and found the following strip settings to work well for Release builds:

  • Deployment Postprocessing = Yes
  • Strip Linked Product = Yes
  • Perform Single-Object Prelink = No
  • Use Separate Strip: Optional, doesn't make a difference
  • Strip Style:
    • All Symbols for the main app (equivalent to -Xlinker -s according to this guide)
    • Non-Global Symbols for libraries (equivalent to -Xlinker -x)
  • Other Linker Flags: None; already provided by "Strip Style"

Strip names after linking a static library

No, you can't. A static library is simply a collection of object files and the object files within the static library have no special privileges over those using the static library.

You can obviously strip the final binary.

If you must hide symbols then they need to be static, which forces you to use fewer implementations files to allow the symbol to be shared, which is inconvenient.

Is there a downside to running `strip -S -x` on all frameworks in my macOS binary? If not, how can I automate that process?

The best (i.e. most aggressive while being reliable) linker flags I have found for Release builds can now be found at https://stackoverflow.com/a/63188437/153354.

Embedding Share Icons Inline Within Another View

As discussed in another answer, reverse engineering UIActivityViewController is the only option in order to be able to achieve a similar effect. I tried this using iPhone 6s - 10.3 Simulator. The following findings may not be accurate for iOS 9.x or 11.x or above.

A. Find out all internal variables for UIActivityViewController

var variablesCount: UInt32 = 0
let variables = class_copyIvarList(UIActivityViewController.self, &variablesCount)

for i in 0..<variablesCount {
if let variable = variables?[Int(i)] {
let name = String(cString: ivar_getName(variable))
let typeEncoding = String(cString: ivar_getTypeEncoding(variable))
print("\(name)\n\(typeEncoding)\n\n")
}
}

free(variables)

The ones those got my attention at first sight are (in order) -

_activityViewController
@"UIViewController"

_contentController
@"_UIActivityViewControllerContentController"

_activityAlertController
@"UIAlertController"

On inspecting them further, I found out that _contentController is the one we should be looking for. We need to look one level deeper in hierarchy for UICollectionViewController to get to where we want to be.

if let activityContentController = activityVC.value(forKeyPath: "_contentController") as? UIViewController {
print("Found _contentController!")

for child in activityContentController.childViewControllers {
print(String(describing: child))

if child is UICollectionViewController {
print("Found UICollectionViewController!")
break
}
}
}

Why did I look for UICollectionViewController?

Debug View Hierarchy has the answer for this.

Sample Image

I tried adding this as a childViewController to my UIViewController -

self.addChildViewController(child)
child.didMove(toParentViewController: self)
self.view.addSubview(child.view)

child.view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
child.view.topAnchor.constraint(equalTo: self.view.topAnchor),
child.view.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
child.view.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
child.view.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
])

IT SHOWS UP CORRECTLY ONLY IF YOU HAVE LOADED/PRESENTED UIActivityViewController FIRST.

I was able to achieve this using a silent present/dismiss call -

self.present(activityVC, animated: false, completion: {
self.dismiss(animated: false, completion: nil)
})

IS THIS APP STORE SAFE? - Most likely not.

As soon as you start stealing the view(s) or viewController(s) from UIKit's standard components, the behavior is not stable and it will break with upcoming updates for sure.

What Google Photos has is the result of way more advanced reverse engineering. In above implementation, you can't see More option screen. The hierarchy UIActivityViewController expects is broken.

Hope this helps.

How to replace emoji characters with their descriptions in a Swift string

Simply do not use a Character in the first place but use a String as input:

let cfstr = NSMutableString(string: "This is my string ) as CFMutableString

that will finally output

This {SMILING FACE WITH OPEN MOUTH AND SMILING EYES} is my string {SMILING FACE WITH OPEN MOUTH AND SMILING EYES}

Put together:

func transformUnicode(input : String) -> String {
let cfstr = NSMutableString(string: input) as CFMutableString
var range = CFRangeMake(0, CFStringGetLength(cfstr))
CFStringTransform(cfstr, &range, kCFStringTransformToUnicodeName, Bool(0))
let newStr = "\(cfstr)"
return newStr.stringByReplacingOccurrencesOfString("\\N", withString:"")
}

transformUnicode("This is my string )

Changing tab bar item image and text color iOS

From UITabBarItem class docs:

By default, the actual unselected and selected images are
automatically created from the alpha values in the source images. To
prevent system coloring, provide images with
UIImageRenderingModeAlwaysOriginal.

The clue is not whether you use UIImageRenderingModeAlwaysOriginal, the important thing is when to use it.

To prevent the grey color for unselected items, you will just need to prevent the system colouring for the unselected image. Here is how to do this:

var firstViewController:UIViewController = UIViewController()
// The following statement is what you need
var customTabBarItem:UITabBarItem = UITabBarItem(title: nil, image: UIImage(named: "YOUR_IMAGE_NAME")?.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal), selectedImage: UIImage(named: "YOUR_IMAGE_NAME"))
firstViewController.tabBarItem = customTabBarItem

As you can see, I asked iOS to apply the original color (white, yellow, red, whatever) of the image ONLY for the UNSELECTED state, and leave the image as it is for the SELECTED state.

Also, you may need to add a tint color for the tab bar in order to apply a different color for the SELECTED state (instead of the default iOS blue color). As per your screenshot above, you are applying white color for the selected state:

self.tabBar.tintColor = UIColor.whiteColor()

EDIT:

Sample Image



Related Topics



Leave a reply



Submit