首页 \ 问答 \ Hibernate:如何使用@Embeddables的自定义集合?(Hibernate: How to use custom collection of @Embeddables?)

Hibernate:如何使用@Embeddables的自定义集合?(Hibernate: How to use custom collection of @Embeddables?)

我想为一组嵌入式使用自定义集合类型。 如何使用基于Java的配置使用Hibernate 4.3.8和Spring Boot?

我的嵌入式看起来像这样

@Embeddable
public class MyEmbeddable implements Entry<Object, Integer> {
}

具有一组嵌入式的实体看起来像这样

@Entity
public class MyOtherClass {
    @ElementCollection(fetch = FetchType.EAGER)
    private Set<MyEmbeddable> embeddables;
}   

我希望实现这样的目标

@Entity
public class MyOtherClass {
    @ElementCollection(fetch = FetchType.EAGER)
    private MyCustomSet embeddables;
}   

public class MyCustomSet extends HashSet<MyEmbeddable> {

    //some custom methods...

}

我尝试使用UserCollectionType@CollectionType但没有成功,并没有找到任何教程/示例。

MyCustomSet

public class MyCustomSet extends HashSet<MyEmbeddable> implements UserCollectionType {

    @Override
    public PersistentCollection instantiate(final SessionImplementor session, final CollectionPersister persister) throws HibernateException {
        return new PersistentSet();
    }

    @Override
    public PersistentCollection wrap(final SessionImplementor session, final Object collection) {
        return new PersistentSet(session, (Set) collection);
    }

    @Override
    public Iterator<Ingredient> getElementsIterator(final Object collection) {
        return ((Set<MyEmbeddable>) collection).iterator();
    }

    @Override
    public boolean contains(final Object collection, final Object entity) {
        return ((Set<MyEmbeddable>) collection).contains(entity);
    }

    @Override
    public Object indexOf(final Object collection, final Object entity) {
        return null;
    }

    @Override
    public Object replaceElements(final Object original, final Object target, final CollectionPersister persister, final Object owner, final Map copyCache,
            final SessionImplementor session) throws HibernateException {

        final Set originalSet = (Set) original;
        final Set targetSet = (Set) target;

        targetSet.clear();
        targetSet.addAll(originalSet);

        return targetSet;
    }

    @Override
    public Object instantiate(final int anticipatedSize) {
        return new MyCustomSet();
    }

}

我的实体与自定义集

@Entity
public class MyEntity {


    @ElementCollection(fetch = FetchType.EAGER)
    @CollectionType(type = "com.blubb.MyCustomSet")
    private MyCustomSet custom;

    public MyEntity() {
    }

    public MyEntity(final MyCustomSet custom) {
        this.custom = custom;
    }


    public MyCustomSet getCustom() {
        return this.custom;
    }

    public void setCustom(final MyCustomSet custom) {
        this.custom = custom;
    }

}

抛出异常是

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1566)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:956)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:747)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:100)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
    at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:259)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:261)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:219)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1239)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.access$600(EntityManagerFactoryBuilderImpl.java:120)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:855)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:845)
    at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:844)
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1625)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1562)
    ... 39 common frames omitted
Caused by: org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: com.blubb.MyEntity.custom
    at org.hibernate.cfg.annotations.CollectionBinder.getCollectionBinder(CollectionBinder.java:330)
    at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1922)
    at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:963)
    at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:796)
    at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3845)
    at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3799)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1412)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:852)
    ... 47 common frames omitted

I want to use a custom collection type for a set of embeddables. How to do this with Hibernate 4.3.8 and Spring Boot using a Java based configuration?

My embeddable looks like this

@Embeddable
public class MyEmbeddable implements Entry<Object, Integer> {
}

And the entity that has a set of this embeddable looks like this

@Entity
public class MyOtherClass {
    @ElementCollection(fetch = FetchType.EAGER)
    private Set<MyEmbeddable> embeddables;
}   

and I want to achieve something like this

@Entity
public class MyOtherClass {
    @ElementCollection(fetch = FetchType.EAGER)
    private MyCustomSet embeddables;
}   

with

public class MyCustomSet extends HashSet<MyEmbeddable> {

    //some custom methods...

}

I tried with UserCollectionType and @CollectionType but did not succeed and didnt find any tutorials/examples.

MyCustomSet

public class MyCustomSet extends HashSet<MyEmbeddable> implements UserCollectionType {

    @Override
    public PersistentCollection instantiate(final SessionImplementor session, final CollectionPersister persister) throws HibernateException {
        return new PersistentSet();
    }

    @Override
    public PersistentCollection wrap(final SessionImplementor session, final Object collection) {
        return new PersistentSet(session, (Set) collection);
    }

    @Override
    public Iterator<Ingredient> getElementsIterator(final Object collection) {
        return ((Set<MyEmbeddable>) collection).iterator();
    }

    @Override
    public boolean contains(final Object collection, final Object entity) {
        return ((Set<MyEmbeddable>) collection).contains(entity);
    }

    @Override
    public Object indexOf(final Object collection, final Object entity) {
        return null;
    }

    @Override
    public Object replaceElements(final Object original, final Object target, final CollectionPersister persister, final Object owner, final Map copyCache,
            final SessionImplementor session) throws HibernateException {

        final Set originalSet = (Set) original;
        final Set targetSet = (Set) target;

        targetSet.clear();
        targetSet.addAll(originalSet);

        return targetSet;
    }

    @Override
    public Object instantiate(final int anticipatedSize) {
        return new MyCustomSet();
    }

}

My entity with the custom set

@Entity
public class MyEntity {


    @ElementCollection(fetch = FetchType.EAGER)
    @CollectionType(type = "com.blubb.MyCustomSet")
    private MyCustomSet custom;

    public MyEntity() {
    }

    public MyEntity(final MyCustomSet custom) {
        this.custom = custom;
    }


    public MyCustomSet getCustom() {
        return this.custom;
    }

    public void setCustom(final MyCustomSet custom) {
        this.custom = custom;
    }

}

Throwns exception is

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1566)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:956)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:747)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:100)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
    at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:259)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:261)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:219)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1239)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.access$600(EntityManagerFactoryBuilderImpl.java:120)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:855)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:845)
    at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:844)
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1625)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1562)
    ... 39 common frames omitted
Caused by: org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: com.blubb.MyEntity.custom
    at org.hibernate.cfg.annotations.CollectionBinder.getCollectionBinder(CollectionBinder.java:330)
    at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1922)
    at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:963)
    at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:796)
    at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3845)
    at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3799)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1412)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:852)
    ... 47 common frames omitted

原文:https://stackoverflow.com/questions/29880263
更新时间:2022-03-03 13:03

最满意答案

尝试使用外围对象时出现的错误源于您将外围设备的名称添加到阵列而不是外围设备本身。 因此,替换

[_periferalDevices addObject:peripheral.name]; 

[_periferalDevices addObject:peripheral];

而且,显然,只要插入名称,您就必须修复。 例如,您的cellForRowAtIndexPath带有一行说明:

cell.textLabel.text = [_periferalDevices objectAtIndex:indexPath.row];

您可能希望用以下内容替换它:

CBPeripheral *peripheral = _periferalDevices[indexPath.row];
cell.textLabel.text = peripheral.name;

你的didDiscover...正在立即连接。 它可能不应该。 您应该只尝试连接用户选择的设备。 如果您再次尝试连接,这可能会导致问题(如果您尝试连接两次,我不知道它会怎么做)。 你的didSelectRow...连接用户选择的那些,所以你应该把它didSelectRow...

你说“我正面临着连接问题”。 那么,究竟是什么做过的didFailToConnectPeripheral报告?

顺便说一句,我不清楚你为什么两次调用discoverServices 。 要么发现所有服务(慢),要么只发现特定服务,但您可能不必同时执行这两项服务。


我的原始答案(基于原始代码示例)如下。


你有代码说:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    NSString *cellText = cell.textLabel.text;

    if([cellText isEqualToString:@""])
    {

    }
    else
    {
        UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"Connected to "
                                                      message:cellText delegate:self cancelButtonTitle:@"ok"
                                            otherButtonTitles: nil];
        [alert show];
    }

    _discoveredPeripheral.delegate = self;
    [self.centralManager connectPeripheral:_discoveredPeripheral options:nil];
    NSLog(@"discovered peripheral is %@", _discoveredPeripheral);
    NSString *datstr = [_discoveredPeripheral valueForKey:@"identifier"];
    NSLog(@"value for key is ........%@", datstr);
}

您正在检索所选单元格的信息(虽然Hot Licks是正确的,您应该转到模型,而不是查看该信息的视图),检索cellText ,但是您继续使用_discoveredPeripheral ,这是一个变量与用户刚刚选择的单元格没有明显的关系。

您希望维护外围设备阵列的模型,当用户点击单元时,使用indexPath.row在模型阵列中查找外设,并在连接代码中使用该CBPeripheral


The errors that you get when you try to use the peripheral object stems from the fact that you added the name of the peripheral to your array rather than the peripheral, itself. Thus, replace

[_periferalDevices addObject:peripheral.name]; 

With

[_periferalDevices addObject:peripheral];

And, obviously, you'll have to fix wherever you took advantage of just inserting the name. For example, your cellForRowAtIndexPath bears a line that says:

cell.textLabel.text = [_periferalDevices objectAtIndex:indexPath.row];

You'd probably want to replace that with something like:

CBPeripheral *peripheral = _periferalDevices[indexPath.row];
cell.textLabel.text = peripheral.name;

Your didDiscover... is connecting immediately. It probably shouldn't. You should probably only try connecting to the device the user selected. This could cause problems if you try to connect again (I don't know what it does if you try to connect twice). Your didSelectRow... connects on the ones the user chooses, so you should probably leave it at that.

You say "am facing problem connecting". So, what precisely did didFailToConnectPeripheral report?

As an aside, I'm unclear why you're calling discoverServices twice, too. Either discover all services (slow) or discover just the particular service, but you probably don't have to do both.


My original answer (based upon original code sample) is below.


You have code that says:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    NSString *cellText = cell.textLabel.text;

    if([cellText isEqualToString:@""])
    {

    }
    else
    {
        UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"Connected to "
                                                      message:cellText delegate:self cancelButtonTitle:@"ok"
                                            otherButtonTitles: nil];
        [alert show];
    }

    _discoveredPeripheral.delegate = self;
    [self.centralManager connectPeripheral:_discoveredPeripheral options:nil];
    NSLog(@"discovered peripheral is %@", _discoveredPeripheral);
    NSString *datstr = [_discoveredPeripheral valueForKey:@"identifier"];
    NSLog(@"value for key is ........%@", datstr);
}

You are retrieving the information on the selected cell (though Hot Licks is correct, you should be going to your model, not to the view for that information), retrieving the cellText, but you proceed to use _discoveredPeripheral, which is some variable that bears no obvious relation to the cell the user just selected.

You want to maintain your model of the array of peripherals, and when a user taps on the cell, use the indexPath.row to look up the peripheral in your model array, and use that CBPeripheral in your connection code.

相关问答

更多
  • 不,它不能。 要创建与任何外围设备的连接,该设备必须使用可连接的广告进行宣传。 想要连接的设备将必须通过连接请求回复其中一个广告。 No, it cannot. To create a connection to any peripheral device, that device would have to advertise using connectable advertising. The device that wants to connect, will then have to reply t ...
  • 尝试使用外围对象时出现的错误源于您将外围设备的名称添加到阵列而不是外围设备本身。 因此,替换 [_periferalDevices addObject:peripheral.name]; 同 [_periferalDevices addObject:peripheral]; 而且,显然,只要插入名称,您就必须修复。 例如,您的cellForRowAtIndexPath带有一行说明: cell.textLabel.text = [_periferalDevices objectAtIndex:index ...
  • 所有的答案都是肯定的,有一些自定义算法。 但是我必须提醒一下,在Android 4.3中,没有用户交互的连接是非常危险的。 由于存在错误,Android 4.3无法取消任何传出连接,并且没有连接超时的回调。 如果外围设备超出范围/电池耗尽/连接期间只是故障,手机的蓝牙堆栈将只是STUCK直到您重新启动手机。 如果用户在ui中启动连接,我们可以在用户出错时提醒用户,但如果您在后台自动启动连接,则可能会在没有用户了解最新情况的情况下破坏蓝牙。 All the answers are YES , with som ...
  • 是。 您可以使用标准Windows API来读取/写入GATT特征。 您可以选择Win32 API( https://msdn.microsoft.com/en-us/library/windows/hardware/hh450825 ( v=vs.85 ) .aspx )和较新的Windows RT API( https:// msdn.microsoft.com/en-us/library/windows/apps/windows.devices.bluetooth.genericattributepr ...
  • 蓝牙核心规范版本4在第200页上说明了这一点: “外围角色针对支持单一连接且不如中央设备复杂的设备进行了优化。支持外设角色的设备只需要支持Controller的从属角色的控制器.Central角色支持多个连接,是所有人的发起者与外围角色设备的连接。支持中心角色的设备需要一个支持Controller主角色的Controller,并且与其他LE GAP角色相比,通常支持更复杂的功能。 对我来说这看起来不对,但它并不像你希望的那样具体。 您可以在以下链接中找到bluetooth.com(以前称为bluetooth ...
  • 你根本没有提到它,但通过你提到的使用故事板的segue来判断。 使用故事板时,有一种新方法可以显示新的视图控制器。 通过使用seque将UITableViewCell连接到Interface Builder中的新视图控制器。 当你这样做时,不需要使用didSelectRowAtIndexPath:因为新的视图控制器会自动显示。 然而,你可以准备你的segue ,并在新视图控制器上设置参数,例如: - (void) prepareForSegue:(UIStoryboardSegue *)segue send ...
  • 属性: _readChar应该是CBCharacteristicPropertyRead _writeChar应该是CBCharacteristicPropertyWriteWithoutResponse 有关详细信息,请参见此处 CBCharacteristicPropertyNotify不允许该特性可写或可读,它只能通知(订阅/取消订阅)。 The properties for: _readChar should be CBCharacteristicPropertyRead _writeChar sh ...
  • 如果没有GuidedAccess或越狱手机,手机启动时无法运行应用程序。 您需要这样做才能将您的应用重新连接到外围设备。 请参阅: 使iOS应用程序在启动时运行 Without GuidedAccess or jailbreaking your phone, you can't run an app when the phone starts. You'd need to do that in order to reconnect your app to the peripheral. See: Make ...
  • 由于我在写完这个问题之后学到了很多蓝牙LE,并且没有人回答,我在这里写了一个答案。 两个设备之间的长时间关系通过绑定完成。 绑定导致两个设备交换和保存密钥,这些密钥将用于进一步连接以相互验证。 此外,密钥用于加密线路。 如果一般广告外围设备想要定位特定中心,则通过广告数据来实现。 核心规范补充(CSS)v6有两种数据类型可用于此目的: 公共目标地址 (1.13)和随机目标地址 (1.14)。 或者作为开发人员,您可以通过某种方式获得制造商特定数据 。 由于广告外围设备针对特定设备,因此可能会阻止来自其他中心 ...
  • 我最近没有检查,但我不认为PyBluez可以做BLE。 您在扫描时尝试连接的问题是某些硬件发生的已知问题。 这是某些硬件特有的问题。 基本上你需要停止扫描,建立你的L2CAP / GATT连接,然后重新开始扫描...或购买一个没有这个问题的不同加密狗。 我在Python中用BLE完成的所有工作都是模仿hcitool和gatttool在Python中的作用。 这很不幸,但是还没有库(我知道)还有BLE。 这是一个可以帮助您入门的代码片段: 使用python查找蓝牙低功耗 或者,您可以使用它提供的DBUS接口与 ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。