Author Archive Tobias Stephan

ByTobias Stephan

Amazon MWS XML Feed Sample CountryOfOrigin

The CountryOfOrigin field is now a required field when sending product feeds via Amazon MWS Api. Actually a small thing, but sometimes it is a real struggle to figure out where to insert the value. Important to know…the country code is entered with 2 characters as value, so here in the example with UK.

<?xml version=“1.0” encoding=“UTF-8”?> <AmazonEnvelope> <Header> <DocumentVersion>1.01</DocumentVersion> <MerchantIdentifier>A2BKDHGADKHKH</MerchantIdentifier> </Header> <MessageType>Product</MessageType> <PurgeAndReplace>false</PurgeAndReplace> <Message> <MessageID>1</MessageID> <OperationType>Update</OperationType> <Product> <SKU>16001</SKU> <StandardProductID> <Type>ASIN</Type> <Value>B07TXABCD3</Value> </StandardProductID> <Condition> <ConditionType>New</ConditionType> <ConditionNote /> </Condition> <DescriptionData> <Title>Fork cable lug 10mm2 to 16mm2 M6 insulated 4x ring eye Press eye Crimp cable lug blue</Title> <Brand>eXODA</Brand> <Description>High-quality press eye of the manufacturer eXODA. This ring eyelet is characterised by the fact that a manufacturing process was used here, that guarantees accuracy. Diameter specifications for the cross section of the cable or screw inlet are exact and perfect. They can be pressed or soldered for correct processing. The unit in mm² describes the cross-section of the cable. The diameter of the opening for the eyelet is represented by the M specification in millimeters. The inside and outside diameters represent the diameter of the opening for the cable to be inserted. cable. When selecting the right article or the right press eye, it is important to pay attention, that the cable cross section and cable diameter are not the same. The cable cross section describes the area in mm² when looking at the interface. The insulation is made of nylon, we therefore recommend according to Open the package to consume the contents in 3 months.</Description> <BulletPoint>Suitable for cable cross section: 10mm2 to 16mm2 corresponds to 3.6 mm to 4.5 mm diameter</BulletPoint> <BulletPoint>Diameter of screw opening: 6 mm</BulletPoint> <BulletPoint>Inner diameter: 6 mm unpressed</BulletPoint> <BulletPoint>Diameter at the outer insulation Cable lug: 11 mm unpressed</BulletPoint> <BulletPoint>Diameter Insulation for cable entry inside: 9 mm outside: 11.7 mm</BulletPoint> <PackageDimensions> <Length unitOfMeasure=“CM”>10</Length> <Width unitOfMeasure=“CM”>9.8</Width> <Height unitOfMeasure=“CM”>1.2</Height> </PackageDimensions> <Manufacturer>eBrand</Manufacturer> <MfrPartNumber>16001</MfrPartNumber> <SearchTerms>car battery cable</SearchTerms> <SearchTerms>car battery cable connectors</SearchTerms> <RecommendedBrowseNode>1342892031</RecommendedBrowseNode> <CountryOfOrigin>DE</CountryOfOrigin> <IsExpirationDatedProduct>false</IsExpirationDatedProduct> </DescriptionData> <ProductData> <HomeImprovement> <ProductType> <Hardware /> </ProductType> </HomeImprovement> </ProductData> <IsHeatSensitive>false</IsHeatSensitive> </Product> </Message> </AmazonEnvelope>

“”< xsd:element name=”CountryOfOrigin” type=”CountryOfOriginType” minOccurs=”0″/>””

For the “CountryOfOriginType” attribute, the rules allow valid values as follows: “value=”[a-zA-Z][a-zA-Z]|unknown””

ByTobias Stephan

Flashforge 3D Printer experience

My advice is not to buy a device from Flashforge. No Adventurer 3, Dreamer, Inventor, Creator or guider. Simply none at all.

Well, I don’t know what to say. To develop an app, Apple requires the consent of the manufacturer. This is not understandable for me but it’s a fact.

My request to the company Flashforge to give me permission to access only the webcam stream was rejected. Apart from the fact that I cannot be forbidden to do so, I find the answer impudent. The rights of the pictures are not owned by Flashforge and if I buy a Mercedes, I don’t need permission from the manufacturer to move the steering wheel.

But Flashforge once refused. They forbid me to use the device the way I want to. So my conclusion is clear. I don’t like anything about this device, because I am not allowed to use it of my own free will. But actually you are right. Imagine someone bought a flower pot and had the idea to fill it with tea bags. Where would we go from there.

ByTobias Stephan

Generate Regex from String

Link to the Regex-Generator

I myself was looking for such a generator, because that is quite a fiddle. With this generator you can easily convert a string into a regex. This is a great basis to adjust the generated regex pattern. For this I use one of the numerous regex testers. There are enough of those.

ByTobias Stephan

Amazon account locked hotline

Here is the link to the contact form

If you can no longer log in as a seller, on Amazon as a seller has a real problem. This has also happened to me, for me it was a new credit card – it was not possible to click on the seller service and the entry of the new credit card number was not successful. “You look stupid out of the laundry!” – I just found a fresh link in Sellercentral more by chance and hope to help colleagues with it. It’s not a phone number, but it’s a form that you can contact.

Kontakt zum Amazon Verkäuferservice, wenn sonst mal nichts mehr geht
ByTobias Stephan

SwiftUI Menue Button example Hamburger Menu

Here you go. Here you have a ready sample for a Swift UI hamburger menu. You can easily hide the menu with a slide or tap on the hamburger symbol. Simply create a new SwiftUI project as a single app with the default settings. Simply copy and paste everything and play around with the project.

//
//  ContentView.swift
//  SlideMenuSwiftSample
//
//  Created by T. Stephan on 03.05.20.
//  Copyright © 2020 eCommerce - Tobias Stephan. All rights reserved.
//

import SwiftUI

struct ContentView: View {
    @State var showHamburgerMenu = false
    
    
    var body: some View {
        
        
        let drag = DragGesture()
            .onEnded {
                if $0.translation.width < -100 {
                    withAnimation {
                        self.showHamburgerMenu = false
                    }
                }
        }
        
        return NavigationView {
            GeometryReader { geometry in
                ZStack(alignment: .leading) {
                    MainView(showHamburgerMenu: self.$showHamburgerMenu)
                        .frame(width: geometry.size.width, height: geometry.size.height)
                        .offset(x: self.showHamburgerMenu ? geometry.size.width/2 : 0)
                        .disabled(self.showHamburgerMenu ? true : false)
                    
                    if self.showHamburgerMenu {
                        MenuView()
                            .frame(width: geometry.size.width/2)
                            .transition(.move(edge: .leading))
                    }
                }
                .gesture(drag)
                
            }
            .navigationBarTitle("Side Menu", displayMode: .inline)
            .navigationBarItems(leading: (
                Button(action: {
                    withAnimation {
                        self.showHamburgerMenu.toggle()
                    }
                }) {
                    Image(systemName: "line.horizontal.3")
                        .imageScale(.large)
                }
            ))
        }
        
    }
}

struct MainView: View {
    @Binding var showHamburgerMenu: Bool
    
    var body: some View {
        Button(action: {
            withAnimation {
                self.showHamburgerMenu = true
            }
        }) {
            Text("Show Menu")
        }
    }
}

struct MenuView: View {
    var body: some View {
        VStack(alignment: .leading) {
            HStack {
                Image(systemName: "person")
                    .foregroundColor(.gray)
                    .imageScale(.large)
                NavigationLink(destination: ProfileView()) {
                    Text("Profile")
                        .foregroundColor(.gray)
                        .font(.headline)
                }
            }
            .padding(.top, 100)
            HStack {
                Image(systemName: "envelope")
                    .foregroundColor(.gray)
                    .imageScale(.large)
                NavigationLink(destination: MessagesView()) {
                    Text("Messages")
                        .foregroundColor(.gray)
                        .font(.headline)
                }
            }
            .padding(.top, 30)
            HStack {
                Image(systemName: "gear")
                    .foregroundColor(.gray)
                    .imageScale(.large)
                NavigationLink(destination: SettingsView()) {
                    Text("Settings")
                        .foregroundColor(.gray)
                        .font(.headline)
                }
            }
            .padding(.top, 30)
            Spacer()
        }
        .padding()
        .frame(maxWidth: .infinity, alignment: .leading)
        .background(Color(red: 32/255, green: 32/255, blue: 32/255))
        .edgesIgnoringSafeArea(.all)
    }
}

struct SettingsView: View {
    var body: some View {
        VStack{
            Text("Settings Subview")
        }
    }
}
struct MessagesView: View {
    var body: some View {
        VStack{
            Text("Messages Subview")
        }
    }
}
struct ProfileView: View {
    var body: some View {
        VStack{
            Text("Profile Subview")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

ByTobias Stephan

Listory generates lists

Lists created with Listory are especially easy to share with others. You can work on the list simultaneously with several people. Imagine going shopping with your family. 4 people start to collect the things in the supermarket that are on the list. If you click on done…the item will disappear for you and the other users. But the entry reappears! That is the special thing about it! So your lists are reusable. This is a decisive advantage.

You can use the Listory Lister from eXODA for your daily tasks. That can also be shopping. Here Listory even has a special function. Listory can scan and store photos. If you take a photo of a product, others who have access to the lists will see how the product looks like.

What do I need the app for?
The App, which is currently only available for IOS, i.e. Apple devices, has a lot more functions. The App is available in a free and a paid version.

What about data protection?
Listory works just like that, without registration. How does that work? Listory Lister generates a unique token (key) the first time you use it. Whoever has the key has access! The key is in the link. So you should secure the link well. But we don’t know who you are and don’t want to know. Your data belongs to you!

Are cookies used?
Yes, but only for the basic function. Listory Lister recognizes that you have been there before and receives the key immediately. More cookies are not stored.

Schon Listory.net gecheckt?


Listory is the tool without account registration for quick listings. Tasks? Shopping list? …whatever, Listory helps you quickly and free of charge.

ByTobias Stephan

swiftui multiple pickers in a form

This is the first time I have used the Picker under SwiftUI. Simple insight – the OS decides which appearance your picker takes on. Of course you can decide that yourself. Now I had the strange behaviour that when I selected an entry of 5 pickers, all pickers were run through. My pickers are in a form. In this form a NavigationView. Solution of the problem was the Section. This example is not suitable for copy-paste because you are missing the data source. This is for illustration purposes only.

import SwiftUI

struct ContentView: View {
    @State public var selectedCrossSection = 0
    @State private var selectedColor = 0
    @State private var selectedLength = 0
    @State private var selectedEyelet1 = 0
    @State private var selectedEyelet2 = 0

    var selCrossSectionStr = ""

    @ObservedObject var oListDatasource = ListDataSource()
    var body: some View {

        NavigationView{

            VStack (spacing: 10) {
                Form {
                    Section {
                        Picker(selection: self.$selectedCrossSection, label: Text("Querschnitt")) {

                            ForEach(self.oListDatasource.CrossSections, id: \.self) { item in
                                Text(item.CrossSection).tag(item.rowIndex)
                            }
                        }
                            //.pickerStyle(SegmentedPickerStyle()).foregroundColor(Color.orange)

                            .font(Font.custom("ArialMT", size: 12))
                            .onReceive([self.selectedCrossSection].publisher.first()) { (value) in
                                print(self.oListDatasource.CrossSections[self.selectedCrossSection].CrossSection)

                        }
                    }
                    Section {
                        Picker(selection: self.$selectedColor, label: Text("Farbe")) {

                            ForEach(self.oListDatasource.Colors) { item in
                                Text(item.Color).tag(item.rowIndex)
                            }
                        }
                            //.pickerStyle(SegmentedPickerStyle()).foregroundColor(Color.orange)
                            .font(Font.custom("ArialMT", size: 12))
                    }

                    Section {
                        Picker(selection: self.$selectedLength, label: Text("Länge")) {

                            ForEach(self.oListDatasource.Lengths) { item in
                                Text(item.Length).tag(item.rowIndex)
                            }
                        }
                        .font(Font.custom("ArialMT", size: 12))
                    }

                Section {
                    Picker(selection: $selectedEyelet1, label: Text("Öse 1")) {

                        ForEach(oListDatasource.Eyelets) { item in
                            Text(item.Eyelet).tag(item.rowIndex)
                        }
                    }
                    .font(Font.custom("ArialMT", size: 12))
                }
                Section {
                    Picker(selection: $selectedEyelet2, label: Text("Öse 2")) {

                        ForEach(oListDatasource.Eyelets) { item in
                            Text(item.Eyelet).tag(item.rowIndex)
                        }
                    }
                    .font(Font.custom("ArialMT", size: 12))
                }
                }

            NavigationLink(destination: ListItems(selectedCrossSection: selectedCrossSection)) {
                Text("Liste").frame(width: 100)

            }
            }

            .navigationBarTitle("Kabelshop")

        }

    }
}
Mehrere Picker in einer View

Styles:

  • Navigation view style.
  • Wheel picker.
  • Segmented picker.
  • Date picker style.
ByTobias Stephan

SwiftUI Elements

Sr.No. UI Specific Elements
1 Text Fields

It is an UI element that enables the app to get user input.

2 Input types – TextFields

We can set the type of input that user can give by using the keyboard property of UITextField.

3 Buttons

It is used for handling user actions.

4 Label

It is used for displaying static content.

5 Toolbar

It is used if we want to manipulate something based on our current view.

6 Status Bar

It displays the key information of device.

7 Navigation Bar

It contains the navigation buttons of a navigation controller, which is a stack of view controllers which can be pushed and popped.

8 Tab bar

It is generally used to switch between various subtasks, views or models within the same view.

9 Image View

It is used to display a simple image or sequence of images.

10 Scroll View

It is used to display content that is more than the area of screen.

11 Table View

It is used for displaying scrollable list of data in multiple rows and sections.

12 Split View

It is used for displaying two panes with master pane controlling the information on detail pane.

13 Text View

It is used for diplaying scrollable list of text information that is optionally editable.

14 View Transition

It explains the various view transitions between views.

15 Pickers

It is used for displaying for selecting a specific data from a list.

16 Switches

It is used as disable and enable for actions.

17 Sliders

It is used to allow users to make adjustments to a value or process throughout a range of allowed values.

18 Alerts

It is used to give important information to users.

19 Icons

It is an image representation used for an action or depict something related to the application.

ByTobias Stephan

Swift UI Mac OS remove help menu

I now want to publish my app as a Mac OS app as well. This is now possible. During the check, however, the app was rejected because no help was stored and no help text was displayed when clicking on the Help menu. With the following addition I simply removed the superfluous menu items.

//Insert in AppDelegate.swift
override func buildMenu(with builder: UIMenuBuilder) {
        super.buildMenu(with: builder)
        /* Do something */
        builder.remove(menu: .view)
        builder.remove(menu: .format)
        builder.remove(menu: .edit)
        builder.remove(menu: .file)
        builder.remove(menu: .window)
        builder.remove(menu: .help)
}
ByTobias Stephan

Website-Watcher App track Sites

There will be the eXODA WebsiteWatch. An easy to use iPhone app that allows you to monitor a url for changes.
The app will be available in April 2020.

What makes the app special?
The website requests are handled externally by a server. So the app is not dependent on the goodwill of your IOS. What does that mean? The Apple IOS organizes the allocation of background computing capacity on your iPhone or iPad. Therefore it makes sense in this case to have an external server do the calculation and check for website changes. If you add a URL to your watchlist, it will be visited in regular intervals. The notification is a push message.