Swift how to send eMail mail in AppDelegate fetch?
Im totally helpless right now, i'm trying to send an eMail for data upload in an iOS Swift 4 App. I found the Obj-C Mailcore library which works in normal code, for example in a button press callback. But if i'm trying to use the same code in my AppDelegate
fetch func it doesn't return from the completionHandler.
The Mailcore send operation is async so i used a semaphore wrapper around it, but the completion handler is never called.
Edit:
Apparently the code does not work in the button with the Semaphore. Only if i remove the
let _ = semaphore.wait(timeout: DispatchTime.distantFuture)
part.
So is there another way to wait for the completion of the async completionBlock?
Yes, look at my answer :-)
My code:
let smtpSession = MCOSMTPSession()
[...]
let sendOperation = smtpSession.sendOperation(with: rfc822Data!)
[...]
let semaphore = DispatchSemaphore(value: 0)
if (sendOperation != nil) {
print("Starting sendOperation...")
sendOperation?.start { (error) -> Void in
if (error != nil) {
sendingError = true
print("Error sending email: (error)")
} else {
print("Successfully sent email!")
}
sendingDone = true
semaphore.signal()
}
let _ = semaphore.wait(timeout: DispatchTime.distantFuture)
} else {
print("Cant init sendOperation")
sendingError = true
}
ios swift swift4 appdelegate mailcore2
add a comment |
Im totally helpless right now, i'm trying to send an eMail for data upload in an iOS Swift 4 App. I found the Obj-C Mailcore library which works in normal code, for example in a button press callback. But if i'm trying to use the same code in my AppDelegate
fetch func it doesn't return from the completionHandler.
The Mailcore send operation is async so i used a semaphore wrapper around it, but the completion handler is never called.
Edit:
Apparently the code does not work in the button with the Semaphore. Only if i remove the
let _ = semaphore.wait(timeout: DispatchTime.distantFuture)
part.
So is there another way to wait for the completion of the async completionBlock?
Yes, look at my answer :-)
My code:
let smtpSession = MCOSMTPSession()
[...]
let sendOperation = smtpSession.sendOperation(with: rfc822Data!)
[...]
let semaphore = DispatchSemaphore(value: 0)
if (sendOperation != nil) {
print("Starting sendOperation...")
sendOperation?.start { (error) -> Void in
if (error != nil) {
sendingError = true
print("Error sending email: (error)")
} else {
print("Successfully sent email!")
}
sendingDone = true
semaphore.signal()
}
let _ = semaphore.wait(timeout: DispatchTime.distantFuture)
} else {
print("Cant init sendOperation")
sendingError = true
}
ios swift swift4 appdelegate mailcore2
Are you suresendOperation
is not-nil when you callstart
? Theres nothing special about an object that adoptsUIApplicationDelegate
– Warren Burton
Nov 23 '18 at 12:23
@Warren Burton Im not sure, but i just copy and pasted it from the button code where it worked so i doesnt bothered. I will check this but shouldnt it crash if i call start() on a nil object?
– skilled-solutions
Nov 23 '18 at 12:25
sendOperation
appears to beOptional
from your code. You can see that fromsendOperation?
using optional chaining.
– Warren Burton
Nov 23 '18 at 12:41
@Warren Burton Now i see what you mean. I will check if it is nil.
– skilled-solutions
Nov 23 '18 at 12:49
@WarrenBurton It is not nil, i added a check and start is executed.
– skilled-solutions
Nov 23 '18 at 12:56
add a comment |
Im totally helpless right now, i'm trying to send an eMail for data upload in an iOS Swift 4 App. I found the Obj-C Mailcore library which works in normal code, for example in a button press callback. But if i'm trying to use the same code in my AppDelegate
fetch func it doesn't return from the completionHandler.
The Mailcore send operation is async so i used a semaphore wrapper around it, but the completion handler is never called.
Edit:
Apparently the code does not work in the button with the Semaphore. Only if i remove the
let _ = semaphore.wait(timeout: DispatchTime.distantFuture)
part.
So is there another way to wait for the completion of the async completionBlock?
Yes, look at my answer :-)
My code:
let smtpSession = MCOSMTPSession()
[...]
let sendOperation = smtpSession.sendOperation(with: rfc822Data!)
[...]
let semaphore = DispatchSemaphore(value: 0)
if (sendOperation != nil) {
print("Starting sendOperation...")
sendOperation?.start { (error) -> Void in
if (error != nil) {
sendingError = true
print("Error sending email: (error)")
} else {
print("Successfully sent email!")
}
sendingDone = true
semaphore.signal()
}
let _ = semaphore.wait(timeout: DispatchTime.distantFuture)
} else {
print("Cant init sendOperation")
sendingError = true
}
ios swift swift4 appdelegate mailcore2
Im totally helpless right now, i'm trying to send an eMail for data upload in an iOS Swift 4 App. I found the Obj-C Mailcore library which works in normal code, for example in a button press callback. But if i'm trying to use the same code in my AppDelegate
fetch func it doesn't return from the completionHandler.
The Mailcore send operation is async so i used a semaphore wrapper around it, but the completion handler is never called.
Edit:
Apparently the code does not work in the button with the Semaphore. Only if i remove the
let _ = semaphore.wait(timeout: DispatchTime.distantFuture)
part.
So is there another way to wait for the completion of the async completionBlock?
Yes, look at my answer :-)
My code:
let smtpSession = MCOSMTPSession()
[...]
let sendOperation = smtpSession.sendOperation(with: rfc822Data!)
[...]
let semaphore = DispatchSemaphore(value: 0)
if (sendOperation != nil) {
print("Starting sendOperation...")
sendOperation?.start { (error) -> Void in
if (error != nil) {
sendingError = true
print("Error sending email: (error)")
} else {
print("Successfully sent email!")
}
sendingDone = true
semaphore.signal()
}
let _ = semaphore.wait(timeout: DispatchTime.distantFuture)
} else {
print("Cant init sendOperation")
sendingError = true
}
ios swift swift4 appdelegate mailcore2
ios swift swift4 appdelegate mailcore2
edited Nov 26 '18 at 7:25
skilled-solutions
asked Nov 23 '18 at 12:13
skilled-solutionsskilled-solutions
216
216
Are you suresendOperation
is not-nil when you callstart
? Theres nothing special about an object that adoptsUIApplicationDelegate
– Warren Burton
Nov 23 '18 at 12:23
@Warren Burton Im not sure, but i just copy and pasted it from the button code where it worked so i doesnt bothered. I will check this but shouldnt it crash if i call start() on a nil object?
– skilled-solutions
Nov 23 '18 at 12:25
sendOperation
appears to beOptional
from your code. You can see that fromsendOperation?
using optional chaining.
– Warren Burton
Nov 23 '18 at 12:41
@Warren Burton Now i see what you mean. I will check if it is nil.
– skilled-solutions
Nov 23 '18 at 12:49
@WarrenBurton It is not nil, i added a check and start is executed.
– skilled-solutions
Nov 23 '18 at 12:56
add a comment |
Are you suresendOperation
is not-nil when you callstart
? Theres nothing special about an object that adoptsUIApplicationDelegate
– Warren Burton
Nov 23 '18 at 12:23
@Warren Burton Im not sure, but i just copy and pasted it from the button code where it worked so i doesnt bothered. I will check this but shouldnt it crash if i call start() on a nil object?
– skilled-solutions
Nov 23 '18 at 12:25
sendOperation
appears to beOptional
from your code. You can see that fromsendOperation?
using optional chaining.
– Warren Burton
Nov 23 '18 at 12:41
@Warren Burton Now i see what you mean. I will check if it is nil.
– skilled-solutions
Nov 23 '18 at 12:49
@WarrenBurton It is not nil, i added a check and start is executed.
– skilled-solutions
Nov 23 '18 at 12:56
Are you sure
sendOperation
is not-nil when you call start
? Theres nothing special about an object that adopts UIApplicationDelegate
– Warren Burton
Nov 23 '18 at 12:23
Are you sure
sendOperation
is not-nil when you call start
? Theres nothing special about an object that adopts UIApplicationDelegate
– Warren Burton
Nov 23 '18 at 12:23
@Warren Burton Im not sure, but i just copy and pasted it from the button code where it worked so i doesnt bothered. I will check this but shouldnt it crash if i call start() on a nil object?
– skilled-solutions
Nov 23 '18 at 12:25
@Warren Burton Im not sure, but i just copy and pasted it from the button code where it worked so i doesnt bothered. I will check this but shouldnt it crash if i call start() on a nil object?
– skilled-solutions
Nov 23 '18 at 12:25
sendOperation
appears to be Optional
from your code. You can see that from sendOperation?
using optional chaining.– Warren Burton
Nov 23 '18 at 12:41
sendOperation
appears to be Optional
from your code. You can see that from sendOperation?
using optional chaining.– Warren Burton
Nov 23 '18 at 12:41
@Warren Burton Now i see what you mean. I will check if it is nil.
– skilled-solutions
Nov 23 '18 at 12:49
@Warren Burton Now i see what you mean. I will check if it is nil.
– skilled-solutions
Nov 23 '18 at 12:49
@WarrenBurton It is not nil, i added a check and start is executed.
– skilled-solutions
Nov 23 '18 at 12:56
@WarrenBurton It is not nil, i added a check and start is executed.
– skilled-solutions
Nov 23 '18 at 12:56
add a comment |
2 Answers
2
active
oldest
votes
The completion is either coming on the same thread or runs something in that thread.
The normal thing to do is to not wait, but instead do whatever you need to do after it completes in the completion itself.
If you must do it with a semaphore, move the start call to another thread.
add a comment |
So i found a solution:
SyncManager.swift
import Foundation
/// A generic Cocoa-Style completion handler
typealias CompletionHandler = (Error?) -> Void
/// Provides syncronous access to results returned by
/// asynchronous processes with completion handlers
class SyncMaker {
var result: Error? = nil
/// Generates a synchronous-compliant completion handler
func completion() -> CompletionHandler{
return {
(error: Error?) in
// Store result, return control
self.result = error
CFRunLoopStop(CFRunLoopGetCurrent())
}
}
// Perform task (that must use custom completion handler) and wait
func run(_ task: @escaping () -> Void) -> Error? {
task()
CFRunLoopRun()
return result
}
}
AppDelegate.swift (partly)
[...]
let syncMaker = SyncMaker()
let result = syncMaker.run {
sendOperation?.start(
syncMaker.completion())
}
if (result != nil) {
print("Error sending email: (result)")
} else {
sendingError = false
print("Successfully sent email!")
}
[...]
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53446533%2fswift-how-to-send-email-mail-in-appdelegate-fetch%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
The completion is either coming on the same thread or runs something in that thread.
The normal thing to do is to not wait, but instead do whatever you need to do after it completes in the completion itself.
If you must do it with a semaphore, move the start call to another thread.
add a comment |
The completion is either coming on the same thread or runs something in that thread.
The normal thing to do is to not wait, but instead do whatever you need to do after it completes in the completion itself.
If you must do it with a semaphore, move the start call to another thread.
add a comment |
The completion is either coming on the same thread or runs something in that thread.
The normal thing to do is to not wait, but instead do whatever you need to do after it completes in the completion itself.
If you must do it with a semaphore, move the start call to another thread.
The completion is either coming on the same thread or runs something in that thread.
The normal thing to do is to not wait, but instead do whatever you need to do after it completes in the completion itself.
If you must do it with a semaphore, move the start call to another thread.
answered Nov 23 '18 at 14:37
Lou FrancoLou Franco
74.3k14115173
74.3k14115173
add a comment |
add a comment |
So i found a solution:
SyncManager.swift
import Foundation
/// A generic Cocoa-Style completion handler
typealias CompletionHandler = (Error?) -> Void
/// Provides syncronous access to results returned by
/// asynchronous processes with completion handlers
class SyncMaker {
var result: Error? = nil
/// Generates a synchronous-compliant completion handler
func completion() -> CompletionHandler{
return {
(error: Error?) in
// Store result, return control
self.result = error
CFRunLoopStop(CFRunLoopGetCurrent())
}
}
// Perform task (that must use custom completion handler) and wait
func run(_ task: @escaping () -> Void) -> Error? {
task()
CFRunLoopRun()
return result
}
}
AppDelegate.swift (partly)
[...]
let syncMaker = SyncMaker()
let result = syncMaker.run {
sendOperation?.start(
syncMaker.completion())
}
if (result != nil) {
print("Error sending email: (result)")
} else {
sendingError = false
print("Successfully sent email!")
}
[...]
add a comment |
So i found a solution:
SyncManager.swift
import Foundation
/// A generic Cocoa-Style completion handler
typealias CompletionHandler = (Error?) -> Void
/// Provides syncronous access to results returned by
/// asynchronous processes with completion handlers
class SyncMaker {
var result: Error? = nil
/// Generates a synchronous-compliant completion handler
func completion() -> CompletionHandler{
return {
(error: Error?) in
// Store result, return control
self.result = error
CFRunLoopStop(CFRunLoopGetCurrent())
}
}
// Perform task (that must use custom completion handler) and wait
func run(_ task: @escaping () -> Void) -> Error? {
task()
CFRunLoopRun()
return result
}
}
AppDelegate.swift (partly)
[...]
let syncMaker = SyncMaker()
let result = syncMaker.run {
sendOperation?.start(
syncMaker.completion())
}
if (result != nil) {
print("Error sending email: (result)")
} else {
sendingError = false
print("Successfully sent email!")
}
[...]
add a comment |
So i found a solution:
SyncManager.swift
import Foundation
/// A generic Cocoa-Style completion handler
typealias CompletionHandler = (Error?) -> Void
/// Provides syncronous access to results returned by
/// asynchronous processes with completion handlers
class SyncMaker {
var result: Error? = nil
/// Generates a synchronous-compliant completion handler
func completion() -> CompletionHandler{
return {
(error: Error?) in
// Store result, return control
self.result = error
CFRunLoopStop(CFRunLoopGetCurrent())
}
}
// Perform task (that must use custom completion handler) and wait
func run(_ task: @escaping () -> Void) -> Error? {
task()
CFRunLoopRun()
return result
}
}
AppDelegate.swift (partly)
[...]
let syncMaker = SyncMaker()
let result = syncMaker.run {
sendOperation?.start(
syncMaker.completion())
}
if (result != nil) {
print("Error sending email: (result)")
} else {
sendingError = false
print("Successfully sent email!")
}
[...]
So i found a solution:
SyncManager.swift
import Foundation
/// A generic Cocoa-Style completion handler
typealias CompletionHandler = (Error?) -> Void
/// Provides syncronous access to results returned by
/// asynchronous processes with completion handlers
class SyncMaker {
var result: Error? = nil
/// Generates a synchronous-compliant completion handler
func completion() -> CompletionHandler{
return {
(error: Error?) in
// Store result, return control
self.result = error
CFRunLoopStop(CFRunLoopGetCurrent())
}
}
// Perform task (that must use custom completion handler) and wait
func run(_ task: @escaping () -> Void) -> Error? {
task()
CFRunLoopRun()
return result
}
}
AppDelegate.swift (partly)
[...]
let syncMaker = SyncMaker()
let result = syncMaker.run {
sendOperation?.start(
syncMaker.completion())
}
if (result != nil) {
print("Error sending email: (result)")
} else {
sendingError = false
print("Successfully sent email!")
}
[...]
answered Nov 25 '18 at 13:48
skilled-solutionsskilled-solutions
216
216
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53446533%2fswift-how-to-send-email-mail-in-appdelegate-fetch%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Are you sure
sendOperation
is not-nil when you callstart
? Theres nothing special about an object that adoptsUIApplicationDelegate
– Warren Burton
Nov 23 '18 at 12:23
@Warren Burton Im not sure, but i just copy and pasted it from the button code where it worked so i doesnt bothered. I will check this but shouldnt it crash if i call start() on a nil object?
– skilled-solutions
Nov 23 '18 at 12:25
sendOperation
appears to beOptional
from your code. You can see that fromsendOperation?
using optional chaining.– Warren Burton
Nov 23 '18 at 12:41
@Warren Burton Now i see what you mean. I will check if it is nil.
– skilled-solutions
Nov 23 '18 at 12:49
@WarrenBurton It is not nil, i added a check and start is executed.
– skilled-solutions
Nov 23 '18 at 12:56