Posts

Post not yet marked as solved
2 Replies
14k Views
I'm trying to display one embedded content by using the WKWebView and I can not click some of these links. Is there anything I did wrong?Here is the Link which I get the embedded content from:https://publish.twitter.com Here is the embedded content:<a class="twitter-timeline" href="https://twitter.com/Google?ref_src=twsrc%5Etfw">Tweets by Google</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>Here is my code:import UIKit import WebKit class ViewController: UIViewController { private var mWebView: WKWebView! let embeddedTwittContent = "<a class='twitter-timeline' href='https://twitter.com/Google?ref_src=twsrc%5Etfw'>Tweets by Google</a>" // let embeddedTwittContent = "<a class=\"twitter-timeline\" href=\"https://twitter.com/Smaforetagarna?ref_src=twsrc%5Etfw\">Tweets by Smaforetagarna</a>" let scriptValue = "<script async src=\"https://platform.twitter.com/widgets.js\" charset=\"utf-8\"></script>" let redirectLink = "https://twitter.com/Smaforetagarna/status/" override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. let preferences = WKPreferences() preferences.javaScriptEnabled = true let configuration = WKWebViewConfiguration() configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent() configuration.preferences = preferences self.mWebView = WKWebView(frame: CGRect.zero, configuration: configuration) self.mWebView.translatesAutoresizingMaskIntoConstraints = false self.mWebView.allowsLinkPreview = true self.mWebView.allowsBackForwardNavigationGestures = true self.mWebView.navigationDelegate = self self.view.addSubview(self.mWebView) // Add Constraints self.mWebView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 100).isActive = true self.mWebView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0).isActive = true self.mWebView.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: 0).isActive = true self.mWebView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 0).isActive = true loadTweetNews() } func loadTweetNews(){ let htmlHeader = "<!DOCTYPE html> <html><meta name=\'viewport\' content=\'initial-scale=1.0\'/> <head> \(scriptValue) </head> <body>" let htmlFooter = "</body> </html>" let orderHtml = htmlHeader + embeddedTwittContent + htmlFooter let url: URL = URL(string: "https:")! self.mWebView.loadHTMLString(orderHtml, baseURL: url) } } extension ViewController: WKNavigationDelegate{ func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { print("page finished load") } func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) { print("didReceiveServerRedirectForProvisionalNavigation: \(navigation.debugDescription)") } func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { print("didStartProvisionalNavigation") } func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { if navigationAction.navigationType == .linkActivated { if let url = navigationAction.request.url, UIApplication.shared.canOpenURL(url) { UIApplication.shared.open(url) print(url) decisionHandler(.cancel) } else { decisionHandler(.allow) } } else { decisionHandler(.allow) } }
Posted
by www0488.
Last updated
.
Post not yet marked as solved
0 Replies
563 Views
Hello, I'm new to SwiftUI and right now I'm trying to create one simple Application by using @State, @ObservedObject, and @Environment. For some reason, I got error "Cannot preview in this file" after I tried to add Environment object. The canvas is not working, but I can actually run the application in a simulator and actual device without any problem. Here is how I added my environment object. SceneDelegate:func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). let channelData = ChannelData() // Create the SwiftUI view that provides the window contents. let contentView = ContentView().environmentObject(channelData) // Use a UIHostingController as window root view controller. if let windowScene = scene as? UIWindowScene { let window = UIWindow(windowScene: windowScene) window.rootViewController = UIHostingController(rootView: contentView) self.window = window window.makeKeyAndVisible( } }ChannelData class:import Combine final class ChannelData: ObservableObject{ @Published var channelName = "YouTube Channel" }ContentView:import SwiftUI struct ContentView: View { @State private var showingSecondVC = false @ObservedObject var videoIdea = VideoIdea() @EnvironmentObject var channelData: ChannelData var body: some View { NavigationView{ VStack(alignment: .leading){ Text(videoIdea.title) .font(.title) Text(videoIdea.contentIdea) .font(.subheadline) Divider() NavigationLink(destination: ChannelView()){ Text("Add Channel") } Button(action: { self.showingSecondVC.toggle() }){ Text("Add New Idea") }.sheet(isPresented: $showingSecondVC){ SecondView(videoTitle: self.$videoIdea.title, videoContent: self.$videoIdea.contentIdea).environmentObject(self.channelData) } Spacer() }.padding() .navigationBarTitle(channelData.channelName) } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }SecondView:import SwiftUI struct SecondView: View { @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode> @Binding var videoTitle: String @Binding var videoContent: String @EnvironmentObject var channelData:ChannelData var body: some View { NavigationView { VStack(alignment: .leading){ TextField("Video title", text: $videoTitle) TextField("Video Content", text: $videoContent) Divider() Button(action: { self.presentationMode.wrappedValue.dismiss() }){ Text("Dismiss this VC") } Spacer() }.padding() .navigationBarTitle(channelData.channelName) } } }ChannelView:import SwiftUI struct ChannelView: View { @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode> @State private var channelName = "My Channel" @EnvironmentObject var channelData: ChannelData var body: some View { NavigationView{ VStack(alignment: .leading){ TextField("Channel Name", text: $channelName) Divider() Button(action: { self.presentationMode.wrappedValue.dismiss() }){ Text("Dismiss this VS") } Spacer() }.padding() .navigationBarTitle(channelData.channelName) } } }
Posted
by www0488.
Last updated
.
Post not yet marked as solved
1 Replies
1.2k Views
Hello guys, like the title says. I'm tying to implment code so I can report the the call before I receive the remote VoIP notification call in methodfunc pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion pushProcessingCompletion: @escaping () -> Void)But under my research time I did get banned from the system and I was not aware for the change which apple announced before:https://developer.apple.com/documentation/pushkit/pkpushregistrydelegate/2875784-pushregistry?language=objcOn iOS 13.0 and later, if you fail to report a call to CallKit, the system will terminate your app. Repeatedly failing to report calls may cause the system to stop delivering any more VoIP push notifications to your app.So my question is is there any chance I can get myself "unban" from the system so I can at least debug my code to verify if my code is working or not
Posted
by www0488.
Last updated
.
Post not yet marked as solved
12 Replies
10k Views
Hellow, I was using one iPhone with version 12.4 to run application for development. Suddely when I updated from version 12.4 to 13.1, one of my http rest api just stopped working and it returns me error:"019-09-25 16:56:56.578750+0200 SmaforetagarnasAPP[487:44045] task challenge NSURLAuthenticationMethodServerTrustFAILURE: Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLStringKey=https://appapi2.bankid.com/rp/v5/auth, NSErrorFailingURLKey=https://appapi2.bankid.com/rp/v5/auth, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask <1FDB0948-469A-4333-BA23-9CAB3452F59B>.<1>"), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <1FDB0948-469A-4333-BA23-9CAB3452F59B>.<1>, NSLocalizedDescription=cancelled}2019-09-25 16:56:56.590973+0200 SmaforetagarnasAPP[487:44045] Task <1FDB0948-469A-4333-BA23-9CAB3452F59B>.<1> HTTP load failed, 0/0 bytes (error code: -999 [1:89])2019-09-25 16:56:56.592230+0200 SmaforetagarnasAPP[487:44045] Connection 3: unable to determine interface type without an established connection2019-09-25 16:56:56.592313+0200 SmaforetagarnasAPP[487:44045] Connection 3: unable to determine fallback status without a connection"Im using Alamofire SessionManager to make the http callThe http call requires certificate and here is my code:Calling function:func authenticate(completion: @escaping ModelCompletion<Bool>) { let configuration = URLSessionConfiguration.default // configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders let sessionManager = Alamofire.SessionManager( configuration: configuration) let endUserIp: String = self.getIPAddress() ?? "192.168.8.103" let parameters: Parameters = ["endUserIp": endUserIp] //set condition // certificatePolicies to “1.2.752.78.1.5” to restrict the order to Mobile BankID only. var header = HTTPHeaders() header["Content-Type"] = "application/json" sessionManager.request("https://appapi2.bankid.com/rp/v5/auth", method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: header) .validate() .responseJSON { [weak self] data in print(data) guard let strongSelf = self else { return } switch data.result { case .success(let value): let bankIDJson = JSON(value) strongSelf.autoStartToken = bankIDJson[RequestJsonTag.autoStartToken.rawValue].string strongSelf.orderRef = bankIDJson[RequestJsonTag.orderRef.rawValue].string SessionManager.sharedInstance.orderRef = strongSelf.orderRef! completion(ModelResult.success(true)) case .failure(let error): completion(ModelResult.failure(error: error.localizedDescription)) } }.session.finishTasksAndInvalidate() // Seeion delegate let delegate = sessionManager.delegate self.didReceiveSessionManagerChallenge(delegate: delegate) }Once I receive Challenge this function will get called:private func didReceiveSessionManagerChallenge(delegate: SessionDelegate) { // Did Receive Challenge delegate.sessionDidReceiveChallenge = { urlSession, challenge in let protectionSpace = challenge.protectionSpace NSLog("task challenge %@", protectionSpace.authenticationMethod) switch (protectionSpace.authenticationMethod, protectionSpace.host) { case (NSURLAuthenticationMethodServerTrust, "appapi2.bankid.com"): if self.shouldTrustBankID(protectionSpace: protectionSpace) { let credential = URLCredential(trust: protectionSpace.serverTrust!) return (.useCredential, credential) } else { return (.cancelAuthenticationChallenge, nil) } case (NSURLAuthenticationMethodClientCertificate, "appapi2.bankid.com"): let identity = Bundle.main.identityForBankIDPayment(named: "smaforetagarnasrpca", password: "Helsingborg#1977") let credential = URLCredential(identity: identity, certificates: nil, persistence: .forSession) return (.useCredential, credential) default: return (.performDefaultHandling, nil) } } }Here is extension once it requires the certificate:extension Bundle { func certificateForBankIDPayment(named: String) -> SecCertificate { let cerURL = self.url(forResource: named, withExtension: "der")! let cerData = try! Data(contentsOf: cerURL) return SecCertificateCreateWithData(nil, cerData as NSData)! } func identityForBankIDPayment(named: String, password: String) -> SecIdentity { let p12URL = Bundle.main.url(forResource: named, withExtension: "p12")! let p12Data = try! Data(contentsOf: p12URL) var importResult: CFArray? = nil let err = SecPKCS12Import( p12Data as NSData, [kSecImportExportPassphrase: password] as NSDictionary, &importResult) assert(err == errSecSuccess) let identityDicts = importResult! as! [[String:Any]] return identityDicts.first![kSecImportItemIdentity as String]! as! SecIdentity } }My Info.plist:<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> <string>$(DEVELOPMENT_LANGUAGE)</string> <key>CFBundleDisplayName</key> <string>Småföretagarnas</string> <key>CFBundleExecutable</key> <string>$(EXECUTABLE_NAME)</string> <key>CFBundleIdentifier</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>$(PRODUCT_NAME)</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> <string>1.0.0</string> <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleTypeRole</key> <string>Editor</string> <key>CFBundleURLName</key> <string>com.curamet.SmaforetagarnasAPP</string> <key>CFBundleURLSchemes</key> <array> <string>sfrapp</string> </array> </dict> </array> <key>CFBundleVersion</key> <string>1</string> <key>LSRequiresIPhoneOS</key> <true/> <key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> <key>NSExceptionDomains</key> <dict> <key>appapi2.bankid.com</key> <dict> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> <key>NSIncludesSubdomains</key> <true/> </dict> </dict> </dict> <key>UILaunchStoryboardName</key> <string>LaunchScreen</string> <key>UIMainStoryboardFile</key> <string>MainTapBarView</string> <key>UIRequiredDeviceCapabilities</key> <array> <string>armv7</string> </array> <key>UISupportedInterfaceOrientations</key> <array> <string>UIInterfaceOrientationPortrait</string> </array> <key>UISupportedInterfaceOrientations~ipad</key> <array> <string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationPortraitUpsideDown</string> <string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeRight</string> </array> </dict> </plist>P.s. I updated my Xcode till support the latest iOS 13.1 version as well.
Posted
by www0488.
Last updated
.
Post not yet marked as solved
0 Replies
3k Views
I want to know if it's possible to disable full-screen mode when WKWebView open local video file by using the file's local url.Because I always receive error "Plug-in handled load" when WKWebView is loading(but the video is still playing in full screen mode).I checked some solutions from StackOverFlow:https://stackoverflow.com/a/10194888/11055217https://stackoverflow.com/questions/2143763/does-uiwebview-send-the-same-user-agent-in-the-request-headers-as-mobile-safari/5916330#5916330But these link still cannot solve my problem.Here is my WKWebView code setup:// // WebViewController.swift // HelpieMeApp // // Created by Guests on 11/9/18. // Copyright © 2018 Menjie Mao. All rights reserved. // import WebKit class WebViewController: UIViewController { private var webView: WKWebView! @IBOutlet var viewTitle: UILabel! @IBOutlet weak var loadingIndicator: UIActivityIndicatorView! var urlString: String = "" var url: URL? = nil var webViewTitle: String = "" override func viewDidLoad() { super.viewDidLoad() self.viewTitle.text = self.webViewTitle self.initWebView() self.loadingIndicator.stopAnimating() self.loadingIndicator.isHidden = true // Load file url else use load link url to support both ways if let fileURL = self.url { self.webView.loadFileURL(fileURL, allowingReadAccessTo: fileURL) self.webView.customUserAgent = UIWebView().stringByEvaluatingJavaScript(from: "navigator.userAgent") } else { self.webView.load(URLRequest(url: URL(string: self.urlString)!)) } } @IBAction func cancelAction(_ sender: UIButton) { self.dismiss(animated: true, completion: nil) } private func initWebView() { let preferences = WKPreferences() preferences.javaScriptEnabled = true // Setup Web View let configuration = WKWebViewConfiguration() configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent() configuration.preferences = preferences self.webView = WKWebView(frame: CGRect.zero, configuration: configuration) self.webView.translatesAutoresizingMaskIntoConstraints = false self.webView.allowsLinkPreview = true self.webView.allowsBackForwardNavigationGestures = true self.webView.navigationDelegate = self self.view.addSubview(self.webView) self.view.bringSubviewToFront(self.loadingIndicator) // Add Constraints self.webView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 80).isActive = true self.webView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0).isActive = true self.webView.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: 0).isActive = true self.webView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 0).isActive = true if #available(iOS 11.0, *) { self.webView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true } else { self.webView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0).isActive = true } } } // MARK: - WKNavigationDelegate extension WebViewController: WKNavigationDelegate { func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { self.loadingIndicator.startAnimating() } func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void) { decisionHandler(.allow) } func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Swift.Void) { decisionHandler(.allow) } func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { let cred = URLCredential(trust: challenge.protectionSpace.serverTrust!) completionHandler(.useCredential, cred) } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { self.loadingIndicator.stopAnimating() } func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { self.loadingIndicator.stopAnimating() self.loadingIndicator.isHidden = true AlertUtil.showErrorMessage(vc: self, title: error.localizedDescription) } func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { self.loadingIndicator.stopAnimating() self.loadingIndicator.isHidden = true AlertUtil.showErrorMessage(vc: self, title: error.localizedDescription) } }And the error triggered atfunc webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error)
Posted
by www0488.
Last updated
.
Post marked as solved
1 Replies
1.4k Views
Hello, Im trying to make a API call to a server by using a https certificate, but I already get stuck at the server trust stage. I'm using a server certificate with extension .cer and here is my code:private func shouldTrust(protectionSpace: URLProtectionSpace) -> Bool { guard let trust = protectionSpace.serverTrust else { return false } // First try evaluating trust with any custom anchor. If that succeeds, we're good to go. var trustResult = SecTrustResultType.invalid var err = SecTrustEvaluate(trust, &trustResult) guard err == errSecSuccess else { return false } if [.proceed, .unspecified].contains(trustResult) { return true } // If it fails, apply our custom anchor and try again. let root = Bundle.main.certificateForBankIDPayment(named: "sebtekniskbankinfoserverca") err = SecTrustSetAnchorCertificates(trust, [root] as NSArray) guard err == errSecSuccess else { return false } err = SecTrustEvaluate(trust, &trustResult) guard err == errSecSuccess else { return false } return [.proceed, .unspecified].contains(trustResult) }extension Bundle { func certificateForBankIDPayment(named: String) -> SecCertificate { let cerURL = self.url(forResource: named, withExtension: "cer")! let cerData = try! Data(contentsOf: cerURL) return SecCertificateCreateWithData(nil, cerData as NSData)! } }Here is the server certificate in txt form:-----BEGIN CERTIFICATE-----MIIFvjCCA6agAwIBAgIITyTh/u1bExowDQYJKoZIhvcNAQENBQAwYjEkMCIGA1UECgwbRmluYW5zaWVsbCBJRC1UZWtuaWsgQklEIEFCMRowGAYDVQQLDBFJbmZyYXN0cnVjdHVyZSBDQTEeMBwGA1UEAwwVQmFua0lEIFNTTCBSb290IENBIHYxMB4XDTExMTIwNzEyMzQwN1oXDTM0MTIzMTEyMzQwN1owYjEkMCIGA1UECgwbRmluYW5zaWVsbCBJRC1UZWtuaWsgQklEIEFCMRowGAYDVQQLDBFJbmZyYXN0cnVjdHVyZSBDQTEeMBwGA1UEAwwVQmFua0lEIFNTTCBSb290IENBIHYxMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwVA4snZiSFI3r64LvYu4mOsI42A9aLKEQGq4IZo257iqvPH82SMvgBJgE52kCx7gQMmZ7iSm39CEA19hlILh8JEJNTyJNxMxVDN6cfJP1jMHJeTES1TmVbWUqGyLpyT8LCJhC9Vq4W3t/O1svGJNOUQIQL4eAHSvWTVoalxzomJhOn97ENjXAt4BLb6sHfVBvmB5ReK0UfwpNACFM1RN8btEaDdWC4PfA72yzV3wK/cY5h2k1RM1s19PjoxnpJqrmn4qZmP4tN/nk2d7c4FErJAP0pnNsll1+JfkdMfiPD35+qcclpspzP2LpauQVyPbO21Nh+EPtr7+Iic2tkgz0g1kK0IL/foFrJ0Ievyr3Drm2uRnA0esZ45GOmZhE22mycEX9l7w9jrdsKtqs7N/T46hil4xBiGblXkqKNG6TvARk6XqOp3RtUvGGaKZnGllsgTvP38/nrSMlszNojrlbDnm16GGoRTQnwr8l+Yvbz/ev/e6wVFDjb52ZB0Z/KTfjXOl5cAJ7OCbODMWf8Na56OTlIkrk5NyU/uGzJFUQSvGdLHUipJ/sTZCbqNSZUwboI0oQNO/Ygez2J6zgWXGpDWiN4LGLDmBhB3T8CMQu9J/BcFvgjnUyhyim35kDpjVPC8nrSir5OkaYgGdYWdDuv1456lFNPNNQcdZdt5fcmMCAwEAAaN4MHYwHQYDVR0OBBYEFPgqsux5RtcrIhAVeuLBSgBuRDFVMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU+Cqy7HlG1ysiEBV64sFKAG5EMVUwEwYDVR0gBAwwCjAIBgYqhXBOAQQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDQUAA4ICAQAJOjUOS2GJPNrrrqf539aN1/EbUj5ZVRjG4wzVtX5yVqPGcRZjUQlNTcfOpwPoczKBnNX2OMF+Qm94bb+xXc/08AERqJJ3FPKu8oDNeK+Rv1X4nh95J4RHZcvl4AGhECmGMyhyCea0qZBFBsBqQR7oC9afYOxsSovaPqX31QMLULWUYoBKWWHLVVIoHjAmGtAzMkLwe0/lrVyApr9iyXWhVr+qYGmFGw1+rwmvDmmSLWNWawYgH4NYxTf8z5hBiDOdAgilvyiAF8Yl0kCKUB2fAPhRNYlEcN+UP/KL24h/pB+hZ9mvR0tM6nW3HVZaDrvRz4VihZ8vRi3fYnOAkNE6kZdrrdO7LdBc9yYkfQdTcy0N+Aw7q4TkQ8npomrVmTKaPhtGhA7VICyRNBVcvyoxr+CY7aRQyHn/C7n/jRsQYxs7uc+msq6jRS4HPK8olnF9usWZX6KY+8mweJiTE4uN4ZUUBUtt8WcXXDiK/bxEG2amjPcZ/b4LXwGCJb+aNWP4+iY6kBKrMANs01pLvtVjUS9RtRrY3cNEOhmKhO0qJSDXhsTcVtpbDr37UTSqQVw83dReiARPwGdURmmkaheH6z4k6qEUSXuFch0w53UAc+1aBXR1bgyFqMdy7Yxib2AYu7wnrHioDWqP6DTkUSUeMB/zqWPM/qx6QNNOcaOcjA==-----END CERTIFICATE-----Im pretty sure about the server root certificate is valid because I can add it to the keychain access.With debug mode, I can pass code line:let cerURL = self.url(forResource: named, withExtension: "cer")! let cerData = try! Data(contentsOf: cerURL)But I will receive the error message "error: Unexpectedly found nil while unwrapping an Optional value" when I trying to pass code line: return SecCertificateCreateWithData(nil, cerData as NSData)!Is there anything I was missing?
Posted
by www0488.
Last updated
.
Post not yet marked as solved
0 Replies
360 Views
Right now I'm looking for a good tool which can help me track down user activity when they are using application. I know there is App Analytics, but I need some more information which is a little more specific. Information which I would like to know is:How many user clicked on one specific button, image, text or link.How many times user has viewd on one specific UI page.
Posted
by www0488.
Last updated
.
Post marked as solved
4 Replies
2.6k Views
I was trying to create a UIButton by code, and I want to add the UIButton as a subview into a UITextView. Here is the code:private func initTermsTextView() { let filePath = Bundle.main.path(forResource: "terms", ofType: "html", inDirectory: nil, forLocalization: nil) ?? "" let htmlString = try! String(contentsOfFile: filePath) let htmlData = NSString(string: htmlString).data(using: String.Encoding.unicode.rawValue) let options = [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html] let attributedString = try! NSMutableAttributedString(data: htmlData!, options: options, documentAttributes: nil) let font = UIFont(name: "BrandonGrotesque-Regular", size: 20) ?? UIFont.systemFont(ofSize: 20) attributedString.setFontFace(font: font, color: UIColor.grayMetalic()) let btn: UIButton = UIButton(frame: CGRect(x: 8, y: termsTextView.contentSize.height*11-135, width: 48, height: 48)) btn.setTitle("asdasdasdasda", for: .normal) btn.addTarget(self, action: #selector(buttonAction), for: .touchUpInside) btn.clipsToBounds = true btn.setImage(UIImage(named: "uncheckedBox"), for: .normal) let path = UIBezierPath(rect: CGRect(x: 8, y: termsTextView.contentSize.height*11-135, width: btn.frame.width, height: btn.frame.height)) self.termsTextView.textContainer.exclusionPaths = [path] self.termsTextView.attributedText = attributedString self.termsTextView.text.append(TermConditionSingleton.getInstance.setTCGetString()) self.termsTextView.addSubview(btn) }Since I have no idea how to add UIButton at the bottom of a UITextView, I did hardcore and count out the UITextView length(text length*11-135) and added the button under the UITextView.After I was running my code with devices which is above the iPhone 6 (include 6s and plus) and the UIButton has displayed in the UITextView. But when I tried with iPhone 6 plus and iPhone 6s plus, the UIButton sub view did not show in the UITextView and I have no idea why.Is there any way I can fix this type of problem?
Posted
by www0488.
Last updated
.