Core Data Many-To-Many relationship - core-data

I have a sample app that I am working through some Swift & Core Data work before moving the code over to the real app. I have a need for a Many-To-Many relationship. The sample below shows you the One-To-Many that works just fine using the default boiler coded when you create a new app in Xcode and selecting Core Data.
import UIKit
import CoreData
class ViewController: UIViewController {
let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext
let appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
var teamInformation:TeamInformation?
var playerInformation:PlayerInformation?
var position:Position?
var rosterInformation:RosterInformation?
var positionsSet = NSMutableSet()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
loadData()
}
func loadData() {
//Team Information
var newTeamInformation1 = NSEntityDescription.insertNewObjectForEntityForName("TeamInformation", inManagedObjectContext: managedObjectContext!) as TeamInformation
newTeamInformation1.teamName = "Team 1"
var newTeamInformation2 = NSEntityDescription.insertNewObjectForEntityForName("TeamInformation", inManagedObjectContext: managedObjectContext!) as TeamInformation
newTeamInformation2.teamName = "Team 2"
var newTeamInformation3 = NSEntityDescription.insertNewObjectForEntityForName("TeamInformation", inManagedObjectContext: managedObjectContext!) as TeamInformation
newTeamInformation3.teamName = "Team 3"
var newTeamInformation4 = NSEntityDescription.insertNewObjectForEntityForName("TeamInformation", inManagedObjectContext: managedObjectContext!) as TeamInformation
newTeamInformation4.teamName = "Team 4"
var newTeamInformation5 = NSEntityDescription.insertNewObjectForEntityForName("TeamInformation", inManagedObjectContext: managedObjectContext!) as TeamInformation
newTeamInformation5.teamName = "Team 5"
//Save Data
appDelegate.saveContext()
//Player Information
var newPlayerInformation1 = NSEntityDescription.insertNewObjectForEntityForName("PlayerInformation", inManagedObjectContext: managedObjectContext!) as PlayerInformation
newPlayerInformation1.firstName = "Player 1"
var newPlayerInformation2 = NSEntityDescription.insertNewObjectForEntityForName("PlayerInformation", inManagedObjectContext: managedObjectContext!) as PlayerInformation
newPlayerInformation2.firstName = "Player 2"
var newPlayerInformation3 = NSEntityDescription.insertNewObjectForEntityForName("PlayerInformation", inManagedObjectContext: managedObjectContext!) as PlayerInformation
newPlayerInformation3.firstName = "Player 3"
var newPlayerInformation4 = NSEntityDescription.insertNewObjectForEntityForName("PlayerInformation", inManagedObjectContext: managedObjectContext!) as PlayerInformation
newPlayerInformation4.firstName = "Player 4"
var newPlayerInformation5 = NSEntityDescription.insertNewObjectForEntityForName("PlayerInformation", inManagedObjectContext: managedObjectContext!) as PlayerInformation
newPlayerInformation5.firstName = "Player 5"
//Save Data
appDelegate.saveContext()
//Positions
var newposition1 = NSEntityDescription.insertNewObjectForEntityForName("Position", inManagedObjectContext: managedObjectContext!) as Position
newposition1.position = "C"
var newposition2 = NSEntityDescription.insertNewObjectForEntityForName("Position", inManagedObjectContext: managedObjectContext!) as Position
newposition2.position = "LW"
var newposition3 = NSEntityDescription.insertNewObjectForEntityForName("Position", inManagedObjectContext: managedObjectContext!) as Position
newposition3.position = "RW"
var newposition4 = NSEntityDescription.insertNewObjectForEntityForName("Position", inManagedObjectContext: managedObjectContext!) as Position
newposition4.position = "G"
var newposition5 = NSEntityDescription.insertNewObjectForEntityForName("Position", inManagedObjectContext: managedObjectContext!) as Position
newposition5.position = "D"
//Save Data
appDelegate.saveContext()
//Add players to Team 1 Roster
var newPlayerToAddToRoster1 = NSEntityDescription.insertNewObjectForEntityForName("RosterInformation", inManagedObjectContext: managedObjectContext!) as RosterInformation
newPlayerToAddToRoster1.rosterInformationToPlayerInformationRelationship = newPlayerInformation1
newPlayerToAddToRoster1.rosterInformationToTeamInformationRelationship = newTeamInformation1
newPlayerToAddToRoster1.rosterInformationToPositionRelationship = newposition4
newPlayerToAddToRoster1.playerNumber = "29"
//Save Data
appDelegate.saveContext()
var newPlayerToAddToRoster2 = NSEntityDescription.insertNewObjectForEntityForName("RosterInformation", inManagedObjectContext: managedObjectContext!) as RosterInformation
newPlayerToAddToRoster2.rosterInformationToPlayerInformationRelationship = newPlayerInformation2
newPlayerToAddToRoster2.rosterInformationToTeamInformationRelationship = newTeamInformation1
newPlayerToAddToRoster2.rosterInformationToPositionRelationship = newposition1
newPlayerToAddToRoster2.playerNumber = "5"
//Save Data
appDelegate.saveContext()
}
}
When I examine the tables in SQLite3, everything is working as expected and the relationships (ZROSTERINFORMATION) are functioning. So the next step is to move the Position Entity to Many. A play in the roster can have many positions and a Roster has many players.
sqlite> select * from ZPLAYERINFORMATION;
1|1|1|Player 4|
2|1|1|Player 3|
3|1|2|Player 2|
4|1|2|Player 1|
5|1|1|Player 5|
sqlite> select * from ZPOSITION;
1|2|2|C
2|2|1|D
3|2|1|LW
4|2|1|RW
5|2|2|G
sqlite> select * from ZROSTERINFORMATION;
1|3|1|4|5|3|29
2|3|1|3|1|3|5
sqlite> select * from ZTEAMINFORMATION;
1|4|1|Team 3
2|4|1|Team 4
3|4|3|Team 1
4|4|1|Team 5
5|4|1|Team 2
When I change to rosterInformationToPositionRelationship to Many-To-Many, it changes the relationship to an NSSet.
I thought by doing the following would satisfy the NSset:
//Add players to Team 1 Roster
var newPlayerToAddToRoster1 = NSEntityDescription.insertNewObjectForEntityForName("RosterInformation", inManagedObjectContext: managedObjectContext!) as RosterInformation
newPlayerToAddToRoster1.rosterInformationToPlayerInformationRelationship = newPlayerInformation1
newPlayerToAddToRoster1.rosterInformationToTeamInformationRelationship = newTeamInformation1
//Add multiple positions...
newPlayerToAddToRoster1.rosterInformationToPositionRelationship.setByAddingObject(newposition4)
newPlayerToAddToRoster1.rosterInformationToPositionRelationship.setByAddingObject(newposition5)
//Add player number
newPlayerToAddToRoster1.playerNumber = "29"
But by looking at the SQLite3 tables, but the player added should have 2 positions ("G" & "D") So it appears it's only taking the last entry.
sqlite> select * from ZROSTERINFORMATION;
1|3|1|2|2|29
2|3|1|3|2|5
sqlite> select * from ZPLAYERINFORMATION;
1|1|1|Player 3|
2|1|2|Player 1|
3|1|2|Player 2|
4|1|1|Player 4|
5|1|1|Player 5|
sqlite> select * from ZPOSITION;
1|2|1|C
2|2|1|D
3|2|1|LW
4|2|1|RW
5|2|1|G
So I tried this:
//Add players to Team 1 Roster
var newPlayerToAddToRoster1 = NSEntityDescription.insertNewObjectForEntityForName("RosterInformation", inManagedObjectContext: managedObjectContext!) as RosterInformation
newPlayerToAddToRoster1.rosterInformationToPlayerInformationRelationship = newPlayerInformation1
newPlayerToAddToRoster1.rosterInformationToTeamInformationRelationship = newTeamInformation1
//Add multiple positions...
positionsSet.setByAddingObject(newposition4)
positionsSet.setByAddingObject(newposition5)
newPlayerToAddToRoster1.rosterInformationToPositionRelationship.setByAddingObject(positionsSet)
//Add player number
newPlayerToAddToRoster1.playerNumber = "29"
When I check the SQLite3, I can see that once again it's only displaying the last object in the positionsSet NSMutableSet...
What am I doing wrong?
sqlite> select * from ZPLAYERINFORMATION;
1|1|1|Player 5|
2|1|2|Player 1|
3|1|1|Player 3|
4|1|2|Player 2|
5|1|1|Player 4|
sqlite> select * from ZPOSITION;
1|2|1|RW
2|2|1|G
3|2|1|D
4|2|1|C
5|2|1|LW
sqlite> select * from ZTEAMINFORMATION;
1|4|1|Team 5
2|4|3|Team 1
3|4|1|Team 2
4|4|1|Team 3
5|4|1|Team 4
sqlite> select * from ZROSTERINFORMATION;
1|3|1|2|2|29
2|3|1|4|2|5
When I change to the following code:
positionsSet.addObject(newposition4)
positionsSet.addObject(newposition5)
println("positionsSet \(positionsSet.description)");
Here is the output:
positionsSet {(
<One_To_Many.Position: 0x7fef8b492370> (entity: Position; id: 0xd000000000100004 <x-coredata://AE608FC7-7683-490E-A6E1-17D4F058D54A/Position/p4> ; data: {
position = G;
positionToRosterInformationRelationship = (
);
}),
<One_To_Many.Position: 0x7fef8b492540> (entity: Position; id: 0xd000000000140004 <x-coredata://AE608FC7-7683-490E-A6E1-17D4F058D54A/Position/p5> ; data: {
position = D;
positionToRosterInformationRelationship = (
);
})
)}
What am I missing?
class RosterInformation: NSManagedObject {
#NSManaged var playerNumber: String
#NSManaged var rosterInformationToPlayerInformationRelationship: PlayerInformation
#NSManaged var rosterInformationToPositionRelationship: NSSet
#NSManaged var rosterInformationToTeamInformationRelationship: TeamInformation
}
class Position: NSManagedObject {
#NSManaged var position: String
#NSManaged var positionToRosterInformationRelationship: NSSet
}
class TeamInformation: NSManagedObject {
#NSManaged var teamName: String
#NSManaged var teamInformationToRosterInformationRelationship: NSSet
}
class PlayerInformation: NSManagedObject {
#NSManaged var firstName: String
#NSManaged var lastName: String
#NSManaged var playerInformationToRosterInformationRelationship: NSSet
}

Related

Add dimension between link and element

i am tried to find the link wall face,but when i use the reference to create a new dimension , i will get result about 'invaild number of references'. i cant trans link face to active face.
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIDocument uidoc = commandData.Application.ActiveUIDocument;
Document doc = uidoc.Document;
var rf1 = uidoc.Selection.PickObject(ObjectType.PointOnElement, "select");
var element1 = doc.GetElement(rf1);
var location = element1.Location as LocationPoint;
var point = location.Point;
var rf2 = uidoc.Selection.PickObject(ObjectType.LinkedElement, "select");
var linkElement = doc.GetElement(rf2) as RevitLinkInstance;
var linkDoc = linkElement.GetLinkDocument();
var linkWall = linkDoc.GetElement(rf2.LinkedElementId) as Wall;
var wallLocation = linkWall.Location as LocationCurve;
var curve = wallLocation.Curve;
var cRf = curve.Reference;
var solid = BIMTools.Geometry.GetSolid(linkWall);
Face face = null;
foreach (var solidFace in solid.Faces)
{
XYZ normal = ((Face)solidFace).ComputeNormal(new UV(0, 0));
if (normal.Y < 0)
{
face = solidFace as Face;
break;
}
}
var viewLevel = uidoc.ActiveView.GenLevel.Elevation;
var tPoint = new XYZ(point.X,(face as PlanarFace).Origin.Y, viewLevel);
point = new XYZ(point.X, point.Y, viewLevel);
var line = Line.CreateBound(point, tPoint);
var references = new ReferenceArray();
references.Append(rf1);
references.Append(face.Reference);
using (Transaction trans = new Transaction(doc,"create"))
{
trans.Start();
var dimension = doc.Create.NewDimension(uidoc.ActiveView, line, references);
trans.Commit();
}
return Result.Succeeded;
}
The Building Coder provides a whole list of articles on creating dimensioning.

NaN is schown when a calculation has no value inside. How can "0" or "-" be displayed instead in SwiftUI

If a calculation is performed in SwiftUI and no values are added to the Textfield it displays "-NaN" (Not a Nummber?) instead.
How can a value (for example "0", "-") be displayed until values are inserted?
I have tried adding #State private var display = 0 but it displayed both values...
Example code:
struct ContentView: View {
#EnvironmentObject var userData: UserData
var Brutto: Double{
let price = Double(userData.BPrice) ?? 0
let rent = Double(userData.Rent) ?? 0
let Brutto = rent * 12 / price * 100
return Brutto
}
var body: some View {
VStack {
Text ("\(Brutto, specifier: "%.1f")")
}
// The UserData File:
class UserData : ObservableObject {
private static let userDefaultBPrice = "BPrice"
private static let userDefaultRent = "Rent"
#Published var BuyingPrice = UserDefaults.standard.string(forKey: UserData.userDefaultBPrice) ?? ""
{
didSet {
UserDefaults.standard.set(self.BPrice, forKey: UserData.userDefaultBPrice)
}
}
#Published var Rent = UserDefaults.standard.string(forKey: UserData.userDefaultRent) ?? "" {
didSet {
UserDefaults.standard.set(self.Rent, forKey: UserData.userDefaultRent)
}
}
private var canc: AnyCancellable!
}
Thanks
Here is possible approach
VStack {
Text ("\(Brutto.isNaN ? 0 : Brutto, specifier: "%.1f")")
}

How to Sum in Core Data

I have a data model like this:
I want to get a sum list by group by catalog.item,money.year,money.month, and I have tried to do it in several ways which is found in internet, but I failed.
I have tried "let fetchRequest = NSFetchRequest(entityName:"CashFlow")" and "let fetchRequest = NSFetchRequest< CashFlow >(entityName:"CashFlow")"
It is always the same error:Printing description of fetchRequest:
expression produced error: error: /var/folders/8j/g0yb8vwx23z2s1qykxz2q7hh0000gn/T/expr51-6487f6..swift:1:65: error: use of undeclared type 'CoreData'
Swift._DebuggerSupport.stringForPrintObject(Swift.UnsafePointer>(bitPattern: 0x127497460)!.pointee)
class MonthlySum {
public var year:Int16 = 0
public var month:Int16 = 0
public var emoji:String = ""
public var item:String = ""
public var budget:Int16 = 0
public var total:Int16 = 0
}
//I also have tried to define MonthlySum as NSManagedObject
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName:"CashFlow")
// Set the batch size to a suitable number.
//fetchRequest.fetchBatchSize = 32
fetchRequest.predicate = NSPredicate(format: "money.year = %d and money.month = %d",year,month)
// sort by day
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "money.cata.item", ascending: true)]
//group by day for sum
//fetchRequest.propertiesToGroupBy = ["money.cata.emoji","money.cata.item","money.budget"]
var expressionDescriptions = [AnyObject]()
var expD = NSExpressionDescription()
// select year
expD.name = "year"
expD.expression = NSExpression(forKeyPath: "money.year")
expD.expressionResultType = .integer16AttributeType
expressionDescriptions.append(expD)
// select month
expD.name = "month"
expD.expression = NSExpression(forKeyPath: "money.month")
expD.expressionResultType = .integer16AttributeType
expressionDescriptions.append(expD)
// select category item
expD.name = "item"
expD.expression = NSExpression(forKeyPath: "money.cata.item")
expD.expressionResultType = .stringAttributeType
expressionDescriptions.append(expD)
// select category emoji
expD.name = "emoji"
expD.expression = NSExpression(forKeyPath: "money.cata.emoji")
expD.expressionResultType = .stringAttributeType
expressionDescriptions.append(expD)
// select month
expD.name = "budget"
expD.expression = NSExpression(forKeyPath: "money.budget")
expD.expressionResultType = .integer16AttributeType
expressionDescriptions.append(expD)
//select #sum.amount as dailysum
expD = NSExpressionDescription()
expD.name = "total"
expD.expression = NSExpression(forFunction: "sum:", arguments: [NSExpression(forKeyPath: "amount")])
expD.expressionResultType = .integer16AttributeType
expressionDescriptions.append(expD)
fetchRequest.propertiesToFetch = expressionDescriptions
fetchRequest.resultType = .dictionaryResultType
var result = [MonthlySum]()
let m = MonthlySum()
do {
let fetchResult = try viewContext.fetch(fetchRequest) as! [MonthlySum]
/*
for item in fetchResult {
m.budget = item.value(forKey: "budget") as! Int16
m.emoji = item.value(forKey: "emoji") as! String
m.item = item.value(forKey: "item") as! String
m.month = item.value(forKey: "month") as! Int16
m.total = item.value(forKey: "total") as! Int16
m.year = item.value(forKey: "year") as! Int16
result.append(m)
} */
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
no matter what it works as this:
let fetchRequest = NSFetchRequest<NSDictionary>(entityName:"Trade")
fetchRequest.predicate = NSPredicate(format: "year = %d and month = %d",year,month)
// sort by day
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "day", ascending: true)]
//group by day for sum
fetchRequest.propertiesToGroupBy = ["day"]
var expressionDescriptions = [AnyObject]()
var expD = NSExpressionDescription()
// select day
expD.name = "day"
expD.expression = NSExpression(forKeyPath: "day")
expD.expressionResultType = .integer16AttributeType
expressionDescriptions.append(expD)
//select #sum.amount as dailysum
expD = NSExpressionDescription()
expD.name = "total"
expD.expression = NSExpression(forFunction: "sum:", arguments: [NSExpression(forKeyPath: "amount")])
expD.expressionResultType = .integer16AttributeType
expressionDescriptions.append(expD)
fetchRequest.propertiesToFetch = expressionDescriptions
fetchRequest.resultType = .dictionaryResultType
var result = [Int:String]()
do {
let fetchResult = try viewContext.fetch(fetchRequest)
for item in fetchResult {
result[item.value(forKey: "day") as! Int] = String(describing: item.value(forKey: "total") as! Int)}
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
return result

fetch core data string and place in a label (Swift4)

I am trying to call 2 different core data strings and place them each on separate labels. Right now I am getting the error Cannot invoke initializer for type 'init(_:)' with an argument list of type '([NSManagedObject])'. This error is coming from j1.text = String(itemsName). I added both view controllers for saving and displaying.
import UIKit
import CoreData
class ViewController: UIViewController {
#IBOutlet var j1 : UITextField!
#IBOutlet var j2 : UITextField!
#IBAction func save(){
let appD = UIApplication.shared.delegate as! AppDelegate
let context = appD.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Team", in : context)!
let theTitle = NSManagedObject(entity: entity, insertInto: context)
theTitle.setValue(j1.text, forKey: "score")
theTitle.setValue(j2.text, forKey: "alba")
do {
try context.save()
}
catch {
print("Tom Corley")
}
}}
class twoVC: UIViewController {
#IBOutlet var j1 : UILabel!
#IBOutlet var j2 : UILabel!
var itemsName : [NSManagedObject] = []
var itemsName2 : [NSManagedObject] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let appD = UIApplication.shared.delegate as! AppDelegate
let context = appD.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Team")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "score", ascending: true)]
let fetchRequest2 = NSFetchRequest<NSManagedObject>(entityName: "Team")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "alba", ascending: true)]
do {
itemsName = try context.fetch(fetchRequest)
itemsName2 = try context.fetch(fetchRequest2)
if let score = itemsName[0].value(forKey: "score") {
j1.text = (score as! String)
}
if let alba = itemsName2[0].value(forKey: "alba") {
j2.text = (alba as? String)
}
}catch {
print("Ashley Tisdale")
}
}}
Loop over the result from the fetch and append to a string that is then used as value for the label, this goes inside the do{...} where you do the fetch today. Note that I am only using one fetch request here.
itemsName = try context.fetch(fetchRequest)
var mergedScore: String = ""
var mergedAlba: String = ""
for item in itemsName {
if let score = item.value(forKey: "score") as? String {
mergedScore.append(score)
mergedScore.append(" ") //separator
}
if let alba = item.value(forKey: "alba") as? String {
mergedScore.append(alba)
mergedScore.append(" ") //separator
}
}
j1.text = mergedScore
j2.text = mergedAlba
Try this one it's Working for me Swift 4 I think You need to store the value as int which are used as sortDescriptor.
func FetchManagedObjectFromDatabaseForStoreData(Entity :NSEntityDescription) ->
[NSManagedObject]
{
let fetchRequest = NSFetchRequest<NSFetchRequestResult>()
// Add Sort Descriptor
let sortDescriptor = NSSortDescriptor(key: "order", ascending: true)
let sortDescriptor1 = NSSortDescriptor(key: "is_favourite", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor,sortDescriptor1]
// Create Entity Description
fetchRequest.entity = Entity
let result : [NSManagedObject] = []
// Execute Fetch Request
do{
let result = try appDelegate.managedObjectContext.fetch(fetchRequest) as! [NSManagedObject]
if result.count > 0
{
return result
}
else
{
// return result
}
}
catch{
let fetchError = error as NSError
print(fetchError)
}
return result
}
For Fetch Data
// Create Entity Description
let entityDescription = NSEntityDescription.entity(forEntityName: "Your Entity Name Here", in: appDel.managedObjectContext)
let DataObject = FetchManagedObjectFromDatabaseForStoreData(Entity: entityDescription!)
//Convert Array of NSManagedObject into array of [String:AnyObject]
for item in DataObject{
let keys = Array(item.entity.attributesByName.keys)
// Here is your result
print((item.dictionaryWithValues(forKeys: keys) as NSDictionary).value(forKey: "id") as Any) // And so On Whatewer you Fetch
}

How to use the ThumbnailCard in IDialog Context

Hi I am developing one bot using Microsoft botframework project in that I am using IDialog interface. In that I am using the ThumbnailCard for displaying the cards. Here when I am attaching some data to my cards and the data is attaching properly but within the PostAsync method it’s not providing the reply.
public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)
{
ThumbnailCard plCard = null;
IMessageActivity replyToConversation =await argument;
replyToConversation.Type = "message";
replyToConversation.Attachments = new List<Attachment>();
replyToConversation.Text = "welcome to book my show";
Dictionary<string, string> cardContentList = new Dictionary<string, string>();
cardContentList.Add("Jason Bourne", "URL");
cardContentList.Add("The Land", "URL");
cardContentList.Add("Yoga Hosers", "URL");
foreach (KeyValuePair<string, string> cardContent in cardContentList)
{
List<CardImage> cardImages = new List<CardImage>();
cardImages.Add(new CardImage(url: cardContent.Value));
List<CardAction> cardButtons = new List<CardAction>();
if (cardContent.Key == "Jason Bourne")
{
CardAction plButton1 = new CardAction()
{
Value = $"",
Type = "openUrl",
Title = "Book Now"
};
CardAction plButton2 = new CardAction()
{
Value = "tel:1-800-800-5705",
Type = "call",
Title = "Show timings"
};
cardButtons.Add(plButton1);
cardButtons.Add(plButton2);
plCard = new ThumbnailCard()
{
Title = $"Jason Bourne",
Subtitle = " ",
Images = cardImages,
Buttons = cardButtons,
};
Attachment plAttachment = plCard.ToAttachment();
replyToConversation.Attachments.Add(plAttachment);
}
else if (cardContent.Key == "The Land")
{
CardAction plButton1 = new CardAction()
{
Value = $"",
Type = "openUrl",
Title = "Book Now"
};
CardAction plButton2 = new CardAction()
{
Value = "tel:1-800-800-5705",
Type = "call",
Title = "Show Timings"
};
cardButtons.Add(plButton1);
cardButtons.Add(plButton2);
plCard = new ThumbnailCard()
{
Title = $"The Land",
Subtitle = "",
Images = cardImages,
Buttons = cardButtons,
};
Attachment plAttachment = plCard.ToAttachment();
replyToConversation.Attachments.Add(plAttachment);
}
else if (cardContent.Key == "Yoga Hosers")
{
CardAction plButton1 = new CardAction()
{
Value = $"",
Type = "openUrl",
Title = "Book Now"
};
CardAction plButton2 = new CardAction()
{
Value = "tel:1-800-800-5705",
Type = "call",
Title = "Show timings"
};
cardButtons.Add(plButton1);
cardButtons.Add(plButton2);
plCard = new ThumbnailCard()
{
Title = $"Yoga Hosers",
Subtitle = "",
Images = cardImages,
Buttons = cardButtons,
};
Attachment plAttachment = plCard.ToAttachment();
replyToConversation.Attachments.Add(plAttachment);
}
}
replyToConversation.AttachmentLayout = AttachmentLayoutTypes.List;
await context.PostAsync(replyToConversation);
}
When I run the bot its show the following error
Can we use cards in IDialog Context for attachments?
The issue is with the IMessageActivity, you are trying to send IMessageActicity in context.PostAsync. That's the reason it is failing.
Do the following changes to make it work
Change the method signature like below
private async Task messageReceived(IDialogContext context, IAwaitable<object> argument)
and modify the IMessageActivity replyToConversation =await argument; to like below
var message = await argument as Activity;
Activity replyToConversation = message.CreateReply("Welcome." + "(Hi)");
replyToConversation.Recipient = message.From;
Now it should work, if you still have issue please comment here.
-Kishore

Resources