Note: xcode is Version 11.4.1 (11E503a)I have created customized UITextView so that to add additional menus and tried to disable several default UIMenuItems, but I couldn't find a way to do so. The code is like below:class MyUITextViewController: UIViewController {
var textView: UITextView! = UITextView()
override func viewDidLoad() {
super.viewDidLoad()
textView.isScrollEnabled = true
textView.isEditable = true
textView.isUserInteractionEnabled = true
view.addSubview(textView)
UIMenuController.shared.menuItems = [
UIMenuItem(title: "My Menu", action: #selector(myMenu))
]
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
textView.frame = view.frame
}
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if action == Selector(("_lookup:")) {
var responder: UIResponder? = self.next
while responder != nil {
print("responder = \(responder!)")
print("canPerformAction = \(responder!.canPerformAction(action, withSender: sender))")
responder = responder?.next
}
}
return action == #selector(myMenu)
}
@objc
func myMenu() {
print("my menu")
}
}
struct MyTextViewController: UIViewControllerRepresentable {
@Binding var text: String
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIViewController(context: Context) -> MyUITextViewController {
let viewController = MyUITextViewController()
viewController.textView.delegate = context.coordinator
return viewController
}
func updateUIViewController(_ vc: MyUITextViewController, context: Context) {
if vc.textView.text != text {
vc.textView.text = text
}
}
class Coordinator: NSObject, UITextViewDelegate {
var parent: MyTextViewController
init(_ textView: MyTextViewController) {
self.parent = textView
}
func textViewDidChange(_ textView: UITextView) {
self.parent.text = textView.text
}
}
}
struct MyView: View {
@State var text = ""
var body: some View {
MyTextViewController(text: $text)
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}canPerformAction returns false except for my menu, but there still be other menus such as select, paste, look up, learn, share, etc.So I debugged to find out which responder returns true for for example lookup menu, and it dumps below log:responder = <_TtGC7SwiftUI16PlatformViewHostGVS_42PlatformViewControllerRepresentableAdaptorV8clipping20MyTextViewController__: 0x105097b00; frame = (0 20; 375 647); anchorPoint = (0, 0); tintColor = UIExtendedSRGBColorSpace 0 0.478431 1 1; layer = >
canPerformAction = false
responder = <_TtGC7SwiftUI14_UIHostingViewGVS_15ModifiedContentV8clipping6MyViewGVS_30_EnvironmentKeyWritingModifierGSqCS2_15EnvironmentData____: 0x1050882a0; frame = (0 0; 375 667); autoresize = W+H; gestureRecognizers = ; layer = >
canPerformAction = true
responder = <_TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentV8clipping6MyViewGVS_30_EnvironmentKeyWritingModifierGSqCS2_15EnvironmentData____: 0x105083cf0>
canPerformAction = false
responder = >
canPerformAction = false
responder = >
canPerformAction = false
responder = ; layer = >
canPerformAction = false
responder = ; persistentIdentifier = 6942827B-F542-40EF-8B48-57719BE39C64; activationState = UISceneActivationStateForegroundActive; settingsCanvas = ; windows = (
"; layer = >",
">"
)>
canPerformAction = false
responder =
canPerformAction = false
responder =
canPerformAction = falseI am not sure what_TtGC7SwiftUI14_UIHostingViewGVS_15ModifiedContentV8clipping6MyViewGVS_30_EnvironmentKeyWritingModifierGSqCS2_15EnvironmentData____ is exactly which class, but it contains UIHostingView so I doubt that UIHostingVIew, which seems view of UIHostingController, responds lookup action should be enabled.Is there any way to disable those default menus? Is it able to customize canPerformAction of UIHostingView?
Post
Replies
Boosts
Views
Activity
Hello,I am trying to create a certificate via App Store Connect API.First, I created csr by the following command. I confirmed that the generated csr can be successfuly registered to developer.apple.com manually.openssl genrsa 2048 > private.key
openssl req -new -key private.key -out private.csr -subj "/emailAddress=<my email address>/O=<my name>/C=JP"Then, I tried to create a certificate using certificates API. The token is generated using an API key with Developer role (I tried also Admin and AppManager role and all are same).curl -i \
-H'Authorization: Bearer <token>' \
-H'Content-Type: application/json' \
-d '{"data":{"attributes":{"certificateType":"IOS_DISTRIBUTION","csrContent":"'$(cat private.csr | base64)'"},"type":"certificates"}}' \
https://api.appstoreconnect.apple.com/v1/certificatesThe response was:HTTP/1.1 401 Unauthorized
Server: daiquiri/3.0.0
Date: Tue, 29 Oct 2019 03:31:38 GMT
Content-Type: application/json
Content-Length: 350
Connection: keep-alive
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Request-ID: QUKNKFNK2BDNPUUDIDEHJY7W
X-Rate-Limit: user-hour-lim:3600;user-hour-rem:3592;
x-daiquiri-instance: daiquiri:18493001:mr85p00it-hyhk03154801:7987:19N28
{
"errors": [{
"status": "401",
"code": "NOT_AUTHORIZED",
"title": "Authentication credentials are missing or invalid.",
"detail": "Provide a properly configured and signed bearer token, and make sure that it has not expired. Learn more about Generating Tokens for API Requests https://developer.apple.com/go/?id=api-generating-tokens"
}]
}This error message says that my token is wrong or missing. Next, so I checked if the token is valid or not by invoking other API.curl -i \
-H'Authorization: Bearer <token>' \
https://api.appstoreconnect.apple.com/v1/certificatesThis API call succeeded and showed the list of my certificates.Are there something wrong in my commands?(I wonder that the api is not available currently...)Appendix: my ruby script to generate jwtrequire 'jwt'
require 'base64'
require 'optparse'
params = {}
opt = OptionParser.new
opt.on('-i val', '--iss') { |v| params[:iss] = v }
opt.on('-k val', '--kid') { |v| params[:kid] = v }
opt.parse!
private_key = STDIN.readlines.join
key = OpenSSL::PKey::EC.new(private_key)
payload = {
iss: params[:iss],
exp: Time.now.utc.to_i + 10 * 60,
aud: 'appstoreconnect-v1'
}
header_fields = {
"kid": params[:kid],
"typ": 'JWT'
}
token = JWT.encode(payload, key, 'ES256', header_fields=header_fields)
puts tokenThank you.