Links in Apple Mail (App in iOS) are not working - ios

Our users have reported that the the links in our mails are not clickable in Apple's Mail App as they are just recognized as pure texts(underlined blue colored text). But links become clickable when the same mail is forwarded (in quoted text). This problem only occurs in Apple Mail App and not in any other third party mail apps like gmail etc. Any reason or fix for this? Are we missing something that Mail App needs specifically to be mentioned while creating links? Why Links become operational when the same email is forwarded? This happens on all iOS devices (tested on Ipads and Iphones)
Any additional information from our side can be provided on the same, if needed for better clarification.
Thank You

Are you sure you are adding link attribute to your mailTo: link text?
You may want to give it a try while setting mail content attributed text.
let attrText = NSMutableAttributedString.init(string: "Email me")
let mailLink = "mailTo:test#example.com"
let url = NSURL.init(string: mailLink) as NSURL?
attrText.addAttribute(NSAttributedStringKey.link, value: url ?? "", range: NSMakeRange(0, attrText.length))
let documentAttributes = [NSAttributedString.DocumentAttributeKey.documentType : NSAttributedString.DocumentType.html]
do {
let htmlData = try! attrText.data(from: NSMakeRange(0, attrText.length), documentAttributes:documentAttributes)
if let htmlString = String(data:htmlData, encoding:String.Encoding.utf8) {
let messageVC = MFMailComposeViewController()
messageVC.setMessageBody(htmlString, isHTML: true)
}
}

Related

Override or customize default "longpress mailto:" behavior

Currently I'm developing an email app and want all links with mailto scheme to be opened via my app, not default Apple's Mail app.
For instance, I have a link like this one
<a href="mailto:email#example.com\>mailto_test</a>
in UIWebView or UITextView (doesn't matter which one, they have similar behavior).
When I longpress this link iOS will show UIAlertController with 3 options:
The first one option, "New Message", will open default Mail app. So my question is how to override this behavior? How can i force this option to launch my own email app?
For those who think it is impossible - take a look at iOS Gmail app. Gmail devs have implemented what I'm asking about, but I don't understand how.
In a text view, link behavior is completely up to you. Give the text view a delegate and implement textView(_:shouldInteractWith:in:interaction:). A long press is the .presentActions interaction. Return false and substitute your own response. You can put up your own .actionSheet alert that looks just like the default one, but does what you want it to.
The solution is to change the default click action of the mail link to the way you want.
Make a UITextView example:
Suppose we have UITextView textView, its attributeString is
<a href="mailto:email#example.com\>mailto_test</a>
and its documentType is html. The code is below:
let textView = UITextView(frame: view.bounds)
textView.frame.origin.y += 100
let attrStr = try! NSAttributedString(
data: "mailto_test".data(using: .utf8, allowLossyConversion: true)!,
options:[.documentType: NSAttributedString.DocumentType.html],
documentAttributes: nil)
textView.attributedText = attrStr
view.addSubview(textView)
This the default effect that after pressed the mailto_test text in the screen the native mail app functions waked up. So we add a delegate to the textView to modify the click action.
textView.isEditable = false
textView.dataDetectorTypes = .link
textView.delegate = self
Here is the delegate function to control the specific click action:
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
print(URL)
return false
}
Whenever you pressed the mail link, the functions invoked without calling the native mail app. And the URL is just the mail url.
You are looking for something like this, right? Where you can open your app from anywhere you click email URL.
I can't find the exact answer right now, but you want to add your app as a URL Scheme (Apple documentation)
Edit: more apple documentation

How to enable camera in MFMessageComposeViewController?

I am developing an iOS application with a button to report an issue using SMS/iMessage. I am using MFMessageComposeViewController to present the message composition interface using the following code (Swift 3):
if(MFMessageComposeViewController.canSendText()){
let controller = MFMessageComposeViewController()
controller.messageComposeDelegate = self
controller.body = "Example Message"
controller.recipients = ["2345678901"]
self.present(controller, animated: true, completion: nil)
}
I have also implemented the MFMessageComposeViewControllerDelegate function to dismiss properly. A standard text message / iMessage sends successfully, but the user does not have the option to attach an image. The buttons for camera, iMessage Apps, etc. are there, but they are disabled and cannot be pressed. How can I enable these buttons (camera, specifically) to allow my users to attach images to messages composed with the app?
The Buttons in Question:
EDIT:
Thanks Abdelahad for the suggestion. I've modified his response to allow multiple recipients and to include a message body. I also updated it to remove the deprecated addingPercentEscapes(using: ) method.
Here is a solution using a url to open the Messages app. NOTE: This takes users out of the app.
let recipients = "2345678901,3456789012" //Phone Numbers
let messageBody = "This is a test"
let sms: String = "sms://open?addresses=\(recipients)&body=\(messageBody)"
let smsEncoded = sms.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed)
let url = URL(string: smsEncoded!)
UIApplication.shared.openURL(url!)
But still I would like a solution that does not take the user out of the app. Is this possible? Why would the MFMessageComposeViewController show the buttons without enabling them?
Don't use MFMessageComposeViewController use UIApplication.shared.openURL(url!) but this will takes the user out of the app
var phoneToCall: String = "sms: +201016588557"
var phoneToCallEncoded = phoneToCall.addingPercentEscapes(using: String.Encoding.ascii)
var url = URL(string: phoneToCallEncoded)
UIApplication.shared.openURL(url!)

Using Branch.io generated link with Facebook share dialog

I went through Branch.io's documentation a lot over the past few days and I can't seem to pinpoint the problem. I got the generated link to work properly by setting up the BranchUniversalObject as follows:
let branchUniversalObject: BranchUniversalObject = BranchUniversalObject(canonicalIdentifier: "ios_share_user")
branchUniversalObject.title = "My Title"
branchUniversalObject.contentDescription = "My Description"
branchUniversalObject.imageUrl = "www.example.com/image.jpg"
branchUniversalObject.addMetadataKey("id", value: self.userId)
branchUniversalObject.addMetadataKey("type", value: self.userType)
let linkProperties = BranchLinkProperties()
linkProperties.channel = "Facebook"
linkProperties.feature = "Share"
branchUniversalObject.getShortUrl(with: linkProperties, andCallback: { (shareURL, error) in
if error != nil {
print(error!)
return
}
// using shareURL here
})
The generated URL works perfectly fine, but only when launched from Notes or Messages apps. Safari always redirects me to the AppStore and so does the Facebook app when I try sharing the URL like this:
let content = FBSDKShareLinkContent()
content.contentTitle = "My Title"
content.contentURL = shareURL // generated above
content.contentDescription = "My Description"
content.imageURL = "www.example.com/image.jpg"
let dialog = FBSDKShareDialog()
dialog.fromViewController = self
dialog.delegate = self
dialog.shareContent = content
if dialog.canShow() {
dialog.show()
}
That shows up the dialog and shares the content as intended, but the link always redirects me to the AppStore just like in Safari.
Here's a screenshot of the Dashboard:
I also have applinks:myLinkDomain.app.link and applinks:myLinkDomain-alternate.app.link in the Associated Domains, branch_app_domain = myLinkDomain.app.link along with branch_key = ["live": "key_live_myKey"] in Info.plist, and AppDelegate is properly set.
What am I missing to get the app to open from Safari and Facebook instead of getting redirected to the AppStore?
I'm deploying the app for iOS 9.3+
Thanks!
I came across this link and it shows that the problem isn't with Branch.io SDK's setup by any means, but a limitation imposed by Apple. The only workaround is using Branch's Deepviews, which unfortunately I can't use in my case.
Hope Branch.io figure out a way around that! ...And possibly update their documentation to clearly state that some app browsers are not supported

Detect and open a Postal Address in Swift(iOS) using NSDataDetector

I currently have a UITextView with Address detection active, this detects any addresses in this field and makes them into a clickable link that opens up Apple Maps with the address as the focus. I really like this functionality but my users would rather have a button to click on instead of the inline link.
With this in mind I have researched into NSDataDetector and managed to get this functionality working for emailing and phone numbers but I am stuck on Addresses. The code I am using to detect the address is below:
let types: NSTextCheckingType = [.Address]
let detector = try! NSDataDetector(types: types.rawValue)
let matches = detector.matchesInString(input, options: [], range: NSMakeRange(0, input.characters.count))
for match in matches {
return NSURL(string: "\((input as NSString).substringWithRange(match.range))")
}
However the NSURL fails to be created, I believe the syntax must be wrong, it works for phone numbers as below:
let types: NSTextCheckingType = [.PhoneNumber]
let detector = try! NSDataDetector(types: types.rawValue)
let matches = detector.matchesInString(input, options: [], range: NSMakeRange(0, input.characters.count))
for match in matches {
return NSURL(string: "telprompt://\((input as NSString).substringWithRange(match.range))")
}
If the address is valid it returns the components of the address(street, city etc.) in the matches object. I was hoping the NSURL could be used with address just like phone numbers but I may be wrong so is there an alternate way I could use the results from the detector and display them on Apple Maps manually?
Or as a side note could I hide the UITextView and trigger the link touch programatically based on a button touch?
Any more information can be provided as needed,
thank you in advance for any help.

Error when Facebook Open Graph Action shared from iOS (unsafe link)

I tried to share a Facebook Open Graph Action via official iOS SDK (last version) but for a few days now, this action returns an error and it has now stopped working.
The app passed the Facebook approval, including actions and related objects and it all seems correct.
Object creation and share action
// ############## OpenGraph - Arrive At a Marina
// Photo
var photoURL = ""
if let image = firstMarina.images.first {
photoURL = image.width1440
} else {
photoURL = "https://fbstatic-a.akamaihd.net/images/devsite/attachment_blank.png"
}
let photo = FBSDKSharePhoto(imageURL: NSURL(string: photoURL)!, userGenerated: false)
// Properties
let properties = [
"fb:app_id": "xxxxxxxxxxxxxxxxxxxxx",
"og:locale": NSLocale.preferredLanguages()[0].stringByReplacingOccurrencesOfString("-", withString: "_"),
"og:type": "smartsea:marina",
"og:title": firstMarina.name!.text,
"og:description": firstMarina.desc!.text,
"og:image": [photo],
"place:location:latitude": firstMarina.location!.lat,
"place:location:longitude": firstMarina.location!.lng
]
// Object
let object = FBSDKShareOpenGraphObject(properties: properties as [NSObject : AnyObject])
// Action
let action = FBSDKShareOpenGraphAction(type: "smartsea:arrive_at", object: object, key: "marina")
// Content
let content = FBSDKShareOpenGraphContent()
content.action = action
content.previewPropertyName = "marina"
// Share
FBSDKShareDialog.showFromViewController(self, withContent: content, delegate: self)
and the error returned
Error Domain=com.facebook.Facebook.platform Code=102 "(null)" UserInfo={error_reason=The content you're trying to share includes a link that our security systems detected to be unsafe:
https://m.facebook.com/appcenter/smartsea?fbs=9909&fb_object_id=1684374595135519
Please remove this link to continue., error_description=An error occurred during publishing., app_id=xxxxxxxxxxxxxxxxxxxxx, error_code=102}
The strange thing is that the error URL is a Facebook domain and I haven't share it this URL directly. It seems to be generated with every share action.
Any idea?
Thanks!
Unfortunately I can't post a simple comment, so I have to post it as an 'answer'. I have found this article. It's about blocked URLs, but unfortunately not about blocked 'Facebook' URLs. I hope it can help.
http://www.technerves.com/2015/07/unblock-your-website-url-from-facebook.html
It connection might be getting blocked due to App transport security. App transport security is a new thing introduced in iOS9.
It blocks connections to servers that don't meet certain security requirements, such as minimum TLS version etc
Please try again after turning ATS OFF from info.plist. See this link which shows how to turn ATS OFF.

Resources