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
)
- All Symbols for the main app (equivalent to
- 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.
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:
Related Topics
Duplicating a Particle Emitter Effect in Sprite Kit
Changing Tab Bar Font in Swift
How to Get Current Location with Swiftui
Update Core Data Object Order - Not Working
How to Convert Nsset to [String] Array
How to Position Banner Ads Over Uitabbar
Swiftui Views with a Custom Init
How to Implement Hash(Into:) from Hashvalue in Swift
How to Call a Static Function on a Protocol in a Generic Way
Insert, Update and Delete Animations with Foreach in Swiftui
Iaps Actually Validating the Receipt (Swift)
Is Removing a Notificationcenter Observer That Was Created with Closure Syntax by Name Adequate