0

I'm able to fetch messages form gmail api. In the response i'm getting From and To mails as like below

enter image description here.

{
    "name": "From",
    "value": Mail Delivery Subsystem **Symbol lessthan**mailer-daemon@googlemail.com**Symbol greaterthan**
}

{
    "name": "To",
    "value": Rahul, kumar **Symbol greaterthan**rahulkumar1234@gmail.com**Symbol lessthan**
}

I can able to access value as like below by looping.

 if element.name == "From" {
   print("From ::: \(String(describing: element.value!))")
 }

OutPut is :

From ::: Mail Delivery Subsystem <mailer-daemon@googlemail.com>

Instead of sender name and mail. I want to get only mail and sender name individullay. how can i devide the value into two parts/strings one for name and another for mail.

Some times there is no sender name as well as lessthan and greaterthan symbols, in that time i'm getting only mail.

@vadian I've specified below of all the formats in the response. sometimes i'm not getting lessthan and greater than. And also i want to save name and email as a two seperate strings. if there is no name in the response then there is no need to grab it as a string only mail is enough to grab as a string. enter image description here

2 Answers2

0

2 options i can think of,

1st: Quick and Dirty

Split the string using the '<' operator, get the second part, which will be bit after '<' then remove the '>' from that result to clean it up. This could be dangerous if it's possible for a user to have a '<' or '>' in their name so wouldn't rely on this approach.

2nd: RegEx

Use regular expressions to grab the email from the value

var value = "Some Guy <email@example.com>"

// no idea how robust this pattern is I just grabbed it from google so feel free to change
var pattern = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
let regex = try NSRegularExpression(pattern: pattern)
let results = regex.matches(in: value, range: NSRange(value.startIndex..., in: value))

// Generates a string array of emails
var emails = results.map {
    String(value[Range($0.range, in: value)!])
}

you'll probably only ever have one email in the From field but this will allow you to grab multiple emails if there are in the To field.

Keith Mthunzi
  • 141
  • 1
  • 7
0

First of all \(String(describing: element.value!) is horrible. element.value! is supposed to be a string anyway and wrapping in String(describing: and again in String Interpolation is twice redundant.

Don't abuse String(describing for types which conform to ExpressibleByStringLiteral anyway.

Just write print("From ::: ", element.value!)


This function returns a tuple for name and email. It checks if there is a < character.

If there is none, it returns an empty string as name and the input string as email.
If there is one, it returns the substring after < until second last character as email and the rest trimmed by double quote, space and < as name.

func extractNameAndMail(in string: String) -> (name:String, email:String) {
    if let rangeOfLessThan = string.range(of: "<") {
        let email = string[rangeOfLessThan.upperBound...].dropLast()
        let name = string[...rangeOfLessThan.lowerBound].trimmingCharacters(in: CharacterSet(charactersIn: "\" <"))
        return (name: String(name), email: String(email))
    } else {
        return (name:"", email:string)
    }
}

let string = "\"Some Guy\" <mailer-daemon@googlemail.com>"
let extractedString = extractNameAndMail(in: string)
vadian
  • 274,689
  • 30
  • 353
  • 361
  • @please see my edited question screenshot there i've specified all formats. i want sender name and email id as a two separate strings. –  May 14 '18 at 13:28
  • Why don't you put **all** your requirements in the question from the very first? I updated the answer to match all cases. – vadian May 14 '18 at 13:34
  • I need to save sender name also as a different string. In that example response need some guy as a seperate string. I mean skip mail need only name. –  May 14 '18 at 13:44
  • Can you please suggest me solution to the issue in the old question. https://stackoverflow.com/questions/49810965/how-to-convert-form-any-date-format-to-one-date-format-which-is-ddmmmmyyyy10apr . Here for one date it returns nil i've included that date in my edited question kindly look over and help me. –  May 29 '18 at 05:51
  • @IOSDeveloper `+0580` is not a valid time zone. – vadian May 29 '18 at 06:45
  • Thu, 3 Sep 2015 13:41:38 +0580 & Tue, 8 Sep 2015 11:28:17 +0580 . I'm fetching around sixty thousand mails in that only two mails are having timezone as +0580. Can you please kindly help me to fix this issue. –  May 29 '18 at 08:58
  • Hi vadian. Google servers are returning these dates of not valid time zone. how can i solve this issue i'm not getting any idea please help me. –  May 30 '18 at 13:12
  • The issue is not the regex parsing, the issue is the date formatter which does not consider the invalid time zone. Just add an if condition which replaces any occurrence of `+0580` with something valid just before converting the string to `Date`. – vadian May 30 '18 at 13:17